2021-05-13 06:44:52 +00:00
|
|
|
import { Data } from "types"
|
|
|
|
import * as vec from "utils/vec"
|
|
|
|
import BaseSession from "./base-session"
|
|
|
|
import commands from "state/commands"
|
|
|
|
import { current } from "immer"
|
2021-05-19 21:24:41 +00:00
|
|
|
import { v4 as uuid } from "uuid"
|
2021-05-13 06:44:52 +00:00
|
|
|
|
|
|
|
export default class TranslateSession extends BaseSession {
|
|
|
|
delta = [0, 0]
|
|
|
|
origin: number[]
|
|
|
|
snapshot: TranslateSnapshot
|
2021-05-19 21:24:41 +00:00
|
|
|
isCloning = false
|
2021-05-13 06:44:52 +00:00
|
|
|
|
2021-05-20 08:19:13 +00:00
|
|
|
constructor(data: Data, point: number[], isCloning = false) {
|
2021-05-13 06:44:52 +00:00
|
|
|
super(data)
|
|
|
|
this.origin = point
|
|
|
|
this.snapshot = getTranslateSnapshot(data)
|
|
|
|
}
|
|
|
|
|
2021-05-20 08:19:13 +00:00
|
|
|
update(data: Data, point: number[], isAligned: boolean, isCloning: boolean) {
|
2021-05-19 21:24:41 +00:00
|
|
|
const { currentPageId, clones, initialShapes } = this.snapshot
|
2021-05-20 08:19:13 +00:00
|
|
|
const { shapes } = data.document.pages[currentPageId]
|
2021-05-13 06:44:52 +00:00
|
|
|
const delta = vec.vec(this.origin, point)
|
|
|
|
|
2021-05-20 08:19:13 +00:00
|
|
|
if (isAligned) {
|
|
|
|
if (Math.abs(delta[0]) < Math.abs(delta[1])) {
|
|
|
|
delta[0] = 0
|
|
|
|
} else {
|
|
|
|
delta[1] = 0
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-19 21:24:41 +00:00
|
|
|
if (isCloning && !this.isCloning) {
|
|
|
|
this.isCloning = true
|
|
|
|
for (let id in clones) {
|
|
|
|
const clone = clones[id]
|
2021-05-20 08:19:13 +00:00
|
|
|
shapes[clone.id] = clone
|
2021-05-19 21:24:41 +00:00
|
|
|
}
|
|
|
|
} else if (!isCloning && this.isCloning) {
|
|
|
|
this.isCloning = false
|
|
|
|
for (let id in clones) {
|
|
|
|
const clone = clones[id]
|
2021-05-20 08:19:13 +00:00
|
|
|
delete shapes[clone.id]
|
2021-05-19 21:24:41 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (let id in initialShapes) {
|
2021-05-20 08:19:13 +00:00
|
|
|
shapes[id].point = vec.add(initialShapes[id].point, delta)
|
2021-05-13 06:44:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
cancel(data: Data) {
|
2021-05-19 21:24:41 +00:00
|
|
|
const { initialShapes, clones, currentPageId } = this.snapshot
|
2021-05-20 08:19:13 +00:00
|
|
|
const { shapes } = data.document.pages[currentPageId]
|
2021-05-19 21:24:41 +00:00
|
|
|
|
|
|
|
for (let id in initialShapes) {
|
|
|
|
shapes[id].point = initialShapes[id].point
|
|
|
|
delete shapes[clones[id].id]
|
2021-05-13 06:44:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
complete(data: Data) {
|
2021-05-19 21:24:41 +00:00
|
|
|
commands.translate(
|
|
|
|
data,
|
|
|
|
this.snapshot,
|
|
|
|
getTranslateSnapshot(data),
|
|
|
|
this.isCloning
|
|
|
|
)
|
2021-05-13 06:44:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getTranslateSnapshot(data: Data) {
|
|
|
|
const {
|
|
|
|
document: { pages },
|
|
|
|
currentPageId,
|
|
|
|
} = current(data)
|
|
|
|
|
2021-05-19 21:24:41 +00:00
|
|
|
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.
|
2021-05-13 06:44:52 +00:00
|
|
|
|
|
|
|
return {
|
|
|
|
currentPageId,
|
2021-05-19 21:24:41 +00:00
|
|
|
initialShapes: Object.fromEntries(shapes.map((shape) => [shape.id, shape])),
|
|
|
|
clones: Object.fromEntries(
|
|
|
|
shapes.map((shape) => [shape.id, { ...shape, id: uuid() }])
|
|
|
|
),
|
2021-05-13 06:44:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export type TranslateSnapshot = ReturnType<typeof getTranslateSnapshot>
|