@weasel-js/geom 1.15.1 → 1.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/3d/index.d.ts +16 -2
- package/dist/3d/index.js +17 -10
- package/dist/3d/index.js.map +1 -1
- package/dist/booleans/index.js +5 -5
- package/dist/{chunk-B3D6KWW3.js → chunk-346XYYMX.js} +154 -3
- package/dist/chunk-346XYYMX.js.map +1 -0
- package/dist/{chunk-FROQPADA.js → chunk-5W425HJA.js} +82 -16
- package/dist/chunk-5W425HJA.js.map +1 -0
- package/dist/chunk-DNX24KBT.js +82 -0
- package/dist/chunk-DNX24KBT.js.map +1 -0
- package/dist/chunk-FOXMA54X.js +266 -0
- package/dist/chunk-FOXMA54X.js.map +1 -0
- package/dist/{chunk-3HQJGI63.js → chunk-HTT5AQIU.js} +3 -4
- package/dist/chunk-HTT5AQIU.js.map +1 -0
- package/dist/chunk-IOD2NFHQ.js +212 -0
- package/dist/chunk-IOD2NFHQ.js.map +1 -0
- package/dist/{chunk-HNLJO3E7.js → chunk-MOCSUHEI.js} +22 -8
- package/dist/chunk-MOCSUHEI.js.map +1 -0
- package/dist/{chunk-3YH5XU3H.js → chunk-OBPXEPUH.js} +14 -23
- package/dist/chunk-OBPXEPUH.js.map +1 -0
- package/dist/chunk-QSVZO7QZ.js +40 -0
- package/dist/chunk-QSVZO7QZ.js.map +1 -0
- package/dist/{chunk-EURWZUNY.js → chunk-TBS4NHGQ.js} +70 -93
- package/dist/chunk-TBS4NHGQ.js.map +1 -0
- package/dist/{chunk-HMGGJZTM.js → chunk-VJG5ZWCR.js} +7 -21
- package/dist/chunk-VJG5ZWCR.js.map +1 -0
- package/dist/{chunk-ZOMUTU7J.js → chunk-ZV24QZ6X.js} +5 -11
- package/dist/chunk-ZV24QZ6X.js.map +1 -0
- package/dist/{curvature-CDOI32hv.d.ts → curvature-DKPO4Qeh.d.ts} +0 -27
- package/dist/curves/index.d.ts +1 -1
- package/dist/curves/index.js +4 -4
- package/dist/index.d.ts +193 -13
- package/dist/index.js +409 -273
- package/dist/index.js.map +1 -1
- package/dist/lengthTable-Cv3W6lsH.d.ts +64 -0
- package/dist/nd/index.d.ts +28 -1
- package/dist/nd/index.js +2 -5
- package/dist/nd/index.js.map +1 -1
- package/dist/tessellate/index.d.ts +23 -1
- package/dist/tessellate/index.js +31 -17
- package/dist/tessellate/index.js.map +1 -1
- package/dist/warp/index.js +9 -15
- package/dist/warp/index.js.map +1 -1
- package/package.json +2 -2
- package/dist/chunk-2N6OWA7E.js +0 -104
- package/dist/chunk-2N6OWA7E.js.map +0 -1
- package/dist/chunk-3HQJGI63.js.map +0 -1
- package/dist/chunk-3YH5XU3H.js.map +0 -1
- package/dist/chunk-755Y4YZS.js +0 -32
- package/dist/chunk-755Y4YZS.js.map +0 -1
- package/dist/chunk-B3D6KWW3.js.map +0 -1
- package/dist/chunk-EURWZUNY.js.map +0 -1
- package/dist/chunk-FROQPADA.js.map +0 -1
- package/dist/chunk-HMGGJZTM.js.map +0 -1
- package/dist/chunk-HNLJO3E7.js.map +0 -1
- package/dist/chunk-ZOMUTU7J.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,29 +1,50 @@
|
|
|
1
|
-
import { carryCorners, parseSubpaths, intersectSegments, evalSeg, keepCorners, anchorRange, subSeg, writePath, derivSeg } from './chunk-
|
|
2
|
-
export { CORNER_RESTORE_TOLERANCE, cornerTraces, intersectSegments, keepCorners, restoreCorners } from './chunk-
|
|
1
|
+
import { carryCorners, parseSubpaths, intersectSegments, evalSeg, keepCorners, anchorRange, subSeg, writePath, derivSeg } from './chunk-OBPXEPUH.js';
|
|
2
|
+
export { CORNER_RESTORE_TOLERANCE, cornerTraces, intersectSegments, keepCorners, restoreCorners } from './chunk-OBPXEPUH.js';
|
|
3
|
+
import { lengthTable, closingAnchor, tableInternals, segmentArc, pointOnSegment } from './chunk-FOXMA54X.js';
|
|
4
|
+
export { anchorAtLength, closingAnchor, lengthAtAnchor, lengthAtSegmentFraction, lengthAtSubpath, lengthTable, pointAtLength } from './chunk-FOXMA54X.js';
|
|
3
5
|
import { createBvh } from './chunk-XXNK4N7Z.js';
|
|
4
6
|
import { PORT_REACH, portControls, portCurvePoints } from './chunk-YQADYJJ7.js';
|
|
5
7
|
export { PORT_REACH } from './chunk-YQADYJJ7.js';
|
|
6
|
-
import { eulerAngleAt, eulerSegmentCubic, eulerCubicError, integrateEuler, eulerPointAt, eulerCurvatureAt, cubicDerivativeAt, cubicCurvatureAt } from './chunk-
|
|
7
|
-
export { SPIRO_KINDS, combTeeth, cubicCurvatureAt, cubicCurvatureSource, cubicDerivativeAt, curvatureComb, eulerAngleAt, eulerCurvatureAt, eulerCurvatureDerivativesAt, eulerPointAt, fitEulerSegment, isSpiroKind, placeEulerSegment, solveSpiro, spiroContoursFromControl, spiroContoursOf, spiroControlPath, spiroToPath } from './chunk-
|
|
8
|
-
import { extractPolylines } from './chunk-
|
|
9
|
-
import
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
8
|
+
import { wrapPositive, eulerAngleAt, eulerSegmentCubic, eulerCubicError, integrateEuler, eulerPointAt, eulerCurvatureAt, DEG_TO_RAD, RAD_TO_DEG, cubicDerivativeAt, cubicCurvatureAt } from './chunk-MOCSUHEI.js';
|
|
9
|
+
export { DEG_TO_RAD, RAD_TO_DEG, SPIRO_KINDS, combTeeth, cubicCurvatureAt, cubicCurvatureSource, cubicDerivativeAt, curvatureComb, eulerAngleAt, eulerCurvatureAt, eulerCurvatureDerivativesAt, eulerPointAt, fitEulerSegment, isSpiroKind, placeEulerSegment, solveSpiro, spiroContoursFromControl, spiroContoursOf, spiroControlPath, spiroToPath, wrapAngle, wrapPositive } from './chunk-MOCSUHEI.js';
|
|
10
|
+
import { extractPolylines, polylineAtCurve } from './chunk-5W425HJA.js';
|
|
11
|
+
import './chunk-QSVZO7QZ.js';
|
|
12
|
+
import { boundsOfPath, fitPointRun, keepCorner } from './chunk-ZV24QZ6X.js';
|
|
13
|
+
export { boundsOfPath } from './chunk-ZV24QZ6X.js';
|
|
14
|
+
import { countPathAnchors, pathToAnchors, anchorsToPath, isAnchorSmooth, segmentEnds, isStraightSegment, nearestSegmentT } from './chunk-HTT5AQIU.js';
|
|
15
|
+
export { anchorsToPath, countPathAnchors, isAnchorSmooth, isStraightSegment, nearestSegmentT, pathToAnchors, segmentEnds } from './chunk-HTT5AQIU.js';
|
|
16
|
+
import { resolveCornersWithSources, resolveCorners, pointInPolygon, cornerCuts, fillsOpenSubpaths, schneiderFit, fitCubicWithTangents, flattenCubic, DEFAULT_FLATTEN_TOLERANCE, segmentsCross, flattenQuadratic, tangentAt } from './chunk-TBS4NHGQ.js';
|
|
17
|
+
export { CORNER_FIT_TOLERANCE, CORNER_KEYWORDS, DEFAULT_FLATTEN_TOLERANCE, cornerCenter, cornerCuts, cornerFrameAt, cornerFrames, cornerKeywordOf, cornerShapeK, cornerShapePieces, cornerShapePoint, defaultOpenFill, fillsOpenSubpaths, fitCubicWithTangents, flattenCubic, flattenCubicWithArcLen, flattenQuadratic, flattenQuadraticWithArcLen, isCornerShape, nextCornerShape, pointInPolygon, remapPerAnchor, resolveCorners, resolveCornersWithSources, ringSignedArea, schneiderFit, segmentsCross, setDefaultOpenFill } from './chunk-TBS4NHGQ.js';
|
|
18
|
+
import { lookupLength, lookupT, flatPoints, segmentLength, segmentTAtLength } from './chunk-IOD2NFHQ.js';
|
|
19
|
+
export { segmentLength, segmentTAtLength } from './chunk-IOD2NFHQ.js';
|
|
20
|
+
import { nearestOnLine, forEachSegment, PATH_M, PATH_L, PATH_Q, PATH_C, worldCoords, PATH_Z, PathBuilder, withCorner, scaleCorners, originFor, coordsFrom, pathCommandCoordCount, withoutCorners, elevateQuadraticToCubic, cubicEvalAt, nearestOnPath, cubicPointAt, splitCubicAtT, nearestOnCubic, cubicAxisExtremaTs, rectToContour, pointSegmentDist2, lerpPoint, distance, originOf, splitCubicAt, nearestOnQuadratic, boxesIntersect } from './chunk-346XYYMX.js';
|
|
21
|
+
export { ORIGIN_THRESHOLD, PATH_C, PATH_CMD_LENGTHS, PATH_COMMANDS, PATH_L, PATH_M, PATH_Q, PATH_Z, PathBuilder, addOrigin, asPolygonPath, boundsOfCoords, boxContainsBox, boxContainsPoint, boxesIntersect, compactCorners, coordsFrom, cornerAt, cornerSpecAt, cubicAxisExtremaTs, cubicBounds, cubicEvalAt, cubicPointAt, distance, distance2, elevateQuadraticToCubic, ellipsePath, forEachSegment, hasCorners, joinPaths, lerpCorners, lerpPoint, linePath, nearestOnCubic, nearestOnLine, nearestOnPath, nearestOnQuadratic, originFor, originOf, pathCommandCoordCount, pathPoint, pointSegmentDist, pointSegmentDist2, polygonFromPoints, polylineFromPoints, quadraticEvalAt, rectContainsPoint, rectContainsPointHalfOpen, rectPath, rectToContour, rectsIntersect, rectsOverlap, regularPolygonPath, scaleCorners, segmentT, splitCubicAt, splitCubicAtT, splitLineAt, splitQuadraticAt, starPath, unionBox, unionRects, withCorner, withoutCorners, worldCoords } from './chunk-346XYYMX.js';
|
|
22
|
+
import { SINGULAR_RATIO, clamp } from './chunk-DNX24KBT.js';
|
|
23
|
+
export { EPS, approxEq, clamp, clamp01, cross, dot, len2, lerp, sign, sub } from './chunk-DNX24KBT.js';
|
|
21
24
|
|
|
22
25
|
// src/view.ts
|
|
23
26
|
var ZOOM_FLOOR = 1e-9;
|
|
24
27
|
function normalizeZoom(zoom) {
|
|
25
28
|
return zoom >= ZOOM_FLOOR && zoom < Infinity ? zoom : ZOOM_FLOOR;
|
|
26
29
|
}
|
|
30
|
+
function viewWorldToScreen(view, p) {
|
|
31
|
+
return { x: (p.x - view.x) * view.scale.x, y: (p.y - view.y) * view.scale.y };
|
|
32
|
+
}
|
|
33
|
+
function viewScreenToWorld(view, p) {
|
|
34
|
+
return { x: p.x / view.scale.x + view.x, y: p.y / view.scale.y + view.y };
|
|
35
|
+
}
|
|
36
|
+
function viewRectToScreen(view, r) {
|
|
37
|
+
const x0 = (r.x - view.x) * view.scale.x;
|
|
38
|
+
const y0 = (r.y - view.y) * view.scale.y;
|
|
39
|
+
const w = r.width * view.scale.x;
|
|
40
|
+
const h = r.height * view.scale.y;
|
|
41
|
+
return {
|
|
42
|
+
x: w < 0 ? x0 + w : x0,
|
|
43
|
+
y: h < 0 ? y0 + h : y0,
|
|
44
|
+
width: Math.abs(w),
|
|
45
|
+
height: Math.abs(h)
|
|
46
|
+
};
|
|
47
|
+
}
|
|
27
48
|
|
|
28
49
|
// src/affine.ts
|
|
29
50
|
function identity() {
|
|
@@ -87,12 +108,12 @@ function transformCoords(coords, m) {
|
|
|
87
108
|
function lineShape(from, to) {
|
|
88
109
|
const dx2 = to.x - from.x;
|
|
89
110
|
const dy2 = to.y - from.y;
|
|
90
|
-
const
|
|
91
|
-
const tangent =
|
|
111
|
+
const length = Math.hypot(dx2, dy2);
|
|
112
|
+
const tangent = length === 0 ? { x: 1, y: 0 } : { x: dx2 / length, y: dy2 / length };
|
|
92
113
|
const normal2 = { x: tangent.y, y: -tangent.x };
|
|
93
114
|
return {
|
|
94
115
|
kind: "line",
|
|
95
|
-
length
|
|
116
|
+
length,
|
|
96
117
|
closed: false,
|
|
97
118
|
at(f, options) {
|
|
98
119
|
const t = options?.open ? f : clamp(f, 0, 1);
|
|
@@ -104,25 +125,23 @@ function lineShape(from, to) {
|
|
|
104
125
|
},
|
|
105
126
|
nearest(p, options) {
|
|
106
127
|
const n = nearestOnLine(p.x, p.y, from.x, from.y, to.x, to.y);
|
|
107
|
-
if (!options?.open ||
|
|
108
|
-
const f = ((p.x - from.x) * dx2 + (p.y - from.y) * dy2) / (
|
|
128
|
+
if (!options?.open || length === 0) return { f: n.t, dist: n.dist };
|
|
129
|
+
const f = ((p.x - from.x) * dx2 + (p.y - from.y) * dy2) / (length * length);
|
|
109
130
|
return { f, dist: n.dist };
|
|
110
131
|
}
|
|
111
132
|
};
|
|
112
133
|
}
|
|
113
134
|
|
|
114
135
|
// src/track/arc.ts
|
|
115
|
-
var RAD = Math.PI / 180;
|
|
116
|
-
var mod360 = (a) => (a % 360 + 360) % 360;
|
|
117
136
|
function arcShape(spec) {
|
|
118
137
|
const { center, radius, start } = spec;
|
|
119
138
|
const sign2 = spec.direction === "ccw" ? -1 : 1;
|
|
120
|
-
const raw =
|
|
139
|
+
const raw = wrapPositive(sign2 * (spec.end - start), 360);
|
|
121
140
|
const sweep = raw === 0 ? 360 : raw;
|
|
122
|
-
const
|
|
141
|
+
const length = radius * sweep * DEG_TO_RAD;
|
|
123
142
|
const at2 = (f, options) => {
|
|
124
143
|
const t = options?.open ? f : clamp(f, 0, 1);
|
|
125
|
-
const theta = (start + sign2 * t * sweep) *
|
|
144
|
+
const theta = (start + sign2 * t * sweep) * DEG_TO_RAD;
|
|
126
145
|
const s = Math.sin(theta);
|
|
127
146
|
const c = Math.cos(theta);
|
|
128
147
|
return {
|
|
@@ -133,14 +152,14 @@ function arcShape(spec) {
|
|
|
133
152
|
};
|
|
134
153
|
const shape = {
|
|
135
154
|
kind: "arc",
|
|
136
|
-
length
|
|
155
|
+
length,
|
|
137
156
|
closed: raw === 0,
|
|
138
157
|
at: at2,
|
|
139
158
|
nearest(p, options) {
|
|
140
159
|
const dx2 = p.x - center.x;
|
|
141
160
|
const dy2 = p.y - center.y;
|
|
142
|
-
const angle = dx2 === 0 && dy2 === 0 ? 0 : Math.atan2(dx2, -dy2) /
|
|
143
|
-
const offset2 =
|
|
161
|
+
const angle = dx2 === 0 && dy2 === 0 ? 0 : Math.atan2(dx2, -dy2) / DEG_TO_RAD;
|
|
162
|
+
const offset2 = wrapPositive(sign2 * (angle - start), 360);
|
|
144
163
|
let f;
|
|
145
164
|
if (offset2 <= sweep) f = offset2 / sweep;
|
|
146
165
|
else f = 360 - offset2 < offset2 - sweep ? 0 : 1;
|
|
@@ -148,7 +167,7 @@ function arcShape(spec) {
|
|
|
148
167
|
const dist = Math.hypot(p.x - q.x, p.y - q.y);
|
|
149
168
|
if (!options?.open) return { f, dist };
|
|
150
169
|
const mid = (options.about ?? 0.5) * sweep;
|
|
151
|
-
const unwrapped = mid +
|
|
170
|
+
const unwrapped = mid + wrapPositive(offset2 - mid + 180, 360) - 180;
|
|
152
171
|
return { f: unwrapped / sweep, dist };
|
|
153
172
|
}
|
|
154
173
|
};
|
|
@@ -157,20 +176,18 @@ function arcShape(spec) {
|
|
|
157
176
|
}
|
|
158
177
|
|
|
159
178
|
// src/track/ellipse.ts
|
|
160
|
-
var RAD2 = Math.PI / 180;
|
|
161
|
-
var mod3602 = (a) => (a % 360 + 360) % 360;
|
|
162
179
|
var PIECES = 128;
|
|
163
180
|
var PANELS = 4;
|
|
164
181
|
var RING = 256;
|
|
165
182
|
var pointAt = ({ center, a, b, t0, sign: sign2 }, u) => {
|
|
166
|
-
const t = (t0 + sign2 * u) *
|
|
183
|
+
const t = (t0 + sign2 * u) * DEG_TO_RAD;
|
|
167
184
|
return { x: center.x + a * Math.sin(t), y: center.y - b * Math.cos(t) };
|
|
168
185
|
};
|
|
169
186
|
var speed = ({ a, b, t0, sign: sign2 }, u) => {
|
|
170
|
-
const t = (t0 + sign2 * u) *
|
|
171
|
-
return Math.hypot(a * Math.cos(t), b * Math.sin(t)) *
|
|
187
|
+
const t = (t0 + sign2 * u) * DEG_TO_RAD;
|
|
188
|
+
return Math.hypot(a * Math.cos(t), b * Math.sin(t)) * DEG_TO_RAD;
|
|
172
189
|
};
|
|
173
|
-
function
|
|
190
|
+
function lengthTable2(e, sweep) {
|
|
174
191
|
const simpson = (u0, u1) => {
|
|
175
192
|
const h = (u1 - u0) / PANELS;
|
|
176
193
|
let sum = speed(e, u0) + speed(e, u1);
|
|
@@ -180,7 +197,7 @@ function lengthTable(e, sweep) {
|
|
|
180
197
|
const du = sweep / PIECES;
|
|
181
198
|
const table = [0];
|
|
182
199
|
for (let i = 0; i < PIECES; i++) table.push(table[i] + simpson(i * du, (i + 1) * du));
|
|
183
|
-
const
|
|
200
|
+
const length = table[PIECES];
|
|
184
201
|
const lengthTo = (u) => {
|
|
185
202
|
if (u >= 0 && u <= sweep) {
|
|
186
203
|
const i = Math.min(PIECES - 1, Math.floor(u / du));
|
|
@@ -192,8 +209,8 @@ function lengthTable(e, sweep) {
|
|
|
192
209
|
return s;
|
|
193
210
|
};
|
|
194
211
|
const offsetAt = (f) => {
|
|
195
|
-
if (
|
|
196
|
-
const s = f *
|
|
212
|
+
if (length === 0) return f * sweep;
|
|
213
|
+
const s = f * length;
|
|
197
214
|
let lo = 0;
|
|
198
215
|
let hi = PIECES;
|
|
199
216
|
while (hi - lo > 1) {
|
|
@@ -210,7 +227,7 @@ function lengthTable(e, sweep) {
|
|
|
210
227
|
}
|
|
211
228
|
return u;
|
|
212
229
|
};
|
|
213
|
-
return { length
|
|
230
|
+
return { length, lengthTo, offsetAt };
|
|
214
231
|
}
|
|
215
232
|
var dist2 = (e, p, u) => {
|
|
216
233
|
const q = pointAt(e, u);
|
|
@@ -230,13 +247,13 @@ function footBetween(e, p, lo, hi, n, late) {
|
|
|
230
247
|
const dy2 = p.y - e.center.y;
|
|
231
248
|
let u = best;
|
|
232
249
|
for (let i = 0; i < 12; i++) {
|
|
233
|
-
const t = (t0 + sign2 * u) *
|
|
250
|
+
const t = (t0 + sign2 * u) * DEG_TO_RAD;
|
|
234
251
|
const s = Math.sin(t);
|
|
235
252
|
const c = Math.cos(t);
|
|
236
253
|
const g = (a * a - b * b) * s * c - dx2 * a * c - dy2 * b * s;
|
|
237
254
|
const g1 = (a * a - b * b) * (c * c - s * s) + dx2 * a * s - dy2 * b * c;
|
|
238
255
|
if (!(g1 > 0)) break;
|
|
239
|
-
const next = clamp(u - sign2 * g / g1 /
|
|
256
|
+
const next = clamp(u - sign2 * g / g1 / DEG_TO_RAD, Math.max(lo, best - step), Math.min(hi, best + step));
|
|
240
257
|
if (Math.abs(next - u) < 1e-12) break;
|
|
241
258
|
u = next;
|
|
242
259
|
}
|
|
@@ -245,24 +262,24 @@ function footBetween(e, p, lo, hi, n, late) {
|
|
|
245
262
|
function ellipseShape(spec) {
|
|
246
263
|
const { center, radiusX: a, radiusY: b } = spec;
|
|
247
264
|
const sign2 = spec.direction === "ccw" ? -1 : 1;
|
|
248
|
-
const param = (seenDeg) => Math.atan2(b * Math.sin(seenDeg *
|
|
265
|
+
const param = (seenDeg) => Math.atan2(b * Math.sin(seenDeg * DEG_TO_RAD), a * Math.cos(seenDeg * DEG_TO_RAD)) / DEG_TO_RAD;
|
|
249
266
|
const e = { center, a, b, t0: param(spec.start), sign: sign2 };
|
|
250
|
-
const raw =
|
|
267
|
+
const raw = wrapPositive(sign2 * (param(spec.end) - e.t0), 360);
|
|
251
268
|
const sweep = raw === 0 ? 360 : raw;
|
|
252
|
-
const { length
|
|
269
|
+
const { length, lengthTo, offsetAt } = lengthTable2(e, sweep);
|
|
253
270
|
const offsetPast = (f) => {
|
|
254
271
|
if (raw === 0) return offsetAt((f % 1 + 1) % 1);
|
|
255
272
|
let u = f * sweep;
|
|
256
273
|
for (let i = 0; i < 8; i++) {
|
|
257
274
|
const v = speed(e, u);
|
|
258
275
|
if (!(v > 0)) break;
|
|
259
|
-
u -= (lengthTo(u) - f *
|
|
276
|
+
u -= (lengthTo(u) - f * length) / v;
|
|
260
277
|
}
|
|
261
278
|
return u;
|
|
262
279
|
};
|
|
263
280
|
const at2 = (f, options) => {
|
|
264
281
|
const u = options?.open && (f < 0 || f > 1) ? offsetPast(f) : offsetAt(clamp(f, 0, 1));
|
|
265
|
-
const t = (e.t0 + sign2 * u) *
|
|
282
|
+
const t = (e.t0 + sign2 * u) * DEG_TO_RAD;
|
|
266
283
|
const s = Math.sin(t);
|
|
267
284
|
const c = Math.cos(t);
|
|
268
285
|
const k = Math.hypot(a * c, b * s);
|
|
@@ -272,56 +289,94 @@ function ellipseShape(spec) {
|
|
|
272
289
|
};
|
|
273
290
|
const shape = {
|
|
274
291
|
kind: "ellipse",
|
|
275
|
-
length
|
|
292
|
+
length,
|
|
276
293
|
closed: raw === 0,
|
|
277
294
|
at: at2,
|
|
278
295
|
nearest(p, options) {
|
|
279
296
|
const u = footBetween(e, p, 0, sweep, PIECES, true);
|
|
280
|
-
const f =
|
|
297
|
+
const f = length === 0 ? 0 : clamp(lengthTo(u) / length, 0, 1);
|
|
281
298
|
const dist = Math.sqrt(dist2(e, p, u));
|
|
282
|
-
if (!options?.open ||
|
|
299
|
+
if (!options?.open || length === 0) return { f, dist };
|
|
283
300
|
const mid = offsetAt(options.about ?? 0.5);
|
|
284
|
-
return { f: lengthTo(footBetween(e, p, mid - 180, mid + 180, RING, false)) /
|
|
301
|
+
return { f: lengthTo(footBetween(e, p, mid - 180, mid + 180, RING, false)) / length, dist };
|
|
285
302
|
}
|
|
286
303
|
};
|
|
287
304
|
Object.defineProperty(shape, "ellipse", { value: spec, enumerable: false });
|
|
288
305
|
return shape;
|
|
289
306
|
}
|
|
290
307
|
|
|
308
|
+
// src/along/pathTable.ts
|
|
309
|
+
var tables = /* @__PURE__ */ new WeakMap();
|
|
310
|
+
function pathLengthTable(path) {
|
|
311
|
+
const hit = tables.get(path);
|
|
312
|
+
if (hit) return hit;
|
|
313
|
+
let table;
|
|
314
|
+
if (path.kind === "rect") {
|
|
315
|
+
table = lengthTable(extractPolylines(path), 2);
|
|
316
|
+
} else {
|
|
317
|
+
const { path: resolved, anchorSources } = resolveCornersWithSources(path);
|
|
318
|
+
const controls2 = controlsByAnchor(resolved);
|
|
319
|
+
table = lengthTable(extractPolylines(resolved).map((pl) => anchorRun(pl, controls2)), 2, anchorSources);
|
|
320
|
+
}
|
|
321
|
+
tables.set(path, table);
|
|
322
|
+
return table;
|
|
323
|
+
}
|
|
324
|
+
function controlsByAnchor(path) {
|
|
325
|
+
const out = [];
|
|
326
|
+
const { commands, coords } = path;
|
|
327
|
+
forEachSegment(commands, coords, (cmd, ci) => {
|
|
328
|
+
if (cmd === PATH_M || cmd === PATH_L) out.push(null);
|
|
329
|
+
else if (cmd === PATH_Q) out.push([coords[ci], coords[ci + 1]]);
|
|
330
|
+
else if (cmd === PATH_C) out.push([coords[ci], coords[ci + 1], coords[ci + 2], coords[ci + 3]]);
|
|
331
|
+
});
|
|
332
|
+
return out;
|
|
333
|
+
}
|
|
334
|
+
function anchorRun(pl, controls2) {
|
|
335
|
+
const n = pl.points.length / 2;
|
|
336
|
+
const { anchorA: A, anchorB: B } = pl;
|
|
337
|
+
const points = [];
|
|
338
|
+
const ids = [];
|
|
339
|
+
for (let i = 0; i < n; i++) {
|
|
340
|
+
if (A && B && A[i] !== B[i]) continue;
|
|
341
|
+
points.push(pl.points[i * 2], pl.points[i * 2 + 1]);
|
|
342
|
+
ids.push(A ? A[i] : i);
|
|
343
|
+
}
|
|
344
|
+
const segControls = ids.slice(1).map((id) => controls2[id] ?? null);
|
|
345
|
+
const close = closingAnchor(pl);
|
|
346
|
+
if (pl.closed && n >= 2) segControls.push(close === void 0 ? null : controls2[close] ?? null);
|
|
347
|
+
const anchors = Uint32Array.from(ids);
|
|
348
|
+
return {
|
|
349
|
+
points,
|
|
350
|
+
closed: pl.closed,
|
|
351
|
+
anchorA: anchors,
|
|
352
|
+
anchorB: anchors.slice(),
|
|
353
|
+
anchorT: new Float32Array(ids.length),
|
|
354
|
+
...close !== void 0 ? { closeAnchor: close } : {},
|
|
355
|
+
controls: segControls
|
|
356
|
+
};
|
|
357
|
+
}
|
|
358
|
+
|
|
291
359
|
// src/paths/pathMeasure.ts
|
|
292
360
|
function measurePath(path, opts = {}) {
|
|
293
361
|
const polylines = extractPolylines(
|
|
294
362
|
path,
|
|
295
363
|
opts.flattenTolerance === void 0 ? {} : { flattenTolerance: opts.flattenTolerance }
|
|
296
364
|
);
|
|
365
|
+
const table = pathLengthTable(path);
|
|
366
|
+
const cornerTolerance = opts.keepCorners ? opts.flattenTolerance ?? 0.5 : null;
|
|
297
367
|
const segments = [];
|
|
298
|
-
let total = 0;
|
|
299
368
|
let first;
|
|
300
369
|
let contours = 0;
|
|
301
370
|
let lastClosed = false;
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
if (count === 0) continue;
|
|
371
|
+
polylines.forEach((pl, r) => {
|
|
372
|
+
if (pl.points.length === 0) return;
|
|
305
373
|
contours++;
|
|
306
374
|
lastClosed = pl.closed;
|
|
307
375
|
first ??= { x: pl.points[0], y: pl.points[1] };
|
|
308
376
|
const startIndex = segments.length;
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
const ax = pl.points[i * 2];
|
|
313
|
-
const ay = pl.points[i * 2 + 1];
|
|
314
|
-
const bx = pl.points[j * 2];
|
|
315
|
-
const by = pl.points[j * 2 + 1];
|
|
316
|
-
const len = Math.hypot(bx - ax, by - ay);
|
|
317
|
-
if (len === 0) continue;
|
|
318
|
-
const tx = (bx - ax) / len;
|
|
319
|
-
const ty = (by - ay) / len;
|
|
320
|
-
segments.push({ ax, ay, bx, by, start: total, len, tx, ty, t0x: tx, t0y: ty, t1x: tx, t1y: ty });
|
|
321
|
-
total += len;
|
|
322
|
-
}
|
|
323
|
-
smoothVertexHeadings(segments, startIndex, pl.closed, opts.keepCorners ? opts.flattenTolerance ?? 0.5 : null);
|
|
324
|
-
}
|
|
377
|
+
pushChords(pl, r, table, segments);
|
|
378
|
+
smoothVertexHeadings(segments, startIndex, pl.closed, cornerTolerance);
|
|
379
|
+
});
|
|
325
380
|
if (first === void 0) return null;
|
|
326
381
|
const origin = first;
|
|
327
382
|
const closed = contours === 1 && lastClosed;
|
|
@@ -338,15 +393,20 @@ function measurePath(path, opts = {}) {
|
|
|
338
393
|
})
|
|
339
394
|
};
|
|
340
395
|
}
|
|
396
|
+
const total = table.total;
|
|
397
|
+
const pointAt2 = (seg, s) => {
|
|
398
|
+
const { point } = pointOnSegment(table, seg.run, seg.seg, s);
|
|
399
|
+
return { x: point[0], y: point[1] };
|
|
400
|
+
};
|
|
341
401
|
return {
|
|
342
402
|
length: total,
|
|
343
403
|
closed,
|
|
344
404
|
at(s, smooth = false) {
|
|
345
405
|
const target = Math.min(Math.max(s, 0), total);
|
|
346
406
|
const seg = segments[segmentAt(segments, target)];
|
|
347
|
-
const
|
|
348
|
-
const point = { x: seg.ax + (seg.bx - seg.ax) * u, y: seg.ay + (seg.by - seg.ay) * u };
|
|
407
|
+
const point = pointAt2(seg, target);
|
|
349
408
|
if (!smooth) return { point, tangent: { x: seg.tx, y: seg.ty } };
|
|
409
|
+
const u = seg.arc > 0 ? Math.min(Math.max((target - seg.start) / seg.arc, 0), 1) : 0;
|
|
350
410
|
const x = seg.t0x + (seg.t1x - seg.t0x) * u;
|
|
351
411
|
const y = seg.t0y + (seg.t1y - seg.t0y) * u;
|
|
352
412
|
const l = Math.hypot(x, y);
|
|
@@ -365,15 +425,58 @@ function measurePath(path, opts = {}) {
|
|
|
365
425
|
bestDist = d;
|
|
366
426
|
}
|
|
367
427
|
}
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
point: { x: best.ax + (best.bx - best.ax) * bestU, y: best.ay + (best.by - best.ay) * bestU },
|
|
372
|
-
tangent: { x: best.tx, y: best.ty }
|
|
373
|
-
};
|
|
428
|
+
const s = best.start + best.arc * bestU;
|
|
429
|
+
const point = pointAt2(best, s);
|
|
430
|
+
return { s, dist: Math.hypot(p.x - point.x, p.y - point.y), point, tangent: { x: best.tx, y: best.ty } };
|
|
374
431
|
}
|
|
375
432
|
};
|
|
376
433
|
}
|
|
434
|
+
function pushChords(pl, r, table, segments) {
|
|
435
|
+
const c = tableInternals(table).cum[r];
|
|
436
|
+
const { points, anchorA: A, anchorB: B, anchorT: T } = pl;
|
|
437
|
+
const count = points.length / 2;
|
|
438
|
+
const segOf = new Int32Array(count);
|
|
439
|
+
const lenOf = new Float64Array(count);
|
|
440
|
+
let k = -1;
|
|
441
|
+
for (let i = 0; i < count; i++) {
|
|
442
|
+
const aligned = !A || !B || A[i] === B[i];
|
|
443
|
+
if (aligned) k++;
|
|
444
|
+
const at2 = Math.max(k, 0);
|
|
445
|
+
segOf[i] = Math.min(at2, c.length - 2);
|
|
446
|
+
lenOf[i] = aligned || !T ? c[at2] : c[at2] + T[i] * (c[at2 + 1] - c[at2]);
|
|
447
|
+
}
|
|
448
|
+
const last = pl.closed ? count : count - 1;
|
|
449
|
+
for (let i = 0; i < last; i++) {
|
|
450
|
+
const j = (i + 1) % count;
|
|
451
|
+
const ax = points[i * 2];
|
|
452
|
+
const ay = points[i * 2 + 1];
|
|
453
|
+
const bx = points[j * 2];
|
|
454
|
+
const by = points[j * 2 + 1];
|
|
455
|
+
const len = Math.hypot(bx - ax, by - ay);
|
|
456
|
+
if (len === 0) continue;
|
|
457
|
+
const tx = (bx - ax) / len;
|
|
458
|
+
const ty = (by - ay) / len;
|
|
459
|
+
const start = lenOf[i];
|
|
460
|
+
const arc2 = (j === 0 ? c[c.length - 1] : lenOf[j]) - start;
|
|
461
|
+
segments.push({
|
|
462
|
+
ax,
|
|
463
|
+
ay,
|
|
464
|
+
bx,
|
|
465
|
+
by,
|
|
466
|
+
len,
|
|
467
|
+
start,
|
|
468
|
+
arc: arc2,
|
|
469
|
+
run: r,
|
|
470
|
+
seg: segOf[i],
|
|
471
|
+
tx,
|
|
472
|
+
ty,
|
|
473
|
+
t0x: tx,
|
|
474
|
+
t0y: ty,
|
|
475
|
+
t1x: tx,
|
|
476
|
+
t1y: ty
|
|
477
|
+
});
|
|
478
|
+
}
|
|
479
|
+
}
|
|
377
480
|
function smoothVertexHeadings(segments, from, closed, cornerTolerance) {
|
|
378
481
|
const n = segments.length - from;
|
|
379
482
|
if (n < 2) return;
|
|
@@ -413,22 +516,22 @@ function segmentAt(segments, s) {
|
|
|
413
516
|
function pathShape(path, options = {}) {
|
|
414
517
|
const measure2 = measurePath(path, { ...options, keepCorners: true });
|
|
415
518
|
if (!measure2) return null;
|
|
416
|
-
const { length
|
|
519
|
+
const { length, closed } = measure2;
|
|
417
520
|
const shape = {
|
|
418
521
|
kind: "path",
|
|
419
|
-
length
|
|
522
|
+
length,
|
|
420
523
|
closed,
|
|
421
524
|
at(f, options2) {
|
|
422
525
|
const open = options2?.open === true && (f < 0 || f > 1);
|
|
423
526
|
const g = open && closed ? (f % 1 + 1) % 1 : clamp(f, 0, 1);
|
|
424
|
-
const { point, tangent } = measure2.at(g *
|
|
425
|
-
const past = open && !closed ? (f - g) *
|
|
527
|
+
const { point, tangent } = measure2.at(g * length, true);
|
|
528
|
+
const past = open && !closed ? (f - g) * length : 0;
|
|
426
529
|
return { point: { x: point.x + past * tangent.x, y: point.y + past * tangent.y }, tangent, normal: { x: tangent.y, y: -tangent.x } };
|
|
427
530
|
},
|
|
428
531
|
nearest(p, opts) {
|
|
429
532
|
const n = measure2.nearest(p);
|
|
430
|
-
const f =
|
|
431
|
-
if (!opts?.open || !closed ||
|
|
533
|
+
const f = length === 0 ? 0 : n.s / length;
|
|
534
|
+
if (!opts?.open || !closed || length === 0) return { f, dist: n.dist };
|
|
432
535
|
const about = opts.about ?? 0.5;
|
|
433
536
|
const unwrapped = [f - 1, f + 1].reduce((best, g) => Math.abs(g - about) < Math.abs(best - about) ? g : best, f);
|
|
434
537
|
return { f: unwrapped, dist: n.dist };
|
|
@@ -456,7 +559,7 @@ function trackRun(shape, from = 0, to = 1, options = {}) {
|
|
|
456
559
|
const at2 = (g, options2) => {
|
|
457
560
|
const s = options2?.open ? shape.at(toShape(g), options2) : shape.at(toShape(clamp(g, 0, 1)));
|
|
458
561
|
const dir = reading(s.normal);
|
|
459
|
-
const angle = Math.atan2(dir.y, dir.x) *
|
|
562
|
+
const angle = Math.atan2(dir.y, dir.x) * RAD_TO_DEG;
|
|
460
563
|
const normal2 = { x: sgn * s.normal.x, y: sgn * s.normal.y };
|
|
461
564
|
return {
|
|
462
565
|
point: s.point,
|
|
@@ -556,7 +659,7 @@ function trackShapeD(shape, from = 0, to = 1) {
|
|
|
556
659
|
const param = (p) => Math.atan2((p.x - center.x) / radiusX, (center.y - p.y) / radiusY);
|
|
557
660
|
const sign2 = direction === "ccw" ? -1 : 1;
|
|
558
661
|
const whole = (shape.ellipse.start - shape.ellipse.end) % 360 === 0 && Math.abs(to - from) >= 1 - 1e-12;
|
|
559
|
-
const raw = (sign2 * Math.sign(to - from) * (param(b) - param(a))
|
|
662
|
+
const raw = wrapPositive(sign2 * Math.sign(to - from) * (param(b) - param(a)));
|
|
560
663
|
return arcsD(a, b, m, radiusX, radiusY, whole ? 2 * Math.PI : raw, direction === "ccw" === to < from ? 1 : 0);
|
|
561
664
|
}
|
|
562
665
|
let d = `M ${pt(a)}`;
|
|
@@ -591,15 +694,15 @@ function shiftTrack(shape, shift) {
|
|
|
591
694
|
table[i] = table[i - 1] + Math.hypot(step.x, step.y);
|
|
592
695
|
prev = next;
|
|
593
696
|
}
|
|
594
|
-
const
|
|
697
|
+
const length = table[SAMPLES2];
|
|
595
698
|
const per = shape.length / SAMPLES2;
|
|
596
699
|
const startRatio = table[1] > 0 ? per / table[1] : 1;
|
|
597
700
|
const endRatio = table[SAMPLES2] - table[SAMPLES2 - 1] > 0 ? per / (table[SAMPLES2] - table[SAMPLES2 - 1]) : 1;
|
|
598
701
|
const toBase = (f) => {
|
|
599
|
-
const d = f *
|
|
600
|
-
if (
|
|
702
|
+
const d = f * length;
|
|
703
|
+
if (length <= 0 || shape.length <= 0) return f;
|
|
601
704
|
if (d < 0) return d * startRatio / shape.length;
|
|
602
|
-
if (d >
|
|
705
|
+
if (d > length) return 1 + (d - length) * endRatio / shape.length;
|
|
603
706
|
let lo = 0;
|
|
604
707
|
let hi = SAMPLES2;
|
|
605
708
|
while (hi - lo > 1) {
|
|
@@ -611,17 +714,17 @@ function shiftTrack(shape, shift) {
|
|
|
611
714
|
return (lo + (span > 0 ? (d - table[lo]) / span : 0)) / SAMPLES2;
|
|
612
715
|
};
|
|
613
716
|
const fromBase = (g) => {
|
|
614
|
-
if (
|
|
615
|
-
if (g < 0) return g * shape.length / startRatio /
|
|
616
|
-
if (g > 1) return (
|
|
717
|
+
if (length <= 0 || shape.length <= 0) return g;
|
|
718
|
+
if (g < 0) return g * shape.length / startRatio / length;
|
|
719
|
+
if (g > 1) return (length + (g - 1) * shape.length / endRatio) / length;
|
|
617
720
|
const x = g * SAMPLES2;
|
|
618
721
|
const i = Math.min(SAMPLES2 - 1, Math.floor(x));
|
|
619
|
-
return (table[i] + (x - i) * (table[i + 1] - table[i])) /
|
|
722
|
+
return (table[i] + (x - i) * (table[i + 1] - table[i])) / length;
|
|
620
723
|
};
|
|
621
724
|
const at2 = (f, options) => moved2(shape.at(toBase(options?.open ? f : clamp(f, 0, 1)), options));
|
|
622
725
|
return {
|
|
623
726
|
kind: shape.kind,
|
|
624
|
-
length
|
|
727
|
+
length,
|
|
625
728
|
closed: shape.closed,
|
|
626
729
|
at: at2,
|
|
627
730
|
nearest(p, options) {
|
|
@@ -634,8 +737,7 @@ function shiftTrack(shape, shift) {
|
|
|
634
737
|
}
|
|
635
738
|
|
|
636
739
|
// src/track/slice.ts
|
|
637
|
-
var
|
|
638
|
-
var seen = (c, p) => Math.atan2(p.x - c.x, c.y - p.y) / RAD3;
|
|
740
|
+
var seen = (c, p) => Math.atan2(p.x - c.x, c.y - p.y) / DEG_TO_RAD;
|
|
639
741
|
function trackSlice(shape, from, to) {
|
|
640
742
|
const lo = clamp(Math.min(from, to), 0, 1);
|
|
641
743
|
const hi = clamp(Math.max(from, to), 0, 1);
|
|
@@ -675,25 +777,25 @@ function runPlaces(lengths, gap, room, align, offset2, at2) {
|
|
|
675
777
|
const fits = at2 === void 0 && total <= room;
|
|
676
778
|
const lead = align === "start" ? 0 : align === "end" ? total : total / 2;
|
|
677
779
|
let lo = at2 !== void 0 ? at2 - offset2 - lead : !fits ? -offset2 : align === "start" ? 0 : align === "end" ? room - total : (room - total) / 2;
|
|
678
|
-
return lengths.map((
|
|
780
|
+
return lengths.map((length) => {
|
|
679
781
|
const start = lo;
|
|
680
|
-
const hi = start +
|
|
782
|
+
const hi = start + length;
|
|
681
783
|
lo = hi + gap;
|
|
682
|
-
return { center: start +
|
|
784
|
+
return { center: start + length / 2, clipped: fits ? "none" : clipOf(start, hi, 0, room) };
|
|
683
785
|
});
|
|
684
786
|
}
|
|
685
787
|
function runLength(lengths, gap) {
|
|
686
|
-
return lengths.reduce((sum,
|
|
788
|
+
return lengths.reduce((sum, length, i) => sum + length + (i > 0 ? gap : 0), 0);
|
|
687
789
|
}
|
|
688
|
-
function runStationAt(run2,
|
|
689
|
-
const { length
|
|
690
|
-
if (past === "follow" &&
|
|
691
|
-
const place2 = run2.at(
|
|
790
|
+
function runStationAt(run2, distance3, shift = 0, past = "extend") {
|
|
791
|
+
const { length } = run2;
|
|
792
|
+
if (past === "follow" && length > 0) {
|
|
793
|
+
const place2 = run2.at(distance3 / length, { open: true });
|
|
692
794
|
const { point: point2, normal: normal3 } = place2;
|
|
693
795
|
return { ...place2, point: { x: point2.x + shift * normal3.x, y: point2.y + shift * normal3.y } };
|
|
694
796
|
}
|
|
695
|
-
const place = run2.at(
|
|
696
|
-
const beyond =
|
|
797
|
+
const place = run2.at(length === 0 ? 0 : distance3 / length);
|
|
798
|
+
const beyond = distance3 < 0 ? distance3 : distance3 > length ? distance3 - length : 0;
|
|
697
799
|
const { point, tangent, normal: normal2 } = place;
|
|
698
800
|
return {
|
|
699
801
|
...place,
|
|
@@ -702,22 +804,22 @@ function runStationAt(run2, distance, shift = 0, past = "extend") {
|
|
|
702
804
|
}
|
|
703
805
|
function placeAlongRun(run2, lengths, options = {}) {
|
|
704
806
|
const { gap = 0, align = "center", offset: offset2 = 0, at: at2, shift = 0, wrap = false, past = "extend", order = "reading" } = options;
|
|
705
|
-
const { length
|
|
807
|
+
const { length } = run2;
|
|
706
808
|
const mirror = order === "track" && run2.reversed;
|
|
707
|
-
const spots = runPlaces(lengths, gap,
|
|
708
|
-
const lap = wrap && run2.closed && spots.length > 0 ? wrapWindow(spots[0], lengths[0],
|
|
809
|
+
const spots = runPlaces(lengths, gap, length, align, offset2, at2);
|
|
810
|
+
const lap = wrap && run2.closed && spots.length > 0 ? wrapWindow(spots[0], lengths[0], length) : null;
|
|
709
811
|
return spots.map((spot, i) => {
|
|
710
812
|
const half = lengths[i] / 2;
|
|
711
813
|
const clipped = lap ? clipOf(spot.center - half, spot.center + half, lap.start, lap.end, lap.hair) : spot.clipped;
|
|
712
|
-
let
|
|
713
|
-
if (past === "hold" && clipped === "past")
|
|
714
|
-
if (lap &&
|
|
715
|
-
return { ...runStationAt(run2, mirror ?
|
|
814
|
+
let distance3 = spot.center;
|
|
815
|
+
if (past === "hold" && clipped === "past") distance3 = clamp(distance3, lap?.start ?? 0, lap?.end ?? length);
|
|
816
|
+
if (lap && length > 0) distance3 = (distance3 % length + length) % length;
|
|
817
|
+
return { ...runStationAt(run2, mirror ? length - distance3 : distance3, shift, past === "extend" ? "extend" : "follow"), center: spot.center, clipped };
|
|
716
818
|
});
|
|
717
819
|
}
|
|
718
|
-
function wrapWindow(first, firstLength,
|
|
820
|
+
function wrapWindow(first, firstLength, length) {
|
|
719
821
|
const start = first.center - firstLength / 2;
|
|
720
|
-
return { start, end: start +
|
|
822
|
+
return { start, end: start + length, hair: 1e-9 * Math.max(1, length) };
|
|
721
823
|
}
|
|
722
824
|
|
|
723
825
|
// src/portCurve2.ts
|
|
@@ -734,6 +836,52 @@ function portCurvePoints2(ax, ay, bx, by, outNormal, inNormal, samples, reach =
|
|
|
734
836
|
);
|
|
735
837
|
}
|
|
736
838
|
|
|
839
|
+
// src/along/curvePosition.ts
|
|
840
|
+
function runSegments(t, r) {
|
|
841
|
+
return tableInternals(t).cum[r].length - 1;
|
|
842
|
+
}
|
|
843
|
+
function curveSpan(t, span) {
|
|
844
|
+
const from = Math.max(span.from, 0);
|
|
845
|
+
const to = Math.min(span.to, t.total);
|
|
846
|
+
if (!(from < to)) return null;
|
|
847
|
+
const a = curveAtLength(t, from, true);
|
|
848
|
+
const b = curveAtLength(t, to, false);
|
|
849
|
+
return a && b ? { from: a, to: b } : null;
|
|
850
|
+
}
|
|
851
|
+
function lengthAtCurve(t, at2) {
|
|
852
|
+
const { cum } = tableInternals(t);
|
|
853
|
+
const r = Math.min(Math.max(at2.run, 0), t.runs.length - 1);
|
|
854
|
+
if (r < 0) return 0;
|
|
855
|
+
const c = cum[r];
|
|
856
|
+
const segs = c.length - 1;
|
|
857
|
+
if (segs <= 0) return c[0];
|
|
858
|
+
const k = Math.min(Math.max(Math.floor(at2.segment), 0), segs - 1);
|
|
859
|
+
const f = Math.min(Math.max(at2.t, 0), 1);
|
|
860
|
+
const len = c[k + 1] - c[k];
|
|
861
|
+
const arc2 = f <= 0 || f >= 1 || !(len > 0) ? null : segmentArc(t, r, k);
|
|
862
|
+
if (!arc2) return c[k] + f * len;
|
|
863
|
+
return c[k] + Math.min(lookupLength(arc2.coords, t.dim, arc2.lookup, f), len);
|
|
864
|
+
}
|
|
865
|
+
function curveAtLength(t, s, starts2) {
|
|
866
|
+
const { cum } = tableInternals(t);
|
|
867
|
+
for (let r = 0; r < cum.length; r++) {
|
|
868
|
+
const c = cum[r];
|
|
869
|
+
const end = c[c.length - 1];
|
|
870
|
+
if (c.length < 2 || !(end > c[0]) || (starts2 ? s >= end : s > end)) continue;
|
|
871
|
+
for (let k = 0; k < c.length - 1; k++) {
|
|
872
|
+
const len = c[k + 1] - c[k];
|
|
873
|
+
if (!(len > 0) || (starts2 ? s >= c[k + 1] : s > c[k + 1])) continue;
|
|
874
|
+
return { run: r, segment: k, t: paramAt(t, r, k, s - c[k], len) };
|
|
875
|
+
}
|
|
876
|
+
}
|
|
877
|
+
return null;
|
|
878
|
+
}
|
|
879
|
+
function paramAt(t, r, k, local, len) {
|
|
880
|
+
const arc2 = segmentArc(t, r, k);
|
|
881
|
+
if (!arc2) return Math.min(Math.max(local / len, 0), 1);
|
|
882
|
+
return lookupT(arc2.coords, t.dim, arc2.lookup, local);
|
|
883
|
+
}
|
|
884
|
+
|
|
737
885
|
// src/pathSubpaths.ts
|
|
738
886
|
function flatSubpaths(path, tolerance) {
|
|
739
887
|
const drawn = resolveCorners(path);
|
|
@@ -802,6 +950,71 @@ function closedSubpaths(path, opts) {
|
|
|
802
950
|
return regionSubpaths(path, opts).closed;
|
|
803
951
|
}
|
|
804
952
|
|
|
953
|
+
// src/outlineSegments.ts
|
|
954
|
+
function someSegment(path, tolerance, span, visit) {
|
|
955
|
+
if (path.kind === "rect") return someRectEdge(path, span, visit);
|
|
956
|
+
if (!span) return someFlatEdge(path, tolerance, visit);
|
|
957
|
+
const o = originOf(path);
|
|
958
|
+
const polylines = extractPolylines(path, { flattenTolerance: tolerance ?? DEFAULT_FLATTEN_TOLERANCE });
|
|
959
|
+
const { runs } = pathLengthTable(path);
|
|
960
|
+
for (let r = Math.max(span.from.run, 0); r <= Math.min(span.to.run, polylines.length - 1); r++) {
|
|
961
|
+
const pl = polylines[r];
|
|
962
|
+
const place = (at2) => polylineAtCurve(pl, at2.segment, at2.t, runs[r]);
|
|
963
|
+
const head = r === span.from.run ? place(span.from) : null;
|
|
964
|
+
const tail = r === span.to.run ? place(span.to) : null;
|
|
965
|
+
const from = head?.length ?? 0;
|
|
966
|
+
const to = tail?.length ?? Infinity;
|
|
967
|
+
if (!(from < to)) continue;
|
|
968
|
+
const p = pl.points;
|
|
969
|
+
const n = p.length / 2;
|
|
970
|
+
const end = pl.closed && n >= 2 ? n : n - 1;
|
|
971
|
+
let s = 0;
|
|
972
|
+
for (let i = 0; i < end; i++) {
|
|
973
|
+
const j = (i + 1) % n;
|
|
974
|
+
const ax = p[i * 2], ay = p[i * 2 + 1];
|
|
975
|
+
const bx = p[j * 2], by = p[j * 2 + 1];
|
|
976
|
+
const s0 = s;
|
|
977
|
+
s += Math.hypot(bx - ax, by - ay);
|
|
978
|
+
if (head && s <= from) continue;
|
|
979
|
+
if (tail && s0 >= to) break;
|
|
980
|
+
const [x0, y0] = head && s0 < from ? [head.x, head.y] : [ax, ay];
|
|
981
|
+
const [x1, y1] = tail && s > to ? [tail.x, tail.y] : [bx, by];
|
|
982
|
+
if (visit(x0 + o.x, y0 + o.y, x1 + o.x, y1 + o.y)) return true;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
return false;
|
|
986
|
+
}
|
|
987
|
+
function someFlatEdge(path, tolerance, visit) {
|
|
988
|
+
const { closed, open } = flatSubpaths(path, tolerance ?? DEFAULT_FLATTEN_TOLERANCE);
|
|
989
|
+
const run2 = (sub3, wrap) => {
|
|
990
|
+
const n = sub3.length;
|
|
991
|
+
const last = wrap ? n : n - 2;
|
|
992
|
+
for (let i = 0; i < last; i += 2) {
|
|
993
|
+
const j = (i + 2) % n;
|
|
994
|
+
if (visit(sub3[i], sub3[i + 1], sub3[j], sub3[j + 1])) return true;
|
|
995
|
+
}
|
|
996
|
+
return false;
|
|
997
|
+
};
|
|
998
|
+
return closed.some((sub3) => run2(sub3, true)) || open.some((sub3) => run2(sub3, false));
|
|
999
|
+
}
|
|
1000
|
+
function someRectEdge(rect, span, visit) {
|
|
1001
|
+
const { x, y, width: w, height: h } = rect;
|
|
1002
|
+
const cx = [x, x + w, x + w, x];
|
|
1003
|
+
const cy = [y, y, y + h, y + h];
|
|
1004
|
+
const lo = span ? span.from : { run: 0, segment: 0, t: 0 };
|
|
1005
|
+
const hi = span ? span.to : { run: 0, segment: 3, t: 1 };
|
|
1006
|
+
if (lo.run !== 0 || hi.run !== 0) return false;
|
|
1007
|
+
for (let i = Math.max(lo.segment, 0); i <= Math.min(hi.segment, 3); i++) {
|
|
1008
|
+
const j = i + 1 & 3;
|
|
1009
|
+
const t0 = i === lo.segment ? lo.t : 0;
|
|
1010
|
+
const t1 = i === hi.segment ? hi.t : 1;
|
|
1011
|
+
if (!(t1 > t0) && lo.segment === hi.segment) return false;
|
|
1012
|
+
const at2 = (f) => [cx[i] + (cx[j] - cx[i]) * f, cy[i] + (cy[j] - cy[i]) * f];
|
|
1013
|
+
if (visit(...at2(t0), ...at2(t1))) return true;
|
|
1014
|
+
}
|
|
1015
|
+
return false;
|
|
1016
|
+
}
|
|
1017
|
+
|
|
805
1018
|
// src/screenBand.ts
|
|
806
1019
|
function stretchOf(m) {
|
|
807
1020
|
const e = (m.a + m.d) / 2;
|
|
@@ -933,30 +1146,16 @@ function strokeHitTest(path, x, y, threshold, opts = {}) {
|
|
|
933
1146
|
const st = stretchOf(m);
|
|
934
1147
|
if (st.s1 === 0) return false;
|
|
935
1148
|
if (isSimilarity(st)) {
|
|
936
|
-
return strokeHitTest(path, x, y, threshold + slop.px / st.s1, { tolerance: opts.tolerance });
|
|
1149
|
+
return strokeHitTest(path, x, y, threshold + slop.px / st.s1, { tolerance: opts.tolerance, span: opts.span });
|
|
937
1150
|
}
|
|
938
1151
|
const sx = a * x + c * y, sy = b * x + d * y;
|
|
939
|
-
return
|
|
1152
|
+
return walk(path, opts, (ax, ay, bx, by) => capsuleWithinPx(sx, sy, ax, ay, bx, by, threshold, slop.px, m, st));
|
|
940
1153
|
}
|
|
941
1154
|
const t2 = threshold * threshold;
|
|
942
|
-
return
|
|
1155
|
+
return walk(path, opts, (ax, ay, bx, by) => pointSegmentDist2(x, y, ax, ay, bx, by) <= t2);
|
|
943
1156
|
}
|
|
944
|
-
function
|
|
945
|
-
|
|
946
|
-
const { x: rx, y: ry, width: w, height: h } = path;
|
|
947
|
-
return visit(rx, ry, rx + w, ry) || visit(rx + w, ry, rx + w, ry + h) || visit(rx + w, ry + h, rx, ry + h) || visit(rx, ry + h, rx, ry);
|
|
948
|
-
}
|
|
949
|
-
const { closed, open } = flatSubpaths(path, tolerance ?? DEFAULT_FLATTEN_TOLERANCE);
|
|
950
|
-
const run2 = (sub3, wrap) => {
|
|
951
|
-
const n = sub3.length;
|
|
952
|
-
const last = wrap ? n : n - 2;
|
|
953
|
-
for (let i = 0; i < last; i += 2) {
|
|
954
|
-
const j = (i + 2) % n;
|
|
955
|
-
if (visit(sub3[i], sub3[i + 1], sub3[j], sub3[j + 1])) return true;
|
|
956
|
-
}
|
|
957
|
-
return false;
|
|
958
|
-
};
|
|
959
|
-
return closed.some((sub3) => run2(sub3, true)) || open.some((sub3) => run2(sub3, false));
|
|
1157
|
+
function walk(path, opts, visit) {
|
|
1158
|
+
return someSegment(path, opts.tolerance, opts.span, visit);
|
|
960
1159
|
}
|
|
961
1160
|
function rectToVerts(r) {
|
|
962
1161
|
return [
|
|
@@ -1128,8 +1327,8 @@ function polygonIntersectsPath(polygon, path, opts = {}) {
|
|
|
1128
1327
|
}
|
|
1129
1328
|
|
|
1130
1329
|
// src/paths/cornerOffset.ts
|
|
1131
|
-
function offsetCornerTraces(path,
|
|
1132
|
-
if (path.kind !== "polygon" ||
|
|
1330
|
+
function offsetCornerTraces(path, distance3) {
|
|
1331
|
+
if (path.kind !== "polygon" || distance3 === 0) return [];
|
|
1133
1332
|
const drawn = resolveCorners(path);
|
|
1134
1333
|
const out = [];
|
|
1135
1334
|
for (const cut of cornerCuts(path)) {
|
|
@@ -1146,9 +1345,9 @@ function offsetCornerTraces(path, distance) {
|
|
|
1146
1345
|
const half = Math.acos(Math.max(-1, Math.min(1, din.x * b.x + din.y * b.y)));
|
|
1147
1346
|
const probe = Math.min(inLen, outLen) * 0.01;
|
|
1148
1347
|
const sign2 = pointInPath(drawn, v.x + b.x * probe, v.y + b.y * probe) ? -1 : 1;
|
|
1149
|
-
const radius = spec.radius + sign2 *
|
|
1348
|
+
const radius = spec.radius + sign2 * distance3 / Math.tan(half);
|
|
1150
1349
|
if (!(radius > 0)) continue;
|
|
1151
|
-
const at2 = { x: v.x - b.x * sign2 *
|
|
1350
|
+
const at2 = { x: v.x - b.x * sign2 * distance3 / Math.sin(half), y: v.y - b.y * sign2 * distance3 / Math.sin(half) };
|
|
1152
1351
|
const reach = radius * 2 + 1;
|
|
1153
1352
|
const wedge = new PathBuilder().moveTo(at2.x + din.x * reach, at2.y + din.y * reach).lineTo(at2.x, at2.y).lineTo(at2.x + dout.x * reach, at2.y + dout.y * reach).build();
|
|
1154
1353
|
const [moved2] = cornerCuts(withCorner(wedge, 1, { shape: spec.shape, radius }));
|
|
@@ -1704,7 +1903,7 @@ function arcToCubics(x1, y1, x2, y2, rx, ry, xAxisRotationDeg, largeArc, sweep,
|
|
|
1704
1903
|
b.lineTo(x2, y2);
|
|
1705
1904
|
return;
|
|
1706
1905
|
}
|
|
1707
|
-
const phi = xAxisRotationDeg *
|
|
1906
|
+
const phi = xAxisRotationDeg * DEG_TO_RAD;
|
|
1708
1907
|
const cosPhi = Math.cos(phi);
|
|
1709
1908
|
const sinPhi = Math.sin(phi);
|
|
1710
1909
|
const dx2 = (x1 - x2) / 2;
|
|
@@ -2306,64 +2505,11 @@ function crossingStops(path, cutters) {
|
|
|
2306
2505
|
return stops;
|
|
2307
2506
|
}
|
|
2308
2507
|
|
|
2309
|
-
// src/paths/segmentLength.ts
|
|
2310
|
-
var GL_X = [
|
|
2311
|
-
-0.9602898564975363,
|
|
2312
|
-
-0.7966664774136267,
|
|
2313
|
-
-0.525532409916329,
|
|
2314
|
-
-0.1834346424956498,
|
|
2315
|
-
0.1834346424956498,
|
|
2316
|
-
0.525532409916329,
|
|
2317
|
-
0.7966664774136267,
|
|
2318
|
-
0.9602898564975363
|
|
2319
|
-
];
|
|
2320
|
-
var GL_W2 = [
|
|
2321
|
-
0.1012285362903763,
|
|
2322
|
-
0.2223810344533745,
|
|
2323
|
-
0.3137066458778873,
|
|
2324
|
-
0.362683783378362,
|
|
2325
|
-
0.362683783378362,
|
|
2326
|
-
0.3137066458778873,
|
|
2327
|
-
0.2223810344533745,
|
|
2328
|
-
0.1012285362903763
|
|
2329
|
-
];
|
|
2330
|
-
var speed2 = (s, t) => {
|
|
2331
|
-
const d = derivSeg(s, t);
|
|
2332
|
-
return Math.hypot(d.x, d.y);
|
|
2333
|
-
};
|
|
2334
|
-
function segmentLength(s, a = 0, b = 1) {
|
|
2335
|
-
if (s.length === 2) return speed2(s, 0) * (b - a);
|
|
2336
|
-
const panels = 8, h = (b - a) / panels;
|
|
2337
|
-
let sum = 0;
|
|
2338
|
-
for (let k = 0; k < panels; k++) {
|
|
2339
|
-
const mid = a + (k + 0.5) * h;
|
|
2340
|
-
for (let i = 0; i < GL_X.length; i++) sum += GL_W2[i] * speed2(s, mid + GL_X[i] * h / 2);
|
|
2341
|
-
}
|
|
2342
|
-
return sum * h / 2;
|
|
2343
|
-
}
|
|
2344
|
-
function segmentTAtLength(s, length2) {
|
|
2345
|
-
const total = segmentLength(s);
|
|
2346
|
-
if (length2 <= 0 || !(total > 0)) return 0;
|
|
2347
|
-
if (length2 >= total) return 1;
|
|
2348
|
-
if (s.length === 2) return length2 / total;
|
|
2349
|
-
let lo = 0, hi = 1, t = length2 / total;
|
|
2350
|
-
for (let i = 0; i < 30; i++) {
|
|
2351
|
-
const err = segmentLength(s, 0, t) - length2;
|
|
2352
|
-
if (Math.abs(err) < 1e-10 * Math.max(1, total)) break;
|
|
2353
|
-
if (err > 0) hi = t;
|
|
2354
|
-
else lo = t;
|
|
2355
|
-
const v = speed2(s, t);
|
|
2356
|
-
let next = v > 0 ? t - err / v : NaN;
|
|
2357
|
-
if (!(next > lo && next < hi)) next = (lo + hi) / 2;
|
|
2358
|
-
t = next;
|
|
2359
|
-
}
|
|
2360
|
-
return t;
|
|
2361
|
-
}
|
|
2362
|
-
|
|
2363
2508
|
// src/snap/segmentFeatures.ts
|
|
2364
2509
|
function segmentMidT(s) {
|
|
2365
2510
|
if (s.length === 2) return 0.5;
|
|
2366
|
-
|
|
2511
|
+
const c = flatPoints(s);
|
|
2512
|
+
return segmentTAtLength(c, 2, segmentLength(c, 2) / 2);
|
|
2367
2513
|
}
|
|
2368
2514
|
function unitQuadraticRoots(a, b, c) {
|
|
2369
2515
|
const inside = (t) => t >= -1e-9 && t <= 1 + 1e-9;
|
|
@@ -2559,8 +2705,8 @@ function findPathSnaps(index, probe, query) {
|
|
|
2559
2705
|
const skip = query.skip ?? (() => false);
|
|
2560
2706
|
const hits = [];
|
|
2561
2707
|
const offer = (kind, x, y, paths) => {
|
|
2562
|
-
const
|
|
2563
|
-
if (
|
|
2708
|
+
const distance3 = metric(x - probe.x, y - probe.y);
|
|
2709
|
+
if (distance3 <= r) hits.push({ kind, x, y, distance: distance3, paths });
|
|
2564
2710
|
};
|
|
2565
2711
|
const rx = sx > 0 ? r / sx : Infinity, ry = sy > 0 ? r / sy : Infinity;
|
|
2566
2712
|
const box = [probe.x - rx, probe.y - ry, probe.x + rx, probe.y + ry];
|
|
@@ -3057,14 +3203,14 @@ function segmentAt2(set, x, y, opts) {
|
|
|
3057
3203
|
const hit = nearestSegmentT(screenAnchors, x * scale3.x, y * scale3.y, set.closed);
|
|
3058
3204
|
if (!hit) return null;
|
|
3059
3205
|
const ends = segmentEnds(set.anchors, set.closed, hit.sub, hit.segIdx);
|
|
3060
|
-
const point =
|
|
3206
|
+
const point = pointOnSegment2(ends.a, ends.b, hit.t);
|
|
3061
3207
|
const tol = opts.tolerancePx;
|
|
3062
3208
|
if (!withinPxRadius(point.x - x, point.y - y, tol, scale3)) return null;
|
|
3063
3209
|
if (withinPxRadius(point.x - ends.a.x, point.y - ends.a.y, tol, scale3)) return null;
|
|
3064
3210
|
if (withinPxRadius(point.x - ends.b.x, point.y - ends.b.y, tol, scale3)) return null;
|
|
3065
3211
|
return { sub: hit.sub, segIdx: hit.segIdx, t: hit.t, x: point.x, y: point.y };
|
|
3066
3212
|
}
|
|
3067
|
-
function
|
|
3213
|
+
function pointOnSegment2(a, b, t) {
|
|
3068
3214
|
if (isStraightSegment(a, b)) return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };
|
|
3069
3215
|
return cubicPointAt(a, a.outHandle ?? a, b.inHandle ?? b, b, t);
|
|
3070
3216
|
}
|
|
@@ -3142,12 +3288,12 @@ var FULL = 2 * Math.PI;
|
|
|
3142
3288
|
var FIT_SHARE = 1e-4;
|
|
3143
3289
|
var FIT_FLOOR = 1e-3;
|
|
3144
3290
|
var MAX_SPLITS = 6;
|
|
3145
|
-
function extensionPieces(frame,
|
|
3146
|
-
if (!(
|
|
3147
|
-
const bends = Math.abs(frame.curvature) *
|
|
3148
|
-
if (mode === "curvature" && bends) return arcPieces(frame,
|
|
3149
|
-
if (mode === "eased" && bends) return easedPieces(frame,
|
|
3150
|
-
return [line(frame.point, frame.tangent,
|
|
3291
|
+
function extensionPieces(frame, distance3, mode, opts = {}) {
|
|
3292
|
+
if (!(distance3 > 0)) return [];
|
|
3293
|
+
const bends = Math.abs(frame.curvature) * distance3 > STRAIGHT_TURN;
|
|
3294
|
+
if (mode === "curvature" && bends) return arcPieces(frame, distance3);
|
|
3295
|
+
if (mode === "eased" && bends) return easedPieces(frame, distance3, easeTurnOf(opts));
|
|
3296
|
+
return [line(frame.point, frame.tangent, distance3)];
|
|
3151
3297
|
}
|
|
3152
3298
|
function easeLength(frame, opts = {}) {
|
|
3153
3299
|
const k = Math.abs(frame.curvature);
|
|
@@ -3157,16 +3303,16 @@ function easeTurnOf(opts) {
|
|
|
3157
3303
|
const turn = opts.easeTurn;
|
|
3158
3304
|
return turn !== void 0 && Number.isFinite(turn) && turn > 0 ? Math.min(turn, QUARTER) : DEFAULT_EASE_TURN;
|
|
3159
3305
|
}
|
|
3160
|
-
function line(from, dir,
|
|
3161
|
-
return { pts: [from, { x: from.x + dir.x *
|
|
3306
|
+
function line(from, dir, length) {
|
|
3307
|
+
return { pts: [from, { x: from.x + dir.x * length, y: from.y + dir.y * length }], length };
|
|
3162
3308
|
}
|
|
3163
3309
|
function arcCenter({ point, tangent, curvature }) {
|
|
3164
3310
|
return { x: point.x - tangent.y / curvature, y: point.y + tangent.x / curvature };
|
|
3165
3311
|
}
|
|
3166
|
-
function arcPieces(frame,
|
|
3312
|
+
function arcPieces(frame, distance3) {
|
|
3167
3313
|
const s = Math.sign(frame.curvature);
|
|
3168
3314
|
const r = 1 / Math.abs(frame.curvature);
|
|
3169
|
-
const sweep = Math.min(
|
|
3315
|
+
const sweep = Math.min(distance3 / r, FULL);
|
|
3170
3316
|
const count = Math.max(1, Math.ceil(sweep / QUARTER - 1e-9));
|
|
3171
3317
|
const step = sweep / count;
|
|
3172
3318
|
const reach = 4 / 3 * Math.tan(step / 4) * r;
|
|
@@ -3197,7 +3343,7 @@ function arcPieces(frame, distance) {
|
|
|
3197
3343
|
}
|
|
3198
3344
|
return out;
|
|
3199
3345
|
}
|
|
3200
|
-
function easeSpiral(frame,
|
|
3346
|
+
function easeSpiral(frame, length, turn) {
|
|
3201
3347
|
const sign2 = Math.sign(frame.curvature);
|
|
3202
3348
|
const k0 = sign2 * turn;
|
|
3203
3349
|
const k1 = -2 * sign2 * turn;
|
|
@@ -3212,19 +3358,19 @@ function easeSpiral(frame, length2, turn) {
|
|
|
3212
3358
|
chordAngle: Math.atan2(c.y, c.x),
|
|
3213
3359
|
p0: frame.point,
|
|
3214
3360
|
p1: frame.point,
|
|
3215
|
-
length
|
|
3361
|
+
length,
|
|
3216
3362
|
rotation
|
|
3217
3363
|
};
|
|
3218
3364
|
return { ...seg, p1: eulerPointAt(seg, 1) };
|
|
3219
3365
|
}
|
|
3220
|
-
function easedPieces(frame,
|
|
3366
|
+
function easedPieces(frame, distance3, turn) {
|
|
3221
3367
|
const ease = 2 * turn / Math.abs(frame.curvature);
|
|
3222
3368
|
const spiral = easeSpiral(frame, ease, turn);
|
|
3223
|
-
const drawn =
|
|
3369
|
+
const drawn = distance3 < ease ? spiralPiece(spiral, 0, distance3 / ease) : spiral;
|
|
3224
3370
|
const out = fitSpiral(drawn, Math.max(FIT_FLOOR, FIT_SHARE * ease), 0);
|
|
3225
|
-
if (
|
|
3371
|
+
if (distance3 > ease) {
|
|
3226
3372
|
const a = eulerAngleAt(spiral, 1);
|
|
3227
|
-
out.push(line(spiral.p1, { x: Math.cos(a), y: Math.sin(a) },
|
|
3373
|
+
out.push(line(spiral.p1, { x: Math.cos(a), y: Math.sin(a) }, distance3 - ease));
|
|
3228
3374
|
}
|
|
3229
3375
|
return out;
|
|
3230
3376
|
}
|
|
@@ -3291,8 +3437,9 @@ function g2Cubic(seg) {
|
|
|
3291
3437
|
}
|
|
3292
3438
|
function pieceLengthAt(piece, t) {
|
|
3293
3439
|
if (piece.pts.length === 2) return piece.length * t;
|
|
3294
|
-
const
|
|
3295
|
-
|
|
3440
|
+
const c = flatPoints(piece.pts);
|
|
3441
|
+
const whole = segmentLength(c, 2);
|
|
3442
|
+
return whole > 0 ? piece.length * segmentLength(c, 2, 0, t) / whole : 0;
|
|
3296
3443
|
}
|
|
3297
3444
|
|
|
3298
3445
|
// src/paths/lengthenPathEnd.ts
|
|
@@ -3315,9 +3462,9 @@ function pathEndAnchorIndex(set, end) {
|
|
|
3315
3462
|
function pathEndFrame(set, end) {
|
|
3316
3463
|
return atTail(set, end, tailFrame) ?? null;
|
|
3317
3464
|
}
|
|
3318
|
-
function lengthenPathEnd(set, end,
|
|
3319
|
-
if (!(
|
|
3320
|
-
return atTail(set, end, (sub3) =>
|
|
3465
|
+
function lengthenPathEnd(set, end, distance3, mode, opts = {}) {
|
|
3466
|
+
if (!(distance3 !== 0 && Number.isFinite(distance3))) return false;
|
|
3467
|
+
return atTail(set, end, (sub3) => distance3 < 0 ? trimTail(sub3, -distance3) : growTail(sub3, distance3, mode, opts)) ?? false;
|
|
3321
3468
|
}
|
|
3322
3469
|
function lengthToward(set, end, mode, point, near2 = 0, opts = {}) {
|
|
3323
3470
|
const frame = pathEndFrame(set, end);
|
|
@@ -3393,10 +3540,10 @@ function lengthAlongEased(frame, point, opts) {
|
|
|
3393
3540
|
}
|
|
3394
3541
|
return best.length;
|
|
3395
3542
|
}
|
|
3396
|
-
function growTail(sub3,
|
|
3543
|
+
function growTail(sub3, distance3, mode, opts) {
|
|
3397
3544
|
const frame = tailFrame(sub3);
|
|
3398
3545
|
if (!frame) return false;
|
|
3399
|
-
const pieces = extensionPieces(frame,
|
|
3546
|
+
const pieces = extensionPieces(frame, distance3, mode, opts);
|
|
3400
3547
|
const end = sub3[sub3.length - 1];
|
|
3401
3548
|
const first = pieces[0];
|
|
3402
3549
|
if (pieces.length === 1 && first.pts.length === 2 && isStraightSegment(sub3[sub3.length - 2], end)) {
|
|
@@ -3423,7 +3570,7 @@ function appendPieces(sub3, pieces) {
|
|
|
3423
3570
|
function tailLength(sub3) {
|
|
3424
3571
|
const [p0, p1, p2, p3] = tailCubic(sub3);
|
|
3425
3572
|
if (isStraightSegment(p0, p3)) return Math.hypot(p3.x - p0.x, p3.y - p0.y);
|
|
3426
|
-
return segmentLength([p0, p1, p2, p3]);
|
|
3573
|
+
return segmentLength(flatPoints([p0, p1, p2, p3]), 2);
|
|
3427
3574
|
}
|
|
3428
3575
|
function subpathLength(sub3) {
|
|
3429
3576
|
let total = 0;
|
|
@@ -3453,7 +3600,7 @@ function cutTail(sub3, keep, len) {
|
|
|
3453
3600
|
p3.y = p0.y + (p3.y - p0.y) * f;
|
|
3454
3601
|
return;
|
|
3455
3602
|
}
|
|
3456
|
-
const t = segmentTAtLength([p0, p1, p2, p3], keep);
|
|
3603
|
+
const t = segmentTAtLength(flatPoints([p0, p1, p2, p3]), 2, keep);
|
|
3457
3604
|
const { left } = splitCubicAtT(p0, p1, p2, p3, t);
|
|
3458
3605
|
if (p0.outHandle) p0.outHandle = left[1];
|
|
3459
3606
|
p3.inHandle = left[2];
|
|
@@ -3479,9 +3626,9 @@ function segmentsBesideEnd(path, end) {
|
|
|
3479
3626
|
return s === end.sub ? segs.filter((g) => g.index !== (end.end === "last" ? g.count - 1 : 0)) : segs;
|
|
3480
3627
|
});
|
|
3481
3628
|
}
|
|
3482
|
-
function lengthenOpenEnd(path, end,
|
|
3483
|
-
if (!(
|
|
3484
|
-
return editAnchorSetTracked(path, (set) => lengthenPathEnd(set, end,
|
|
3629
|
+
function lengthenOpenEnd(path, end, distance3, mode = "tangent", opts = {}) {
|
|
3630
|
+
if (!(distance3 > 0) || path.kind !== "polygon") return null;
|
|
3631
|
+
return editAnchorSetTracked(path, (set) => lengthenPathEnd(set, end, distance3, mode, opts))?.path ?? null;
|
|
3485
3632
|
}
|
|
3486
3633
|
function extendToMeet(path, boundaries, end, opts = {}) {
|
|
3487
3634
|
if (path.kind !== "polygon") return null;
|
|
@@ -3564,7 +3711,7 @@ function simplifySpan(sub3, closed, from, to, tolerance, opts = {}) {
|
|
|
3564
3711
|
function fitParams(tolerance, opts) {
|
|
3565
3712
|
return {
|
|
3566
3713
|
tol: Math.max(tolerance, 1e-6),
|
|
3567
|
-
cosCorner: Math.cos((opts.cornerAngle ?? 40) *
|
|
3714
|
+
cosCorner: Math.cos((opts.cornerAngle ?? 40) * DEG_TO_RAD)
|
|
3568
3715
|
};
|
|
3569
3716
|
}
|
|
3570
3717
|
function breaksOf(sub3, closed, cosCorner) {
|
|
@@ -3649,12 +3796,12 @@ function unit(p) {
|
|
|
3649
3796
|
// src/paths/growRegion.ts
|
|
3650
3797
|
var MAX_DEPTH = 6;
|
|
3651
3798
|
var SAMPLES3 = [0.2, 0.35, 0.5, 0.65, 0.8];
|
|
3652
|
-
function growRegion(path,
|
|
3799
|
+
function growRegion(path, distance3, opts = {}) {
|
|
3653
3800
|
const b = new PathBuilder();
|
|
3654
|
-
if (!(
|
|
3801
|
+
if (!(distance3 > 0)) return b.build();
|
|
3655
3802
|
const sigma = pathSignedArea(path) < 0 ? -1 : 1;
|
|
3656
3803
|
const ctx = {
|
|
3657
|
-
d:
|
|
3804
|
+
d: distance3,
|
|
3658
3805
|
sigma,
|
|
3659
3806
|
tol: opts.tolerance ?? 0.1,
|
|
3660
3807
|
join: opts.join ?? "miter",
|
|
@@ -3887,7 +4034,7 @@ function segmentCrossings(segs) {
|
|
|
3887
4034
|
const out = [];
|
|
3888
4035
|
for (let a = 0; a < segs.length; a++) {
|
|
3889
4036
|
for (let b = a + 1; b < segs.length; b++) {
|
|
3890
|
-
if (!
|
|
4037
|
+
if (!boxesIntersect(boxes[a], boxes[b])) continue;
|
|
3891
4038
|
const pa = flat[a], pb = flat[b];
|
|
3892
4039
|
for (let i = 0; i + 1 < pa.length; i++) {
|
|
3893
4040
|
for (let j = 0; j + 1 < pb.length; j++) {
|
|
@@ -3921,7 +4068,6 @@ function boxOf(pts) {
|
|
|
3921
4068
|
}
|
|
3922
4069
|
return b;
|
|
3923
4070
|
}
|
|
3924
|
-
var overlaps = (p, q) => p[0] <= q[2] && q[0] <= p[2] && p[1] <= q[3] && q[1] <= p[3];
|
|
3925
4071
|
function linesCross(a, b, c, d) {
|
|
3926
4072
|
const rx = b[0] - a[0], ry = b[1] - a[1], sx = d[0] - c[0], sy = d[1] - c[1];
|
|
3927
4073
|
const den = rx * sy - ry * sx;
|
|
@@ -4204,7 +4350,7 @@ function measure(a, b, from) {
|
|
|
4204
4350
|
}
|
|
4205
4351
|
return { a, c1, c2, b, straight, from, len: table[LENGTH_SAMPLES], table };
|
|
4206
4352
|
}
|
|
4207
|
-
function
|
|
4353
|
+
function paramAt2(seg, d) {
|
|
4208
4354
|
const { table } = seg;
|
|
4209
4355
|
if (seg.len === 0) return 0;
|
|
4210
4356
|
let lo = 0;
|
|
@@ -4221,21 +4367,21 @@ function paramAt(seg, d) {
|
|
|
4221
4367
|
function arcRun(sub3, from, to) {
|
|
4222
4368
|
const n = sub3.length;
|
|
4223
4369
|
const segs = [];
|
|
4224
|
-
let
|
|
4370
|
+
let length = 0;
|
|
4225
4371
|
for (let i = from; i < to; i++) {
|
|
4226
|
-
const seg = measure(sub3[i % n], sub3[(i + 1) % n],
|
|
4372
|
+
const seg = measure(sub3[i % n], sub3[(i + 1) % n], length);
|
|
4227
4373
|
segs.push(seg);
|
|
4228
|
-
|
|
4374
|
+
length += seg.len;
|
|
4229
4375
|
}
|
|
4230
4376
|
const locate = (s, arriving) => {
|
|
4231
|
-
const d = Math.min(Math.max(s, 0),
|
|
4377
|
+
const d = Math.min(Math.max(s, 0), length);
|
|
4232
4378
|
let k = 0;
|
|
4233
4379
|
while (k < segs.length - 1 && (arriving ? segs[k].from + segs[k].len < d : segs[k].from + segs[k].len <= d)) k++;
|
|
4234
|
-
return { seg: segs[k], t:
|
|
4380
|
+
return { seg: segs[k], t: paramAt2(segs[k], d - segs[k].from) };
|
|
4235
4381
|
};
|
|
4236
4382
|
const start = { x: sub3[from % n].x, y: sub3[from % n].y };
|
|
4237
4383
|
return {
|
|
4238
|
-
length
|
|
4384
|
+
length,
|
|
4239
4385
|
pointAt(s) {
|
|
4240
4386
|
if (segs.length === 0) return start;
|
|
4241
4387
|
const { seg, t } = locate(s, false);
|
|
@@ -5179,7 +5325,10 @@ function poseFrameInverseOf(pose) {
|
|
|
5179
5325
|
function pathThroughPoseFrame(path, pose) {
|
|
5180
5326
|
if (poseLinearOf(pose)) {
|
|
5181
5327
|
const frame = poseFrameOf(pose);
|
|
5182
|
-
|
|
5328
|
+
if (!frame) return path;
|
|
5329
|
+
const [a, b, c, d] = frame;
|
|
5330
|
+
const uniform = isSimilarity(stretchOf({ a, b, c, d }));
|
|
5331
|
+
return transformPath(path.kind === "polygon" && !uniform ? resolveCorners(path) : path, frame);
|
|
5183
5332
|
}
|
|
5184
5333
|
const r = poseRotationOf(pose);
|
|
5185
5334
|
return r ? rotatePathAround(path, r.cx, r.cy, r.rotation) : path;
|
|
@@ -5189,17 +5338,13 @@ function pathThroughPoseFrame(path, pose) {
|
|
|
5189
5338
|
function anchorsUnderBrush(set, from, to, opts) {
|
|
5190
5339
|
const scale3 = opts.scale ?? { x: 1, y: 1 };
|
|
5191
5340
|
const ax = from.x * scale3.x, ay = from.y * scale3.y;
|
|
5192
|
-
const
|
|
5193
|
-
const len22 = dx2 * dx2 + dy2 * dy2;
|
|
5341
|
+
const bx = to.x * scale3.x, by = to.y * scale3.y;
|
|
5194
5342
|
const r2 = opts.radiusPx * opts.radiusPx;
|
|
5195
5343
|
const hits = [];
|
|
5196
5344
|
let flat = 0;
|
|
5197
5345
|
for (const sub3 of set.anchors) {
|
|
5198
5346
|
for (const a of sub3) {
|
|
5199
|
-
|
|
5200
|
-
const t = len22 === 0 ? 0 : Math.max(0, Math.min(1, (px * dx2 + py * dy2) / len22));
|
|
5201
|
-
const ex = px - t * dx2, ey = py - t * dy2;
|
|
5202
|
-
if (ex * ex + ey * ey <= r2) hits.push(flat);
|
|
5347
|
+
if (pointSegmentDist2(a.x * scale3.x, a.y * scale3.y, ax, ay, bx, by) <= r2) hits.push(flat);
|
|
5203
5348
|
flat++;
|
|
5204
5349
|
}
|
|
5205
5350
|
}
|
|
@@ -5321,8 +5466,8 @@ function bendSegment(set, grip, dx2, dy2) {
|
|
|
5321
5466
|
const aSmooth = isAnchorSmooth(a);
|
|
5322
5467
|
const bSmooth = isAnchorSmooth(b);
|
|
5323
5468
|
const straight = isStraightSegment(a, b);
|
|
5324
|
-
const p1 = a.outHandle ?? (straight ?
|
|
5325
|
-
const p2 = b.inHandle ?? (straight ?
|
|
5469
|
+
const p1 = a.outHandle ?? (straight ? lerpPoint(a, b, 1 / 3) : { x: a.x, y: a.y });
|
|
5470
|
+
const p2 = b.inHandle ?? (straight ? lerpPoint(a, b, 2 / 3) : { x: b.x, y: b.y });
|
|
5326
5471
|
const t = Math.min(1 - T_MARGIN, Math.max(T_MARGIN, grip.t));
|
|
5327
5472
|
const u = 1 - t;
|
|
5328
5473
|
const k = 1 / (3 * t * u * (u * u + t * t));
|
|
@@ -5332,9 +5477,6 @@ function bendSegment(set, grip, dx2, dy2) {
|
|
|
5332
5477
|
if (bSmooth) b.outHandle = alignedOpposite(b, b.inHandle, b.outHandle);
|
|
5333
5478
|
return true;
|
|
5334
5479
|
}
|
|
5335
|
-
function lerp(a, b, f) {
|
|
5336
|
-
return { x: a.x + (b.x - a.x) * f, y: a.y + (b.y - a.y) * f };
|
|
5337
|
-
}
|
|
5338
5480
|
function alignedOpposite(anchor, moved2, other2) {
|
|
5339
5481
|
const mx = moved2.x - anchor.x;
|
|
5340
5482
|
const my = moved2.y - anchor.y;
|
|
@@ -5483,10 +5625,10 @@ function same2(p, q) {
|
|
|
5483
5625
|
}
|
|
5484
5626
|
|
|
5485
5627
|
// src/paths/softSelection.ts
|
|
5486
|
-
function softFalloff(falloff,
|
|
5487
|
-
if (!(radius > 0) ||
|
|
5488
|
-
if (
|
|
5489
|
-
const u =
|
|
5628
|
+
function softFalloff(falloff, distance3, radius) {
|
|
5629
|
+
if (!(radius > 0) || distance3 >= radius) return 0;
|
|
5630
|
+
if (distance3 <= 0) return 1;
|
|
5631
|
+
const u = distance3 / radius;
|
|
5490
5632
|
switch (falloff) {
|
|
5491
5633
|
case "linear":
|
|
5492
5634
|
return 1 - u;
|
|
@@ -5581,7 +5723,7 @@ function softSelectionBand(measure2, set, selected, radius) {
|
|
|
5581
5723
|
sub3.segments.forEach((seg, i) => {
|
|
5582
5724
|
const c = segmentControls2(anchors, sub3.closed, i);
|
|
5583
5725
|
if (!c) return;
|
|
5584
|
-
const at2 = (t) => isStraight(c) ?
|
|
5726
|
+
const at2 = (t) => isStraight(c) ? lerpPoint(c[0], c[3], t) : cubicPointAt(c[0], c[1], c[2], c[3], t);
|
|
5585
5727
|
const steps = seg.lengths.length - 1;
|
|
5586
5728
|
for (let k = 0; k <= steps; k++) {
|
|
5587
5729
|
const len = seg.lengths[k];
|
|
@@ -5631,9 +5773,6 @@ function crossing2(a, b, aIn, inside) {
|
|
|
5631
5773
|
}
|
|
5632
5774
|
return (lo + hi) / 2;
|
|
5633
5775
|
}
|
|
5634
|
-
function lerp2(a, b, t) {
|
|
5635
|
-
return { x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t };
|
|
5636
|
-
}
|
|
5637
5776
|
|
|
5638
5777
|
// src/paths/balanceHandles.ts
|
|
5639
5778
|
function handleBalances(set) {
|
|
@@ -5661,7 +5800,7 @@ function segmentHandles(set, sub3, segIdx) {
|
|
|
5661
5800
|
if (!ends || isStraightSegment(ends.a, ends.b)) return null;
|
|
5662
5801
|
const { a, b } = ends;
|
|
5663
5802
|
if (!a.outHandle || !b.inHandle) return null;
|
|
5664
|
-
if (
|
|
5803
|
+
if (distance(a, a.outHandle) === 0 || distance(b, b.inHandle) === 0) return null;
|
|
5665
5804
|
return { a, b, from: a.outHandle, to: b.inHandle };
|
|
5666
5805
|
}
|
|
5667
5806
|
function scaleSegmentHandles(set, sub3, segIdx, factor, syms = []) {
|
|
@@ -5691,8 +5830,8 @@ function equalizeSegmentHandles(set, sub3, segIdx) {
|
|
|
5691
5830
|
const handles = segmentHandles(set, sub3, segIdx);
|
|
5692
5831
|
if (!handles) return false;
|
|
5693
5832
|
const { a, b, from, to } = handles;
|
|
5694
|
-
const lenA =
|
|
5695
|
-
const lenB =
|
|
5833
|
+
const lenA = distance(a, from);
|
|
5834
|
+
const lenB = distance(b, to);
|
|
5696
5835
|
const ua = { x: (from.x - a.x) / lenA, y: (from.y - a.y) / lenA };
|
|
5697
5836
|
const ub = { x: (to.x - b.x) / lenB, y: (to.y - b.y) / lenB };
|
|
5698
5837
|
const corner = rayCrossing(a, ua, b, ub);
|
|
@@ -5719,9 +5858,6 @@ function rayCrossing(p, u, q, v) {
|
|
|
5719
5858
|
const tb = (dx2 * u.y - dy2 * u.x) / den;
|
|
5720
5859
|
return ta > 0 && tb > 0 ? { ta, tb } : null;
|
|
5721
5860
|
}
|
|
5722
|
-
function length(a, b) {
|
|
5723
|
-
return Math.hypot(b.x - a.x, b.y - a.y);
|
|
5724
|
-
}
|
|
5725
5861
|
function scaledFrom(anchor, handle, k) {
|
|
5726
5862
|
return { x: anchor.x + (handle.x - anchor.x) * k, y: anchor.y + (handle.y - anchor.y) * k };
|
|
5727
5863
|
}
|
|
@@ -6917,11 +7053,11 @@ function handleOf(a, side) {
|
|
|
6917
7053
|
function handleTarget(a, h, part, entry) {
|
|
6918
7054
|
if (part === "X") return { x: apply2(h.x, entry), y: h.y };
|
|
6919
7055
|
if (part === "Y") return { x: h.x, y: apply2(h.y, entry) };
|
|
6920
|
-
const
|
|
7056
|
+
const length = Math.hypot(h.x - a.x, h.y - a.y);
|
|
6921
7057
|
const angle = angleOf(a, h);
|
|
6922
7058
|
const nextAngle = part === "Angle" ? apply2(angle, entry) : angle;
|
|
6923
|
-
const nextLength = part === "Length" ? Math.max(0, apply2(
|
|
6924
|
-
const rad = nextAngle *
|
|
7059
|
+
const nextLength = part === "Length" ? Math.max(0, apply2(length, entry)) : length;
|
|
7060
|
+
const rad = nextAngle * DEG_TO_RAD;
|
|
6925
7061
|
return { x: a.x + Math.cos(rad) * nextLength, y: a.y - Math.sin(rad) * nextLength };
|
|
6926
7062
|
}
|
|
6927
7063
|
function apply2(current, entry) {
|
|
@@ -6929,7 +7065,7 @@ function apply2(current, entry) {
|
|
|
6929
7065
|
}
|
|
6930
7066
|
function angleOf(a, h) {
|
|
6931
7067
|
if (h.x === a.x && h.y === a.y) return 0;
|
|
6932
|
-
return Math.atan2(a.y - h.y, h.x - a.x) *
|
|
7068
|
+
return Math.atan2(a.y - h.y, h.x - a.x) * RAD_TO_DEG;
|
|
6933
7069
|
}
|
|
6934
7070
|
function agreed(values) {
|
|
6935
7071
|
const first = values[0];
|
|
@@ -7020,6 +7156,6 @@ function typedArrayReplacer(_key, value) {
|
|
|
7020
7156
|
return tagTypedArray(value) ?? value;
|
|
7021
7157
|
}
|
|
7022
7158
|
|
|
7023
|
-
export { ANCHOR_FIELDS, CONSTRAINT_TOLERANCE, EASINGS, PATH_SNAP_KINDS, SPRING_PRESETS, TYPED_ARRAY_CONSTRUCTORS, ZOOM_FLOOR, addExtremaAnchors, anchorAt, anchorCount, anchorOriginsOf, anchorSymmetries, anchorSymmetry, anchorsBefore, anchorsInRect, anchorsUnderBrush, anchorsWhere, applyToPoint, arcShape, averageAnchorsAt, balanceFactorToward, bendAlongPath, bendSegment, bendSide, blendPaths, boxFrameOf, boxToBox, circlePath, clampRectWithin, closestOpenEnds, composePath, conflictingConstraints, constrainPathEdit, constrainPathsEdit, constraintAnchors, constraintApplies, constraintFits, convertSegments, cornerAnchors, createPathSnapIndex, cubicBezierEasing, cubicContoursToPath, decomposePath, deleteAnchorsAt, directionMarks, easeIn, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOut, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeLength, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, editAnchorSet, editAnchorSetTracked, ellipseShape, equalizeSegmentHandles, everyNthAnchor, extendToMeet, extensionPieces, findPathSnap, findPathSnaps, fitAffine, fitCubicThroughDeletion, flatAnchorIndex, flatIndexesAfterReverse, growAnchorSelection, growRegion, handleAlongItsAngle, handleAtItsLength, handleBalances, harmonizeAnchors, hasOpenSubpath, identity, insertAnchorOnSegment, invert, invertAnchorSelection, isSegmentStraight, joinAnchorsAt, joinSubpathEnds, lengthToward, lengthenOpenEnd, lengthenPathEnd, lineShape, linear, locateAnchor, makeHandlesSymmetric, mapConstraintAnchors, mat3, meanScale, measureAnchorPath, measurePath, mergeRegion, moveHandleSymmetric, moveHandleTo, multiply, nearestPathAnchor, normalizeZoom, offsetCornerTraces, openEndAt, openEndRay, openPathEnds, openSubpathAt, pathAnchorPoints, pathAwayFromAnchors, pathContainsPoint, pathContainsPolygon, pathContainsRect, pathCrossings, pathDistanceToPoint, pathEndAnchorIndex, pathEndFrame, pathFromD, pathInPoseFrame, pathInWorld, pathIntersectsPolygon, pathIntersectsRect, pathSegments, pathShape, pathSignedArea, pathThroughPoseFrame, pathToCubicContours, pathToD, placeAlongRun, placeRect, pointAlongPath, pointInPath, polygonContainsPath, polygonIntersectsPath, portControls2 as portControls, portCurvePoints2 as portCurvePoints, poseFrameInverseOf, poseFrameOf, poseLinearOf, poseRotationOf, prepareBlend, puckerBloatPath, pxExtent, pxExtentInFrame, readAnchorFields, rectMarkerPath, remapAnchorValues, remapConstraints, remapPointValues, repeatAlongPath, resamplePath, resolveEasing, retractHandles, reverseAnchors, reversePath, reverseSubpaths, reviveTypedArrays, rotate, rotateAboutPoint, rotatePathAround, roughenPath, roundRectPath, runLength, runPlaces, runStationAt, scale, scaleDelta, scalePathToBounds, scaleSegmentHandles, screenAngleOf, segmentAt2 as segmentAt, segmentBetween, segmentExtremaTs, segmentsBetweenAnchors, setSubpathStart, shiftTrack, shrinkAnchorSelection, simplifyAnchorsAt, simplifyPath, simplifySpan, simplifySubpath, smoothAnchors, smudgePath, softFalloff, softSelectionBand, softSelectionWeights, solveConstraints, solvePathConstraints, splitByClosure, splitSubpaths, squarePath, standoff, stationsAlongPath, strokeHitTest, subpathEndAt, subpathsOfAnchors, tagTypedArray, tagTypedArrays, trackRun, trackShapeD, trackSlice, transformCoords, transformPath, translate, translateAnchorBy, translateAnchorsSymmetric, translatePath, trimPathAt, typedArrayReplacer, unionBoundsPath, unsatisfiedConstraints, untagTypedArray, viewToMat3, withAnchorPoints, withinPxBox, withinPxRadius, worldEditToStorage, writeAnchorField, zigzagPath };
|
|
7159
|
+
export { ANCHOR_FIELDS, CONSTRAINT_TOLERANCE, EASINGS, PATH_SNAP_KINDS, SPRING_PRESETS, TYPED_ARRAY_CONSTRUCTORS, ZOOM_FLOOR, addExtremaAnchors, anchorAt, anchorCount, anchorOriginsOf, anchorSymmetries, anchorSymmetry, anchorsBefore, anchorsInRect, anchorsUnderBrush, anchorsWhere, applyToPoint, arcShape, averageAnchorsAt, balanceFactorToward, bendAlongPath, bendSegment, bendSide, blendPaths, boxFrameOf, boxToBox, circlePath, clampRectWithin, closestOpenEnds, composePath, conflictingConstraints, constrainPathEdit, constrainPathsEdit, constraintAnchors, constraintApplies, constraintFits, convertSegments, cornerAnchors, createPathSnapIndex, cubicBezierEasing, cubicContoursToPath, curveSpan, decomposePath, deleteAnchorsAt, directionMarks, easeIn, easeInBack, easeInBounce, easeInCirc, easeInCubic, easeInElastic, easeInExpo, easeInOut, easeInOutBack, easeInOutBounce, easeInOutCirc, easeInOutCubic, easeInOutElastic, easeInOutExpo, easeInOutQuad, easeInOutQuart, easeInOutQuint, easeInOutSine, easeInQuad, easeInQuart, easeInQuint, easeInSine, easeLength, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, editAnchorSet, editAnchorSetTracked, ellipseShape, equalizeSegmentHandles, everyNthAnchor, extendToMeet, extensionPieces, findPathSnap, findPathSnaps, fitAffine, fitCubicThroughDeletion, flatAnchorIndex, flatIndexesAfterReverse, growAnchorSelection, growRegion, handleAlongItsAngle, handleAtItsLength, handleBalances, harmonizeAnchors, hasOpenSubpath, identity, insertAnchorOnSegment, invert, invertAnchorSelection, isSegmentStraight, joinAnchorsAt, joinSubpathEnds, lengthAtCurve, lengthToward, lengthenOpenEnd, lengthenPathEnd, lineShape, linear, locateAnchor, makeHandlesSymmetric, mapConstraintAnchors, mat3, meanScale, measureAnchorPath, measurePath, mergeRegion, moveHandleSymmetric, moveHandleTo, multiply, nearestPathAnchor, normalizeZoom, offsetCornerTraces, openEndAt, openEndRay, openPathEnds, openSubpathAt, pathAnchorPoints, pathAwayFromAnchors, pathContainsPoint, pathContainsPolygon, pathContainsRect, pathCrossings, pathDistanceToPoint, pathEndAnchorIndex, pathEndFrame, pathFromD, pathInPoseFrame, pathInWorld, pathIntersectsPolygon, pathIntersectsRect, pathLengthTable, pathSegments, pathShape, pathSignedArea, pathThroughPoseFrame, pathToCubicContours, pathToD, placeAlongRun, placeRect, pointAlongPath, pointInPath, polygonContainsPath, polygonIntersectsPath, portControls2 as portControls, portCurvePoints2 as portCurvePoints, poseFrameInverseOf, poseFrameOf, poseLinearOf, poseRotationOf, prepareBlend, puckerBloatPath, pxExtent, pxExtentInFrame, readAnchorFields, rectMarkerPath, remapAnchorValues, remapConstraints, remapPointValues, repeatAlongPath, resamplePath, resolveEasing, retractHandles, reverseAnchors, reversePath, reverseSubpaths, reviveTypedArrays, rotate, rotateAboutPoint, rotatePathAround, roughenPath, roundRectPath, runLength, runPlaces, runSegments, runStationAt, scale, scaleDelta, scalePathToBounds, scaleSegmentHandles, screenAngleOf, segmentAt2 as segmentAt, segmentBetween, segmentExtremaTs, segmentsBetweenAnchors, setSubpathStart, shiftTrack, shrinkAnchorSelection, simplifyAnchorsAt, simplifyPath, simplifySpan, simplifySubpath, smoothAnchors, smudgePath, softFalloff, softSelectionBand, softSelectionWeights, solveConstraints, solvePathConstraints, splitByClosure, splitSubpaths, squarePath, standoff, stationsAlongPath, strokeHitTest, subpathEndAt, subpathsOfAnchors, tagTypedArray, tagTypedArrays, trackRun, trackShapeD, trackSlice, transformCoords, transformPath, translate, translateAnchorBy, translateAnchorsSymmetric, translatePath, trimPathAt, typedArrayReplacer, unionBoundsPath, unsatisfiedConstraints, untagTypedArray, viewRectToScreen, viewScreenToWorld, viewToMat3, viewWorldToScreen, withAnchorPoints, withinPxBox, withinPxRadius, worldEditToStorage, writeAnchorField, zigzagPath };
|
|
7024
7160
|
//# sourceMappingURL=index.js.map
|
|
7025
7161
|
//# sourceMappingURL=index.js.map
|