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.

transform-single-session.ts 2.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. import { Data, Edge, Corner } from 'types'
  2. import * as vec from 'utils/vec'
  3. import BaseSession from './base-session'
  4. import commands from 'state/commands'
  5. import { current } from 'immer'
  6. import { getShapeUtils } from 'lib/shape-utils'
  7. import {
  8. getTransformedBoundingBox,
  9. getCommonBounds,
  10. getRotatedCorners,
  11. getTransformAnchor,
  12. getPage,
  13. getShape,
  14. getSelectedShapes,
  15. updateParents,
  16. } from 'utils/utils'
  17. export default class TransformSingleSession extends BaseSession {
  18. transformType: Edge | Corner
  19. origin: number[]
  20. scaleX = 1
  21. scaleY = 1
  22. snapshot: TransformSingleSnapshot
  23. isCreating: boolean
  24. constructor(
  25. data: Data,
  26. transformType: Corner | Edge,
  27. point: number[],
  28. isCreating = false
  29. ) {
  30. super(data)
  31. this.origin = point
  32. this.transformType = transformType
  33. this.snapshot = getTransformSingleSnapshot(data, transformType)
  34. this.isCreating = isCreating
  35. }
  36. update(data: Data, point: number[], isAspectRatioLocked = false) {
  37. const { transformType } = this
  38. const { initialShapeBounds, currentPageId, initialShape, id } =
  39. this.snapshot
  40. const shape = getShape(data, id, currentPageId)
  41. const newBoundingBox = getTransformedBoundingBox(
  42. initialShapeBounds,
  43. transformType,
  44. vec.vec(this.origin, point),
  45. shape.rotation,
  46. isAspectRatioLocked || !getShapeUtils(initialShape).canChangeAspectRatio
  47. )
  48. this.scaleX = newBoundingBox.scaleX
  49. this.scaleY = newBoundingBox.scaleY
  50. getShapeUtils(shape).transformSingle(shape, newBoundingBox, {
  51. initialShape,
  52. type: this.transformType,
  53. scaleX: this.scaleX,
  54. scaleY: this.scaleY,
  55. transformOrigin: [0.5, 0.5],
  56. })
  57. updateParents(data, [id])
  58. }
  59. cancel(data: Data) {
  60. const { id, initialShape } = this.snapshot
  61. const page = getPage(data)
  62. page.shapes[id] = initialShape
  63. updateParents(data, [id])
  64. }
  65. complete(data: Data) {
  66. if (!this.snapshot.hasUnlockedShape) return
  67. commands.transformSingle(
  68. data,
  69. this.snapshot,
  70. getTransformSingleSnapshot(data, this.transformType),
  71. this.isCreating
  72. )
  73. }
  74. }
  75. export function getTransformSingleSnapshot(
  76. data: Data,
  77. transformType: Edge | Corner
  78. ) {
  79. const shape = getSelectedShapes(current(data))[0]
  80. const bounds = getShapeUtils(shape).getBounds(shape)
  81. return {
  82. id: shape.id,
  83. hasUnlockedShape: !shape.isLocked,
  84. currentPageId: data.currentPageId,
  85. type: transformType,
  86. initialShape: shape,
  87. initialShapeBounds: bounds,
  88. }
  89. }
  90. export type TransformSingleSnapshot = ReturnType<
  91. typeof getTransformSingleSnapshot
  92. >