adds aligned dragging / cloning
This commit is contained in:
parent
e8b13103ac
commit
b126b1af65
4 changed files with 80 additions and 66 deletions
|
@ -15,7 +15,11 @@ export default function useKeyboardEvents() {
|
|||
}
|
||||
}
|
||||
|
||||
if (e.altKey) {
|
||||
if (e.key === "Shift") {
|
||||
state.send("PRESSED_SHIFT_KEY", getKeyboardEventInfo(e))
|
||||
}
|
||||
|
||||
if (e.key === "Alt") {
|
||||
state.send("PRESSED_ALT_KEY", getKeyboardEventInfo(e))
|
||||
}
|
||||
|
||||
|
@ -66,12 +70,12 @@ export default function useKeyboardEvents() {
|
|||
}
|
||||
|
||||
function handleKeyUp(e: KeyboardEvent) {
|
||||
if (e.key === "Escape") {
|
||||
state.send("CANCELLED")
|
||||
if (e.key === "Shift") {
|
||||
state.send("RELEASED_SHIFT_KEY", getKeyboardEventInfo(e))
|
||||
}
|
||||
|
||||
if (e.altKey) {
|
||||
state.send("RELEASED_ALT_KEY")
|
||||
if (e.key === "Alt") {
|
||||
state.send("RELEASED_ALT_KEY", getKeyboardEventInfo(e))
|
||||
}
|
||||
|
||||
state.send("RELEASED_KEY", getKeyboardEventInfo(e))
|
||||
|
|
|
@ -19,16 +19,14 @@ export default function translateCommand(
|
|||
if (initial) return
|
||||
|
||||
const { shapes } = data.document.pages[after.currentPageId]
|
||||
const { initialShapes, clones } = after
|
||||
const { initialShapes } = after
|
||||
const { clones } = before // !
|
||||
|
||||
data.selectedIds.clear()
|
||||
|
||||
for (let id in initialShapes) {
|
||||
if (isCloning) {
|
||||
shapes[id] = initialShapes[id]
|
||||
} else {
|
||||
shapes[id].point = initialShapes[id].point
|
||||
}
|
||||
shapes[clones[id].id] = clones[id]
|
||||
data.selectedIds.add(id)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -11,54 +11,47 @@ export default class TranslateSession extends BaseSession {
|
|||
snapshot: TranslateSnapshot
|
||||
isCloning = false
|
||||
|
||||
constructor(data: Data, point: number[]) {
|
||||
constructor(data: Data, point: number[], isCloning = false) {
|
||||
super(data)
|
||||
this.origin = point
|
||||
this.snapshot = getTranslateSnapshot(data)
|
||||
}
|
||||
|
||||
update(data: Data, point: number[], isCloning: boolean) {
|
||||
update(data: Data, point: number[], isAligned: boolean, isCloning: boolean) {
|
||||
const { currentPageId, clones, initialShapes } = this.snapshot
|
||||
const { document } = data
|
||||
const { shapes } = document.pages[this.snapshot.currentPageId]
|
||||
|
||||
const { shapes } = data.document.pages[currentPageId]
|
||||
const delta = vec.vec(this.origin, point)
|
||||
|
||||
if (isCloning && !this.isCloning) {
|
||||
// Enter cloning state, create clones at shape points and move shapes
|
||||
// back to initial point.
|
||||
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]
|
||||
if (isAligned) {
|
||||
if (Math.abs(delta[0]) < Math.abs(delta[1])) {
|
||||
delta[0] = 0
|
||||
} else {
|
||||
delta[1] = 0
|
||||
}
|
||||
}
|
||||
|
||||
if (isCloning && !this.isCloning) {
|
||||
this.isCloning = true
|
||||
for (let id in clones) {
|
||||
const clone = clones[id]
|
||||
shapes[clone.id] = clone
|
||||
}
|
||||
} else if (!isCloning && this.isCloning) {
|
||||
this.isCloning = false
|
||||
for (let id in clones) {
|
||||
const clone = clones[id]
|
||||
delete 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
|
||||
shapes[id].point = vec.add(initialShapes[id].point, delta)
|
||||
}
|
||||
}
|
||||
|
||||
cancel(data: Data) {
|
||||
const { document } = data
|
||||
const { initialShapes, clones, currentPageId } = this.snapshot
|
||||
|
||||
const { shapes } = document.pages[currentPageId]
|
||||
const { shapes } = data.document.pages[currentPageId]
|
||||
|
||||
for (let id in initialShapes) {
|
||||
shapes[id].point = initialShapes[id].point
|
||||
|
|
|
@ -115,15 +115,10 @@ const state = createState({
|
|||
"setPointedId",
|
||||
{
|
||||
if: "isPressingShiftKey",
|
||||
then: {
|
||||
if: "isPointedShapeSelected",
|
||||
do: "pullPointedIdFromSelectedIds",
|
||||
else: {
|
||||
do: "pushPointedIdToSelectedIds",
|
||||
unless: "isPointedShapeSelected",
|
||||
do: ["pushPointedIdToSelectedIds", "clearPointedId"],
|
||||
to: "pointingBounds",
|
||||
},
|
||||
},
|
||||
else: [
|
||||
{
|
||||
unless: "isPointedShapeSelected",
|
||||
do: ["clearSelectedIds", "pushPointedIdToSelectedIds"],
|
||||
|
@ -133,16 +128,21 @@ const state = createState({
|
|||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
pointingBounds: {
|
||||
on: {
|
||||
STOPPED_POINTING: [
|
||||
{
|
||||
unless: ["isPointingBounds", "isPressingShiftKey"],
|
||||
if: "isPressingShiftKey",
|
||||
then: {
|
||||
if: "isPointedShapeSelected",
|
||||
do: "pullPointedIdFromSelectedIds",
|
||||
},
|
||||
else: {
|
||||
if: "isPointingBounds",
|
||||
do: ["clearSelectedIds", "pushPointedIdToSelectedIds"],
|
||||
},
|
||||
},
|
||||
{ to: "notPointing" },
|
||||
],
|
||||
MOVED_POINTER: {
|
||||
|
@ -175,8 +175,10 @@ const state = createState({
|
|||
on: {
|
||||
MOVED_POINTER: "updateTranslateSession",
|
||||
PANNED_CAMERA: "updateTranslateSession",
|
||||
PRESSED_ALT_KEY: "updateCloningTranslateSession",
|
||||
RELEASED_ALT_KEY: "updateCloningTranslateSession",
|
||||
PRESSED_SHIFT_KEY: "keyUpdateTranslateSession",
|
||||
RELEASED_SHIFT_KEY: "keyUpdateTranslateSession",
|
||||
PRESSED_ALT_KEY: "keyUpdateTranslateSession",
|
||||
RELEASED_ALT_KEY: "keyUpdateTranslateSession",
|
||||
STOPPED_POINTING: { do: "completeSession", to: "selecting" },
|
||||
CANCELLED: { do: "cancelSession", to: "selecting" },
|
||||
},
|
||||
|
@ -525,18 +527,29 @@ const state = createState({
|
|||
startTranslateSession(data, payload: PointerInfo) {
|
||||
session = new Sessions.TranslateSession(
|
||||
data,
|
||||
screenToWorld(payload.point, data)
|
||||
screenToWorld(payload.point, data),
|
||||
payload.altKey
|
||||
)
|
||||
},
|
||||
updateCloningTranslateSession(data, payload: { altKey: boolean }) {
|
||||
keyUpdateTranslateSession(
|
||||
data,
|
||||
payload: { shiftKey: boolean; altKey: boolean }
|
||||
) {
|
||||
session.update(
|
||||
data,
|
||||
screenToWorld(inputs.pointer.point, data),
|
||||
payload.shiftKey,
|
||||
payload.altKey
|
||||
)
|
||||
},
|
||||
updateTranslateSession(data, payload: PointerInfo) {
|
||||
session.update(data, screenToWorld(payload.point, data), payload.altKey)
|
||||
console.log(payload.altKey)
|
||||
session.update(
|
||||
data,
|
||||
screenToWorld(payload.point, data),
|
||||
payload.shiftKey,
|
||||
payload.altKey
|
||||
)
|
||||
},
|
||||
|
||||
// Dragging / Translating
|
||||
|
@ -761,6 +774,12 @@ const state = createState({
|
|||
if (selectedIds.size === 0) return null
|
||||
|
||||
if (selectedIds.size === 1) {
|
||||
if (!shapes[0]) {
|
||||
console.error("Could not find that shape! Clearing selected IDs.")
|
||||
data.selectedIds.clear()
|
||||
return null
|
||||
}
|
||||
|
||||
const shapeUtils = getShapeUtils(shapes[0])
|
||||
if (!shapeUtils.canTransform) return null
|
||||
return shapeUtils.getBounds(shapes[0])
|
||||
|
|
Loading…
Reference in a new issue