|
@@ -3,20 +3,19 @@ import vec from 'utils/vec'
|
3
|
3
|
import { DashStyle, DrawShape, ShapeStyles, ShapeType } from 'types'
|
4
|
4
|
import { registerShapeUtils } from './index'
|
5
|
5
|
import { intersectPolylineBounds } from 'utils/intersections'
|
6
|
|
-import { boundsContain, boundsContainPolygon } from 'utils/bounds'
|
7
|
|
-import getStroke from 'perfect-freehand'
|
|
6
|
+import { boundsContain } from 'utils/bounds'
|
|
7
|
+import getStroke, { getStrokePoints } from 'perfect-freehand'
|
8
|
8
|
import {
|
9
|
9
|
getBoundsCenter,
|
10
|
10
|
getBoundsFromPoints,
|
11
|
|
- getRotatedCorners,
|
12
|
11
|
getSvgPathFromStroke,
|
13
|
|
- rotateBounds,
|
14
|
12
|
translateBounds,
|
15
|
13
|
} from 'utils/utils'
|
16
|
|
-import { defaultStyle, getShapeStyle } from 'lib/shape-styles'
|
|
14
|
+import { defaultStyle, getShapeStyle, strokes } from 'lib/shape-styles'
|
17
|
15
|
|
18
|
16
|
const rotatedCache = new WeakMap<DrawShape, number[][]>([])
|
19
|
17
|
const pathCache = new WeakMap<DrawShape['points'], string>([])
|
|
18
|
+const polygonCache = new WeakMap<DrawShape['points'], string>([])
|
20
|
19
|
|
21
|
20
|
const draw = registerShapeUtils<DrawShape>({
|
22
|
21
|
boundsCache: new WeakMap([]),
|
|
@@ -59,17 +58,24 @@ const draw = registerShapeUtils<DrawShape>({
|
59
|
58
|
)
|
60
|
59
|
}
|
61
|
60
|
|
|
61
|
+ const shouldFill =
|
|
62
|
+ points.length > 3 &&
|
|
63
|
+ vec.dist(points[0], points[points.length - 1]) < +styles.strokeWidth * 2
|
|
64
|
+
|
|
65
|
+ if (shouldFill && !polygonCache.has(points)) {
|
|
66
|
+ renderFill(shape, style)
|
|
67
|
+ }
|
|
68
|
+
|
62
|
69
|
return (
|
63
|
70
|
<g id={id}>
|
64
|
|
- {points.length > 3 &&
|
65
|
|
- vec.dist(points[0], points[points.length - 1]) < 8 && (
|
66
|
|
- <polyline
|
67
|
|
- points={points.map((pt) => pt.slice(0, 2)).join(',')}
|
68
|
|
- fill={styles.fill}
|
69
|
|
- stroke="none"
|
70
|
|
- strokeWidth={0}
|
71
|
|
- />
|
72
|
|
- )}
|
|
71
|
+ {shouldFill && (
|
|
72
|
+ <path
|
|
73
|
+ d={polygonCache.get(points)}
|
|
74
|
+ fill={styles.fill}
|
|
75
|
+ strokeWidth="0"
|
|
76
|
+ stroke="none"
|
|
77
|
+ />
|
|
78
|
+ )}
|
73
|
79
|
<path d={pathCache.get(points)} fill={styles.stroke} />
|
74
|
80
|
</g>
|
75
|
81
|
)
|
|
@@ -218,3 +224,24 @@ function renderPath(shape: DrawShape, style: ShapeStyles) {
|
218
|
224
|
|
219
|
225
|
pathCache.set(shape.points, getSvgPathFromStroke(stroke))
|
220
|
226
|
}
|
|
227
|
+
|
|
228
|
+function renderFill(shape: DrawShape, style: ShapeStyles) {
|
|
229
|
+ const styles = getShapeStyle(style)
|
|
230
|
+
|
|
231
|
+ if (shape.points.length < 2) {
|
|
232
|
+ polygonCache.set(shape.points, '')
|
|
233
|
+ return
|
|
234
|
+ }
|
|
235
|
+
|
|
236
|
+ return polygonCache.set(
|
|
237
|
+ shape.points,
|
|
238
|
+ getSvgPathFromStroke(
|
|
239
|
+ getStrokePoints(shape.points, {
|
|
240
|
+ size: 1 + +styles.strokeWidth * 2,
|
|
241
|
+ thinning: 0.85,
|
|
242
|
+ end: { taper: +styles.strokeWidth * 20 },
|
|
243
|
+ start: { taper: +styles.strokeWidth * 20 },
|
|
244
|
+ }).map((pt) => pt.point)
|
|
245
|
+ )
|
|
246
|
+ )
|
|
247
|
+}
|