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.

stretch.ts 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. import Command from './command'
  2. import history from '../history'
  3. import { StretchType, Data, Edge, Corner } from 'types'
  4. import { getCommonBounds, getPage, getSelectedShapes } from 'utils/utils'
  5. import { getShapeUtils } from 'lib/shape-utils'
  6. import { current } from 'immer'
  7. export default function stretchCommand(data: Data, type: StretchType) {
  8. const { currentPageId } = data
  9. const initialShapes = getSelectedShapes(current(data))
  10. const entries = initialShapes.map(
  11. (shape) => [shape.id, getShapeUtils(shape).getBounds(shape)] as const
  12. )
  13. const boundsForShapes = Object.fromEntries(entries)
  14. const commonBounds = getCommonBounds(...entries.map((entry) => entry[1]))
  15. history.execute(
  16. data,
  17. new Command({
  18. name: 'stretched_shapes',
  19. category: 'canvas',
  20. do(data) {
  21. const { shapes } = getPage(data, currentPageId)
  22. switch (type) {
  23. case StretchType.Horizontal: {
  24. for (let id in boundsForShapes) {
  25. const initialShape = initialShapes[id]
  26. const shape = shapes[id]
  27. const oldBounds = boundsForShapes[id]
  28. const newBounds = { ...oldBounds }
  29. newBounds.minX = commonBounds.minX
  30. newBounds.width = commonBounds.width
  31. newBounds.maxX = commonBounds.maxX
  32. getShapeUtils(shape).transform(shape, newBounds, {
  33. type: Corner.TopLeft,
  34. scaleX: newBounds.width / oldBounds.width,
  35. scaleY: 1,
  36. initialShape,
  37. transformOrigin: [0.5, 0.5],
  38. })
  39. }
  40. break
  41. }
  42. case StretchType.Vertical: {
  43. for (let id in boundsForShapes) {
  44. const initialShape = initialShapes[id]
  45. const shape = shapes[id]
  46. const oldBounds = boundsForShapes[id]
  47. const newBounds = { ...oldBounds }
  48. newBounds.minY = commonBounds.minY
  49. newBounds.height = commonBounds.height
  50. newBounds.maxY = commonBounds.maxY
  51. getShapeUtils(shape).transform(shape, newBounds, {
  52. type: Corner.TopLeft,
  53. scaleX: 1,
  54. scaleY: newBounds.height / oldBounds.height,
  55. initialShape,
  56. transformOrigin: [0.5, 0.5],
  57. })
  58. }
  59. }
  60. }
  61. },
  62. undo(data) {
  63. const { shapes } = getPage(data, currentPageId)
  64. for (let id in boundsForShapes) {
  65. const shape = shapes[id]
  66. const initialShape = initialShapes[id]
  67. const initialBounds = boundsForShapes[id]
  68. getShapeUtils(shape).transform(shape, initialBounds, {
  69. type: Corner.BottomRight,
  70. scaleX: 1,
  71. scaleY: 1,
  72. initialShape,
  73. transformOrigin: [0.5, 0.5],
  74. })
  75. }
  76. },
  77. })
  78. )
  79. }