@weasel-js/geom 1.11.1 → 1.13.0-rc.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/booleans/index.js +2 -2
- package/dist/{chunk-EAKE3N7W.js → chunk-2PKPKU4P.js} +178 -178
- package/dist/chunk-2PKPKU4P.js.map +1 -0
- package/dist/{chunk-6FGQML7D.js → chunk-STGSBIOL.js} +3 -3
- package/dist/{chunk-6FGQML7D.js.map → chunk-STGSBIOL.js.map} +1 -1
- package/dist/{chunk-LRVPK7HI.js → chunk-UGE57OTX.js} +3 -3
- package/dist/{chunk-LRVPK7HI.js.map → chunk-UGE57OTX.js.map} +1 -1
- package/dist/{chunk-7F66PQCJ.js → chunk-VHXOCDZ2.js} +3 -3
- package/dist/{chunk-7F66PQCJ.js.map → chunk-VHXOCDZ2.js.map} +1 -1
- package/dist/{chunk-4Y67BZL5.js → chunk-YPWFGFQX.js} +3 -3
- package/dist/{chunk-4Y67BZL5.js.map → chunk-YPWFGFQX.js.map} +1 -1
- package/dist/index.d.ts +262 -56
- package/dist/index.js +663 -180
- package/dist/index.js.map +1 -1
- package/dist/nd/index.d.ts +40 -1
- package/dist/nd/index.js +681 -1
- package/dist/nd/index.js.map +1 -1
- package/dist/tessellate/index.js +3 -3
- package/dist/warp/index.js +3 -3
- package/package.json +2 -2
- package/dist/chunk-EAKE3N7W.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import { carryCorners, evalSeg, parseSubpaths, keepCorners, anchorRange, subSeg, writePath, derivSeg } from './chunk-
|
|
2
|
-
export { CORNER_RESTORE_TOLERANCE, cornerTraces, keepCorners, restoreCorners } from './chunk-
|
|
1
|
+
import { carryCorners, evalSeg, parseSubpaths, keepCorners, anchorRange, subSeg, writePath, derivSeg } from './chunk-YPWFGFQX.js';
|
|
2
|
+
export { CORNER_RESTORE_TOLERANCE, cornerTraces, keepCorners, restoreCorners } from './chunk-YPWFGFQX.js';
|
|
3
3
|
import { PORT_REACH, portControls, portCurvePoints } from './chunk-YQADYJJ7.js';
|
|
4
4
|
export { PORT_REACH } from './chunk-YQADYJJ7.js';
|
|
5
5
|
import { cubicDerivativeAt, cubicCurvatureAt } from './chunk-UI3FUWXM.js';
|
|
6
6
|
export { SPIRO_KINDS, combTeeth, cubicCurvatureAt, cubicCurvatureSource, cubicDerivativeAt, curvatureComb, eulerAngleAt, eulerCurvatureAt, eulerCurvatureDerivativesAt, eulerPointAt, fitEulerSegment, isSpiroKind, placeEulerSegment, solveSpiro, spiroContoursFromControl, spiroContoursOf, spiroControlPath, spiroToPath } from './chunk-UI3FUWXM.js';
|
|
7
|
-
import { extractPolylines } from './chunk-
|
|
8
|
-
import { boundsOfPath, fitPointRun, keepCorner } from './chunk-
|
|
9
|
-
export { boundsOfPath } from './chunk-
|
|
7
|
+
import { extractPolylines } from './chunk-VHXOCDZ2.js';
|
|
8
|
+
import { boundsOfPath, fitPointRun, keepCorner } from './chunk-STGSBIOL.js';
|
|
9
|
+
export { boundsOfPath } from './chunk-STGSBIOL.js';
|
|
10
10
|
import { countPathAnchors, pathToAnchors, anchorsToPath, isAnchorSmooth, segmentEnds, isStraightSegment, nearestSegmentT } from './chunk-Q66NA2FU.js';
|
|
11
11
|
export { anchorsToPath, countPathAnchors, isAnchorSmooth, isStraightSegment, nearestSegmentT, pathToAnchors, segmentEnds } from './chunk-Q66NA2FU.js';
|
|
12
|
-
import {
|
|
12
|
+
import { nearestOnLine, nearestOnPath, nearestOnQuadratic, nearestOnCubic } from './chunk-CE7IY7TB.js';
|
|
13
13
|
export { nearestOnCubic, nearestOnLine, nearestOnPath, nearestOnQuadratic } from './chunk-CE7IY7TB.js';
|
|
14
|
-
import {
|
|
15
|
-
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, pointSegmentDist2, remapPerAnchor, resolveCorners, resolveCornersWithSources, schneiderFit, segmentsCross, setDefaultOpenFill } from './chunk-
|
|
16
|
-
import { SINGULAR_RATIO } from './chunk-755Y4YZS.js';
|
|
14
|
+
import { resolveCorners, pointInPolygon, cornerCuts, fillsOpenSubpaths, schneiderFit, fitCubicWithTangents, flattenCubic, pointSegmentDist2, flattenQuadratic, DEFAULT_FLATTEN_TOLERANCE, segmentsCross } from './chunk-2PKPKU4P.js';
|
|
15
|
+
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, pointSegmentDist2, remapPerAnchor, resolveCorners, resolveCornersWithSources, schneiderFit, segmentsCross, setDefaultOpenFill } from './chunk-2PKPKU4P.js';
|
|
16
|
+
import { SINGULAR_RATIO, clamp } from './chunk-755Y4YZS.js';
|
|
17
17
|
export { EPS, approxEq, clamp, cross, dot, len2, sign, sub } from './chunk-755Y4YZS.js';
|
|
18
|
-
import {
|
|
18
|
+
import { PATH_M, PATH_L, PATH_C, PATH_Q, PATH_Z, PathBuilder, withCorner, scaleCorners, forEachSegment, pathCommandCoordCount, withoutCorners, elevateQuadraticToCubic, cubicEvalAt, cubicPointAt, splitCubicAtT, cubicAxisExtremaTs, rectToContour, splitCubicAt } from './chunk-B53BERKG.js';
|
|
19
19
|
export { PATH_C, PATH_CMD_LENGTHS, PATH_COMMANDS, PATH_L, PATH_M, PATH_Q, PATH_Z, PathBuilder, asPolygonPath, boundsOfCoords, boxContainsBox, boxContainsPoint, compactCorners, cornerAt, cornerSpecAt, cubicAxisExtremaTs, cubicBounds, cubicEvalAt, cubicPointAt, elevateQuadraticToCubic, ellipsePath, forEachSegment, hasCorners, lerpCorners, linePath, pathCommandCoordCount, polygonFromPoints, polylineFromPoints, quadraticEvalAt, rectPath, rectToContour, regularPolygonPath, scaleCorners, splitCubicAt, splitCubicAtT, splitLineAt, splitQuadraticAt, starPath, unionBox, withCorner, withoutCorners } from './chunk-B53BERKG.js';
|
|
20
20
|
|
|
21
21
|
// src/view.ts
|
|
@@ -82,6 +82,640 @@ function transformCoords(coords, m) {
|
|
|
82
82
|
return out;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
+
// src/track/shape.ts
|
|
86
|
+
function lineShape(from, to) {
|
|
87
|
+
const dx2 = to.x - from.x;
|
|
88
|
+
const dy2 = to.y - from.y;
|
|
89
|
+
const length2 = Math.hypot(dx2, dy2);
|
|
90
|
+
const tangent = length2 === 0 ? { x: 1, y: 0 } : { x: dx2 / length2, y: dy2 / length2 };
|
|
91
|
+
const normal2 = { x: tangent.y, y: -tangent.x };
|
|
92
|
+
return {
|
|
93
|
+
kind: "line",
|
|
94
|
+
length: length2,
|
|
95
|
+
closed: false,
|
|
96
|
+
at(f, options) {
|
|
97
|
+
const t = options?.open ? f : clamp(f, 0, 1);
|
|
98
|
+
return {
|
|
99
|
+
point: { x: from.x + t * dx2, y: from.y + t * dy2 },
|
|
100
|
+
tangent: { ...tangent },
|
|
101
|
+
normal: { ...normal2 }
|
|
102
|
+
};
|
|
103
|
+
},
|
|
104
|
+
nearest(p, options) {
|
|
105
|
+
const n = nearestOnLine(p.x, p.y, from.x, from.y, to.x, to.y);
|
|
106
|
+
if (!options?.open || length2 === 0) return { f: n.t, dist: n.dist };
|
|
107
|
+
const f = ((p.x - from.x) * dx2 + (p.y - from.y) * dy2) / (length2 * length2);
|
|
108
|
+
return { f, dist: n.dist };
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// src/track/arc.ts
|
|
114
|
+
var RAD = Math.PI / 180;
|
|
115
|
+
var mod360 = (a) => (a % 360 + 360) % 360;
|
|
116
|
+
function arcShape(spec) {
|
|
117
|
+
const { center, radius, start } = spec;
|
|
118
|
+
const sign2 = spec.direction === "ccw" ? -1 : 1;
|
|
119
|
+
const raw = mod360(sign2 * (spec.end - start));
|
|
120
|
+
const sweep = raw === 0 ? 360 : raw;
|
|
121
|
+
const length2 = radius * sweep * RAD;
|
|
122
|
+
const at2 = (f, options) => {
|
|
123
|
+
const t = options?.open ? f : clamp(f, 0, 1);
|
|
124
|
+
const theta = (start + sign2 * t * sweep) * RAD;
|
|
125
|
+
const s = Math.sin(theta);
|
|
126
|
+
const c = Math.cos(theta);
|
|
127
|
+
return {
|
|
128
|
+
point: { x: center.x + radius * s, y: center.y - radius * c },
|
|
129
|
+
tangent: { x: sign2 * c, y: sign2 * s },
|
|
130
|
+
normal: { x: s, y: -c }
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
const shape = {
|
|
134
|
+
kind: "arc",
|
|
135
|
+
length: length2,
|
|
136
|
+
closed: raw === 0,
|
|
137
|
+
at: at2,
|
|
138
|
+
nearest(p, options) {
|
|
139
|
+
const dx2 = p.x - center.x;
|
|
140
|
+
const dy2 = p.y - center.y;
|
|
141
|
+
const angle = dx2 === 0 && dy2 === 0 ? 0 : Math.atan2(dx2, -dy2) / RAD;
|
|
142
|
+
const offset2 = mod360(sign2 * (angle - start));
|
|
143
|
+
let f;
|
|
144
|
+
if (offset2 <= sweep) f = offset2 / sweep;
|
|
145
|
+
else f = 360 - offset2 < offset2 - sweep ? 0 : 1;
|
|
146
|
+
const q = at2(f).point;
|
|
147
|
+
const dist = Math.hypot(p.x - q.x, p.y - q.y);
|
|
148
|
+
if (!options?.open) return { f, dist };
|
|
149
|
+
const mid = (options.about ?? 0.5) * sweep;
|
|
150
|
+
const unwrapped = mid + mod360(offset2 - mid + 180) - 180;
|
|
151
|
+
return { f: unwrapped / sweep, dist };
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
Object.defineProperty(shape, "arc", { value: spec, enumerable: false });
|
|
155
|
+
return shape;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/track/ellipse.ts
|
|
159
|
+
var RAD2 = Math.PI / 180;
|
|
160
|
+
var mod3602 = (a) => (a % 360 + 360) % 360;
|
|
161
|
+
var PIECES = 128;
|
|
162
|
+
var PANELS = 4;
|
|
163
|
+
var RING = 256;
|
|
164
|
+
var pointAt = ({ center, a, b, t0, sign: sign2 }, u) => {
|
|
165
|
+
const t = (t0 + sign2 * u) * RAD2;
|
|
166
|
+
return { x: center.x + a * Math.sin(t), y: center.y - b * Math.cos(t) };
|
|
167
|
+
};
|
|
168
|
+
var speed = ({ a, b, t0, sign: sign2 }, u) => {
|
|
169
|
+
const t = (t0 + sign2 * u) * RAD2;
|
|
170
|
+
return Math.hypot(a * Math.cos(t), b * Math.sin(t)) * RAD2;
|
|
171
|
+
};
|
|
172
|
+
function lengthTable(e, sweep) {
|
|
173
|
+
const simpson = (u0, u1) => {
|
|
174
|
+
const h = (u1 - u0) / PANELS;
|
|
175
|
+
let sum = speed(e, u0) + speed(e, u1);
|
|
176
|
+
for (let i = 1; i < PANELS; i++) sum += speed(e, u0 + i * h) * (i % 2 ? 4 : 2);
|
|
177
|
+
return sum * h / 3;
|
|
178
|
+
};
|
|
179
|
+
const du = sweep / PIECES;
|
|
180
|
+
const table = [0];
|
|
181
|
+
for (let i = 0; i < PIECES; i++) table.push(table[i] + simpson(i * du, (i + 1) * du));
|
|
182
|
+
const length2 = table[PIECES];
|
|
183
|
+
const lengthTo = (u) => {
|
|
184
|
+
if (u >= 0 && u <= sweep) {
|
|
185
|
+
const i = Math.min(PIECES - 1, Math.floor(u / du));
|
|
186
|
+
return table[i] + simpson(i * du, u);
|
|
187
|
+
}
|
|
188
|
+
const n = Math.max(1, Math.ceil(Math.abs(u) / du));
|
|
189
|
+
let s = 0;
|
|
190
|
+
for (let i = 0; i < n; i++) s += simpson(u * i / n, u * (i + 1) / n);
|
|
191
|
+
return s;
|
|
192
|
+
};
|
|
193
|
+
const offsetAt = (f) => {
|
|
194
|
+
if (length2 === 0) return f * sweep;
|
|
195
|
+
const s = f * length2;
|
|
196
|
+
let lo = 0;
|
|
197
|
+
let hi = PIECES;
|
|
198
|
+
while (hi - lo > 1) {
|
|
199
|
+
const mid = lo + hi >> 1;
|
|
200
|
+
if (table[mid] <= s) lo = mid;
|
|
201
|
+
else hi = mid;
|
|
202
|
+
}
|
|
203
|
+
const piece = table[lo + 1] - table[lo];
|
|
204
|
+
let u = (lo + (piece === 0 ? 0 : (s - table[lo]) / piece)) * du;
|
|
205
|
+
for (let i = 0; i < 3; i++) {
|
|
206
|
+
const v = speed(e, u);
|
|
207
|
+
if (!(v > 0)) break;
|
|
208
|
+
u -= (lengthTo(u) - s) / v;
|
|
209
|
+
}
|
|
210
|
+
return u;
|
|
211
|
+
};
|
|
212
|
+
return { length: length2, lengthTo, offsetAt };
|
|
213
|
+
}
|
|
214
|
+
var dist2 = (e, p, u) => {
|
|
215
|
+
const q = pointAt(e, u);
|
|
216
|
+
return (p.x - q.x) ** 2 + (p.y - q.y) ** 2;
|
|
217
|
+
};
|
|
218
|
+
function footBetween(e, p, lo, hi, n, late) {
|
|
219
|
+
let best = lo;
|
|
220
|
+
let bestD = dist2(e, p, lo);
|
|
221
|
+
const step = (hi - lo) / n;
|
|
222
|
+
for (let i = 1; i <= n; i++) {
|
|
223
|
+
const v = i === n ? hi : lo + i * step;
|
|
224
|
+
const d = dist2(e, p, v);
|
|
225
|
+
if (late ? d <= bestD * (1 + 1e-12) : d < bestD * (1 - 1e-12)) [best, bestD] = [v, d];
|
|
226
|
+
}
|
|
227
|
+
const { a, b, t0, sign: sign2 } = e;
|
|
228
|
+
const dx2 = p.x - e.center.x;
|
|
229
|
+
const dy2 = p.y - e.center.y;
|
|
230
|
+
let u = best;
|
|
231
|
+
for (let i = 0; i < 12; i++) {
|
|
232
|
+
const t = (t0 + sign2 * u) * RAD2;
|
|
233
|
+
const s = Math.sin(t);
|
|
234
|
+
const c = Math.cos(t);
|
|
235
|
+
const g = (a * a - b * b) * s * c - dx2 * a * c - dy2 * b * s;
|
|
236
|
+
const g1 = (a * a - b * b) * (c * c - s * s) + dx2 * a * s - dy2 * b * c;
|
|
237
|
+
if (!(g1 > 0)) break;
|
|
238
|
+
const next = clamp(u - sign2 * g / g1 / RAD2, Math.max(lo, best - step), Math.min(hi, best + step));
|
|
239
|
+
if (Math.abs(next - u) < 1e-12) break;
|
|
240
|
+
u = next;
|
|
241
|
+
}
|
|
242
|
+
return dist2(e, p, u) <= bestD ? u : best;
|
|
243
|
+
}
|
|
244
|
+
function ellipseShape(spec) {
|
|
245
|
+
const { center, radiusX: a, radiusY: b } = spec;
|
|
246
|
+
const sign2 = spec.direction === "ccw" ? -1 : 1;
|
|
247
|
+
const param = (seenDeg) => Math.atan2(b * Math.sin(seenDeg * RAD2), a * Math.cos(seenDeg * RAD2)) / RAD2;
|
|
248
|
+
const e = { center, a, b, t0: param(spec.start), sign: sign2 };
|
|
249
|
+
const raw = mod3602(sign2 * (param(spec.end) - e.t0));
|
|
250
|
+
const sweep = raw === 0 ? 360 : raw;
|
|
251
|
+
const { length: length2, lengthTo, offsetAt } = lengthTable(e, sweep);
|
|
252
|
+
const offsetPast = (f) => {
|
|
253
|
+
if (raw === 0) return offsetAt((f % 1 + 1) % 1);
|
|
254
|
+
let u = f * sweep;
|
|
255
|
+
for (let i = 0; i < 8; i++) {
|
|
256
|
+
const v = speed(e, u);
|
|
257
|
+
if (!(v > 0)) break;
|
|
258
|
+
u -= (lengthTo(u) - f * length2) / v;
|
|
259
|
+
}
|
|
260
|
+
return u;
|
|
261
|
+
};
|
|
262
|
+
const at2 = (f, options) => {
|
|
263
|
+
const u = options?.open && (f < 0 || f > 1) ? offsetPast(f) : offsetAt(clamp(f, 0, 1));
|
|
264
|
+
const t = (e.t0 + sign2 * u) * RAD2;
|
|
265
|
+
const s = Math.sin(t);
|
|
266
|
+
const c = Math.cos(t);
|
|
267
|
+
const k = Math.hypot(a * c, b * s);
|
|
268
|
+
const tangent = k === 0 ? { x: sign2 * c, y: sign2 * s } : { x: sign2 * a * c / k, y: sign2 * b * s / k };
|
|
269
|
+
const normal2 = k === 0 ? { x: s, y: -c } : { x: b * s / k, y: -a * c / k };
|
|
270
|
+
return { point: pointAt(e, u), tangent, normal: normal2 };
|
|
271
|
+
};
|
|
272
|
+
const shape = {
|
|
273
|
+
kind: "ellipse",
|
|
274
|
+
length: length2,
|
|
275
|
+
closed: raw === 0,
|
|
276
|
+
at: at2,
|
|
277
|
+
nearest(p, options) {
|
|
278
|
+
const u = footBetween(e, p, 0, sweep, PIECES, true);
|
|
279
|
+
const f = length2 === 0 ? 0 : clamp(lengthTo(u) / length2, 0, 1);
|
|
280
|
+
const dist = Math.sqrt(dist2(e, p, u));
|
|
281
|
+
if (!options?.open || length2 === 0) return { f, dist };
|
|
282
|
+
const mid = offsetAt(options.about ?? 0.5);
|
|
283
|
+
return { f: lengthTo(footBetween(e, p, mid - 180, mid + 180, RING, false)) / length2, dist };
|
|
284
|
+
}
|
|
285
|
+
};
|
|
286
|
+
Object.defineProperty(shape, "ellipse", { value: spec, enumerable: false });
|
|
287
|
+
return shape;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// src/paths/pathMeasure.ts
|
|
291
|
+
function measurePath(path, opts = {}) {
|
|
292
|
+
const polylines = extractPolylines(
|
|
293
|
+
path,
|
|
294
|
+
opts.flattenTolerance === void 0 ? {} : { flattenTolerance: opts.flattenTolerance }
|
|
295
|
+
);
|
|
296
|
+
const segments = [];
|
|
297
|
+
let total = 0;
|
|
298
|
+
let first;
|
|
299
|
+
let contours = 0;
|
|
300
|
+
let lastClosed = false;
|
|
301
|
+
for (const pl of polylines) {
|
|
302
|
+
const count = pl.points.length / 2;
|
|
303
|
+
if (count === 0) continue;
|
|
304
|
+
contours++;
|
|
305
|
+
lastClosed = pl.closed;
|
|
306
|
+
first ??= { x: pl.points[0], y: pl.points[1] };
|
|
307
|
+
const startIndex = segments.length;
|
|
308
|
+
const last = pl.closed ? count : count - 1;
|
|
309
|
+
for (let i = 0; i < last; i++) {
|
|
310
|
+
const j = (i + 1) % count;
|
|
311
|
+
const ax = pl.points[i * 2];
|
|
312
|
+
const ay = pl.points[i * 2 + 1];
|
|
313
|
+
const bx = pl.points[j * 2];
|
|
314
|
+
const by = pl.points[j * 2 + 1];
|
|
315
|
+
const len = Math.hypot(bx - ax, by - ay);
|
|
316
|
+
if (len === 0) continue;
|
|
317
|
+
const tx = (bx - ax) / len;
|
|
318
|
+
const ty = (by - ay) / len;
|
|
319
|
+
segments.push({ ax, ay, bx, by, start: total, len, tx, ty, t0x: tx, t0y: ty, t1x: tx, t1y: ty });
|
|
320
|
+
total += len;
|
|
321
|
+
}
|
|
322
|
+
smoothVertexHeadings(segments, startIndex, pl.closed, opts.keepCorners ? opts.flattenTolerance ?? 0.5 : null);
|
|
323
|
+
}
|
|
324
|
+
if (first === void 0) return null;
|
|
325
|
+
const origin = first;
|
|
326
|
+
const closed = contours === 1 && lastClosed;
|
|
327
|
+
if (segments.length === 0) {
|
|
328
|
+
return {
|
|
329
|
+
length: 0,
|
|
330
|
+
closed,
|
|
331
|
+
at: () => ({ point: { ...origin }, tangent: { x: 1, y: 0 } }),
|
|
332
|
+
nearest: (p) => ({
|
|
333
|
+
s: 0,
|
|
334
|
+
dist: Math.hypot(p.x - origin.x, p.y - origin.y),
|
|
335
|
+
point: { ...origin },
|
|
336
|
+
tangent: { x: 1, y: 0 }
|
|
337
|
+
})
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
return {
|
|
341
|
+
length: total,
|
|
342
|
+
closed,
|
|
343
|
+
at(s, smooth = false) {
|
|
344
|
+
const target = Math.min(Math.max(s, 0), total);
|
|
345
|
+
const seg = segments[segmentAt(segments, target)];
|
|
346
|
+
const u = Math.min(Math.max((target - seg.start) / seg.len, 0), 1);
|
|
347
|
+
const point = { x: seg.ax + (seg.bx - seg.ax) * u, y: seg.ay + (seg.by - seg.ay) * u };
|
|
348
|
+
if (!smooth) return { point, tangent: { x: seg.tx, y: seg.ty } };
|
|
349
|
+
const x = seg.t0x + (seg.t1x - seg.t0x) * u;
|
|
350
|
+
const y = seg.t0y + (seg.t1y - seg.t0y) * u;
|
|
351
|
+
const l = Math.hypot(x, y);
|
|
352
|
+
return { point, tangent: l === 0 ? { x: seg.tx, y: seg.ty } : { x: x / l, y: y / l } };
|
|
353
|
+
},
|
|
354
|
+
nearest(p) {
|
|
355
|
+
let best = segments[0];
|
|
356
|
+
let bestU = 0;
|
|
357
|
+
let bestDist = Infinity;
|
|
358
|
+
for (const seg of segments) {
|
|
359
|
+
const u = Math.min(Math.max(((p.x - seg.ax) * seg.tx + (p.y - seg.ay) * seg.ty) / seg.len, 0), 1);
|
|
360
|
+
const d = Math.hypot(p.x - (seg.ax + (seg.bx - seg.ax) * u), p.y - (seg.ay + (seg.by - seg.ay) * u));
|
|
361
|
+
if (d < bestDist) {
|
|
362
|
+
best = seg;
|
|
363
|
+
bestU = u;
|
|
364
|
+
bestDist = d;
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return {
|
|
368
|
+
s: best.start + best.len * bestU,
|
|
369
|
+
dist: bestDist,
|
|
370
|
+
point: { x: best.ax + (best.bx - best.ax) * bestU, y: best.ay + (best.by - best.ay) * bestU },
|
|
371
|
+
tangent: { x: best.tx, y: best.ty }
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
};
|
|
375
|
+
}
|
|
376
|
+
function smoothVertexHeadings(segments, from, closed, cornerTolerance) {
|
|
377
|
+
const n = segments.length - from;
|
|
378
|
+
if (n < 2) return;
|
|
379
|
+
const pairs = closed ? n : n - 1;
|
|
380
|
+
for (let k = 0; k < pairs; k++) {
|
|
381
|
+
const a = segments[from + k];
|
|
382
|
+
const b = segments[from + (k + 1) % n];
|
|
383
|
+
if (cornerTolerance !== null && isCorner(a, b, cornerTolerance)) continue;
|
|
384
|
+
let x = a.tx + b.tx;
|
|
385
|
+
let y = a.ty + b.ty;
|
|
386
|
+
const l = Math.hypot(x, y);
|
|
387
|
+
if (l < 1e-9) continue;
|
|
388
|
+
x /= l;
|
|
389
|
+
y /= l;
|
|
390
|
+
a.t1x = x;
|
|
391
|
+
a.t1y = y;
|
|
392
|
+
b.t0x = x;
|
|
393
|
+
b.t0y = y;
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
function isCorner(a, b, tolerance) {
|
|
397
|
+
const turn = Math.acos(Math.min(1, Math.max(-1, a.tx * b.tx + a.ty * b.ty)));
|
|
398
|
+
return turn > 16 * tolerance / Math.min(a.len, b.len);
|
|
399
|
+
}
|
|
400
|
+
function segmentAt(segments, s) {
|
|
401
|
+
let lo = 0;
|
|
402
|
+
let hi = segments.length - 1;
|
|
403
|
+
while (lo < hi) {
|
|
404
|
+
const mid = lo + hi + 1 >> 1;
|
|
405
|
+
if (segments[mid].start <= s) lo = mid;
|
|
406
|
+
else hi = mid - 1;
|
|
407
|
+
}
|
|
408
|
+
return lo;
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
// src/track/path.ts
|
|
412
|
+
function pathShape(path, options = {}) {
|
|
413
|
+
const measure2 = measurePath(path, { ...options, keepCorners: true });
|
|
414
|
+
if (!measure2) return null;
|
|
415
|
+
const { length: length2, closed } = measure2;
|
|
416
|
+
const shape = {
|
|
417
|
+
kind: "path",
|
|
418
|
+
length: length2,
|
|
419
|
+
closed,
|
|
420
|
+
at(f, options2) {
|
|
421
|
+
const open = options2?.open === true && (f < 0 || f > 1);
|
|
422
|
+
const g = open && closed ? (f % 1 + 1) % 1 : clamp(f, 0, 1);
|
|
423
|
+
const { point, tangent } = measure2.at(g * length2, true);
|
|
424
|
+
const past = open && !closed ? (f - g) * length2 : 0;
|
|
425
|
+
return { point: { x: point.x + past * tangent.x, y: point.y + past * tangent.y }, tangent, normal: { x: tangent.y, y: -tangent.x } };
|
|
426
|
+
},
|
|
427
|
+
nearest(p, opts) {
|
|
428
|
+
const n = measure2.nearest(p);
|
|
429
|
+
const f = length2 === 0 ? 0 : n.s / length2;
|
|
430
|
+
if (!opts?.open || !closed || length2 === 0) return { f, dist: n.dist };
|
|
431
|
+
const about = opts.about ?? 0.5;
|
|
432
|
+
const unwrapped = [f - 1, f + 1].reduce((best, g) => Math.abs(g - about) < Math.abs(best - about) ? g : best, f);
|
|
433
|
+
return { f: unwrapped, dist: n.dist };
|
|
434
|
+
}
|
|
435
|
+
};
|
|
436
|
+
Object.defineProperty(shape, "path", { value: path, enumerable: false });
|
|
437
|
+
return shape;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// src/track/run.ts
|
|
441
|
+
var pointsDown = (normal2) => normal2.y > 1e-9;
|
|
442
|
+
function trackRun(shape, from = 0, to = 1, options = {}) {
|
|
443
|
+
const { side = "auto", about = (from + to) / 2 } = options;
|
|
444
|
+
const mid = shape.at(about);
|
|
445
|
+
const flipped = side === "auto" ? pointsDown(mid.normal) : side === "flipped";
|
|
446
|
+
const sgn = flipped ? -1 : 1;
|
|
447
|
+
const reading = (n) => ({ x: -(sgn * n.y), y: sgn * n.x });
|
|
448
|
+
const r0 = reading(mid.normal);
|
|
449
|
+
const reversed3 = r0.x * mid.tangent.x + r0.y * mid.tangent.y < 0;
|
|
450
|
+
const span = to - from;
|
|
451
|
+
const lo = Math.min(from, to);
|
|
452
|
+
const hi = Math.max(from, to);
|
|
453
|
+
const toF = (g) => reversed3 ? to - g * span : from + g * span;
|
|
454
|
+
const at2 = (g, options2) => {
|
|
455
|
+
const s = options2?.open ? shape.at(toF(g), options2) : shape.at(toF(clamp(g, 0, 1)));
|
|
456
|
+
const dir = reading(s.normal);
|
|
457
|
+
const angle = Math.atan2(dir.y, dir.x) * 180 / Math.PI;
|
|
458
|
+
const normal2 = { x: sgn * s.normal.x, y: sgn * s.normal.y };
|
|
459
|
+
return {
|
|
460
|
+
point: s.point,
|
|
461
|
+
tangent: dir,
|
|
462
|
+
normal: normal2,
|
|
463
|
+
angle: angle === 0 ? 0 : angle === -180 ? 180 : angle,
|
|
464
|
+
turned: pointsDown(normal2)
|
|
465
|
+
};
|
|
466
|
+
};
|
|
467
|
+
const toG = (f) => span === 0 ? 0 : reversed3 ? (to - f) / span : (f - from) / span;
|
|
468
|
+
const nearest = (p, options2) => {
|
|
469
|
+
const f = clamp(shape.nearest(p).f, lo, hi);
|
|
470
|
+
const q = shape.at(f).point;
|
|
471
|
+
const dist = Math.hypot(p.x - q.x, p.y - q.y);
|
|
472
|
+
if (!options2?.open) return { f: toG(f), dist };
|
|
473
|
+
return { f: toG(shape.nearest(p, { open: true, about: toF(options2.about ?? 0.5) }).f), dist };
|
|
474
|
+
};
|
|
475
|
+
return {
|
|
476
|
+
kind: shape.kind,
|
|
477
|
+
length: shape.length * Math.abs(span),
|
|
478
|
+
closed: shape.closed && Math.abs(span) === 1,
|
|
479
|
+
shape,
|
|
480
|
+
from,
|
|
481
|
+
to,
|
|
482
|
+
flipped,
|
|
483
|
+
reversed: reversed3,
|
|
484
|
+
at: at2,
|
|
485
|
+
nearest
|
|
486
|
+
};
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
// src/paths/pathToD.ts
|
|
490
|
+
var num = (n) => Number.isFinite(n) ? String(Math.round(n * 1e6) / 1e6) : "0";
|
|
491
|
+
function pathToD(given) {
|
|
492
|
+
const path = resolveCorners(given);
|
|
493
|
+
if (path.kind === "rect") {
|
|
494
|
+
const { x, y, width, height } = path;
|
|
495
|
+
return `M${num(x)} ${num(y)}h${num(width)}v${num(height)}h${num(-width)}Z`;
|
|
496
|
+
}
|
|
497
|
+
const cmds = path.commands;
|
|
498
|
+
const xs = path.coords;
|
|
499
|
+
const out = [];
|
|
500
|
+
let ci = 0;
|
|
501
|
+
for (let i = 0; i < cmds.length; i++) {
|
|
502
|
+
const c = cmds[i];
|
|
503
|
+
if (c === PATH_M) {
|
|
504
|
+
out.push(`M${num(xs[ci])} ${num(xs[ci + 1])}`);
|
|
505
|
+
ci += 2;
|
|
506
|
+
} else if (c === PATH_L) {
|
|
507
|
+
out.push(`L${num(xs[ci])} ${num(xs[ci + 1])}`);
|
|
508
|
+
ci += 2;
|
|
509
|
+
} else if (c === PATH_C) {
|
|
510
|
+
out.push(
|
|
511
|
+
`C${num(xs[ci])} ${num(xs[ci + 1])} ${num(xs[ci + 2])} ${num(xs[ci + 3])} ${num(xs[ci + 4])} ${num(xs[ci + 5])}`
|
|
512
|
+
);
|
|
513
|
+
ci += 6;
|
|
514
|
+
} else if (c === PATH_Q) {
|
|
515
|
+
out.push(`Q${num(xs[ci])} ${num(xs[ci + 1])} ${num(xs[ci + 2])} ${num(xs[ci + 3])}`);
|
|
516
|
+
ci += 4;
|
|
517
|
+
} else if (c === PATH_Z) {
|
|
518
|
+
out.push("Z");
|
|
519
|
+
}
|
|
520
|
+
}
|
|
521
|
+
return out.join("");
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
// src/track/pathData.ts
|
|
525
|
+
var SAMPLES = 64;
|
|
526
|
+
var num2 = (v) => {
|
|
527
|
+
const r = Math.round(v * 1e4) / 1e4;
|
|
528
|
+
return String(r === 0 ? 0 : r);
|
|
529
|
+
};
|
|
530
|
+
var pt = (p) => `${num2(p.x)} ${num2(p.y)}`;
|
|
531
|
+
var isArc = (s) => s.kind === "arc" && "arc" in s;
|
|
532
|
+
var isPath = (s) => s.kind === "path" && "path" in s;
|
|
533
|
+
var isEllipse = (s) => s.kind === "ellipse" && "ellipse" in s;
|
|
534
|
+
function arcsD(a, b, m, rx, ry, turn, sweep) {
|
|
535
|
+
const r = `${num2(rx)} ${num2(ry)}`;
|
|
536
|
+
if (turn >= 2 * Math.PI - 1e-9) return `M ${pt(a)} A ${r} 0 0 ${sweep} ${pt(m())} A ${r} 0 0 ${sweep} ${pt(b)}`;
|
|
537
|
+
return `M ${pt(a)} A ${r} 0 ${turn > Math.PI + 1e-9 ? 1 : 0} ${sweep} ${pt(b)}`;
|
|
538
|
+
}
|
|
539
|
+
function trackShapeD(shape, from = 0, to = 1) {
|
|
540
|
+
if (isPath(shape) && from === 0 && to === 1) return pathToD(shape.path);
|
|
541
|
+
const a = shape.at(from).point;
|
|
542
|
+
const b = shape.at(to).point;
|
|
543
|
+
if (shape.kind === "line") return `M ${pt(a)} L ${pt(b)}`;
|
|
544
|
+
const m = () => shape.at((from + to) / 2).point;
|
|
545
|
+
if (isArc(shape)) {
|
|
546
|
+
const { radius, direction } = shape.arc;
|
|
547
|
+
const turn = shape.length * Math.abs(to - from) / radius;
|
|
548
|
+
return arcsD(a, b, m, radius, radius, turn, direction === "ccw" === to < from ? 1 : 0);
|
|
549
|
+
}
|
|
550
|
+
if (isEllipse(shape)) {
|
|
551
|
+
const { radiusX, radiusY, direction, center } = shape.ellipse;
|
|
552
|
+
const param = (p) => Math.atan2((p.x - center.x) / radiusX, (center.y - p.y) / radiusY);
|
|
553
|
+
const sign2 = direction === "ccw" ? -1 : 1;
|
|
554
|
+
const whole = (shape.ellipse.start - shape.ellipse.end) % 360 === 0 && Math.abs(to - from) >= 1 - 1e-12;
|
|
555
|
+
const raw = (sign2 * Math.sign(to - from) * (param(b) - param(a)) + 4 * Math.PI) % (2 * Math.PI);
|
|
556
|
+
return arcsD(a, b, m, radiusX, radiusY, whole ? 2 * Math.PI : raw, direction === "ccw" === to < from ? 1 : 0);
|
|
557
|
+
}
|
|
558
|
+
let d = `M ${pt(a)}`;
|
|
559
|
+
for (let i = 1; i <= SAMPLES; i++)
|
|
560
|
+
d += ` L ${pt(shape.at(from + (to - from) * i / SAMPLES).point)}`;
|
|
561
|
+
return d;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
// src/track/shift.ts
|
|
565
|
+
var SAMPLES2 = 256;
|
|
566
|
+
var dot2 = (a, b) => a.x * b.x + a.y * b.y;
|
|
567
|
+
function bendSide(shape) {
|
|
568
|
+
let turn = 0;
|
|
569
|
+
let prev = shape.at(0);
|
|
570
|
+
for (let i = 1; i <= SAMPLES2; i++) {
|
|
571
|
+
const next = shape.at(i / SAMPLES2);
|
|
572
|
+
turn += dot2({ x: next.tangent.x - prev.tangent.x, y: next.tangent.y - prev.tangent.y }, prev.normal);
|
|
573
|
+
prev = next;
|
|
574
|
+
}
|
|
575
|
+
return Math.abs(turn) < 1e-9 ? 0 : turn > 0 ? 1 : -1;
|
|
576
|
+
}
|
|
577
|
+
function shiftTrack(shape, shift) {
|
|
578
|
+
if (shift === 0) return shape;
|
|
579
|
+
const moved2 = (s) => ({ ...s, point: { x: s.point.x + shift * s.normal.x, y: s.point.y + shift * s.normal.y } });
|
|
580
|
+
const table = new Float64Array(SAMPLES2 + 1);
|
|
581
|
+
let prev = moved2(shape.at(0));
|
|
582
|
+
for (let i = 1; i <= SAMPLES2; i++) {
|
|
583
|
+
const next = moved2(shape.at(i / SAMPLES2));
|
|
584
|
+
const step = { x: next.point.x - prev.point.x, y: next.point.y - prev.point.y };
|
|
585
|
+
const tangent = { x: prev.tangent.x + next.tangent.x, y: prev.tangent.y + next.tangent.y };
|
|
586
|
+
if (shape.length > 0 && dot2(step, tangent) <= 0) return null;
|
|
587
|
+
table[i] = table[i - 1] + Math.hypot(step.x, step.y);
|
|
588
|
+
prev = next;
|
|
589
|
+
}
|
|
590
|
+
const length2 = table[SAMPLES2];
|
|
591
|
+
const per = shape.length / SAMPLES2;
|
|
592
|
+
const startRatio = table[1] > 0 ? per / table[1] : 1;
|
|
593
|
+
const endRatio = table[SAMPLES2] - table[SAMPLES2 - 1] > 0 ? per / (table[SAMPLES2] - table[SAMPLES2 - 1]) : 1;
|
|
594
|
+
const toBase = (f) => {
|
|
595
|
+
const d = f * length2;
|
|
596
|
+
if (length2 <= 0 || shape.length <= 0) return f;
|
|
597
|
+
if (d < 0) return d * startRatio / shape.length;
|
|
598
|
+
if (d > length2) return 1 + (d - length2) * endRatio / shape.length;
|
|
599
|
+
let lo = 0;
|
|
600
|
+
let hi = SAMPLES2;
|
|
601
|
+
while (hi - lo > 1) {
|
|
602
|
+
const mid = lo + hi >> 1;
|
|
603
|
+
if (table[mid] <= d) lo = mid;
|
|
604
|
+
else hi = mid;
|
|
605
|
+
}
|
|
606
|
+
const span = table[hi] - table[lo];
|
|
607
|
+
return (lo + (span > 0 ? (d - table[lo]) / span : 0)) / SAMPLES2;
|
|
608
|
+
};
|
|
609
|
+
const fromBase = (g) => {
|
|
610
|
+
if (length2 <= 0 || shape.length <= 0) return g;
|
|
611
|
+
if (g < 0) return g * shape.length / startRatio / length2;
|
|
612
|
+
if (g > 1) return (length2 + (g - 1) * shape.length / endRatio) / length2;
|
|
613
|
+
const x = g * SAMPLES2;
|
|
614
|
+
const i = Math.min(SAMPLES2 - 1, Math.floor(x));
|
|
615
|
+
return (table[i] + (x - i) * (table[i + 1] - table[i])) / length2;
|
|
616
|
+
};
|
|
617
|
+
const at2 = (f, options) => moved2(shape.at(toBase(options?.open ? f : clamp(f, 0, 1)), options));
|
|
618
|
+
return {
|
|
619
|
+
kind: shape.kind,
|
|
620
|
+
length: length2,
|
|
621
|
+
closed: shape.closed,
|
|
622
|
+
at: at2,
|
|
623
|
+
nearest(p, options) {
|
|
624
|
+
const base = shape.nearest(p, options?.open ? { open: true, about: toBase(options.about ?? 0.5) } : void 0);
|
|
625
|
+
const f = fromBase(base.f);
|
|
626
|
+
const q = at2(f, options).point;
|
|
627
|
+
return { f, dist: Math.hypot(p.x - q.x, p.y - q.y) };
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
}
|
|
631
|
+
|
|
632
|
+
// src/track/slice.ts
|
|
633
|
+
var RAD3 = Math.PI / 180;
|
|
634
|
+
var seen = (c, p) => Math.atan2(p.x - c.x, c.y - p.y) / RAD3;
|
|
635
|
+
function trackSlice(shape, from, to) {
|
|
636
|
+
const lo = clamp(Math.min(from, to), 0, 1);
|
|
637
|
+
const hi = clamp(Math.max(from, to), 0, 1);
|
|
638
|
+
if (lo === 0 && hi === 1) return shape;
|
|
639
|
+
const a = shape.at(lo).point;
|
|
640
|
+
const b = shape.at(hi).point;
|
|
641
|
+
if (shape.kind === "line") return lineShape(a, b);
|
|
642
|
+
if (shape.kind === "arc" && "arc" in shape) {
|
|
643
|
+
const { center, radius, direction } = shape.arc;
|
|
644
|
+
if (hi === lo) return arcShape({ center, radius: 0, start: 0, end: 0 });
|
|
645
|
+
return arcShape({ center, radius, start: seen(center, a), end: seen(center, b), direction });
|
|
646
|
+
}
|
|
647
|
+
if (shape.kind === "ellipse" && "ellipse" in shape) {
|
|
648
|
+
const { center, radiusX, radiusY, direction } = shape.ellipse;
|
|
649
|
+
if (hi === lo) return ellipseShape({ center, radiusX: 0, radiusY: 0, start: 0, end: 0 });
|
|
650
|
+
return ellipseShape({ center, radiusX, radiusY, start: seen(center, a), end: seen(center, b), direction });
|
|
651
|
+
}
|
|
652
|
+
const span = hi - lo;
|
|
653
|
+
return {
|
|
654
|
+
kind: shape.kind,
|
|
655
|
+
length: shape.length * span,
|
|
656
|
+
closed: false,
|
|
657
|
+
at: (f, options) => shape.at(lo + (options?.open ? f : clamp(f, 0, 1)) * span, options),
|
|
658
|
+
nearest(p) {
|
|
659
|
+
const n = shape.nearest(p);
|
|
660
|
+
const f = clamp(n.f, lo, hi);
|
|
661
|
+
const q = shape.at(f).point;
|
|
662
|
+
return { f: span === 0 ? 0 : (f - lo) / span, dist: Math.hypot(p.x - q.x, p.y - q.y) };
|
|
663
|
+
}
|
|
664
|
+
};
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
// src/track/place.ts
|
|
668
|
+
var clipOf = (lo, hi, start, end, hair = 0) => lo >= start - hair && hi <= end + hair ? "none" : hi <= start + hair || lo >= end - hair ? "past" : "part";
|
|
669
|
+
function runPlaces(lengths, gap, room, align, offset2, at2) {
|
|
670
|
+
const total = runLength(lengths, gap);
|
|
671
|
+
const fits = at2 === void 0 && total <= room;
|
|
672
|
+
const lead = align === "start" ? 0 : align === "end" ? total : total / 2;
|
|
673
|
+
let lo = at2 !== void 0 ? at2 - offset2 - lead : !fits ? -offset2 : align === "start" ? 0 : align === "end" ? room - total : (room - total) / 2;
|
|
674
|
+
return lengths.map((length2) => {
|
|
675
|
+
const start = lo;
|
|
676
|
+
const hi = start + length2;
|
|
677
|
+
lo = hi + gap;
|
|
678
|
+
return { center: start + length2 / 2, clipped: fits ? "none" : clipOf(start, hi, 0, room) };
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
function runLength(lengths, gap) {
|
|
682
|
+
return lengths.reduce((sum, length2, i) => sum + length2 + (i > 0 ? gap : 0), 0);
|
|
683
|
+
}
|
|
684
|
+
function runStationAt(run2, distance, shift = 0, past = "extend") {
|
|
685
|
+
const { length: length2 } = run2;
|
|
686
|
+
if (past === "follow" && length2 > 0) {
|
|
687
|
+
const place2 = run2.at(distance / length2, { open: true });
|
|
688
|
+
const { point: point2, normal: normal3 } = place2;
|
|
689
|
+
return { ...place2, point: { x: point2.x + shift * normal3.x, y: point2.y + shift * normal3.y } };
|
|
690
|
+
}
|
|
691
|
+
const place = run2.at(length2 === 0 ? 0 : distance / length2);
|
|
692
|
+
const beyond = distance < 0 ? distance : distance > length2 ? distance - length2 : 0;
|
|
693
|
+
const { point, tangent, normal: normal2 } = place;
|
|
694
|
+
return {
|
|
695
|
+
...place,
|
|
696
|
+
point: { x: point.x + beyond * tangent.x + shift * normal2.x, y: point.y + beyond * tangent.y + shift * normal2.y }
|
|
697
|
+
};
|
|
698
|
+
}
|
|
699
|
+
function placeAlongRun(run2, lengths, options = {}) {
|
|
700
|
+
const { gap = 0, align = "center", offset: offset2 = 0, at: at2, shift = 0, wrap = false, past = "extend", order = "reading" } = options;
|
|
701
|
+
const { length: length2 } = run2;
|
|
702
|
+
const mirror = order === "track" && run2.reversed;
|
|
703
|
+
const spots = runPlaces(lengths, gap, length2, align, offset2, at2);
|
|
704
|
+
const lap = wrap && run2.closed && spots.length > 0 ? wrapWindow(spots[0], lengths[0], length2) : null;
|
|
705
|
+
return spots.map((spot, i) => {
|
|
706
|
+
const half = lengths[i] / 2;
|
|
707
|
+
const clipped = lap ? clipOf(spot.center - half, spot.center + half, lap.start, lap.end, lap.hair) : spot.clipped;
|
|
708
|
+
let distance = spot.center;
|
|
709
|
+
if (past === "hold" && clipped === "past") distance = clamp(distance, lap?.start ?? 0, lap?.end ?? length2);
|
|
710
|
+
if (lap && length2 > 0) distance = (distance % length2 + length2) % length2;
|
|
711
|
+
return { ...runStationAt(run2, mirror ? length2 - distance : distance, shift, past === "extend" ? "extend" : "follow"), center: spot.center, clipped };
|
|
712
|
+
});
|
|
713
|
+
}
|
|
714
|
+
function wrapWindow(first, firstLength, length2) {
|
|
715
|
+
const start = first.center - firstLength / 2;
|
|
716
|
+
return { start, end: start + length2, hair: 1e-9 * Math.max(1, length2) };
|
|
717
|
+
}
|
|
718
|
+
|
|
85
719
|
// src/portCurve2.ts
|
|
86
720
|
function portControls2(ax, ay, bx, by, outNormal, inNormal, reach = PORT_REACH) {
|
|
87
721
|
const [c1, c2] = portControls([ax, ay], [bx, by], outNormal, inNormal, reach);
|
|
@@ -1074,17 +1708,17 @@ function arcToCubics(x1, y1, x2, y2, rx, ry, xAxisRotationDeg, largeArc, sweep,
|
|
|
1074
1708
|
rys = ryFixed * ryFixed;
|
|
1075
1709
|
}
|
|
1076
1710
|
const sign2 = largeArc === sweep ? -1 : 1;
|
|
1077
|
-
const
|
|
1711
|
+
const num3 = rxs * rys - rxs * y1ps - rys * x1ps;
|
|
1078
1712
|
const den = rxs * y1ps + rys * x1ps;
|
|
1079
|
-
const factor = sign2 * Math.sqrt(Math.max(0,
|
|
1713
|
+
const factor = sign2 * Math.sqrt(Math.max(0, num3 / den));
|
|
1080
1714
|
const cxp = factor * (rxFixed * y1p) / ryFixed;
|
|
1081
1715
|
const cyp = factor * -(ryFixed * x1p) / rxFixed;
|
|
1082
1716
|
const cx = cosPhi * cxp - sinPhi * cyp + (x1 + x2) / 2;
|
|
1083
1717
|
const cy = sinPhi * cxp + cosPhi * cyp + (y1 + y2) / 2;
|
|
1084
1718
|
const angle = (ux, uy, vx, vy) => {
|
|
1085
|
-
const
|
|
1719
|
+
const dot3 = ux * vx + uy * vy;
|
|
1086
1720
|
const len = Math.sqrt((ux * ux + uy * uy) * (vx * vx + vy * vy));
|
|
1087
|
-
let a = Math.acos(Math.max(-1, Math.min(1,
|
|
1721
|
+
let a = Math.acos(Math.max(-1, Math.min(1, dot3 / len)));
|
|
1088
1722
|
if (ux * vy - uy * vx < 0) a = -a;
|
|
1089
1723
|
return a;
|
|
1090
1724
|
};
|
|
@@ -1124,157 +1758,6 @@ function arcToCubics(x1, y1, x2, y2, rx, ry, xAxisRotationDeg, largeArc, sweep,
|
|
|
1124
1758
|
}
|
|
1125
1759
|
}
|
|
1126
1760
|
|
|
1127
|
-
// src/paths/pathToD.ts
|
|
1128
|
-
var num = (n) => Number.isFinite(n) ? String(Math.round(n * 1e6) / 1e6) : "0";
|
|
1129
|
-
function pathToD(given) {
|
|
1130
|
-
const path = resolveCorners(given);
|
|
1131
|
-
if (path.kind === "rect") {
|
|
1132
|
-
const { x, y, width, height } = path;
|
|
1133
|
-
return `M${num(x)} ${num(y)}h${num(width)}v${num(height)}h${num(-width)}Z`;
|
|
1134
|
-
}
|
|
1135
|
-
const cmds = path.commands;
|
|
1136
|
-
const xs = path.coords;
|
|
1137
|
-
const out = [];
|
|
1138
|
-
let ci = 0;
|
|
1139
|
-
for (let i = 0; i < cmds.length; i++) {
|
|
1140
|
-
const c = cmds[i];
|
|
1141
|
-
if (c === PATH_M) {
|
|
1142
|
-
out.push(`M${num(xs[ci])} ${num(xs[ci + 1])}`);
|
|
1143
|
-
ci += 2;
|
|
1144
|
-
} else if (c === PATH_L) {
|
|
1145
|
-
out.push(`L${num(xs[ci])} ${num(xs[ci + 1])}`);
|
|
1146
|
-
ci += 2;
|
|
1147
|
-
} else if (c === PATH_C) {
|
|
1148
|
-
out.push(
|
|
1149
|
-
`C${num(xs[ci])} ${num(xs[ci + 1])} ${num(xs[ci + 2])} ${num(xs[ci + 3])} ${num(xs[ci + 4])} ${num(xs[ci + 5])}`
|
|
1150
|
-
);
|
|
1151
|
-
ci += 6;
|
|
1152
|
-
} else if (c === PATH_Q) {
|
|
1153
|
-
out.push(`Q${num(xs[ci])} ${num(xs[ci + 1])} ${num(xs[ci + 2])} ${num(xs[ci + 3])}`);
|
|
1154
|
-
ci += 4;
|
|
1155
|
-
} else if (c === PATH_Z) {
|
|
1156
|
-
out.push("Z");
|
|
1157
|
-
}
|
|
1158
|
-
}
|
|
1159
|
-
return out.join("");
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
// src/paths/pathMeasure.ts
|
|
1163
|
-
function measurePath(path, opts = {}) {
|
|
1164
|
-
const polylines = extractPolylines(
|
|
1165
|
-
path,
|
|
1166
|
-
opts.flattenTolerance === void 0 ? {} : { flattenTolerance: opts.flattenTolerance }
|
|
1167
|
-
);
|
|
1168
|
-
const segments = [];
|
|
1169
|
-
let total = 0;
|
|
1170
|
-
let first;
|
|
1171
|
-
let contours = 0;
|
|
1172
|
-
let lastClosed = false;
|
|
1173
|
-
for (const pl of polylines) {
|
|
1174
|
-
const count = pl.points.length / 2;
|
|
1175
|
-
if (count === 0) continue;
|
|
1176
|
-
contours++;
|
|
1177
|
-
lastClosed = pl.closed;
|
|
1178
|
-
first ??= { x: pl.points[0], y: pl.points[1] };
|
|
1179
|
-
const startIndex = segments.length;
|
|
1180
|
-
const last = pl.closed ? count : count - 1;
|
|
1181
|
-
for (let i = 0; i < last; i++) {
|
|
1182
|
-
const j = (i + 1) % count;
|
|
1183
|
-
const ax = pl.points[i * 2];
|
|
1184
|
-
const ay = pl.points[i * 2 + 1];
|
|
1185
|
-
const bx = pl.points[j * 2];
|
|
1186
|
-
const by = pl.points[j * 2 + 1];
|
|
1187
|
-
const len = Math.hypot(bx - ax, by - ay);
|
|
1188
|
-
if (len === 0) continue;
|
|
1189
|
-
const tx = (bx - ax) / len;
|
|
1190
|
-
const ty = (by - ay) / len;
|
|
1191
|
-
segments.push({ ax, ay, bx, by, start: total, len, tx, ty, t0x: tx, t0y: ty, t1x: tx, t1y: ty });
|
|
1192
|
-
total += len;
|
|
1193
|
-
}
|
|
1194
|
-
smoothVertexHeadings(segments, startIndex, pl.closed);
|
|
1195
|
-
}
|
|
1196
|
-
if (first === void 0) return null;
|
|
1197
|
-
const origin = first;
|
|
1198
|
-
const closed = contours === 1 && lastClosed;
|
|
1199
|
-
if (segments.length === 0) {
|
|
1200
|
-
return {
|
|
1201
|
-
length: 0,
|
|
1202
|
-
closed,
|
|
1203
|
-
at: () => ({ point: { ...origin }, tangent: { x: 1, y: 0 } }),
|
|
1204
|
-
nearest: (p) => ({
|
|
1205
|
-
s: 0,
|
|
1206
|
-
dist: Math.hypot(p.x - origin.x, p.y - origin.y),
|
|
1207
|
-
point: { ...origin },
|
|
1208
|
-
tangent: { x: 1, y: 0 }
|
|
1209
|
-
})
|
|
1210
|
-
};
|
|
1211
|
-
}
|
|
1212
|
-
return {
|
|
1213
|
-
length: total,
|
|
1214
|
-
closed,
|
|
1215
|
-
at(s, smooth = false) {
|
|
1216
|
-
const target = Math.min(Math.max(s, 0), total);
|
|
1217
|
-
const seg = segments[segmentAt(segments, target)];
|
|
1218
|
-
const u = Math.min(Math.max((target - seg.start) / seg.len, 0), 1);
|
|
1219
|
-
const point = { x: seg.ax + (seg.bx - seg.ax) * u, y: seg.ay + (seg.by - seg.ay) * u };
|
|
1220
|
-
if (!smooth) return { point, tangent: { x: seg.tx, y: seg.ty } };
|
|
1221
|
-
const x = seg.t0x + (seg.t1x - seg.t0x) * u;
|
|
1222
|
-
const y = seg.t0y + (seg.t1y - seg.t0y) * u;
|
|
1223
|
-
const l = Math.hypot(x, y);
|
|
1224
|
-
return { point, tangent: l === 0 ? { x: seg.tx, y: seg.ty } : { x: x / l, y: y / l } };
|
|
1225
|
-
},
|
|
1226
|
-
nearest(p) {
|
|
1227
|
-
let best = segments[0];
|
|
1228
|
-
let bestU = 0;
|
|
1229
|
-
let bestDist = Infinity;
|
|
1230
|
-
for (const seg of segments) {
|
|
1231
|
-
const u = Math.min(Math.max(((p.x - seg.ax) * seg.tx + (p.y - seg.ay) * seg.ty) / seg.len, 0), 1);
|
|
1232
|
-
const d = Math.hypot(p.x - (seg.ax + (seg.bx - seg.ax) * u), p.y - (seg.ay + (seg.by - seg.ay) * u));
|
|
1233
|
-
if (d < bestDist) {
|
|
1234
|
-
best = seg;
|
|
1235
|
-
bestU = u;
|
|
1236
|
-
bestDist = d;
|
|
1237
|
-
}
|
|
1238
|
-
}
|
|
1239
|
-
return {
|
|
1240
|
-
s: best.start + best.len * bestU,
|
|
1241
|
-
dist: bestDist,
|
|
1242
|
-
point: { x: best.ax + (best.bx - best.ax) * bestU, y: best.ay + (best.by - best.ay) * bestU },
|
|
1243
|
-
tangent: { x: best.tx, y: best.ty }
|
|
1244
|
-
};
|
|
1245
|
-
}
|
|
1246
|
-
};
|
|
1247
|
-
}
|
|
1248
|
-
function smoothVertexHeadings(segments, from, closed) {
|
|
1249
|
-
const n = segments.length - from;
|
|
1250
|
-
if (n < 2) return;
|
|
1251
|
-
const pairs = closed ? n : n - 1;
|
|
1252
|
-
for (let k = 0; k < pairs; k++) {
|
|
1253
|
-
const a = segments[from + k];
|
|
1254
|
-
const b = segments[from + (k + 1) % n];
|
|
1255
|
-
let x = a.tx + b.tx;
|
|
1256
|
-
let y = a.ty + b.ty;
|
|
1257
|
-
const l = Math.hypot(x, y);
|
|
1258
|
-
if (l < 1e-9) continue;
|
|
1259
|
-
x /= l;
|
|
1260
|
-
y /= l;
|
|
1261
|
-
a.t1x = x;
|
|
1262
|
-
a.t1y = y;
|
|
1263
|
-
b.t0x = x;
|
|
1264
|
-
b.t0y = y;
|
|
1265
|
-
}
|
|
1266
|
-
}
|
|
1267
|
-
function segmentAt(segments, s) {
|
|
1268
|
-
let lo = 0;
|
|
1269
|
-
let hi = segments.length - 1;
|
|
1270
|
-
while (lo < hi) {
|
|
1271
|
-
const mid = lo + hi + 1 >> 1;
|
|
1272
|
-
if (segments[mid].start <= s) lo = mid;
|
|
1273
|
-
else hi = mid - 1;
|
|
1274
|
-
}
|
|
1275
|
-
return lo;
|
|
1276
|
-
}
|
|
1277
|
-
|
|
1278
1761
|
// src/paths/pathAt.ts
|
|
1279
1762
|
function pointAlongPath(path, t, opts = {}) {
|
|
1280
1763
|
const measure2 = measurePath(path, opts);
|
|
@@ -1836,17 +2319,17 @@ var GL_W2 = [
|
|
|
1836
2319
|
0.2223810344533745,
|
|
1837
2320
|
0.1012285362903763
|
|
1838
2321
|
];
|
|
1839
|
-
var
|
|
2322
|
+
var speed2 = (s, t) => {
|
|
1840
2323
|
const d = derivSeg(s, t);
|
|
1841
2324
|
return Math.hypot(d.x, d.y);
|
|
1842
2325
|
};
|
|
1843
2326
|
function segmentLength(s, a = 0, b = 1) {
|
|
1844
|
-
if (s.length === 2) return
|
|
2327
|
+
if (s.length === 2) return speed2(s, 0) * (b - a);
|
|
1845
2328
|
const panels = 8, h = (b - a) / panels;
|
|
1846
2329
|
let sum = 0;
|
|
1847
2330
|
for (let k = 0; k < panels; k++) {
|
|
1848
2331
|
const mid = a + (k + 0.5) * h;
|
|
1849
|
-
for (let i = 0; i < GL_X.length; i++) sum += GL_W2[i] *
|
|
2332
|
+
for (let i = 0; i < GL_X.length; i++) sum += GL_W2[i] * speed2(s, mid + GL_X[i] * h / 2);
|
|
1850
2333
|
}
|
|
1851
2334
|
return sum * h / 2;
|
|
1852
2335
|
}
|
|
@@ -1861,7 +2344,7 @@ function segmentTAtLength(s, length2) {
|
|
|
1861
2344
|
if (Math.abs(err) < 1e-10 * Math.max(1, total)) break;
|
|
1862
2345
|
if (err > 0) hi = t;
|
|
1863
2346
|
else lo = t;
|
|
1864
|
-
const v =
|
|
2347
|
+
const v = speed2(s, t);
|
|
1865
2348
|
let next = v > 0 ? t - err / v : NaN;
|
|
1866
2349
|
if (!(next > lo && next < hi)) next = (lo + hi) / 2;
|
|
1867
2350
|
t = next;
|
|
@@ -1952,12 +2435,12 @@ function createPathSnapIndex(paths, extra = []) {
|
|
|
1952
2435
|
if (kind === "center") return out;
|
|
1953
2436
|
if (kind === "anchor") {
|
|
1954
2437
|
segments.forEach((segs, path) => {
|
|
1955
|
-
const
|
|
2438
|
+
const seen2 = /* @__PURE__ */ new Set();
|
|
1956
2439
|
for (const s of segs) {
|
|
1957
2440
|
for (const p of [s.pts[0], s.pts[s.pts.length - 1]]) {
|
|
1958
2441
|
const key = `${p.x},${p.y}`;
|
|
1959
|
-
if (
|
|
1960
|
-
|
|
2442
|
+
if (seen2.has(key)) continue;
|
|
2443
|
+
seen2.add(key);
|
|
1961
2444
|
out.push({ kind: "anchor", x: p.x, y: p.y, paths: [path] });
|
|
1962
2445
|
}
|
|
1963
2446
|
}
|
|
@@ -2868,7 +3351,7 @@ function breaksOf(sub3, closed, cosCorner) {
|
|
|
2868
3351
|
const n = sub3.length;
|
|
2869
3352
|
const breaks = /* @__PURE__ */ new Set();
|
|
2870
3353
|
for (let i = 0; i < n; i++) {
|
|
2871
|
-
if (
|
|
3354
|
+
if (isCorner2(sub3, i, closed, cosCorner)) breaks.add(i);
|
|
2872
3355
|
if (isLongStraight(sub3, i, closed)) {
|
|
2873
3356
|
breaks.add(i);
|
|
2874
3357
|
breaks.add((i + 1) % n);
|
|
@@ -2888,7 +3371,7 @@ function fitStops(sub3, stops, tol, out, closing) {
|
|
|
2888
3371
|
if (!last) keepCorner(out[out.length - 1], sub3[stops[k + 1] % n]);
|
|
2889
3372
|
}
|
|
2890
3373
|
}
|
|
2891
|
-
function
|
|
3374
|
+
function isCorner2(sub3, i, closed, cosCorner) {
|
|
2892
3375
|
const n = sub3.length;
|
|
2893
3376
|
const a = sub3[i];
|
|
2894
3377
|
const prev = sub3[(i - 1 + n) % n];
|
|
@@ -2945,7 +3428,7 @@ function unit(p) {
|
|
|
2945
3428
|
|
|
2946
3429
|
// src/paths/growRegion.ts
|
|
2947
3430
|
var MAX_DEPTH2 = 6;
|
|
2948
|
-
var
|
|
3431
|
+
var SAMPLES3 = [0.2, 0.35, 0.5, 0.65, 0.8];
|
|
2949
3432
|
function growRegion(path, distance, opts = {}) {
|
|
2950
3433
|
const b = new PathBuilder();
|
|
2951
3434
|
if (!(distance > 0)) return b.build();
|
|
@@ -2984,15 +3467,15 @@ function joinPieces(prev, next, v, tin, tout, ctx) {
|
|
|
2984
3467
|
const gap = Math.hypot(b[0] - a[0], b[1] - a[1]);
|
|
2985
3468
|
if (gap <= ctx.tol * 1e-3) return [];
|
|
2986
3469
|
const cross2 = tin[0] * tout[1] - tin[1] * tout[0];
|
|
2987
|
-
const
|
|
2988
|
-
const convex = ctx.sigma * cross2 > 0 || Math.abs(cross2) < 1e-9 &&
|
|
3470
|
+
const dot3 = tin[0] * tout[0] + tin[1] * tout[1];
|
|
3471
|
+
const convex = ctx.sigma * cross2 > 0 || Math.abs(cross2) < 1e-9 && dot3 < 0;
|
|
2989
3472
|
if (gap <= ctx.tol) return snap(prev, next, a);
|
|
2990
3473
|
if (!convex) {
|
|
2991
3474
|
if (trimAtCrossing(prev, next)) return [];
|
|
2992
3475
|
return [lineSegment(a[0], a[1], v[0], v[1]), lineSegment(v[0], v[1], b[0], b[1])];
|
|
2993
3476
|
}
|
|
2994
3477
|
const nin = normal(tin, ctx.sigma), nout = normal(tout, ctx.sigma);
|
|
2995
|
-
if (ctx.join === "round") return arc(v, ctx.d, nin, Math.atan2(cross2,
|
|
3478
|
+
if (ctx.join === "round") return arc(v, ctx.d, nin, Math.atan2(cross2, dot3));
|
|
2996
3479
|
const cos = nin[0] * nout[0] + nin[1] * nout[1];
|
|
2997
3480
|
if (1 + cos < 1e-9 || Math.sqrt(2 / (1 + cos)) > ctx.miterLimit) return [lineSegment(a[0], a[1], b[0], b[1])];
|
|
2998
3481
|
const k = ctx.d / (1 + cos);
|
|
@@ -3118,7 +3601,7 @@ function offsetSeg(seg, ctx, depth) {
|
|
|
3118
3601
|
}
|
|
3119
3602
|
function offsetError(c, q, ctx) {
|
|
3120
3603
|
let worst2 = 0;
|
|
3121
|
-
for (const t of
|
|
3604
|
+
for (const t of SAMPLES3) {
|
|
3122
3605
|
const [dx2, dy2] = derivative(c, t);
|
|
3123
3606
|
const len = Math.hypot(dx2, dy2);
|
|
3124
3607
|
if (len < 1e-12) continue;
|
|
@@ -6304,6 +6787,6 @@ function typedArrayReplacer(_key, value) {
|
|
|
6304
6787
|
return tagTypedArray(value) ?? value;
|
|
6305
6788
|
}
|
|
6306
6789
|
|
|
6307
|
-
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, averageAnchorsAt, balanceFactorToward, bendAlongPath, bendSegment, blendPaths, 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, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, editAnchorSet, editAnchorSetTracked, equalizeSegmentHandles, everyNthAnchor, extendToMeet, findPathSnap, findPathSnaps, fitAffine, fitCubicThroughDeletion, flatAnchorIndex, flatIndexesAfterReverse, growAnchorSelection, growRegion, handleAlongItsAngle, handleAtItsLength, handleBalances, harmonizeAnchors, hasOpenSubpath, identity, insertAnchorOnSegment, intersectSegments, invert, invertAnchorSelection, isSegmentStraight, joinAnchorsAt, joinSubpathEnds, lengthToward, lengthenOpenEnd, lengthenPathEnd, 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, pathSignedArea, pathThroughPoseFrame, pathToCubicContours, pathToD, placeRect, pointAlongPath, pointInPath, polygonContainsPath, polygonIntersectsPath, portControls2 as portControls, portCurvePoints2 as portCurvePoints, poseFrameInverseOf, poseFrameOf, poseLinearOf, poseRotationOf, prepareBlend, pxExtent, readAnchorFields, rectMarkerPath, remapAnchorValues, remapConstraints, remapPointValues, repeatAlongPath, resamplePath, resolveEasing, retractHandles, reverseAnchors, reversePath, reverseSubpaths, reviveTypedArrays, rotate, rotateAboutPoint, rotatePathAround, roundRectPath, scale, scaleDelta, scalePathToBounds, scaleSegmentHandles, screenAngleOf, segmentAt2 as segmentAt, segmentBetween, segmentExtremaTs, segmentsBetweenAnchors, setSubpathStart, shrinkAnchorSelection, simplifyAnchorsAt, simplifyPath, simplifySpan, simplifySubpath, smoothAnchors, smudgePath, softFalloff, softSelectionBand, softSelectionWeights, solveConstraints, solvePathConstraints, splitByClosure, splitSubpaths, squarePath, standoff, stationsAlongPath, strokeHitTest, subpathEndAt, subpathsOfAnchors, tagTypedArray, tagTypedArrays, transformCoords, transformPath, translate, translateAnchorBy, translateAnchorsSymmetric, translatePath, trimPathAt, typedArrayReplacer, unionBoundsPath, unsatisfiedConstraints, untagTypedArray, viewToMat3, withAnchorPoints, withinPxBox, withinPxRadius, worldEditToStorage, writeAnchorField };
|
|
6790
|
+
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, 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, easeOut, easeOutBack, easeOutBounce, easeOutCirc, easeOutCubic, easeOutElastic, easeOutExpo, easeOutQuad, easeOutQuart, easeOutQuint, easeOutSine, editAnchorSet, editAnchorSetTracked, ellipseShape, equalizeSegmentHandles, everyNthAnchor, extendToMeet, findPathSnap, findPathSnaps, fitAffine, fitCubicThroughDeletion, flatAnchorIndex, flatIndexesAfterReverse, growAnchorSelection, growRegion, handleAlongItsAngle, handleAtItsLength, handleBalances, harmonizeAnchors, hasOpenSubpath, identity, insertAnchorOnSegment, intersectSegments, 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, pxExtent, readAnchorFields, rectMarkerPath, remapAnchorValues, remapConstraints, remapPointValues, repeatAlongPath, resamplePath, resolveEasing, retractHandles, reverseAnchors, reversePath, reverseSubpaths, reviveTypedArrays, rotate, rotateAboutPoint, rotatePathAround, 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 };
|
|
6308
6791
|
//# sourceMappingURL=index.js.map
|
|
6309
6792
|
//# sourceMappingURL=index.js.map
|