animot-presenter 0.2.6 → 0.2.8
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/AnimotPresenter.svelte +50 -7
- package/dist/cdn/animot-presenter.esm.js +2404 -2383
- package/dist/cdn/animot-presenter.min.js +8 -8
- package/package.json +1 -1
|
@@ -100,10 +100,23 @@
|
|
|
100
100
|
for (const seg of segs) {
|
|
101
101
|
if (accum + seg.length >= targetLength || seg === segs[segs.length - 1]) {
|
|
102
102
|
const t = Math.max(0, Math.min(1, seg.length > 0 ? (targetLength - accum) / seg.length : 0));
|
|
103
|
+
let dx = cubicBezDeriv(seg.p0x, seg.p1x, seg.p2x, seg.p3x, t);
|
|
104
|
+
let dy = cubicBezDeriv(seg.p0y, seg.p1y, seg.p2y, seg.p3y, t);
|
|
105
|
+
// Degenerate tangent at endpoints (no Bezier handles) — sample nearby
|
|
106
|
+
if (Math.abs(dx) < 0.001 && Math.abs(dy) < 0.001) {
|
|
107
|
+
const epsilon = t < 0.5 ? 0.01 : -0.01;
|
|
108
|
+
dx = cubicBezDeriv(seg.p0x, seg.p1x, seg.p2x, seg.p3x, t + epsilon);
|
|
109
|
+
dy = cubicBezDeriv(seg.p0y, seg.p1y, seg.p2y, seg.p3y, t + epsilon);
|
|
110
|
+
}
|
|
111
|
+
// Still zero (fully degenerate segment) — use chord direction
|
|
112
|
+
if (Math.abs(dx) < 0.001 && Math.abs(dy) < 0.001) {
|
|
113
|
+
dx = seg.p3x - seg.p0x;
|
|
114
|
+
dy = seg.p3y - seg.p0y;
|
|
115
|
+
}
|
|
103
116
|
return {
|
|
104
117
|
x: cubicBez(seg.p0x, seg.p1x, seg.p2x, seg.p3x, t),
|
|
105
118
|
y: cubicBez(seg.p0y, seg.p1y, seg.p2y, seg.p3y, t),
|
|
106
|
-
angle: Math.atan2(
|
|
119
|
+
angle: Math.atan2(dy, dx) * (180 / Math.PI)
|
|
107
120
|
};
|
|
108
121
|
}
|
|
109
122
|
accum += seg.length;
|
|
@@ -114,8 +127,12 @@
|
|
|
114
127
|
function computeMotionPathPosition(
|
|
115
128
|
mpPoint: { x: number; y: number; angle: number },
|
|
116
129
|
startPoint: { x: number; y: number; angle: number },
|
|
117
|
-
animX: number, animY: number, animW: number, animH: number
|
|
130
|
+
animX: number, animY: number, animW: number, animH: number,
|
|
131
|
+
closed: boolean
|
|
118
132
|
): { x: number; y: number } {
|
|
133
|
+
if (!closed) {
|
|
134
|
+
return { x: mpPoint.x - animW / 2, y: mpPoint.y - animH / 2 };
|
|
135
|
+
}
|
|
119
136
|
const offsetX = (animX + animW / 2) - startPoint.x;
|
|
120
137
|
const offsetY = (animY + animH / 2) - startPoint.y;
|
|
121
138
|
const angleDelta = (mpPoint.angle - startPoint.angle) * Math.PI / 180;
|
|
@@ -1017,10 +1034,11 @@
|
|
|
1017
1034
|
{@const mpProgress = animated?.motionPathProgress?.current ?? 0}
|
|
1018
1035
|
{@const mpPoint = mpElement && mpConfig ? getPresenterPointOnPath(mpElement.points, mpElement.closed, (mpConfig.startPercent + (mpConfig.endPercent - mpConfig.startPercent) * mpProgress) / 100) : null}
|
|
1019
1036
|
{@const mpStartPoint = mpElement && mpConfig ? getPresenterPointOnPath(mpElement.points, mpElement.closed, mpConfig.startPercent / 100) : null}
|
|
1020
|
-
{@const mpPos = mpPoint && mpStartPoint && animated
|
|
1037
|
+
{@const mpPos = mpPoint && mpStartPoint && animated && mpElement
|
|
1021
1038
|
? computeMotionPathPosition(mpPoint, mpStartPoint,
|
|
1022
1039
|
animated.x.current, animated.y.current,
|
|
1023
|
-
animated.width.current, animated.height.current
|
|
1040
|
+
animated.width.current, animated.height.current,
|
|
1041
|
+
mpElement.closed)
|
|
1024
1042
|
: null}
|
|
1025
1043
|
{@const elemX = mpPos ? mpPos.x : (animated?.x.current ?? 0)}
|
|
1026
1044
|
{@const elemY = mpPos ? mpPos.y : (animated?.y.current ?? 0)}
|
|
@@ -1240,6 +1258,27 @@
|
|
|
1240
1258
|
</div>
|
|
1241
1259
|
|
|
1242
1260
|
<script module lang="ts">
|
|
1261
|
+
function roundedPolygonPath(pointsStr: string, radius: number): string {
|
|
1262
|
+
const pts = pointsStr.split(/\s+/).map(p => { const [x, y] = p.split(',').map(Number); return { x, y }; });
|
|
1263
|
+
if (pts.length < 3 || radius <= 0) return 'M' + pts.map(p => `${p.x},${p.y}`).join('L') + 'Z';
|
|
1264
|
+
const n = pts.length;
|
|
1265
|
+
const parts: string[] = [];
|
|
1266
|
+
for (let i = 0; i < n; i++) {
|
|
1267
|
+
const prev = pts[(i - 1 + n) % n], curr = pts[i], next = pts[(i + 1) % n];
|
|
1268
|
+
const dx1 = prev.x - curr.x, dy1 = prev.y - curr.y;
|
|
1269
|
+
const dx2 = next.x - curr.x, dy2 = next.y - curr.y;
|
|
1270
|
+
const len1 = Math.sqrt(dx1 * dx1 + dy1 * dy1);
|
|
1271
|
+
const len2 = Math.sqrt(dx2 * dx2 + dy2 * dy2);
|
|
1272
|
+
const r = Math.min(radius, len1 / 2, len2 / 2);
|
|
1273
|
+
const sx = curr.x + (dx1 / len1) * r, sy = curr.y + (dy1 / len1) * r;
|
|
1274
|
+
const ex = curr.x + (dx2 / len2) * r, ey = curr.y + (dy2 / len2) * r;
|
|
1275
|
+
parts.push(i === 0 ? `M${sx},${sy}` : `L${sx},${sy}`);
|
|
1276
|
+
parts.push(`Q${curr.x},${curr.y} ${ex},${ey}`);
|
|
1277
|
+
}
|
|
1278
|
+
parts.push('Z');
|
|
1279
|
+
return parts.join(' ');
|
|
1280
|
+
}
|
|
1281
|
+
|
|
1243
1282
|
function renderShape(type: string, w: number, h: number, br: number, fill: string, stroke: string, sw: number, strokeStyle?: string, strokeDashGap?: number): string {
|
|
1244
1283
|
let dashAttr = '';
|
|
1245
1284
|
if (strokeStyle && strokeStyle !== 'solid') {
|
|
@@ -1249,20 +1288,24 @@
|
|
|
1249
1288
|
const lc = strokeStyle === 'dotted' ? 'round' : 'butt';
|
|
1250
1289
|
dashAttr = ` stroke-dasharray="${da}" stroke-linecap="${lc}"`;
|
|
1251
1290
|
}
|
|
1291
|
+
const polyOrPath = (pts: string) => {
|
|
1292
|
+
if (br > 0) return `<path d="${roundedPolygonPath(pts, br)}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"${dashAttr}/>`;
|
|
1293
|
+
return `<polygon points="${pts}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"${dashAttr} stroke-linejoin="round"/>`;
|
|
1294
|
+
};
|
|
1252
1295
|
switch (type) {
|
|
1253
1296
|
case 'rectangle': return `<rect x="${sw/2}" y="${sw/2}" width="${w-sw}" height="${h-sw}" rx="${br}" ry="${br}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"${dashAttr}/>`;
|
|
1254
1297
|
case 'circle': return `<circle cx="${w/2}" cy="${h/2}" r="${Math.min(w,h)/2-sw/2}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"${dashAttr}/>`;
|
|
1255
1298
|
case 'ellipse': return `<ellipse cx="${w/2}" cy="${h/2}" rx="${w/2-sw/2}" ry="${h/2-sw/2}" fill="${fill}" stroke="${stroke}" stroke-width="${sw}"${dashAttr}/>`;
|
|
1256
|
-
case 'triangle': return
|
|
1299
|
+
case 'triangle': return polyOrPath(`${w/2},${sw/2} ${sw/2},${h-sw/2} ${w-sw/2},${h-sw/2}`);
|
|
1257
1300
|
case 'star': {
|
|
1258
1301
|
const cx = w/2, cy = h/2, outerR = Math.min(w,h)/2-sw/2, innerR = outerR*0.4;
|
|
1259
1302
|
const pts = Array.from({length:10},(_,i)=>{const a=(i*Math.PI/5)-Math.PI/2;const r=i%2===0?outerR:innerR;return`${cx+r*Math.cos(a)},${cy+r*Math.sin(a)}`;}).join(' ');
|
|
1260
|
-
return
|
|
1303
|
+
return polyOrPath(pts);
|
|
1261
1304
|
}
|
|
1262
1305
|
case 'hexagon': {
|
|
1263
1306
|
const cx = w/2, cy = h/2, r = Math.min(w,h)/2-sw/2;
|
|
1264
1307
|
const pts = Array.from({length:6},(_,i)=>{const a=(i*Math.PI/3)-Math.PI/2;return`${cx+r*Math.cos(a)},${cy+r*Math.sin(a)}`;}).join(' ');
|
|
1265
|
-
return
|
|
1308
|
+
return polyOrPath(pts);
|
|
1266
1309
|
}
|
|
1267
1310
|
default: return '';
|
|
1268
1311
|
}
|