選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

transform-single-session.ts 2.7KB

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