2023-06-03 08:59:04 +00:00
|
|
|
import { defineMigrations } from '@tldraw/store'
|
2023-06-03 08:27:44 +00:00
|
|
|
import { T } from '@tldraw/validate'
|
2024-01-03 12:13:15 +00:00
|
|
|
import { vecModelValidator } from '../misc/geometry-types'
|
2023-06-16 10:33:47 +00:00
|
|
|
import { DefaultColorStyle } from '../styles/TLColorStyle'
|
|
|
|
import { DefaultDashStyle } from '../styles/TLDashStyle'
|
|
|
|
import { DefaultFillStyle } from '../styles/TLFillStyle'
|
|
|
|
import { DefaultSizeStyle } from '../styles/TLSizeStyle'
|
|
|
|
import { ShapePropsType, TLBaseShape } from './TLBaseShape'
|
|
|
|
|
|
|
|
export const DrawShapeSegment = T.object({
|
|
|
|
type: T.literalEnum('free', 'straight'),
|
2024-01-03 12:13:15 +00:00
|
|
|
points: T.arrayOf(vecModelValidator),
|
2023-06-16 10:33:47 +00:00
|
|
|
})
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
/** @public */
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLDrawShapeSegment = T.TypeOf<typeof DrawShapeSegment>
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
/** @public */
|
2023-06-16 10:33:47 +00:00
|
|
|
export const drawShapeProps = {
|
|
|
|
color: DefaultColorStyle,
|
|
|
|
fill: DefaultFillStyle,
|
|
|
|
dash: DefaultDashStyle,
|
|
|
|
size: DefaultSizeStyle,
|
|
|
|
segments: T.arrayOf(DrawShapeSegment),
|
|
|
|
isComplete: T.boolean,
|
|
|
|
isClosed: T.boolean,
|
|
|
|
isPen: T.boolean,
|
2023-04-25 11:01:25 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/** @public */
|
2023-06-16 10:33:47 +00:00
|
|
|
export type TLDrawShapeProps = ShapePropsType<typeof drawShapeProps>
|
2023-04-25 11:01:25 +00:00
|
|
|
|
|
|
|
/** @public */
|
|
|
|
export type TLDrawShape = TLBaseShape<'draw', TLDrawShapeProps>
|
|
|
|
|
|
|
|
const Versions = {
|
|
|
|
AddInPen: 1,
|
|
|
|
} as const
|
|
|
|
|
2023-06-03 20:46:53 +00:00
|
|
|
/** @internal */
|
|
|
|
export const drawShapeMigrations = defineMigrations({
|
2023-04-25 11:01:25 +00:00
|
|
|
currentVersion: Versions.AddInPen,
|
|
|
|
migrators: {
|
|
|
|
[Versions.AddInPen]: {
|
|
|
|
up: (shape) => {
|
|
|
|
// Rather than checking to see whether the shape is a pen at runtime,
|
|
|
|
// from now on we're going to use the type of device reported to us
|
|
|
|
// as well as the pressure data received; but for existing shapes we
|
|
|
|
// need to check the pressure data to see if it's a pen or not.
|
|
|
|
|
|
|
|
const { points } = shape.props.segments[0]
|
|
|
|
|
|
|
|
if (points.length === 0) {
|
|
|
|
return {
|
|
|
|
...shape,
|
|
|
|
props: {
|
|
|
|
...shape.props,
|
|
|
|
isPen: false,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let isPen = !(points[0].z === 0 || points[0].z === 0.5)
|
|
|
|
|
|
|
|
if (points[1]) {
|
|
|
|
// Double check if we have a second point (we probably should)
|
|
|
|
isPen = isPen && !(points[1].z === 0 || points[1].z === 0.5)
|
|
|
|
}
|
|
|
|
|
|
|
|
return {
|
|
|
|
...shape,
|
|
|
|
props: {
|
|
|
|
...shape.props,
|
|
|
|
isPen,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
down: (shape) => {
|
|
|
|
const { isPen: _isPen, ...propsWithOutIsPen } = shape.props
|
|
|
|
return {
|
|
|
|
...shape,
|
|
|
|
props: {
|
|
|
|
...propsWithOutIsPen,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|