Adds cloning, fixes some undo bugs
This commit is contained in:
parent
0c205d1377
commit
e8b13103ac
8 changed files with 184 additions and 64 deletions
|
@ -15,6 +15,10 @@ export default function useKeyboardEvents() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.altKey) {
|
||||||
|
state.send("PRESSED_ALT_KEY", getKeyboardEventInfo(e))
|
||||||
|
}
|
||||||
|
|
||||||
if (e.key === "Backspace" && !(metaKey(e) || e.shiftKey || e.altKey)) {
|
if (e.key === "Backspace" && !(metaKey(e) || e.shiftKey || e.altKey)) {
|
||||||
state.send("DELETED", getKeyboardEventInfo(e))
|
state.send("DELETED", getKeyboardEventInfo(e))
|
||||||
}
|
}
|
||||||
|
@ -66,6 +70,10 @@ export default function useKeyboardEvents() {
|
||||||
state.send("CANCELLED")
|
state.send("CANCELLED")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e.altKey) {
|
||||||
|
state.send("RELEASED_ALT_KEY")
|
||||||
|
}
|
||||||
|
|
||||||
state.send("RELEASED_KEY", getKeyboardEventInfo(e))
|
state.send("RELEASED_KEY", getKeyboardEventInfo(e))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ import Command from "./command"
|
||||||
import history from "../history"
|
import history from "../history"
|
||||||
import { Data, TransformCorner, TransformEdge } from "types"
|
import { Data, TransformCorner, TransformEdge } from "types"
|
||||||
import { getShapeUtils } from "lib/shapes"
|
import { getShapeUtils } from "lib/shapes"
|
||||||
|
import { current } from "immer"
|
||||||
import { TransformSingleSnapshot } from "state/sessions/transform-single-session"
|
import { TransformSingleSnapshot } from "state/sessions/transform-single-session"
|
||||||
|
|
||||||
export default function transformSingleCommand(
|
export default function transformSingleCommand(
|
||||||
|
@ -9,38 +10,54 @@ export default function transformSingleCommand(
|
||||||
before: TransformSingleSnapshot,
|
before: TransformSingleSnapshot,
|
||||||
after: TransformSingleSnapshot,
|
after: TransformSingleSnapshot,
|
||||||
scaleX: number,
|
scaleX: number,
|
||||||
scaleY: number
|
scaleY: number,
|
||||||
|
isCreating: boolean
|
||||||
) {
|
) {
|
||||||
|
const shape =
|
||||||
|
current(data).document.pages[after.currentPageId].shapes[after.id]
|
||||||
|
|
||||||
history.execute(
|
history.execute(
|
||||||
data,
|
data,
|
||||||
new Command({
|
new Command({
|
||||||
name: "transform_single_shape",
|
name: "transform_single_shape",
|
||||||
category: "canvas",
|
category: "canvas",
|
||||||
|
manualSelection: true,
|
||||||
do(data) {
|
do(data) {
|
||||||
const { id, currentPageId, type, initialShape, initialShapeBounds } =
|
const { id, currentPageId, type, initialShape, initialShapeBounds } =
|
||||||
after
|
after
|
||||||
|
|
||||||
const shape = data.document.pages[currentPageId].shapes[id]
|
data.selectedIds.clear()
|
||||||
|
data.selectedIds.add(id)
|
||||||
|
|
||||||
getShapeUtils(shape).transformSingle(shape, initialShapeBounds, {
|
if (isCreating) {
|
||||||
type,
|
data.document.pages[currentPageId].shapes[id] = shape
|
||||||
initialShape,
|
} else {
|
||||||
scaleX,
|
getShapeUtils(shape).transformSingle(shape, initialShapeBounds, {
|
||||||
scaleY,
|
type,
|
||||||
})
|
initialShape,
|
||||||
|
scaleX,
|
||||||
|
scaleY,
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
undo(data) {
|
undo(data) {
|
||||||
const { id, currentPageId, type, initialShape, initialShapeBounds } =
|
const { id, currentPageId, type, initialShapeBounds } = before
|
||||||
before
|
|
||||||
|
|
||||||
const shape = data.document.pages[currentPageId].shapes[id]
|
data.selectedIds.clear()
|
||||||
|
|
||||||
getShapeUtils(shape).transform(shape, initialShapeBounds, {
|
if (isCreating) {
|
||||||
type,
|
delete data.document.pages[currentPageId].shapes[id]
|
||||||
initialShape: after.initialShape,
|
} else {
|
||||||
scaleX: 1,
|
const shape = data.document.pages[currentPageId].shapes[id]
|
||||||
scaleY: 1,
|
data.selectedIds.add(id)
|
||||||
})
|
|
||||||
|
getShapeUtils(shape).transform(shape, initialShapeBounds, {
|
||||||
|
type,
|
||||||
|
initialShape: after.initialShape,
|
||||||
|
scaleX: 1,
|
||||||
|
scaleY: 1,
|
||||||
|
})
|
||||||
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
|
|
|
@ -6,25 +6,46 @@ import { Data } from "types"
|
||||||
export default function translateCommand(
|
export default function translateCommand(
|
||||||
data: Data,
|
data: Data,
|
||||||
before: TranslateSnapshot,
|
before: TranslateSnapshot,
|
||||||
after: TranslateSnapshot
|
after: TranslateSnapshot,
|
||||||
|
isCloning: boolean
|
||||||
) {
|
) {
|
||||||
history.execute(
|
history.execute(
|
||||||
data,
|
data,
|
||||||
new Command({
|
new Command({
|
||||||
name: "translate_shapes",
|
name: isCloning ? "clone_shapes" : "translate_shapes",
|
||||||
category: "canvas",
|
category: "canvas",
|
||||||
do(data) {
|
manualSelection: true,
|
||||||
const { shapes } = data.document.pages[after.currentPageId]
|
do(data, initial) {
|
||||||
|
if (initial) return
|
||||||
|
|
||||||
for (let { id, point } of after.shapes) {
|
const { shapes } = data.document.pages[after.currentPageId]
|
||||||
shapes[id].point = point
|
const { initialShapes, clones } = after
|
||||||
|
|
||||||
|
data.selectedIds.clear()
|
||||||
|
|
||||||
|
for (let id in initialShapes) {
|
||||||
|
if (isCloning) {
|
||||||
|
shapes[id] = initialShapes[id]
|
||||||
|
} else {
|
||||||
|
shapes[id].point = initialShapes[id].point
|
||||||
|
}
|
||||||
|
data.selectedIds.add(id)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
undo(data) {
|
undo(data) {
|
||||||
const { shapes } = data.document.pages[before.currentPageId]
|
const { shapes } = data.document.pages[before.currentPageId]
|
||||||
|
const { initialShapes, clones } = before
|
||||||
|
|
||||||
for (let { id, point } of before.shapes) {
|
data.selectedIds.clear()
|
||||||
shapes[id].point = point
|
|
||||||
|
for (let id in initialShapes) {
|
||||||
|
shapes[id].point = initialShapes[id].point
|
||||||
|
data.selectedIds.add(id)
|
||||||
|
|
||||||
|
if (isCloning) {
|
||||||
|
const clone = clones[id]
|
||||||
|
delete shapes[clone.id]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
|
@ -77,6 +77,13 @@ class BaseHistory<T> {
|
||||||
return { ...data }
|
return { ...data }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pop() {
|
||||||
|
if (this.stack.length > 0) {
|
||||||
|
this.stack.pop()
|
||||||
|
this.pointer--
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get disabled() {
|
get disabled() {
|
||||||
return !this._enabled
|
return !this._enabled
|
||||||
}
|
}
|
||||||
|
|
|
@ -86,6 +86,10 @@ class Inputs {
|
||||||
const { shiftKey, ctrlKey, metaKey, altKey } = e
|
const { shiftKey, ctrlKey, metaKey, altKey } = e
|
||||||
return { point: [e.clientX, e.clientY], shiftKey, ctrlKey, metaKey, altKey }
|
return { point: [e.clientX, e.clientY], shiftKey, ctrlKey, metaKey, altKey }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get pointer() {
|
||||||
|
return this.points[Object.keys(this.points)[0]]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new Inputs()
|
export default new Inputs()
|
||||||
|
|
|
@ -12,22 +12,24 @@ import {
|
||||||
} from "utils/utils"
|
} from "utils/utils"
|
||||||
|
|
||||||
export default class TransformSingleSession extends BaseSession {
|
export default class TransformSingleSession extends BaseSession {
|
||||||
delta = [0, 0]
|
transformType: TransformEdge | TransformCorner
|
||||||
|
origin: number[]
|
||||||
scaleX = 1
|
scaleX = 1
|
||||||
scaleY = 1
|
scaleY = 1
|
||||||
transformType: TransformEdge | TransformCorner
|
|
||||||
snapshot: TransformSingleSnapshot
|
snapshot: TransformSingleSnapshot
|
||||||
origin: number[]
|
isCreating: boolean
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
data: Data,
|
data: Data,
|
||||||
transformType: TransformCorner | TransformEdge,
|
transformType: TransformCorner | TransformEdge,
|
||||||
point: number[]
|
point: number[],
|
||||||
|
isCreating = false
|
||||||
) {
|
) {
|
||||||
super(data)
|
super(data)
|
||||||
this.origin = point
|
this.origin = point
|
||||||
this.transformType = transformType
|
this.transformType = transformType
|
||||||
this.snapshot = getTransformSingleSnapshot(data, transformType)
|
this.snapshot = getTransformSingleSnapshot(data, transformType)
|
||||||
|
this.isCreating = isCreating
|
||||||
}
|
}
|
||||||
|
|
||||||
update(data: Data, point: number[]) {
|
update(data: Data, point: number[]) {
|
||||||
|
@ -78,7 +80,8 @@ export default class TransformSingleSession extends BaseSession {
|
||||||
this.snapshot,
|
this.snapshot,
|
||||||
getTransformSingleSnapshot(data, this.transformType),
|
getTransformSingleSnapshot(data, this.transformType),
|
||||||
this.scaleX,
|
this.scaleX,
|
||||||
this.scaleY
|
this.scaleY,
|
||||||
|
this.isCreating
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,11 +3,13 @@ import * as vec from "utils/vec"
|
||||||
import BaseSession from "./base-session"
|
import BaseSession from "./base-session"
|
||||||
import commands from "state/commands"
|
import commands from "state/commands"
|
||||||
import { current } from "immer"
|
import { current } from "immer"
|
||||||
|
import { v4 as uuid } from "uuid"
|
||||||
|
|
||||||
export default class TranslateSession extends BaseSession {
|
export default class TranslateSession extends BaseSession {
|
||||||
delta = [0, 0]
|
delta = [0, 0]
|
||||||
origin: number[]
|
origin: number[]
|
||||||
snapshot: TranslateSnapshot
|
snapshot: TranslateSnapshot
|
||||||
|
isCloning = false
|
||||||
|
|
||||||
constructor(data: Data, point: number[]) {
|
constructor(data: Data, point: number[]) {
|
||||||
super(data)
|
super(data)
|
||||||
|
@ -15,31 +17,62 @@ export default class TranslateSession extends BaseSession {
|
||||||
this.snapshot = getTranslateSnapshot(data)
|
this.snapshot = getTranslateSnapshot(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
update(data: Data, point: number[]) {
|
update(data: Data, point: number[], isCloning: boolean) {
|
||||||
const { currentPageId, shapes } = this.snapshot
|
const { currentPageId, clones, initialShapes } = this.snapshot
|
||||||
const { document } = data
|
const { document } = data
|
||||||
|
const { shapes } = document.pages[this.snapshot.currentPageId]
|
||||||
|
|
||||||
const delta = vec.vec(this.origin, point)
|
const delta = vec.vec(this.origin, point)
|
||||||
|
|
||||||
for (let shape of shapes) {
|
if (isCloning && !this.isCloning) {
|
||||||
document.pages[currentPageId].shapes[shape.id].point = vec.add(
|
// Enter cloning state, create clones at shape points and move shapes
|
||||||
shape.point,
|
// back to initial point.
|
||||||
delta
|
this.isCloning = true
|
||||||
)
|
data.selectedIds.clear()
|
||||||
|
for (let id in clones) {
|
||||||
|
const clone = clones[id]
|
||||||
|
data.selectedIds.add(clone.id)
|
||||||
|
shapes[id].point = initialShapes[id].point
|
||||||
|
data.document.pages[currentPageId].shapes[clone.id] = clone
|
||||||
|
}
|
||||||
|
} else if (!isCloning && this.isCloning) {
|
||||||
|
// Exit cloning state, delete up clones and move shapes to clone points
|
||||||
|
this.isCloning = false
|
||||||
|
data.selectedIds.clear()
|
||||||
|
for (let id in clones) {
|
||||||
|
const clone = clones[id]
|
||||||
|
data.selectedIds.add(id)
|
||||||
|
delete data.document.pages[currentPageId].shapes[clone.id]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Calculate the new points and update data
|
||||||
|
for (let id in initialShapes) {
|
||||||
|
const point = vec.add(initialShapes[id].point, delta)
|
||||||
|
const targetId = this.isCloning ? clones[id].id : id
|
||||||
|
document.pages[currentPageId].shapes[targetId].point = point
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cancel(data: Data) {
|
cancel(data: Data) {
|
||||||
const { document } = data
|
const { document } = data
|
||||||
|
const { initialShapes, clones, currentPageId } = this.snapshot
|
||||||
|
|
||||||
for (let shape of this.snapshot.shapes) {
|
const { shapes } = document.pages[currentPageId]
|
||||||
document.pages[this.snapshot.currentPageId].shapes[shape.id].point =
|
|
||||||
shape.point
|
for (let id in initialShapes) {
|
||||||
|
shapes[id].point = initialShapes[id].point
|
||||||
|
delete shapes[clones[id].id]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
complete(data: Data) {
|
complete(data: Data) {
|
||||||
commands.translate(data, this.snapshot, getTranslateSnapshot(data))
|
commands.translate(
|
||||||
|
data,
|
||||||
|
this.snapshot,
|
||||||
|
getTranslateSnapshot(data),
|
||||||
|
this.isCloning
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,13 +82,19 @@ export function getTranslateSnapshot(data: Data) {
|
||||||
currentPageId,
|
currentPageId,
|
||||||
} = current(data)
|
} = current(data)
|
||||||
|
|
||||||
const { shapes } = pages[currentPageId]
|
const shapes = Array.from(data.selectedIds.values()).map(
|
||||||
|
(id) => pages[currentPageId].shapes[id]
|
||||||
|
)
|
||||||
|
|
||||||
|
// Clones and shapes are keyed under the same id, though the clone itself
|
||||||
|
// has a different id.
|
||||||
|
|
||||||
return {
|
return {
|
||||||
currentPageId,
|
currentPageId,
|
||||||
shapes: Array.from(data.selectedIds.values())
|
initialShapes: Object.fromEntries(shapes.map((shape) => [shape.id, shape])),
|
||||||
.map((id) => shapes[id])
|
clones: Object.fromEntries(
|
||||||
.map(({ id, point }) => ({ id, point })),
|
shapes.map((shape) => [shape.id, { ...shape, id: uuid() }])
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@ import {
|
||||||
TransformEdge,
|
TransformEdge,
|
||||||
CodeControl,
|
CodeControl,
|
||||||
} from "types"
|
} from "types"
|
||||||
|
import inputs from "./inputs"
|
||||||
import { defaultDocument } from "./data"
|
import { defaultDocument } from "./data"
|
||||||
import shapeUtilityMap, { getShapeUtils } from "lib/shapes"
|
import shapeUtilityMap, { getShapeUtils } from "lib/shapes"
|
||||||
import history from "state/history"
|
import history from "state/history"
|
||||||
|
@ -174,6 +175,8 @@ const state = createState({
|
||||||
on: {
|
on: {
|
||||||
MOVED_POINTER: "updateTranslateSession",
|
MOVED_POINTER: "updateTranslateSession",
|
||||||
PANNED_CAMERA: "updateTranslateSession",
|
PANNED_CAMERA: "updateTranslateSession",
|
||||||
|
PRESSED_ALT_KEY: "updateCloningTranslateSession",
|
||||||
|
RELEASED_ALT_KEY: "updateCloningTranslateSession",
|
||||||
STOPPED_POINTING: { do: "completeSession", to: "selecting" },
|
STOPPED_POINTING: { do: "completeSession", to: "selecting" },
|
||||||
CANCELLED: { do: "cancelSession", to: "selecting" },
|
CANCELLED: { do: "cancelSession", to: "selecting" },
|
||||||
},
|
},
|
||||||
|
@ -261,6 +264,7 @@ const state = createState({
|
||||||
states: {
|
states: {
|
||||||
creating: {
|
creating: {
|
||||||
on: {
|
on: {
|
||||||
|
CANCELLED: { to: "selecting" },
|
||||||
POINTED_CANVAS: {
|
POINTED_CANVAS: {
|
||||||
to: "ellipse.editing",
|
to: "ellipse.editing",
|
||||||
},
|
},
|
||||||
|
@ -284,6 +288,7 @@ const state = createState({
|
||||||
states: {
|
states: {
|
||||||
creating: {
|
creating: {
|
||||||
on: {
|
on: {
|
||||||
|
CANCELLED: { to: "selecting" },
|
||||||
POINTED_CANVAS: {
|
POINTED_CANVAS: {
|
||||||
to: "rectangle.editing",
|
to: "rectangle.editing",
|
||||||
},
|
},
|
||||||
|
@ -307,6 +312,7 @@ const state = createState({
|
||||||
states: {
|
states: {
|
||||||
creating: {
|
creating: {
|
||||||
on: {
|
on: {
|
||||||
|
CANCELLED: { to: "selecting" },
|
||||||
POINTED_CANVAS: {
|
POINTED_CANVAS: {
|
||||||
do: "createRay",
|
do: "createRay",
|
||||||
to: "ray.editing",
|
to: "ray.editing",
|
||||||
|
@ -315,11 +321,8 @@ const state = createState({
|
||||||
},
|
},
|
||||||
editing: {
|
editing: {
|
||||||
on: {
|
on: {
|
||||||
STOPPED_POINTING: { do: "completeSession", to: "selecting" },
|
STOPPED_POINTING: { to: "selecting" },
|
||||||
CANCELLED: {
|
CANCELLED: { to: "selecting" },
|
||||||
do: ["cancelSession", "deleteSelectedIds"],
|
|
||||||
to: "selecting",
|
|
||||||
},
|
|
||||||
MOVED_POINTER: {
|
MOVED_POINTER: {
|
||||||
if: "distanceImpliesDrag",
|
if: "distanceImpliesDrag",
|
||||||
to: "drawingShape.direction",
|
to: "drawingShape.direction",
|
||||||
|
@ -333,6 +336,7 @@ const state = createState({
|
||||||
states: {
|
states: {
|
||||||
creating: {
|
creating: {
|
||||||
on: {
|
on: {
|
||||||
|
CANCELLED: { to: "selecting" },
|
||||||
POINTED_CANVAS: {
|
POINTED_CANVAS: {
|
||||||
do: "createLine",
|
do: "createLine",
|
||||||
to: "line.editing",
|
to: "line.editing",
|
||||||
|
@ -341,11 +345,8 @@ const state = createState({
|
||||||
},
|
},
|
||||||
editing: {
|
editing: {
|
||||||
on: {
|
on: {
|
||||||
STOPPED_POINTING: { do: "completeSession", to: "selecting" },
|
STOPPED_POINTING: { to: "selecting" },
|
||||||
CANCELLED: {
|
CANCELLED: { to: "selecting" },
|
||||||
do: ["cancelSession", "deleteSelectedIds"],
|
|
||||||
to: "selecting",
|
|
||||||
},
|
|
||||||
MOVED_POINTER: {
|
MOVED_POINTER: {
|
||||||
if: "distanceImpliesDrag",
|
if: "distanceImpliesDrag",
|
||||||
to: "drawingShape.direction",
|
to: "drawingShape.direction",
|
||||||
|
@ -359,7 +360,10 @@ const state = createState({
|
||||||
},
|
},
|
||||||
drawingShape: {
|
drawingShape: {
|
||||||
on: {
|
on: {
|
||||||
STOPPED_POINTING: { do: "completeSession", to: "selecting" },
|
STOPPED_POINTING: {
|
||||||
|
do: "completeSession",
|
||||||
|
to: "selecting",
|
||||||
|
},
|
||||||
CANCELLED: {
|
CANCELLED: {
|
||||||
do: ["cancelSession", "deleteSelectedIds"],
|
do: ["cancelSession", "deleteSelectedIds"],
|
||||||
to: "selecting",
|
to: "selecting",
|
||||||
|
@ -422,7 +426,8 @@ const state = createState({
|
||||||
point: screenToWorld(payload.point, data),
|
point: screenToWorld(payload.point, data),
|
||||||
})
|
})
|
||||||
|
|
||||||
commands.createShape(data, shape)
|
data.document.pages[data.currentPageId].shapes[shape.id] = shape
|
||||||
|
data.selectedIds.clear()
|
||||||
data.selectedIds.add(shape.id)
|
data.selectedIds.add(shape.id)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -432,7 +437,8 @@ const state = createState({
|
||||||
point: screenToWorld(payload.point, data),
|
point: screenToWorld(payload.point, data),
|
||||||
})
|
})
|
||||||
|
|
||||||
commands.createShape(data, shape)
|
data.document.pages[data.currentPageId].shapes[shape.id] = shape
|
||||||
|
data.selectedIds.clear()
|
||||||
data.selectedIds.add(shape.id)
|
data.selectedIds.add(shape.id)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -443,7 +449,8 @@ const state = createState({
|
||||||
direction: [0, 1],
|
direction: [0, 1],
|
||||||
})
|
})
|
||||||
|
|
||||||
commands.createShape(data, shape)
|
data.document.pages[data.currentPageId].shapes[shape.id] = shape
|
||||||
|
data.selectedIds.clear()
|
||||||
data.selectedIds.add(shape.id)
|
data.selectedIds.add(shape.id)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -453,7 +460,8 @@ const state = createState({
|
||||||
radius: 1,
|
radius: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
commands.createShape(data, shape)
|
data.document.pages[data.currentPageId].shapes[shape.id] = shape
|
||||||
|
data.selectedIds.clear()
|
||||||
data.selectedIds.add(shape.id)
|
data.selectedIds.add(shape.id)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -464,7 +472,8 @@ const state = createState({
|
||||||
radiusY: 1,
|
radiusY: 1,
|
||||||
})
|
})
|
||||||
|
|
||||||
commands.createShape(data, shape)
|
data.document.pages[data.currentPageId].shapes[shape.id] = shape
|
||||||
|
data.selectedIds.clear()
|
||||||
data.selectedIds.add(shape.id)
|
data.selectedIds.add(shape.id)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -474,7 +483,8 @@ const state = createState({
|
||||||
size: [1, 1],
|
size: [1, 1],
|
||||||
})
|
})
|
||||||
|
|
||||||
commands.createShape(data, shape)
|
data.document.pages[data.currentPageId].shapes[shape.id] = shape
|
||||||
|
data.selectedIds.clear()
|
||||||
data.selectedIds.add(shape.id)
|
data.selectedIds.add(shape.id)
|
||||||
},
|
},
|
||||||
/* -------------------- Sessions -------------------- */
|
/* -------------------- Sessions -------------------- */
|
||||||
|
@ -518,8 +528,15 @@ const state = createState({
|
||||||
screenToWorld(payload.point, data)
|
screenToWorld(payload.point, data)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
|
updateCloningTranslateSession(data, payload: { altKey: boolean }) {
|
||||||
|
session.update(
|
||||||
|
data,
|
||||||
|
screenToWorld(inputs.pointer.point, data),
|
||||||
|
payload.altKey
|
||||||
|
)
|
||||||
|
},
|
||||||
updateTranslateSession(data, payload: PointerInfo) {
|
updateTranslateSession(data, payload: PointerInfo) {
|
||||||
session.update(data, screenToWorld(payload.point, data))
|
session.update(data, screenToWorld(payload.point, data), payload.altKey)
|
||||||
},
|
},
|
||||||
|
|
||||||
// Dragging / Translating
|
// Dragging / Translating
|
||||||
|
@ -544,7 +561,8 @@ const state = createState({
|
||||||
session = new Sessions.TransformSingleSession(
|
session = new Sessions.TransformSingleSession(
|
||||||
data,
|
data,
|
||||||
TransformCorner.BottomRight,
|
TransformCorner.BottomRight,
|
||||||
screenToWorld(payload.point, data)
|
screenToWorld(payload.point, data),
|
||||||
|
true
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
updateTransformSession(data, payload: PointerInfo) {
|
updateTransformSession(data, payload: PointerInfo) {
|
||||||
|
@ -642,6 +660,9 @@ const state = createState({
|
||||||
/* ---------------------- History ---------------------- */
|
/* ---------------------- History ---------------------- */
|
||||||
|
|
||||||
// History
|
// History
|
||||||
|
popHistory() {
|
||||||
|
history.pop()
|
||||||
|
},
|
||||||
forceSave(data) {
|
forceSave(data) {
|
||||||
history.save(data)
|
history.save(data)
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in a new issue