Adds manual create and update, more jsdoc
This commit is contained in:
parent
92b8df4b51
commit
16fda2fddf
13 changed files with 304 additions and 61 deletions
|
@ -1,6 +1,11 @@
|
|||
import * as React from 'react'
|
||||
import { TLDraw } from '@tldraw/tldraw'
|
||||
import { TLDraw, TLDrawState } from '@tldraw/tldraw'
|
||||
|
||||
export default function Editor(): JSX.Element {
|
||||
return <TLDraw id="tldraw" />
|
||||
const handleMount = React.useCallback((tlstate: TLDrawState) => {
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
window.tlstate = tlstate
|
||||
}, [])
|
||||
return <TLDraw id="tldraw" onMount={handleMount} />
|
||||
}
|
||||
|
|
|
@ -312,7 +312,7 @@ export class Rectangle extends TLDrawShapeUtil<RectangleShape> {
|
|||
}
|
||||
}
|
||||
|
||||
transformSingle(shape: RectangleShape, bounds: TLBounds) {
|
||||
transformSingle(_shape: RectangleShape, bounds: TLBounds) {
|
||||
return {
|
||||
size: Vec.round([bounds.width, bounds.height]),
|
||||
point: Vec.round([bounds.minX, bounds.minY]),
|
||||
|
|
|
@ -56,7 +56,7 @@ if (typeof window !== 'undefined') {
|
|||
export class Text extends TLDrawShapeUtil<TextShape> {
|
||||
type = TLDrawShapeType.Text as const
|
||||
toolType = TLDrawToolType.Text
|
||||
canChangeAspectRatio = false
|
||||
isAspectRatioLocked = true
|
||||
isEditableText = true
|
||||
canBind = true
|
||||
|
||||
|
@ -325,7 +325,7 @@ export class Text extends TLDrawShapeUtil<TextShape> {
|
|||
transformSingle(
|
||||
_shape: TextShape,
|
||||
bounds: TLBounds,
|
||||
{ initialShape, scaleX }: TLTransformInfo<TextShape>
|
||||
{ initialShape, scaleX, scaleY }: TLTransformInfo<TextShape>
|
||||
): Partial<TextShape> {
|
||||
const {
|
||||
style: { scale = 1 },
|
||||
|
@ -335,7 +335,7 @@ export class Text extends TLDrawShapeUtil<TextShape> {
|
|||
point: Vec.round([bounds.minX, bounds.minY]),
|
||||
style: {
|
||||
...initialShape.style,
|
||||
scale: scale * Math.abs(scaleX),
|
||||
scale: scale * Math.max(Math.abs(scaleY), Math.abs(scaleX)),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -369,7 +369,7 @@ export class Text extends TLDrawShapeUtil<TextShape> {
|
|||
}
|
||||
|
||||
shouldDelete(shape: TextShape): boolean {
|
||||
return shape.text.length === 0
|
||||
return shape.text.trim().length === 0
|
||||
}
|
||||
|
||||
// getBindingPoint(shape, point, origin, direction, expandDistance) {
|
||||
|
|
|
@ -16,3 +16,4 @@ export * from './delete-page'
|
|||
export * from './rename-page'
|
||||
export * from './duplicate-page'
|
||||
export * from './change-page'
|
||||
export * from './update'
|
||||
|
|
|
@ -44,7 +44,7 @@ describe('Move command', () => {
|
|||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['b'])
|
||||
tlstate.select('b')
|
||||
tlstate.moveToBack()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bacd')
|
||||
tlstate.undo()
|
||||
|
@ -56,21 +56,21 @@ describe('Move command', () => {
|
|||
describe('to back', () => {
|
||||
it('moves a shape to back', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['b'])
|
||||
tlstate.select('b')
|
||||
tlstate.moveToBack()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bacd')
|
||||
})
|
||||
|
||||
it('moves two adjacent siblings to back', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['b', 'c'])
|
||||
tlstate.select('b', 'c')
|
||||
tlstate.moveToBack()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bcad')
|
||||
})
|
||||
|
||||
it('moves two non-adjacent siblings to back', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['b', 'd'])
|
||||
tlstate.select('b', 'd')
|
||||
tlstate.moveToBack()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bdac')
|
||||
})
|
||||
|
@ -79,35 +79,35 @@ describe('Move command', () => {
|
|||
describe('backward', () => {
|
||||
it('moves a shape backward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['c'])
|
||||
tlstate.select('c')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('acbd')
|
||||
})
|
||||
|
||||
it('moves a shape at first index backward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['a'])
|
||||
tlstate.select('a')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||
})
|
||||
|
||||
it('moves two adjacent siblings backward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['c', 'd'])
|
||||
tlstate.select('c', 'd')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('acdb')
|
||||
})
|
||||
|
||||
it('moves two non-adjacent siblings backward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['b', 'd'])
|
||||
tlstate.select('b', 'd')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('badc')
|
||||
})
|
||||
|
||||
it('moves two adjacent siblings backward at zero index', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['a', 'b'])
|
||||
tlstate.select('a', 'b')
|
||||
tlstate.moveBackward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||
})
|
||||
|
@ -116,14 +116,14 @@ describe('Move command', () => {
|
|||
describe('forward', () => {
|
||||
it('moves a shape forward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['c'])
|
||||
tlstate.select('c')
|
||||
tlstate.moveForward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abdc')
|
||||
})
|
||||
|
||||
it('moves a shape forward at the top index', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['b'])
|
||||
tlstate.select('b')
|
||||
tlstate.moveForward()
|
||||
tlstate.moveForward()
|
||||
tlstate.moveForward()
|
||||
|
@ -132,21 +132,21 @@ describe('Move command', () => {
|
|||
|
||||
it('moves two adjacent siblings forward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['a', 'b'])
|
||||
tlstate.select('a', 'b')
|
||||
tlstate.moveForward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('cabd')
|
||||
})
|
||||
|
||||
it('moves two non-adjacent siblings forward', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['a', 'c'])
|
||||
tlstate.select('a', 'c')
|
||||
tlstate.moveForward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('badc')
|
||||
})
|
||||
|
||||
it('moves two adjacent siblings forward at top index', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['c', 'd'])
|
||||
tlstate.select('c', 'd')
|
||||
tlstate.moveForward()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||
})
|
||||
|
@ -155,28 +155,28 @@ describe('Move command', () => {
|
|||
describe('to front', () => {
|
||||
it('moves a shape to front', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['b'])
|
||||
tlstate.select('b')
|
||||
tlstate.moveToFront()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('acdb')
|
||||
})
|
||||
|
||||
it('moves two adjacent siblings to front', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['a', 'b'])
|
||||
tlstate.select('a', 'b')
|
||||
tlstate.moveToFront()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('cdab')
|
||||
})
|
||||
|
||||
it('moves two non-adjacent siblings to front', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['a', 'c'])
|
||||
tlstate.select('a', 'c')
|
||||
tlstate.moveToFront()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('bdac')
|
||||
})
|
||||
|
||||
it('moves siblings already at front to front', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.setSelectedIds(['c', 'd'])
|
||||
tlstate.select('c', 'd')
|
||||
tlstate.moveToFront()
|
||||
expect(getSortedShapeIds(tlstate.state)).toBe('abcd')
|
||||
})
|
||||
|
|
|
@ -26,7 +26,7 @@ describe('Toggle command', () => {
|
|||
|
||||
it('toggles on before off when mixed values', () => {
|
||||
tlstate.loadDocument(mockDocument)
|
||||
tlstate.setSelectedIds(['rect2'])
|
||||
tlstate.select('rect2')
|
||||
expect(tlstate.getShape<RectangleShape>('rect1').isAspectRatioLocked).toBe(undefined)
|
||||
expect(tlstate.getShape<RectangleShape>('rect2').isAspectRatioLocked).toBe(undefined)
|
||||
tlstate.toggleAspectRatioLocked()
|
||||
|
|
1
packages/tldraw/src/state/command/update/index.ts
Normal file
1
packages/tldraw/src/state/command/update/index.ts
Normal file
|
@ -0,0 +1 @@
|
|||
export * from './update.command'
|
|
@ -0,0 +1,19 @@
|
|||
import { TLDrawState } from '~state'
|
||||
import { mockDocument } from '~test'
|
||||
import { Utils } from '@tldraw/core'
|
||||
|
||||
const doc = Utils.deepClone(mockDocument)
|
||||
|
||||
describe('Move command', () => {
|
||||
const tlstate = new TLDrawState()
|
||||
|
||||
it('does, undoes and redoes command', () => {
|
||||
tlstate.loadDocument(doc)
|
||||
tlstate.updateShapes({ id: 'rect1', point: [100, 100] })
|
||||
expect(tlstate.getShape('rect1').point).toStrictEqual([100, 100])
|
||||
tlstate.undo()
|
||||
expect(tlstate.getShape('rect1').point).toStrictEqual([0, 0])
|
||||
tlstate.redo()
|
||||
expect(tlstate.getShape('rect1').point).toStrictEqual([100, 100])
|
||||
})
|
||||
})
|
47
packages/tldraw/src/state/command/update/update.command.ts
Normal file
47
packages/tldraw/src/state/command/update/update.command.ts
Normal file
|
@ -0,0 +1,47 @@
|
|||
import type { Data, TLDrawCommand, PagePartial, TLDrawShape } from '~types'
|
||||
import { TLDR } from '~state/tldr'
|
||||
|
||||
export function update(
|
||||
data: Data,
|
||||
updates: ({ id: string } & Partial<TLDrawShape>)[]
|
||||
): TLDrawCommand {
|
||||
const ids = updates.map((update) => update.id)
|
||||
|
||||
const before: PagePartial = {
|
||||
shapes: {},
|
||||
bindings: {},
|
||||
}
|
||||
|
||||
const after: PagePartial = {
|
||||
shapes: {},
|
||||
bindings: {},
|
||||
}
|
||||
|
||||
const change = TLDR.mutateShapes(
|
||||
data,
|
||||
ids,
|
||||
(_shape, i) => updates[i],
|
||||
data.appState.currentPageId
|
||||
)
|
||||
|
||||
before.shapes = change.before
|
||||
after.shapes = change.after
|
||||
|
||||
return {
|
||||
id: 'translate_shapes',
|
||||
before: {
|
||||
document: {
|
||||
pages: {
|
||||
[data.appState.currentPageId]: before,
|
||||
},
|
||||
},
|
||||
},
|
||||
after: {
|
||||
document: {
|
||||
pages: {
|
||||
[data.appState.currentPageId]: after,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
import { TextShape, TLDrawShape, TLDrawStatus } from '~types'
|
||||
import { TextShape, TLDrawStatus } from '~types'
|
||||
import type { Session } from '~types'
|
||||
import type { Data } from '~types'
|
||||
import { TLDR } from '~state/tldr'
|
||||
|
|
|
@ -24,6 +24,7 @@ export class TransformSession implements Session {
|
|||
|
||||
start = () => void null
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
update = (data: Data, point: number[], isAspectRatioLocked = false, _altKey = false) => {
|
||||
const {
|
||||
transformType,
|
||||
|
@ -37,7 +38,7 @@ export class TransformSession implements Session {
|
|||
const newBoundingBox = Utils.getTransformedBoundingBox(
|
||||
initialBounds,
|
||||
transformType,
|
||||
Vec.vec(this.origin, point),
|
||||
Vec.sub(point, this.origin),
|
||||
pageState.boundsRotation,
|
||||
isAspectRatioLocked || isAllAspectRatioLocked
|
||||
)
|
||||
|
|
|
@ -668,8 +668,6 @@ export class TLDR {
|
|||
next = this.onChildrenChange(data, next, pageId) || next
|
||||
}
|
||||
|
||||
// data.page.shapes[next.id] = next
|
||||
|
||||
return next
|
||||
}
|
||||
|
||||
|
|
|
@ -135,14 +135,14 @@ export class TLDrawState extends StateManager<Data> {
|
|||
}
|
||||
/* -------------------- Internal -------------------- */
|
||||
|
||||
protected onStateWillChange = (_state: Data, id: string): void => {
|
||||
if (!id.startsWith('patch')) {
|
||||
this.selectHistory.stack = [[]]
|
||||
this.selectHistory.pointer = 0
|
||||
}
|
||||
}
|
||||
// protected onStateWillChange = (_state: Data, id: string): void => {
|
||||
// }
|
||||
|
||||
protected onStateDidChange = (state: Data, id: string): void => {
|
||||
if (!id.startsWith('patch')) {
|
||||
this.clearSelectHistory()
|
||||
}
|
||||
|
||||
this._onChange?.(this, state, id)
|
||||
}
|
||||
|
||||
|
@ -531,7 +531,9 @@ export class TLDrawState extends StateManager<Data> {
|
|||
|
||||
loadDocument = (document: TLDrawDocument, onChange?: TLDrawState['_onChange']): this => {
|
||||
this._onChange = onChange
|
||||
this.deselectAll()
|
||||
this.resetHistory()
|
||||
this.clearSelectHistory()
|
||||
|
||||
// this.selectHistory.pointer = 0
|
||||
// this.selectHistory.stack = [[]]
|
||||
|
@ -942,7 +944,13 @@ export class TLDrawState extends StateManager<Data> {
|
|||
this.selectHistory.stack.push(ids)
|
||||
}
|
||||
|
||||
setSelectedIds(ids: string[], push = false): this {
|
||||
/**
|
||||
* Set the current selection.
|
||||
* @param ids The ids to select
|
||||
* @param push Whether to add the ids to the current selection instead.
|
||||
* @returns this
|
||||
*/
|
||||
private setSelectedIds(ids: string[], push = false): this {
|
||||
return this.patchState(
|
||||
{
|
||||
appState: {
|
||||
|
@ -961,6 +969,10 @@ export class TLDrawState extends StateManager<Data> {
|
|||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Undo the most recent selection.
|
||||
* @returns this
|
||||
*/
|
||||
undoSelect(): this {
|
||||
if (this.selectHistory.pointer > 0) {
|
||||
this.selectHistory.pointer--
|
||||
|
@ -969,6 +981,10 @@ export class TLDrawState extends StateManager<Data> {
|
|||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Redo the previous selection.
|
||||
* @returns this
|
||||
*/
|
||||
redoSelect(): this {
|
||||
if (this.selectHistory.pointer < this.selectHistory.stack.length - 1) {
|
||||
this.selectHistory.pointer++
|
||||
|
@ -977,12 +993,21 @@ export class TLDrawState extends StateManager<Data> {
|
|||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Select one or more shapes.
|
||||
* @param ids The shape ids to select.
|
||||
* @returns this
|
||||
*/
|
||||
select = (...ids: string[]): this => {
|
||||
this.setSelectedIds(ids)
|
||||
this.addToSelectHistory(ids)
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Select all shapes on the page.
|
||||
* @returns this
|
||||
*/
|
||||
selectAll = (): this => {
|
||||
if (this.session) return this
|
||||
this.setSelectedIds(Object.keys(this.page.shapes))
|
||||
|
@ -993,6 +1018,10 @@ export class TLDrawState extends StateManager<Data> {
|
|||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Deselect any selected shapes.
|
||||
* @returns this
|
||||
*/
|
||||
deselectAll = (): this => {
|
||||
this.setSelectedIds([])
|
||||
this.addToSelectHistory(this.selectedIds)
|
||||
|
@ -1003,66 +1032,213 @@ export class TLDrawState extends StateManager<Data> {
|
|||
/* Shape Functions */
|
||||
/* -------------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Manually create shapes on the page.
|
||||
* @param shapes An array of shape partials, containing the initial props for the shapes.
|
||||
* @command
|
||||
* @returns this
|
||||
*/
|
||||
createShapes = (
|
||||
...shapes: ({ id: string; type: TLDrawShapeType } & Partial<TLDrawShape>)[]
|
||||
): this => {
|
||||
if (shapes.length === 0) return this
|
||||
return this.create(
|
||||
...shapes.map((shape) => {
|
||||
return TLDR.getShapeUtils(shape as TLDrawShape).create(shape)
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Manually update a set of shapes.
|
||||
* @param shapes An array of shape partials, containing the changes to be made to each shape.
|
||||
* @command
|
||||
* @returns this
|
||||
*/
|
||||
updateShapes = (...shapes: ({ id: string } & Partial<TLDrawShape>)[]): this => {
|
||||
if (shapes.length === 0) return this
|
||||
return this.setState(Commands.update(this.state, shapes), 'updated_shape')
|
||||
}
|
||||
|
||||
/**
|
||||
* Create one or more shapes.
|
||||
* @param shapes An array of shapes.
|
||||
* @command
|
||||
* @returns this
|
||||
*/
|
||||
create = (...shapes: TLDrawShape[]): this => {
|
||||
if (shapes.length === 0) return this
|
||||
return this.setState(Commands.create(this.state, shapes))
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete one or more shapes.
|
||||
* @param ids The ids of the shapes to delete.
|
||||
* @command
|
||||
* @returns this
|
||||
*/
|
||||
delete = (ids = this.selectedIds): this => {
|
||||
if (ids.length === 0) return this
|
||||
return this.setState(Commands.deleteShapes(this.state, ids))
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all shapes on the page.
|
||||
* @returns this
|
||||
*/
|
||||
clear = (): this => {
|
||||
this.selectAll()
|
||||
this.delete()
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the style for one or more shapes.
|
||||
* @param style A style partial to apply to the shapes.
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
style = (style: Partial<ShapeStyles>, ids = this.selectedIds) => {
|
||||
return this.setState(Commands.style(this.state, ids, style))
|
||||
}
|
||||
|
||||
/**
|
||||
* Align one or more shapes.
|
||||
* @param direction Whether to align horizontally or vertically.
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
align = (type: AlignType, ids = this.selectedIds) => {
|
||||
return this.setState(Commands.align(this.state, ids, type))
|
||||
}
|
||||
|
||||
distribute = (type: DistributeType, ids = this.selectedIds) => {
|
||||
return this.setState(Commands.distribute(this.state, ids, type))
|
||||
/**
|
||||
* Distribute one or more shapes.
|
||||
* @param direction Whether to distribute horizontally or vertically..
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
distribute = (direction: DistributeType, ids = this.selectedIds) => {
|
||||
return this.setState(Commands.distribute(this.state, ids, direction))
|
||||
}
|
||||
|
||||
stretch = (type: StretchType, ids = this.selectedIds) => {
|
||||
return this.setState(Commands.stretch(this.state, ids, type))
|
||||
/**
|
||||
* Stretch one or more shapes to their common bounds.
|
||||
* @param direction Whether to stretch horizontally or vertically.
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
stretch = (direction: StretchType, ids = this.selectedIds) => {
|
||||
return this.setState(Commands.stretch(this.state, ids, direction))
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip one or more shapes horizontally.
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
flipHorizontal = (ids = this.selectedIds) => {
|
||||
return this.setState(Commands.flip(this.state, ids, FlipType.Horizontal))
|
||||
}
|
||||
|
||||
/**
|
||||
* Flip one or more shapes vertically.
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
flipVertical = (ids = this.selectedIds) => {
|
||||
return this.setState(Commands.flip(this.state, ids, FlipType.Vertical))
|
||||
}
|
||||
|
||||
/**
|
||||
* Move one or more shapes to the back of the page.
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
moveToBack = (ids = this.selectedIds) => {
|
||||
return this.setState(Commands.move(this.state, ids, MoveType.ToBack))
|
||||
}
|
||||
|
||||
/**
|
||||
* Move one or more shapes backward on of the page.
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
moveBackward = (ids = this.selectedIds) => {
|
||||
return this.setState(Commands.move(this.state, ids, MoveType.Backward))
|
||||
}
|
||||
|
||||
/**
|
||||
* Move one or more shapes forward on the page.
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
moveForward = (ids = this.selectedIds) => {
|
||||
return this.setState(Commands.move(this.state, ids, MoveType.Forward))
|
||||
}
|
||||
|
||||
/**
|
||||
* Move one or more shapes to the front of the page.
|
||||
* @param ids The ids of the shapes to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
moveToFront = (ids = this.selectedIds) => {
|
||||
return this.setState(Commands.move(this.state, ids, MoveType.ToFront))
|
||||
}
|
||||
|
||||
/**
|
||||
* Nudge one or more shapes in a direction.
|
||||
* @param delta The direction to nudge the shapes.
|
||||
* @param isMajor Whether this is a major (i.e. shift) nudge.
|
||||
* @param ids The ids to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
nudge = (delta: number[], isMajor = false, ids = this.selectedIds): this => {
|
||||
return this.setState(Commands.translate(this.state, ids, Vec.mul(delta, isMajor ? 10 : 1)))
|
||||
}
|
||||
|
||||
/**
|
||||
* Duplicate one or more shapes.
|
||||
* @param ids The ids to duplicate (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
duplicate = (ids = this.selectedIds): this => {
|
||||
return this.setState(Commands.duplicate(this.state, ids))
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the hidden property of one or more shapes.
|
||||
* @param ids The ids to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
toggleHidden = (ids = this.selectedIds): this => {
|
||||
return this.setState(Commands.toggle(this.state, ids, 'isHidden'))
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the locked property of one or more shapes.
|
||||
* @param ids The ids to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
toggleLocked = (ids = this.selectedIds): this => {
|
||||
return this.setState(Commands.toggle(this.state, ids, 'isLocked'))
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the fixed-aspect-ratio property of one or more shapes.
|
||||
* @param ids The ids to change (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
toggleAspectRatioLocked = (ids = this.selectedIds): this => {
|
||||
return this.setState(Commands.toggle(this.state, ids, 'isAspectRatioLocked'))
|
||||
}
|
||||
|
||||
/**
|
||||
* Toggle the decoration at a handle of one or more shapes.
|
||||
* @param handleId The handle to toggle.
|
||||
* @param ids The ids of the shapes to toggle the decoration on.
|
||||
* @returns this
|
||||
*/
|
||||
toggleDecoration = (handleId: string, ids = this.selectedIds): this => {
|
||||
if (handleId === 'start' || handleId === 'end') {
|
||||
return this.setState(Commands.toggleDecoration(this.state, ids, handleId))
|
||||
|
@ -1071,34 +1247,29 @@ export class TLDrawState extends StateManager<Data> {
|
|||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Rotate one or more shapes by a delta.
|
||||
* @param delta The delta in radians.
|
||||
* @param ids The ids to rotate (defaults to selection).
|
||||
* @returns this
|
||||
*/
|
||||
rotate = (delta = Math.PI * -0.5, ids = this.selectedIds): this => {
|
||||
return this.setState(Commands.rotate(this.state, ids, delta))
|
||||
}
|
||||
|
||||
/**
|
||||
* Group one or more shapes.
|
||||
* @returns this
|
||||
* @todo
|
||||
*/
|
||||
group = (): this => {
|
||||
// TODO
|
||||
//
|
||||
//
|
||||
// this.setState(Commands.toggle(this.state, ids, 'isAspectRatioLocked'))
|
||||
return this
|
||||
}
|
||||
|
||||
create = (...shapes: TLDrawShape[]): this => {
|
||||
return this.setState(Commands.create(this.state, shapes))
|
||||
}
|
||||
|
||||
delete = (ids = this.selectedIds): this => {
|
||||
if (ids.length === 0) return this
|
||||
|
||||
return this.setState(Commands.deleteShapes(this.state, ids))
|
||||
}
|
||||
|
||||
clear = (): this => {
|
||||
this.selectAll()
|
||||
this.delete()
|
||||
return this
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel the current session.
|
||||
* @returns this
|
||||
*/
|
||||
cancel = (): this => {
|
||||
switch (this.state.appState.status.current) {
|
||||
case TLDrawStatus.Idle: {
|
||||
|
|
Loading…
Reference in a new issue