Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

draw-session.ts 3.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  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, getShape, updateParents } from 'utils/utils'
  6. import * as vec from 'utils/vec'
  7. import commands from 'state/commands'
  8. let prevEndPoint: number[]
  9. export default class BrushSession extends BaseSession {
  10. origin: number[]
  11. previous: number[]
  12. last: number[]
  13. points: number[][]
  14. snapshot: DrawSnapshot
  15. isLocked: boolean
  16. lockedDirection: 'horizontal' | 'vertical'
  17. constructor(data: Data, id: string, point: number[], isLocked = false) {
  18. super(data)
  19. this.origin = point
  20. this.previous = point
  21. this.last = point
  22. this.points = [[0, 0]]
  23. this.snapshot = getDrawSnapshot(data, id)
  24. const page = getPage(data)
  25. const shape = page.shapes[id] as DrawShape
  26. getShapeUtils(shape).translateTo(shape, point)
  27. updateParents(data, [shape.id])
  28. }
  29. update = (
  30. data: Data,
  31. point: number[],
  32. pressure: number,
  33. isLocked = false
  34. ) => {
  35. const { snapshot } = this
  36. const delta = vec.vec(this.origin, point)
  37. if (isLocked) {
  38. if (!this.isLocked && this.points.length > 1) {
  39. this.isLocked = true
  40. const returning = [...this.previous]
  41. if (Math.abs(delta[0]) < Math.abs(delta[1])) {
  42. this.lockedDirection = 'vertical'
  43. returning[0] = this.origin[0]
  44. } else {
  45. this.lockedDirection = 'horizontal'
  46. returning[1] = this.origin[1]
  47. }
  48. this.previous = returning
  49. this.points.push(vec.sub(returning, this.origin))
  50. }
  51. } else {
  52. if (this.isLocked) {
  53. this.isLocked = false
  54. }
  55. }
  56. if (this.isLocked) {
  57. if (this.lockedDirection === 'vertical') {
  58. point[0] = this.origin[0]
  59. } else {
  60. point[1] = this.origin[1]
  61. }
  62. }
  63. point = vec.med(this.previous, point)
  64. const next = vec.round([...vec.sub(point, this.origin), pressure])
  65. // Don't add duplicate points
  66. if (vec.isEqual(this.last, next)) return
  67. this.points.push(next)
  68. this.last = next
  69. this.previous = point
  70. const shape = getShape(data, snapshot.id) as DrawShape
  71. getShapeUtils(shape).setProperty(shape, 'points', [...this.points])
  72. updateParents(data, [shape.id])
  73. }
  74. cancel = (data: Data) => {
  75. const { snapshot } = this
  76. const shape = getShape(data, snapshot.id) as DrawShape
  77. getShapeUtils(shape).setProperty(shape, 'points', snapshot.points)
  78. updateParents(data, [shape.id])
  79. }
  80. complete = (data: Data) => {
  81. const { snapshot } = this
  82. const page = getPage(data)
  83. const shape = page.shapes[snapshot.id] as DrawShape
  84. getShapeUtils(shape)
  85. .setProperty(shape, 'points', [...this.points])
  86. .onSessionComplete(shape)
  87. updateParents(data, [shape.id])
  88. commands.draw(data, this.snapshot.id)
  89. }
  90. }
  91. export function getDrawSnapshot(data: Data, shapeId: string) {
  92. const page = getPage(current(data))
  93. const { points } = page.shapes[shapeId] as DrawShape
  94. return {
  95. id: shapeId,
  96. points,
  97. }
  98. }
  99. export type DrawSnapshot = ReturnType<typeof getDrawSnapshot>