Du kannst nicht mehr als 25 Themen auswählen Themen müssen mit entweder einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

polyline.tsx 3.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import { uniqueId } from 'utils'
  2. import vec from 'utils/vec'
  3. import { PolylineShape, ShapeType } from 'types'
  4. import { intersectPolylineBounds } from 'utils/intersections'
  5. import {
  6. boundsContainPolygon,
  7. getBoundsFromPoints,
  8. translateBounds,
  9. } from 'utils'
  10. import { defaultStyle } from 'state/shape-styles'
  11. import { registerShapeUtils } from './register'
  12. const polyline = registerShapeUtils<PolylineShape>({
  13. boundsCache: new WeakMap([]),
  14. create(props) {
  15. return {
  16. id: uniqueId(),
  17. type: ShapeType.Polyline,
  18. isGenerated: false,
  19. name: 'Polyline',
  20. parentId: 'page1',
  21. childIndex: 0,
  22. point: [0, 0],
  23. points: [[0, 0]],
  24. rotation: 0,
  25. isAspectRatioLocked: false,
  26. isLocked: false,
  27. isHidden: false,
  28. style: defaultStyle,
  29. ...props,
  30. }
  31. },
  32. render({ id, points }) {
  33. return <polyline id={id} points={points.toString()} />
  34. },
  35. getBounds(shape) {
  36. if (!this.boundsCache.has(shape)) {
  37. this.boundsCache.set(shape, getBoundsFromPoints(shape.points))
  38. }
  39. return translateBounds(this.boundsCache.get(shape), shape.point)
  40. },
  41. getRotatedBounds(shape) {
  42. return this.getBounds(shape)
  43. },
  44. getCenter(shape) {
  45. const bounds = this.getBounds(shape)
  46. return [bounds.minX + bounds.width / 2, bounds.minY + bounds.height / 2]
  47. },
  48. hitTest(shape, point) {
  49. const pt = vec.sub(point, shape.point)
  50. let prev = shape.points[0]
  51. for (let i = 1; i < shape.points.length; i++) {
  52. const curr = shape.points[i]
  53. if (vec.distanceToLineSegment(prev, curr, pt) < 4) {
  54. return true
  55. }
  56. prev = curr
  57. }
  58. return false
  59. },
  60. hitTestBounds(this, shape, brushBounds) {
  61. const b = this.getBounds(shape)
  62. const center = [b.minX + b.width / 2, b.minY + b.height / 2]
  63. const rotatedCorners = [
  64. [b.minX, b.minY],
  65. [b.maxX, b.minY],
  66. [b.maxX, b.maxY],
  67. [b.minX, b.maxY],
  68. ].map((point) => vec.rotWith(point, center, shape.rotation))
  69. return (
  70. boundsContainPolygon(brushBounds, rotatedCorners) ||
  71. intersectPolylineBounds(
  72. shape.points.map((point) => vec.add(point, shape.point)),
  73. brushBounds
  74. ).length > 0
  75. )
  76. },
  77. transform(shape, bounds, { initialShape, scaleX, scaleY }) {
  78. const initialShapeBounds = this.getBounds(initialShape)
  79. shape.points = shape.points.map((_, i) => {
  80. const [x, y] = initialShape.points[i]
  81. return [
  82. bounds.width *
  83. (scaleX < 0
  84. ? 1 - x / initialShapeBounds.width
  85. : x / initialShapeBounds.width),
  86. bounds.height *
  87. (scaleY < 0
  88. ? 1 - y / initialShapeBounds.height
  89. : y / initialShapeBounds.height),
  90. ]
  91. })
  92. shape.point = [bounds.minX, bounds.minY]
  93. return this
  94. },
  95. transformSingle(shape, bounds, info) {
  96. this.transform(shape, bounds, info)
  97. return this
  98. },
  99. canTransform: true,
  100. canChangeAspectRatio: true,
  101. canStyleFill: false,
  102. })
  103. export default polyline