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.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. } from "utils/utils"
  16. export default class TransformSingleSession extends BaseSession {
  17. transformType: Edge | Corner
  18. origin: number[]
  19. scaleX = 1
  20. scaleY = 1
  21. snapshot: TransformSingleSnapshot
  22. isCreating: boolean
  23. constructor(
  24. data: Data,
  25. transformType: Corner | Edge,
  26. point: number[],
  27. isCreating = false
  28. ) {
  29. super(data)
  30. this.origin = point
  31. this.transformType = transformType
  32. this.snapshot = getTransformSingleSnapshot(data, transformType)
  33. this.isCreating = isCreating
  34. }
  35. update(data: Data, point: number[], isAspectRatioLocked = false) {
  36. const { transformType } = this
  37. const { initialShapeBounds, currentPageId, initialShape, id } =
  38. this.snapshot
  39. const shape = getShape(data, id, currentPageId)
  40. const newBoundingBox = getTransformedBoundingBox(
  41. initialShapeBounds,
  42. transformType,
  43. vec.vec(this.origin, point),
  44. shape.rotation,
  45. isAspectRatioLocked || !getShapeUtils(initialShape).canChangeAspectRatio
  46. )
  47. this.scaleX = newBoundingBox.scaleX
  48. this.scaleY = newBoundingBox.scaleY
  49. getShapeUtils(shape).transformSingle(shape, newBoundingBox, {
  50. initialShape,
  51. type: this.transformType,
  52. scaleX: this.scaleX,
  53. scaleY: this.scaleY,
  54. transformOrigin: [0.5, 0.5],
  55. })
  56. }
  57. cancel(data: Data) {
  58. const { id, initialShape, initialShapeBounds, currentPageId } =
  59. this.snapshot
  60. const shape = getShape(data, id, currentPageId)
  61. getShapeUtils(shape).transform(shape, initialShapeBounds, {
  62. initialShape,
  63. type: this.transformType,
  64. scaleX: this.scaleX,
  65. scaleY: this.scaleY,
  66. transformOrigin: [0.5, 0.5],
  67. })
  68. }
  69. complete(data: Data) {
  70. commands.transformSingle(
  71. data,
  72. this.snapshot,
  73. getTransformSingleSnapshot(data, this.transformType),
  74. this.scaleX,
  75. this.scaleY,
  76. this.isCreating
  77. )
  78. }
  79. }
  80. export function getTransformSingleSnapshot(
  81. data: Data,
  82. transformType: Edge | Corner
  83. ) {
  84. const shape = getSelectedShapes(current(data))[0]
  85. const bounds = getShapeUtils(shape).getBounds(shape)
  86. return {
  87. id: shape.id,
  88. currentPageId: data.currentPageId,
  89. type: transformType,
  90. initialShape: shape,
  91. initialShapeBounds: bounds,
  92. }
  93. }
  94. export type TransformSingleSnapshot = ReturnType<
  95. typeof getTransformSingleSnapshot
  96. >