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

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