您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

paste.ts 2.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778
  1. import Command from './command'
  2. import history from '../history'
  3. import { Data, Shape } from 'types'
  4. import {
  5. getCommonBounds,
  6. getPage,
  7. getSelectedIds,
  8. screenToWorld,
  9. setSelectedIds,
  10. setToArray,
  11. } from 'utils'
  12. import { uniqueId } from 'utils'
  13. import vec from 'utils/vec'
  14. import { getShapeUtils } from 'state/shape-utils'
  15. import state from 'state/state'
  16. export default function pasteCommand(data: Data, initialShapes: Shape[]): void {
  17. const { currentPageId } = data
  18. const center = screenToWorld(
  19. [window.innerWidth / 2, window.innerHeight / 2],
  20. data
  21. )
  22. const bounds = getCommonBounds(
  23. ...initialShapes.map((shape) =>
  24. getShapeUtils(shape).getRotatedBounds(shape)
  25. )
  26. )
  27. const topLeft = vec.sub(center, [bounds.width / 2, bounds.height / 2])
  28. const newIdMap = Object.fromEntries(
  29. initialShapes.map((shape) => [shape.id, uniqueId()])
  30. )
  31. const oldSelectedIds = setToArray(getSelectedIds(data))
  32. history.execute(
  33. data,
  34. new Command({
  35. name: 'paste_new_shapes',
  36. category: 'canvas',
  37. manualSelection: true,
  38. do(data) {
  39. const { shapes } = getPage(data, currentPageId)
  40. let childIndex =
  41. (state.values.currentShapes[state.values.currentShapes.length - 1]
  42. ?.childIndex || 0) + 1
  43. for (const shape of initialShapes) {
  44. const topLeftOffset = vec.sub(shape.point, [bounds.minX, bounds.minY])
  45. const newId = newIdMap[shape.id]
  46. shapes[newId] = {
  47. ...shape,
  48. id: newId,
  49. parentId: oldSelectedIds[shape.parentId] || data.currentPageId,
  50. childIndex: childIndex++,
  51. point: vec.add(topLeft, topLeftOffset),
  52. isGenerated: false,
  53. }
  54. }
  55. setSelectedIds(data, Object.values(newIdMap))
  56. },
  57. undo(data) {
  58. const { shapes } = getPage(data, currentPageId)
  59. Object.values(newIdMap).forEach((id) => delete shapes[id])
  60. setSelectedIds(data, oldSelectedIds)
  61. },
  62. })
  63. )
  64. }