| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- import { ArrowShape, Data, LineShape, RayShape } from 'types'
- import * as vec from 'utils/vec'
- import BaseSession from './base-session'
- import commands from 'state/commands'
- import { current } from 'immer'
- import { getBoundsFromPoints, getPage, updateParents } from 'utils/utils'
- import { getShapeUtils } from 'lib/shape-utils'
-
- export default class PointsSession extends BaseSession {
- points: number[][]
- origin: number[]
- snapshot: ArrowSnapshot
- isLocked: boolean
- lockedDirection: 'horizontal' | 'vertical'
-
- constructor(data: Data, id: string, point: number[], isLocked: boolean) {
- super(data)
- this.origin = point
- this.points = [[0, 0]]
- this.snapshot = getArrowSnapshot(data, id)
- }
-
- update(data: Data, point: number[], isLocked = false) {
- const { id } = this.snapshot
-
- const delta = vec.vec(this.origin, point)
-
- if (isLocked) {
- if (!this.isLocked && this.points.length > 1) {
- this.isLocked = true
-
- if (Math.abs(delta[0]) < Math.abs(delta[1])) {
- this.lockedDirection = 'vertical'
- } else {
- this.lockedDirection = 'horizontal'
- }
- }
- } else {
- if (this.isLocked) {
- this.isLocked = false
- }
- }
-
- if (this.isLocked) {
- if (this.lockedDirection === 'vertical') {
- point[0] = this.origin[0]
- } else {
- point[1] = this.origin[1]
- }
- }
-
- const shape = getPage(data).shapes[id] as ArrowShape
-
- getShapeUtils(shape).onHandleChange(shape, {
- end: {
- ...shape.handles.end,
- point: vec.sub(point, shape.point),
- },
- })
-
- updateParents(data, [shape])
- }
-
- cancel(data: Data) {
- const { id, initialShape } = this.snapshot
-
- const shape = getPage(data).shapes[id] as ArrowShape
-
- getShapeUtils(shape)
- .onHandleChange(shape, { end: initialShape.handles.end })
- .setProperty(shape, 'point', initialShape.point)
-
- updateParents(data, [shape])
- }
-
- complete(data: Data) {
- const { id } = this.snapshot
-
- const shape = getPage(data).shapes[id] as ArrowShape
-
- const { start, end, bend } = shape.handles
-
- // Normalize point and handles
-
- const bounds = getBoundsFromPoints([start.point, end.point])
- const corner = [bounds.minX, bounds.minY]
-
- const newPoint = vec.add(shape.point, corner)
-
- const nextHandles = {
- start: { ...start, point: vec.sub(start.point, corner) },
- end: { ...end, point: vec.sub(end.point, corner) },
- bend: { ...bend, point: vec.sub(bend.point, corner) },
- }
-
- getShapeUtils(shape)
- .setProperty(shape, 'points', [
- nextHandles.start.point,
- nextHandles.end.point,
- ])
- .setProperty(shape, 'handles', nextHandles)
- .setProperty(shape, 'point', newPoint)
- .onHandleChange(shape, nextHandles)
-
- commands.arrow(
- data,
- this.snapshot,
- getArrowSnapshot(data, this.snapshot.id)
- )
- }
- }
-
- export function getArrowSnapshot(data: Data, id: string) {
- const initialShape = getPage(current(data)).shapes[id] as ArrowShape
-
- return {
- id,
- initialShape,
- selectedIds: new Set(data.selectedIds),
- currentPageId: data.currentPageId,
- }
- }
-
- export type ArrowSnapshot = ReturnType<typeof getArrowSnapshot>
|