You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

draw-session.ts 1.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import { current } from "immer"
  2. import { Data, DrawShape } from "types"
  3. import BaseSession from "./base-session"
  4. import { getShapeUtils } from "lib/shape-utils"
  5. import { getPage, simplify } from "utils/utils"
  6. import * as vec from "utils/vec"
  7. import commands from "state/commands"
  8. export default class BrushSession extends BaseSession {
  9. origin: number[]
  10. previous: number[]
  11. points: number[][]
  12. snapshot: DrawSnapshot
  13. shapeId: string
  14. constructor(data: Data, id: string, point: number[]) {
  15. super(data)
  16. this.shapeId = id
  17. this.origin = point
  18. this.previous = point
  19. this.points = []
  20. this.snapshot = getDrawSnapshot(data, id)
  21. const page = getPage(data)
  22. const shape = page.shapes[id]
  23. getShapeUtils(shape).translateTo(shape, point)
  24. }
  25. update = (data: Data, point: number[]) => {
  26. const { shapeId } = this
  27. const lp = vec.med(this.previous, point)
  28. this.points.push(vec.sub(lp, this.origin))
  29. this.previous = lp
  30. const page = getPage(data)
  31. const shape = page.shapes[shapeId]
  32. getShapeUtils(shape).setPoints!(shape, [...this.points])
  33. }
  34. cancel = (data: Data) => {
  35. const { shapeId, snapshot } = this
  36. const page = getPage(data)
  37. const shape = page.shapes[shapeId]
  38. getShapeUtils(shape).setPoints!(shape, snapshot.points)
  39. }
  40. complete = (data: Data) => {
  41. commands.draw(
  42. data,
  43. this.shapeId,
  44. this.snapshot.points,
  45. simplify(this.points, 0.1 / data.camera.zoom).map(([x, y]) => [
  46. Math.trunc(x * 100) / 100,
  47. Math.trunc(y * 100) / 100,
  48. ])
  49. )
  50. }
  51. }
  52. export function getDrawSnapshot(data: Data, shapeId: string) {
  53. const page = getPage(current(data))
  54. const { points } = page.shapes[shapeId] as DrawShape
  55. return {
  56. points,
  57. }
  58. }
  59. export type DrawSnapshot = ReturnType<typeof getDrawSnapshot>