@phin-tech/dottie 0.1.0 → 0.3.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/PARITY.md +2 -1
- package/README.md +19 -0
- package/dist/compile.js +394 -0
- package/dist/dottie-compile.mjs +496 -0
- package/dist/dottie-loader.js +20 -0
- package/dist/dottie-player.js +77 -18
- package/dist/dottie-player.min.js +36 -36
- package/dist/dottie.js +75 -18
- package/dist/types/cli.d.ts +1 -0
- package/dist/types/compile.d.ts +19 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/model.d.ts +8 -1
- package/dist/types/timeline.d.ts +3 -0
- package/package.json +9 -2
package/dist/dottie-player.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! dottie.js 0.
|
|
1
|
+
/*! dottie.js 0.3.0 | Apache-2.0 | https://github.com/phin-tech/dottie */
|
|
2
2
|
var __defProp = Object.defineProperty;
|
|
3
3
|
var __defNormalProp = (obj, key, value2) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value: value2 }) : obj[key] = value2;
|
|
4
4
|
var __export = (target, all) => {
|
|
@@ -16,6 +16,7 @@ __export(index_exports, {
|
|
|
16
16
|
KINDS: () => KINDS,
|
|
17
17
|
KNOWN_FIELDS: () => KNOWN_FIELDS,
|
|
18
18
|
MAX_DURATION: () => MAX_DURATION,
|
|
19
|
+
MAX_MARCH: () => MAX_MARCH,
|
|
19
20
|
Playback: () => Playback,
|
|
20
21
|
SUPPORTED_VERSION: () => SUPPORTED_VERSION,
|
|
21
22
|
VERSION: () => VERSION,
|
|
@@ -23,6 +24,7 @@ __export(index_exports, {
|
|
|
23
24
|
bounds: () => bounds,
|
|
24
25
|
cameraView: () => cameraView,
|
|
25
26
|
clampFPS: () => clampFPS,
|
|
27
|
+
clampMarch: () => clampMarch,
|
|
26
28
|
clampTime: () => clampTime,
|
|
27
29
|
clear: () => clear,
|
|
28
30
|
cloneElement: () => cloneElement,
|
|
@@ -59,13 +61,13 @@ __export(index_exports, {
|
|
|
59
61
|
// src/model.ts
|
|
60
62
|
var SUPPORTED_VERSION = 2;
|
|
61
63
|
var KINDS = ["rectangle", "ellipse", "diamond", "text", "connector", "freehand", "path", "note", "image"];
|
|
62
|
-
var EASES = ["linear", "easeIn", "easeOut", "easeInOut", "hold"];
|
|
64
|
+
var EASES = ["linear", "easeIn", "easeOut", "easeInOut", "hold", "spring", "bounce", "elastic"];
|
|
63
65
|
var KNOWN_FIELDS = {
|
|
64
66
|
file: ["version", "pages", "images"],
|
|
65
67
|
page: ["id", "name", "layers", "elements", "theme", "guidesX", "guidesY", "guidesLocked", "timeline"],
|
|
66
68
|
layer: ["id", "name", "visible", "locked"],
|
|
67
69
|
rgba: ["r", "g", "b", "a"],
|
|
68
|
-
style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "gridSize", "opacity"],
|
|
70
|
+
style: ["stroke", "fill", "fillStyle", "strokeWidth", "dash", "roughness", "bowing", "fontSize", "gridSize", "opacity", "dashOffset"],
|
|
69
71
|
element: [
|
|
70
72
|
"id",
|
|
71
73
|
"kind",
|
|
@@ -95,7 +97,7 @@ var KNOWN_FIELDS = {
|
|
|
95
97
|
endpoint: ["elementID", "port", "x", "y"],
|
|
96
98
|
connector: ["start", "end", "routing", "startHead", "endHead"],
|
|
97
99
|
timeline: ["fps", "duration", "boil", "settle", "poster", "tracks", "camera", "markers"],
|
|
98
|
-
track: ["element", "keys", "boil", "follow", "repeats"],
|
|
100
|
+
track: ["element", "keys", "boil", "follow", "repeats", "march"],
|
|
99
101
|
keyframe: ["t", "x", "y", "width", "height", "rotation", "strokeWidth", "stroke", "fill", "visible", "reveal", "opacity", "ease"],
|
|
100
102
|
follow: ["path", "start", "end", "ease", "reverse", "orient", "laps"],
|
|
101
103
|
repeat: ["start", "end", "count"],
|
|
@@ -103,6 +105,8 @@ var KNOWN_FIELDS = {
|
|
|
103
105
|
marker: ["t", "name"]
|
|
104
106
|
};
|
|
105
107
|
var MAX_DURATION = 3600;
|
|
108
|
+
var MAX_MARCH = 1e4;
|
|
109
|
+
var clampMarch = (v) => v === void 0 || !Number.isFinite(v) || v === 0 ? null : Math.min(Math.max(v, -MAX_MARCH), MAX_MARCH);
|
|
106
110
|
var BOIL_DRAWINGS = 3;
|
|
107
111
|
var black = { r: 0.12, g: 0.12, b: 0.13, a: 1 };
|
|
108
112
|
var clear = { r: 0, g: 0, b: 0, a: 0 };
|
|
@@ -160,7 +164,8 @@ var Reader = class {
|
|
|
160
164
|
bowing: num(s.bowing) ?? 1,
|
|
161
165
|
fontSize: num(s.fontSize) ?? 18,
|
|
162
166
|
gridSize: num(s.gridSize) ?? null,
|
|
163
|
-
opacity: num(s.opacity) ?? null
|
|
167
|
+
opacity: num(s.opacity) ?? null,
|
|
168
|
+
dashOffset: num(s.dashOffset) ?? null
|
|
164
169
|
};
|
|
165
170
|
}
|
|
166
171
|
endpoint(v) {
|
|
@@ -283,7 +288,7 @@ var Reader = class {
|
|
|
283
288
|
const rep = { start, end, count: count === void 0 ? null : Math.trunc(count) };
|
|
284
289
|
return repeatIsValid(rep) ? [rep] : [];
|
|
285
290
|
}) : null;
|
|
286
|
-
return { element, keys, boil: bool(v.boil) ?? null, follow, repeats };
|
|
291
|
+
return { element, keys, boil: bool(v.boil) ?? null, follow, repeats, march: clampMarch(num(v.march)) };
|
|
287
292
|
}
|
|
288
293
|
timeline(v) {
|
|
289
294
|
if (!isObj(v)) return null;
|
|
@@ -2114,7 +2119,40 @@ function applyEase(ease, u) {
|
|
|
2114
2119
|
return u < 0.5 ? 4 * u * u * u : 1 - Math.pow(-2 * u + 2, 3) / 2;
|
|
2115
2120
|
case "hold":
|
|
2116
2121
|
return 0;
|
|
2117
|
-
|
|
2122
|
+
case "spring":
|
|
2123
|
+
return spring(u);
|
|
2124
|
+
case "bounce":
|
|
2125
|
+
return bounce(u);
|
|
2126
|
+
case "elastic":
|
|
2127
|
+
return elastic(u);
|
|
2128
|
+
}
|
|
2129
|
+
}
|
|
2130
|
+
function spring(u) {
|
|
2131
|
+
if (u <= 0) return 0;
|
|
2132
|
+
if (u >= 1) return 1;
|
|
2133
|
+
const s = (u2) => 1 - Math.exp(-6 * u2) * (Math.cos(3 * Math.PI * u2) + 6 / (3 * Math.PI) * Math.sin(3 * Math.PI * u2));
|
|
2134
|
+
return s(u) + u * (1 - s(1));
|
|
2135
|
+
}
|
|
2136
|
+
function bounce(u) {
|
|
2137
|
+
if (u <= 0) return 0;
|
|
2138
|
+
if (u >= 1) return 1;
|
|
2139
|
+
const n = 7.5625, d = 2.75;
|
|
2140
|
+
if (u < 1 / d) return n * u * u;
|
|
2141
|
+
if (u < 2 / d) {
|
|
2142
|
+
const v2 = u - 1.5 / d;
|
|
2143
|
+
return n * v2 * v2 + 0.75;
|
|
2144
|
+
}
|
|
2145
|
+
if (u < 2.5 / d) {
|
|
2146
|
+
const v2 = u - 2.25 / d;
|
|
2147
|
+
return n * v2 * v2 + 0.9375;
|
|
2148
|
+
}
|
|
2149
|
+
const v = u - 2.625 / d;
|
|
2150
|
+
return n * v * v + 0.984375;
|
|
2151
|
+
}
|
|
2152
|
+
function elastic(u) {
|
|
2153
|
+
if (u <= 0) return 0;
|
|
2154
|
+
if (u >= 1) return 1;
|
|
2155
|
+
return Math.pow(2, -10 * u) * Math.sin((u * 10 - 0.75) * (2 * Math.PI / 3)) + 1;
|
|
2118
2156
|
}
|
|
2119
2157
|
var rem = (a, b) => a % b;
|
|
2120
2158
|
function localTime(track, t) {
|
|
@@ -2149,11 +2187,12 @@ function value(track, t, get, base, lerp) {
|
|
|
2149
2187
|
return lerp(get(b), get(a), applyEase(b.ease ?? "linear", u));
|
|
2150
2188
|
}
|
|
2151
2189
|
var lerpNum = (a, b, u) => a + (b - a) * u;
|
|
2190
|
+
var mix01 = (a, b, u) => Math.min(Math.max(a + (b - a) * u, 0), 1);
|
|
2152
2191
|
var lerpColor = (a, b, u) => ({
|
|
2153
|
-
r: a.r
|
|
2154
|
-
g: a.g
|
|
2155
|
-
b: a.b
|
|
2156
|
-
a: a.a
|
|
2192
|
+
r: mix01(a.r, b.r, u),
|
|
2193
|
+
g: mix01(a.g, b.g, u),
|
|
2194
|
+
b: mix01(a.b, b.b, u),
|
|
2195
|
+
a: mix01(a.a, b.a, u)
|
|
2157
2196
|
});
|
|
2158
2197
|
function num2(track, t, p, base) {
|
|
2159
2198
|
return value(track, t, (k) => k[p], base, lerpNum);
|
|
@@ -2191,10 +2230,10 @@ function applyTrack(track, e, t) {
|
|
|
2191
2230
|
if (e.kind === "connector") return e;
|
|
2192
2231
|
e.x = num2(track, t, "x", e.x);
|
|
2193
2232
|
e.y = num2(track, t, "y", e.y);
|
|
2194
|
-
e.width = num2(track, t, "width", e.width);
|
|
2195
|
-
e.height = num2(track, t, "height", e.height);
|
|
2233
|
+
e.width = Math.max(0, num2(track, t, "width", e.width));
|
|
2234
|
+
e.height = Math.max(0, num2(track, t, "height", e.height));
|
|
2196
2235
|
if (track.keys.some((k) => k.rotation !== void 0)) e.rotation = num2(track, t, "rotation", angle(e));
|
|
2197
|
-
e.style.strokeWidth = num2(track, t, "strokeWidth", e.style.strokeWidth);
|
|
2236
|
+
e.style.strokeWidth = Math.max(0, num2(track, t, "strokeWidth", e.style.strokeWidth));
|
|
2198
2237
|
e.style.stroke = value(track, t, (k) => k.stroke, e.style.stroke, lerpColor);
|
|
2199
2238
|
e.style.fill = value(track, t, (k) => k.fill, e.style.fill, lerpColor);
|
|
2200
2239
|
return e;
|
|
@@ -2223,7 +2262,7 @@ function following(track, e, t, page) {
|
|
|
2223
2262
|
if (!pathElement || pathElement.id === e.id) return e;
|
|
2224
2263
|
const line2 = tracing(pathElement, page);
|
|
2225
2264
|
const span = f.end - f.start;
|
|
2226
|
-
let u = applyEase(f.ease ?? "easeInOut", span > 0 ? Math.min(1, (t - f.start) / span) : 1) * (f.laps ?? 1);
|
|
2265
|
+
let u = Math.min(Math.max(applyEase(f.ease ?? "easeInOut", span > 0 ? Math.min(1, (t - f.start) / span) : 1), 0), 1) * (f.laps ?? 1);
|
|
2227
2266
|
if (u > 1) u = rem(u, 1) === 0 ? 1 : rem(u, 1);
|
|
2228
2267
|
if (f.reverse === true) u = 1 - u;
|
|
2229
2268
|
const p = line2.point(u);
|
|
@@ -2237,6 +2276,16 @@ function following(track, e, t, page) {
|
|
|
2237
2276
|
}
|
|
2238
2277
|
return moved;
|
|
2239
2278
|
}
|
|
2279
|
+
function marchOffset(tl, speed, period, t) {
|
|
2280
|
+
if (!(period > 0)) return 0;
|
|
2281
|
+
const d = clampTime(tl.duration);
|
|
2282
|
+
if (d > 0) {
|
|
2283
|
+
const laps = roundHalfAway(speed * d / period);
|
|
2284
|
+
if (laps !== 0) speed = laps * period / d;
|
|
2285
|
+
}
|
|
2286
|
+
const r = rem(speed * t, period);
|
|
2287
|
+
return r < 0 ? -r : r === 0 ? 0 : period - r;
|
|
2288
|
+
}
|
|
2240
2289
|
function trackMap(tl) {
|
|
2241
2290
|
const m = /* @__PURE__ */ new Map();
|
|
2242
2291
|
for (const t of tl.tracks) if (!m.has(t.element)) m.set(t.element, t);
|
|
@@ -2269,6 +2318,11 @@ function resolved(page, t) {
|
|
|
2269
2318
|
if (out === e) out = cloneElement(e);
|
|
2270
2319
|
out.seed = boiled(e.seed, reseed);
|
|
2271
2320
|
}
|
|
2321
|
+
const pattern = track?.march != null ? dashPattern(out.style.dash, out.style.strokeWidth) : null;
|
|
2322
|
+
if (track?.march != null && pattern) {
|
|
2323
|
+
if (out === e) out = cloneElement(e);
|
|
2324
|
+
out.style.dashOffset = marchOffset(timeline, track.march, pattern.reduce((a, b) => a + b, 0), t);
|
|
2325
|
+
}
|
|
2272
2326
|
return out;
|
|
2273
2327
|
});
|
|
2274
2328
|
elements = elements.map((e, i) => hidden.has(e.id) ? page.elements[i] : e);
|
|
@@ -2311,7 +2365,7 @@ function cameraRect(tl, t) {
|
|
|
2311
2365
|
if (!after) return rectOf(before);
|
|
2312
2366
|
const u = applyEase(before.ease ?? "easeInOut", (t - before.t) / Math.max(after.t - before.t, 1e-9));
|
|
2313
2367
|
const mix2 = (p, q) => p + (q - p) * u;
|
|
2314
|
-
return { x: mix2(before.x, after.x), y: mix2(before.y, after.y), width: mix2(before.width, after.width), height: mix2(before.height, after.height) };
|
|
2368
|
+
return { x: mix2(before.x, after.x), y: mix2(before.y, after.y), width: Math.max(1, mix2(before.width, after.width)), height: Math.max(1, mix2(before.height, after.height)) };
|
|
2315
2369
|
}
|
|
2316
2370
|
var rectOf = (k) => ({ x: k.x, y: k.y, width: k.width, height: k.height });
|
|
2317
2371
|
function cameraView(tl, t) {
|
|
@@ -2361,8 +2415,9 @@ function bounds(page, padding = 24) {
|
|
|
2361
2415
|
return inset(rotatedBounds(e), -reach, -reach);
|
|
2362
2416
|
};
|
|
2363
2417
|
if (page.elements.length === 0) return { x: 0, y: 0, width: 200, height: 200 };
|
|
2418
|
+
const shown = page.elements.filter((e) => (e.style.opacity ?? 1) > 0);
|
|
2364
2419
|
let r = null;
|
|
2365
|
-
for (const e of page.elements) r = union(r, box(e));
|
|
2420
|
+
for (const e of shown.length ? shown : page.elements) r = union(r, box(e));
|
|
2366
2421
|
return inset(r, -padding, -padding);
|
|
2367
2422
|
}
|
|
2368
2423
|
function plan(page) {
|
|
@@ -2446,6 +2501,7 @@ function svgElement(e, index, labelBackground) {
|
|
|
2446
2501
|
let strokeAttrs = `stroke="${stroke}" stroke-width="${fmt(e.style.strokeWidth)}" stroke-linecap="round" stroke-linejoin="round"`;
|
|
2447
2502
|
const dash = dashPattern(e.style.dash, e.style.strokeWidth);
|
|
2448
2503
|
if (dash) strokeAttrs += ` stroke-dasharray="${dash.map(fmt).join(" ")}"`;
|
|
2504
|
+
if (dash && e.style.dashOffset !== null && fmt(e.style.dashOffset) !== "0") strokeAttrs += ` stroke-dashoffset="${fmt(e.style.dashOffset)}"`;
|
|
2449
2505
|
let text = e.text;
|
|
2450
2506
|
const r = revealProgress(e);
|
|
2451
2507
|
if (r !== null) {
|
|
@@ -2976,6 +3032,7 @@ function inspectFrame(page, t) {
|
|
|
2976
3032
|
if (e.rotation !== null) d.rotation = r4(e.rotation);
|
|
2977
3033
|
if (e.style.opacity !== null) d.opacity = r4(e.style.opacity);
|
|
2978
3034
|
if (e.reveal !== null) d.reveal = r4(e.reveal);
|
|
3035
|
+
if (e.style.dashOffset !== null) d.dashOffset = r4(e.style.dashOffset);
|
|
2979
3036
|
d.strokeWidth = r4(e.style.strokeWidth);
|
|
2980
3037
|
d.stroke = rgba2(e.style.stroke);
|
|
2981
3038
|
d.fill = rgba2(e.style.fill);
|
|
@@ -3022,7 +3079,7 @@ function render(source, options = {}) {
|
|
|
3022
3079
|
function isFile(v) {
|
|
3023
3080
|
return typeof v === "object" && v !== null && Array.isArray(v.pages) && Array.isArray(v.warnings);
|
|
3024
3081
|
}
|
|
3025
|
-
var VERSION = "0.
|
|
3082
|
+
var VERSION = "0.3.0";
|
|
3026
3083
|
|
|
3027
3084
|
// src/player-entry.ts
|
|
3028
3085
|
definePlayer();
|
|
@@ -3034,6 +3091,7 @@ export {
|
|
|
3034
3091
|
KINDS,
|
|
3035
3092
|
KNOWN_FIELDS,
|
|
3036
3093
|
MAX_DURATION,
|
|
3094
|
+
MAX_MARCH,
|
|
3037
3095
|
Playback,
|
|
3038
3096
|
SUPPORTED_VERSION,
|
|
3039
3097
|
VERSION,
|
|
@@ -3041,6 +3099,7 @@ export {
|
|
|
3041
3099
|
bounds,
|
|
3042
3100
|
cameraView,
|
|
3043
3101
|
clampFPS,
|
|
3102
|
+
clampMarch,
|
|
3044
3103
|
clampTime,
|
|
3045
3104
|
clear,
|
|
3046
3105
|
cloneElement,
|