@bendyline/squisq 2.11.8 → 2.11.10
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/{Doc-CynsGqL4.d.ts → Doc-BWtfp7dT.d.ts} +218 -3
- package/dist/{ImageEditDoc-BVZe_5y4.d.ts → ImageEditDoc-CYRQK8so.d.ts} +1 -1
- package/dist/{chunk-YNO6JV36.js → chunk-2SRF5III.js} +4 -4
- package/dist/{chunk-VU4T74LI.js → chunk-7WN7DDMI.js} +1 -1
- package/dist/{chunk-5FBI3ZW4.js → chunk-BVQZCKXN.js} +2 -2
- package/dist/{chunk-JM2QARY2.js → chunk-CPQCZUBW.js} +311 -19
- package/dist/{chunk-JJO6JFNZ.js → chunk-HVJ6VFDX.js} +2 -2
- package/dist/{chunk-Y4D6TDZT.js → chunk-PFH3WV6J.js} +145 -3
- package/dist/{chunk-ZEONJCP3.js → chunk-PWCIJHZH.js} +1 -1
- package/dist/{chunk-KFZOCWPK.js → chunk-RV5OOBSV.js} +2 -2
- package/dist/{chunk-RMCUZDW5.js → chunk-TYW5VMNP.js} +366 -111
- package/dist/doc/index.d.ts +108 -7
- package/dist/doc/index.js +31 -5
- package/dist/fence/index.d.ts +1 -1
- package/dist/generate/index.d.ts +1 -1
- package/dist/imageEdit/index.d.ts +3 -3
- package/dist/index.d.ts +5 -5
- package/dist/index.js +49 -9
- package/dist/jsonForm/index.d.ts +1 -1
- package/dist/jsonForm/index.js +4 -4
- package/dist/{materializePageSection-CAJoa8fh.d.ts → materializePageSection-Db7pABI0.d.ts} +6 -3
- package/dist/mediaEdit/index.d.ts +2 -2
- package/dist/narration/index.d.ts +1 -1
- package/dist/narration/index.js +4 -4
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/index.js +17 -3
- package/dist/{themeLibrary-z7t3x5CU.d.ts → themeLibrary-Bphz1CRp.d.ts} +1 -1
- package/dist/timing/index.d.ts +1 -1
- package/dist/transform/index.d.ts +2 -2
- package/dist/transform/index.js +3 -3
- package/package.json +1 -1
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
DEFAULT_THEME,
|
|
27
27
|
FRONTMATTER_CUSTOM_TEMPLATES_KEY,
|
|
28
28
|
FRONTMATTER_CUSTOM_THEMES_KEY,
|
|
29
|
+
MOTION_PROFILES,
|
|
29
30
|
VIEWPORT_PRESETS,
|
|
30
31
|
cloneData,
|
|
31
32
|
createTemplateContext,
|
|
@@ -35,13 +36,14 @@ import {
|
|
|
35
36
|
isTemplateBlock,
|
|
36
37
|
oklchDarken,
|
|
37
38
|
pickContrastingText,
|
|
39
|
+
readFrontmatterMotion,
|
|
38
40
|
relativeLuminance,
|
|
39
41
|
resolveFontFamily,
|
|
40
42
|
scaledFontSize2 as scaledFontSize,
|
|
41
43
|
validateCustomTemplateDefinition,
|
|
42
44
|
validateTheme,
|
|
43
45
|
withAlpha
|
|
44
|
-
} from "./chunk-
|
|
46
|
+
} from "./chunk-PFH3WV6J.js";
|
|
45
47
|
import {
|
|
46
48
|
mediaEditValuesFromAttributes,
|
|
47
49
|
mediaEditValuesFromParams,
|
|
@@ -461,6 +463,27 @@ function themedEntrance(context, layerType, fallback) {
|
|
|
461
463
|
if (!type || type === "slowZoom" || type === fallback.type) return fallback;
|
|
462
464
|
return { ...fallback, type };
|
|
463
465
|
}
|
|
466
|
+
function getMotionProfile(context) {
|
|
467
|
+
return context.motion ?? MOTION_PROFILES.calm;
|
|
468
|
+
}
|
|
469
|
+
function motionEntrance(context, fallback, layerType = "text") {
|
|
470
|
+
const themed = themedEntrance(context, layerType, fallback);
|
|
471
|
+
const profile = getMotionProfile(context);
|
|
472
|
+
if (profile.name === "calm") return themed;
|
|
473
|
+
if (themed.type === "typewriter" || themed.type === "none") return themed;
|
|
474
|
+
const { textEntrance } = profile;
|
|
475
|
+
return {
|
|
476
|
+
...themed,
|
|
477
|
+
type: textEntrance.type,
|
|
478
|
+
duration: textEntrance.duration,
|
|
479
|
+
...themed.delay != null ? { delay: motionDelay(context, themed.delay) } : {},
|
|
480
|
+
...textEntrance.easing ? { easing: textEntrance.easing } : {}
|
|
481
|
+
};
|
|
482
|
+
}
|
|
483
|
+
function motionDelay(context, delay) {
|
|
484
|
+
const scale = getMotionProfile(context).textEntrance.delayScale;
|
|
485
|
+
return scale === 1 ? delay : Number((delay * scale).toFixed(3));
|
|
486
|
+
}
|
|
464
487
|
function shouldUseShadow(context) {
|
|
465
488
|
return context.theme.style.textShadow ?? true;
|
|
466
489
|
}
|
|
@@ -676,7 +699,7 @@ function titleBlock(input, context) {
|
|
|
676
699
|
width: layout.maxTextWidth,
|
|
677
700
|
height: `${px(titleH)}%`
|
|
678
701
|
},
|
|
679
|
-
animation:
|
|
702
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 2 })
|
|
680
703
|
}
|
|
681
704
|
);
|
|
682
705
|
if (subtitle && subtitleFit) {
|
|
@@ -1052,7 +1075,7 @@ function sectionHeader(input, context) {
|
|
|
1052
1075
|
width: layout.maxTextWidth,
|
|
1053
1076
|
height: `${px(titleH)}%`
|
|
1054
1077
|
},
|
|
1055
|
-
animation:
|
|
1078
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1.5 })
|
|
1056
1079
|
});
|
|
1057
1080
|
return layers;
|
|
1058
1081
|
}
|
|
@@ -1184,7 +1207,7 @@ function bigText(input, context) {
|
|
|
1184
1207
|
width: `${BIG_TEXT_WIDTH_FRACTION * 100}%`,
|
|
1185
1208
|
height: `${BIG_TEXT_HEIGHT_FRACTION * 100}%`
|
|
1186
1209
|
},
|
|
1187
|
-
animation:
|
|
1210
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1 })
|
|
1188
1211
|
});
|
|
1189
1212
|
return layers;
|
|
1190
1213
|
}
|
|
@@ -2215,6 +2238,59 @@ function contentBlock(input, context) {
|
|
|
2215
2238
|
return layers;
|
|
2216
2239
|
}
|
|
2217
2240
|
|
|
2241
|
+
// src/doc/utils/countUp.ts
|
|
2242
|
+
var STAT_PATTERN = /^([^\d]*?)([-−]?\d[\d,]*(?:\.\d+)?)(.*)$/s;
|
|
2243
|
+
function parseStatNumber(text) {
|
|
2244
|
+
const match = STAT_PATTERN.exec(text.trim());
|
|
2245
|
+
if (!match) return null;
|
|
2246
|
+
const [, prefix, numeric, suffix] = match;
|
|
2247
|
+
const normalized = numeric.replace(/,/g, "").replace("\u2212", "-");
|
|
2248
|
+
const value = Number(normalized);
|
|
2249
|
+
if (!Number.isFinite(value)) return null;
|
|
2250
|
+
const decimals = normalized.includes(".") ? normalized.split(".")[1].length : 0;
|
|
2251
|
+
const bare = /^-?\d{4}$/.test(normalized);
|
|
2252
|
+
const looksLikeYear = bare && Math.abs(value) >= 1e3 && Math.abs(value) <= 2999 && !/^[$€£¥]/.test(prefix);
|
|
2253
|
+
if (looksLikeYear && !/^[%KMB]/i.test(suffix.trim())) return null;
|
|
2254
|
+
return { prefix, value, decimals, grouping: numeric.includes(","), suffix };
|
|
2255
|
+
}
|
|
2256
|
+
function countUpSpecFor(text) {
|
|
2257
|
+
const parsed = parseStatNumber(text);
|
|
2258
|
+
if (!parsed) return null;
|
|
2259
|
+
return {
|
|
2260
|
+
from: 0,
|
|
2261
|
+
to: parsed.value,
|
|
2262
|
+
decimals: parsed.decimals,
|
|
2263
|
+
grouping: parsed.grouping,
|
|
2264
|
+
prefix: parsed.prefix,
|
|
2265
|
+
suffix: parsed.suffix
|
|
2266
|
+
};
|
|
2267
|
+
}
|
|
2268
|
+
function easeOutCubic(t) {
|
|
2269
|
+
const u = 1 - t;
|
|
2270
|
+
return 1 - u * u * u;
|
|
2271
|
+
}
|
|
2272
|
+
function formatCountValue(value, decimals, grouping) {
|
|
2273
|
+
const fixed = Math.abs(value).toFixed(decimals);
|
|
2274
|
+
const [whole, fraction] = fixed.split(".");
|
|
2275
|
+
const grouped = grouping ? whole.replace(/\B(?=(\d{3})+(?!\d))/g, ",") : whole;
|
|
2276
|
+
const sign = value < 0 && Number(fixed) !== 0 ? "-" : "";
|
|
2277
|
+
return `${sign}${grouped}${fraction ? `.${fraction}` : ""}`;
|
|
2278
|
+
}
|
|
2279
|
+
function formatCountUp(text, animation, blockTime) {
|
|
2280
|
+
const count = animation.count ?? countUpSpecFor(text);
|
|
2281
|
+
if (!count) return text;
|
|
2282
|
+
const delay = animation.delay ?? 0;
|
|
2283
|
+
const duration = animation.duration ?? 1.5;
|
|
2284
|
+
const progress = duration <= 0 ? 1 : Math.min(1, Math.max(0, (blockTime - delay) / duration));
|
|
2285
|
+
if (progress >= 1) return animation.count ? formatFinal(count) : text;
|
|
2286
|
+
const from = count.from ?? 0;
|
|
2287
|
+
const value = from + (count.to - from) * easeOutCubic(progress);
|
|
2288
|
+
return `${count.prefix ?? ""}${formatCountValue(value, count.decimals ?? 0, count.grouping ?? false)}${count.suffix ?? ""}`;
|
|
2289
|
+
}
|
|
2290
|
+
function formatFinal(count) {
|
|
2291
|
+
return `${count.prefix ?? ""}${formatCountValue(count.to, count.decimals ?? 0, count.grouping ?? false)}${count.suffix ?? ""}`;
|
|
2292
|
+
}
|
|
2293
|
+
|
|
2218
2294
|
// src/doc/templates/statHighlight.ts
|
|
2219
2295
|
var SAFE_TOP = 0.08;
|
|
2220
2296
|
var SAFE_BOTTOM = 0.92;
|
|
@@ -2235,6 +2311,10 @@ function statHighlight(input, context) {
|
|
|
2235
2311
|
const descFontSize = themedFontSize(32, context, false);
|
|
2236
2312
|
const detailFontSize = themedFontSize(26, context, false);
|
|
2237
2313
|
const layers = [createBackgroundLayer("bg", themedSurfaceGradient(context, 180))];
|
|
2314
|
+
const motion = getMotionProfile(context);
|
|
2315
|
+
const countSpec = motion.countUp ? countUpSpecFor(stat) : null;
|
|
2316
|
+
const statEntrance = getTemplateHint(context, "statHighlight", "entrance", "subtle") === "dramatic" ? { type: "zoomIn", duration: 0.4 } : { type: "zoomIn", duration: 0.6 };
|
|
2317
|
+
const statAnimation = countSpec ? { type: "countUp", duration: motion.countUpDuration, delay: 0.15, count: countSpec } : statEntrance;
|
|
2238
2318
|
if (accentImage) {
|
|
2239
2319
|
layers.push(
|
|
2240
2320
|
...createAccentLayers(
|
|
@@ -2317,7 +2397,7 @@ function statHighlight(input, context) {
|
|
|
2317
2397
|
}
|
|
2318
2398
|
},
|
|
2319
2399
|
position: box(statTop, statBoxH),
|
|
2320
|
-
animation:
|
|
2400
|
+
animation: statAnimation
|
|
2321
2401
|
});
|
|
2322
2402
|
if (descFit) {
|
|
2323
2403
|
layers.push({
|
|
@@ -2337,7 +2417,7 @@ function statHighlight(input, context) {
|
|
|
2337
2417
|
}
|
|
2338
2418
|
},
|
|
2339
2419
|
position: box(descTop, descBoxH),
|
|
2340
|
-
animation: { type: "fadeIn", duration: 1, delay: 0.3 }
|
|
2420
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1, delay: 0.3 })
|
|
2341
2421
|
});
|
|
2342
2422
|
}
|
|
2343
2423
|
if (detailFit) {
|
|
@@ -2361,7 +2441,7 @@ function statHighlight(input, context) {
|
|
|
2361
2441
|
}
|
|
2362
2442
|
},
|
|
2363
2443
|
position: box(detailTop, detailBoxH),
|
|
2364
|
-
animation: { type: "fadeIn", duration: 1, delay: 1 }
|
|
2444
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1, delay: 1 })
|
|
2365
2445
|
});
|
|
2366
2446
|
}
|
|
2367
2447
|
return layers;
|
|
@@ -2524,7 +2604,7 @@ function quoteBlock(input, context) {
|
|
|
2524
2604
|
height: pct(quoteFit.heightPx),
|
|
2525
2605
|
anchor: "top-left"
|
|
2526
2606
|
},
|
|
2527
|
-
animation:
|
|
2607
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 2 })
|
|
2528
2608
|
};
|
|
2529
2609
|
layers.push(quoteLayer);
|
|
2530
2610
|
if (attribution && attrFit) {
|
|
@@ -2657,7 +2737,7 @@ function factCard(input, context) {
|
|
|
2657
2737
|
}
|
|
2658
2738
|
},
|
|
2659
2739
|
position: box(factTop, factBoxH),
|
|
2660
|
-
animation:
|
|
2740
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1.5 })
|
|
2661
2741
|
});
|
|
2662
2742
|
if (explainFit) {
|
|
2663
2743
|
layers.push({
|
|
@@ -2677,7 +2757,7 @@ function factCard(input, context) {
|
|
|
2677
2757
|
}
|
|
2678
2758
|
},
|
|
2679
2759
|
position: box(explainTop, explainBoxH),
|
|
2680
|
-
animation:
|
|
2760
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1, delay: 0.8 })
|
|
2681
2761
|
});
|
|
2682
2762
|
}
|
|
2683
2763
|
if (sourceFit) {
|
|
@@ -2791,7 +2871,7 @@ function twoColumn(input, context) {
|
|
|
2791
2871
|
width: `${bandWidthPct}%`,
|
|
2792
2872
|
anchor: "top-left"
|
|
2793
2873
|
},
|
|
2794
|
-
animation:
|
|
2874
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.8 })
|
|
2795
2875
|
});
|
|
2796
2876
|
}
|
|
2797
2877
|
let leftY;
|
|
@@ -2830,7 +2910,7 @@ function twoColumn(input, context) {
|
|
|
2830
2910
|
anchor: "center",
|
|
2831
2911
|
width: columnWidth
|
|
2832
2912
|
},
|
|
2833
|
-
animation:
|
|
2913
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1 })
|
|
2834
2914
|
});
|
|
2835
2915
|
if (left.sublabel) {
|
|
2836
2916
|
layers.push({
|
|
@@ -2898,7 +2978,7 @@ function twoColumn(input, context) {
|
|
|
2898
2978
|
anchor: "center",
|
|
2899
2979
|
width: columnWidth
|
|
2900
2980
|
},
|
|
2901
|
-
animation:
|
|
2981
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1, delay: 0.5 })
|
|
2902
2982
|
});
|
|
2903
2983
|
if (right.sublabel) {
|
|
2904
2984
|
layers.push({
|
|
@@ -3156,7 +3236,7 @@ function imageWithCaption(input, context) {
|
|
|
3156
3236
|
anchor: "center",
|
|
3157
3237
|
width: layout.maxTextWidth
|
|
3158
3238
|
},
|
|
3159
|
-
animation: { type: "fadeIn", duration: 0.8 }
|
|
3239
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.8 })
|
|
3160
3240
|
});
|
|
3161
3241
|
if (subtitle) {
|
|
3162
3242
|
layers.push({
|
|
@@ -3178,7 +3258,7 @@ function imageWithCaption(input, context) {
|
|
|
3178
3258
|
anchor: "center",
|
|
3179
3259
|
width: layout.maxTextWidth
|
|
3180
3260
|
},
|
|
3181
|
-
animation: { type: "fadeIn", duration: 0.8, delay: 0.2 }
|
|
3261
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.8, delay: 0.2 })
|
|
3182
3262
|
});
|
|
3183
3263
|
}
|
|
3184
3264
|
return layers;
|
|
@@ -3212,7 +3292,10 @@ function imageWithCaption(input, context) {
|
|
|
3212
3292
|
textAlign: "center",
|
|
3213
3293
|
shadow: shouldUseShadow(context),
|
|
3214
3294
|
lineHeight: 1.18,
|
|
3215
|
-
maxLines: 2
|
|
3295
|
+
maxLines: 2,
|
|
3296
|
+
// A two-line caption centres on the band instead of hanging its
|
|
3297
|
+
// second line below it (the block centres on the anchor).
|
|
3298
|
+
shrinkToFit: true
|
|
3216
3299
|
}
|
|
3217
3300
|
},
|
|
3218
3301
|
position: {
|
|
@@ -3221,7 +3304,7 @@ function imageWithCaption(input, context) {
|
|
|
3221
3304
|
anchor: "center",
|
|
3222
3305
|
width: "78%"
|
|
3223
3306
|
},
|
|
3224
|
-
animation: { type: "fadeIn", duration: 1.5, delay: 0.5 }
|
|
3307
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1.5, delay: 0.5 })
|
|
3225
3308
|
});
|
|
3226
3309
|
}
|
|
3227
3310
|
return layers;
|
|
@@ -3409,7 +3492,7 @@ function buildFeatureLayers(input, context, side) {
|
|
|
3409
3492
|
anchor: textAnchor,
|
|
3410
3493
|
width: pctW(titleWrapWidth)
|
|
3411
3494
|
},
|
|
3412
|
-
animation:
|
|
3495
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.8 })
|
|
3413
3496
|
});
|
|
3414
3497
|
}
|
|
3415
3498
|
if (body && bodyFit) {
|
|
@@ -3433,7 +3516,7 @@ function buildFeatureLayers(input, context, side) {
|
|
|
3433
3516
|
anchor: textAnchor,
|
|
3434
3517
|
width: pctW(bodyWrapWidth)
|
|
3435
3518
|
},
|
|
3436
|
-
animation:
|
|
3519
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.8, delay: 0.2 })
|
|
3437
3520
|
});
|
|
3438
3521
|
}
|
|
3439
3522
|
return layers;
|
|
@@ -3626,7 +3709,10 @@ function fullBleedQuote(input, context) {
|
|
|
3626
3709
|
height: pct(fit.heightPx),
|
|
3627
3710
|
anchor: "top-left"
|
|
3628
3711
|
},
|
|
3629
|
-
animation:
|
|
3712
|
+
animation: motionEntrance(
|
|
3713
|
+
context,
|
|
3714
|
+
getTemplateHint(context, "fullBleedQuote", "entrance", "subtle") === "dramatic" ? { type: "zoomIn", duration: 0.8 } : { type: "fadeIn", duration: 1.5 }
|
|
3715
|
+
)
|
|
3630
3716
|
}
|
|
3631
3717
|
];
|
|
3632
3718
|
}
|
|
@@ -3741,7 +3827,7 @@ function listBlock(input, context) {
|
|
|
3741
3827
|
y: adjustY(`${titleTopPct}%`, accentLayout),
|
|
3742
3828
|
width: accentLayout.textWidth
|
|
3743
3829
|
},
|
|
3744
|
-
animation:
|
|
3830
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1 })
|
|
3745
3831
|
});
|
|
3746
3832
|
}
|
|
3747
3833
|
const availablePx = Math.max(0, (bottomLimitPct - startY) / 100 * context.viewport.height);
|
|
@@ -3758,7 +3844,7 @@ function listBlock(input, context) {
|
|
|
3758
3844
|
const itemText = items[i];
|
|
3759
3845
|
const itemHtml = richItems[i]?.text === itemText ? richItems[i]?.html : void 0;
|
|
3760
3846
|
const lineCount = estimateProseLineCount(itemText, itemFontSize, bodyWidthPx);
|
|
3761
|
-
const animation =
|
|
3847
|
+
const animation = motionEntrance(context, {
|
|
3762
3848
|
type: "fadeIn",
|
|
3763
3849
|
duration: 0.8,
|
|
3764
3850
|
delay: 0.3 + 0.3 * i
|
|
@@ -3825,6 +3911,7 @@ function photoGrid(input, context) {
|
|
|
3825
3911
|
const caption = rawCaption ? cleanCaption(rawCaption) : rawCaption;
|
|
3826
3912
|
const { theme, layout } = context;
|
|
3827
3913
|
const treatment = themedImageTreatment(context, input.imageTreatment);
|
|
3914
|
+
const stagger = getMotionProfile(context).photoGridStagger;
|
|
3828
3915
|
const layers = [
|
|
3829
3916
|
// Theme surface background (visible in gaps between images)
|
|
3830
3917
|
{
|
|
@@ -3863,7 +3950,12 @@ function photoGrid(input, context) {
|
|
|
3863
3950
|
height: `${pos.h}%`
|
|
3864
3951
|
},
|
|
3865
3952
|
// Apply ambient motion to the first (largest) image only
|
|
3866
|
-
animation: i === 0 && ambientMotion ? { type: ambientMotion, duration: 15 } :
|
|
3953
|
+
animation: i === 0 && ambientMotion ? { type: ambientMotion, duration: 15 } : stagger > 0 ? {
|
|
3954
|
+
type: "reveal",
|
|
3955
|
+
origin: pos.x < 50 ? "left" : "right",
|
|
3956
|
+
duration: 0.7,
|
|
3957
|
+
delay: Number((0.15 + stagger * i).toFixed(3))
|
|
3958
|
+
} : { type: "fadeIn", duration: 1, delay: 0.2 * i }
|
|
3867
3959
|
});
|
|
3868
3960
|
}
|
|
3869
3961
|
if (caption) {
|
|
@@ -3893,7 +3985,8 @@ function photoGrid(input, context) {
|
|
|
3893
3985
|
textAlign: "center",
|
|
3894
3986
|
shadow: true,
|
|
3895
3987
|
lineHeight: 1.18,
|
|
3896
|
-
maxLines: layout.stackColumns ? 2 : 1
|
|
3988
|
+
maxLines: layout.stackColumns ? 2 : 1,
|
|
3989
|
+
shrinkToFit: true
|
|
3897
3990
|
}
|
|
3898
3991
|
},
|
|
3899
3992
|
position: {
|
|
@@ -3902,7 +3995,7 @@ function photoGrid(input, context) {
|
|
|
3902
3995
|
anchor: "center",
|
|
3903
3996
|
width: "78%"
|
|
3904
3997
|
},
|
|
3905
|
-
animation: { type: "fadeIn", duration: 1, delay: 0.5 }
|
|
3998
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1, delay: 0.5 })
|
|
3906
3999
|
});
|
|
3907
4000
|
}
|
|
3908
4001
|
return layers;
|
|
@@ -4051,7 +4144,7 @@ function definitionCard(input, context) {
|
|
|
4051
4144
|
}
|
|
4052
4145
|
},
|
|
4053
4146
|
position: box(termTop, termH + termFit.fontSize * BOX_SLACK_EM2),
|
|
4054
|
-
animation:
|
|
4147
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1.5 })
|
|
4055
4148
|
});
|
|
4056
4149
|
layers.push({
|
|
4057
4150
|
type: "shape",
|
|
@@ -4088,7 +4181,7 @@ function definitionCard(input, context) {
|
|
|
4088
4181
|
}
|
|
4089
4182
|
},
|
|
4090
4183
|
position: box(defTop, defH + defFit.fontSize * BOX_SLACK_EM2),
|
|
4091
|
-
animation:
|
|
4184
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1, delay: 0.8 })
|
|
4092
4185
|
});
|
|
4093
4186
|
}
|
|
4094
4187
|
if (originText) {
|
|
@@ -4122,8 +4215,8 @@ function comparisonBar(input, context) {
|
|
|
4122
4215
|
const colors = resolveColorScheme(context, colorScheme);
|
|
4123
4216
|
const leftValue = Number.isFinite(input.leftValue) ? input.leftValue : 0;
|
|
4124
4217
|
const rightValue = Number.isFinite(input.rightValue) ? input.rightValue : 0;
|
|
4125
|
-
const labelFontSize = themedFontSize(
|
|
4126
|
-
const valueFontSize = themedFontSize(
|
|
4218
|
+
const labelFontSize = themedFontSize(34, context, false);
|
|
4219
|
+
const valueFontSize = themedFontSize(58, context, true);
|
|
4127
4220
|
const formatValue = (v) => {
|
|
4128
4221
|
if (!Number.isFinite(v)) return "\u2014";
|
|
4129
4222
|
if (v >= 1e6) return `${(v / 1e6).toFixed(1)}M`;
|
|
@@ -4132,16 +4225,40 @@ function comparisonBar(input, context) {
|
|
|
4132
4225
|
};
|
|
4133
4226
|
const leftDisplay = unit ? `${formatValue(leftValue)} ${unit}` : formatValue(leftValue);
|
|
4134
4227
|
const rightDisplay = unit ? `${formatValue(rightValue)} ${unit}` : formatValue(rightValue);
|
|
4135
|
-
const
|
|
4228
|
+
const motion = getMotionProfile(context);
|
|
4229
|
+
const growEasing = motion.textEntrance.easing;
|
|
4230
|
+
const barAnimation = (fallback) => {
|
|
4231
|
+
if (!motion.chartGrowth) return fallback;
|
|
4232
|
+
return {
|
|
4233
|
+
type: "grow",
|
|
4234
|
+
origin: "left",
|
|
4235
|
+
duration: motion.chartGrowthDuration,
|
|
4236
|
+
delay: motionDelay(context, fallback.delay ?? 0),
|
|
4237
|
+
...growEasing ? { easing: growEasing } : {}
|
|
4238
|
+
};
|
|
4239
|
+
};
|
|
4240
|
+
const valueAnimation = (display, fallback) => {
|
|
4241
|
+
const count = motion.countUp ? countUpSpecFor(display) : null;
|
|
4242
|
+
if (!count) return motionEntrance(context, fallback);
|
|
4243
|
+
return {
|
|
4244
|
+
type: "countUp",
|
|
4245
|
+
duration: motion.countUpDuration,
|
|
4246
|
+
delay: motionDelay(context, fallback.delay ?? 0),
|
|
4247
|
+
count
|
|
4248
|
+
};
|
|
4249
|
+
};
|
|
4250
|
+
const labelAnimation = motion.name === "calm" ? void 0 : motionEntrance(context, { type: "fadeIn", duration: 0.6 });
|
|
4136
4251
|
const barHeight = 6;
|
|
4137
|
-
const topBarY =
|
|
4138
|
-
const bottomBarY =
|
|
4252
|
+
const topBarY = 39;
|
|
4253
|
+
const bottomBarY = 61;
|
|
4139
4254
|
const leftExtent = Math.max(0, leftValue);
|
|
4140
4255
|
const rightExtent = Math.max(0, rightValue);
|
|
4141
4256
|
const maxValue = Math.max(leftExtent, rightExtent, 1);
|
|
4142
|
-
const longestLabelPx = Math.max(leftDisplay.length, rightDisplay.length) * valueFontSize * 0.
|
|
4257
|
+
const longestLabelPx = Math.max(leftDisplay.length, rightDisplay.length) * valueFontSize * 0.7;
|
|
4143
4258
|
const labelWidthPct = longestLabelPx / viewport.width * 100;
|
|
4144
|
-
const
|
|
4259
|
+
const marginX = 8;
|
|
4260
|
+
const maxBarWidth = Math.max(20, Math.min(65, 100 - marginX * 2 - labelWidthPct - 2));
|
|
4261
|
+
const barStartX = Math.max(marginX, (100 - (maxBarWidth + 2 + labelWidthPct)) / 2);
|
|
4145
4262
|
const leftBarWidth = leftExtent / maxValue * maxBarWidth;
|
|
4146
4263
|
const rightBarWidth = rightExtent / maxValue * maxBarWidth;
|
|
4147
4264
|
return [
|
|
@@ -4167,7 +4284,8 @@ function comparisonBar(input, context) {
|
|
|
4167
4284
|
color: theme.colors.textMuted
|
|
4168
4285
|
}
|
|
4169
4286
|
},
|
|
4170
|
-
position: { x: `${barStartX}%`, y: `${topBarY - 8}%` }
|
|
4287
|
+
position: { x: `${barStartX}%`, y: `${topBarY - 8}%` },
|
|
4288
|
+
...labelAnimation ? { animation: labelAnimation } : {}
|
|
4171
4289
|
},
|
|
4172
4290
|
// Top bar value
|
|
4173
4291
|
{
|
|
@@ -4183,7 +4301,7 @@ function comparisonBar(input, context) {
|
|
|
4183
4301
|
}
|
|
4184
4302
|
},
|
|
4185
4303
|
position: { x: `${barStartX + leftBarWidth + 2}%`, y: `${topBarY - 1}%` },
|
|
4186
|
-
animation: { type: "fadeIn", duration: 0.8, delay: 0.3 }
|
|
4304
|
+
animation: valueAnimation(leftDisplay, { type: "fadeIn", duration: 0.8, delay: 0.3 })
|
|
4187
4305
|
},
|
|
4188
4306
|
// Top bar
|
|
4189
4307
|
{
|
|
@@ -4200,7 +4318,7 @@ function comparisonBar(input, context) {
|
|
|
4200
4318
|
width: `${leftBarWidth}%`,
|
|
4201
4319
|
height: `${barHeight}%`
|
|
4202
4320
|
},
|
|
4203
|
-
animation: { type: "fadeIn", duration: 1 }
|
|
4321
|
+
animation: barAnimation({ type: "fadeIn", duration: 1 })
|
|
4204
4322
|
},
|
|
4205
4323
|
// Bottom bar label
|
|
4206
4324
|
{
|
|
@@ -4214,7 +4332,8 @@ function comparisonBar(input, context) {
|
|
|
4214
4332
|
color: theme.colors.textMuted
|
|
4215
4333
|
}
|
|
4216
4334
|
},
|
|
4217
|
-
position: { x: `${barStartX}%`, y: `${bottomBarY - 8}%` }
|
|
4335
|
+
position: { x: `${barStartX}%`, y: `${bottomBarY - 8}%` },
|
|
4336
|
+
...labelAnimation ? { animation: labelAnimation } : {}
|
|
4218
4337
|
},
|
|
4219
4338
|
// Bottom bar value
|
|
4220
4339
|
{
|
|
@@ -4230,7 +4349,7 @@ function comparisonBar(input, context) {
|
|
|
4230
4349
|
}
|
|
4231
4350
|
},
|
|
4232
4351
|
position: { x: `${barStartX + rightBarWidth + 2}%`, y: `${bottomBarY - 1}%` },
|
|
4233
|
-
animation: { type: "fadeIn", duration: 0.8, delay: 0.6 }
|
|
4352
|
+
animation: valueAnimation(rightDisplay, { type: "fadeIn", duration: 0.8, delay: 0.6 })
|
|
4234
4353
|
},
|
|
4235
4354
|
// Bottom bar
|
|
4236
4355
|
{
|
|
@@ -4247,7 +4366,7 @@ function comparisonBar(input, context) {
|
|
|
4247
4366
|
width: `${rightBarWidth}%`,
|
|
4248
4367
|
height: `${barHeight}%`
|
|
4249
4368
|
},
|
|
4250
|
-
animation: { type: "fadeIn", duration: 1, delay: 0.3 }
|
|
4369
|
+
animation: barAnimation({ type: "fadeIn", duration: 1, delay: 0.3 })
|
|
4251
4370
|
}
|
|
4252
4371
|
];
|
|
4253
4372
|
}
|
|
@@ -4328,7 +4447,7 @@ function pullQuoteLockup(options, context) {
|
|
|
4328
4447
|
anchor: "top-left",
|
|
4329
4448
|
width: `${COLUMN_WIDTH_PCT}%`
|
|
4330
4449
|
},
|
|
4331
|
-
animation:
|
|
4450
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 2 })
|
|
4332
4451
|
};
|
|
4333
4452
|
const layers = [];
|
|
4334
4453
|
if (showDeco) {
|
|
@@ -4373,7 +4492,7 @@ function pullQuoteLockup(options, context) {
|
|
|
4373
4492
|
anchor: "top-left",
|
|
4374
4493
|
width: `${COLUMN_WIDTH_PCT}%`
|
|
4375
4494
|
},
|
|
4376
|
-
animation: { type: "fadeIn", duration: 1, delay: 1.5 }
|
|
4495
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 1, delay: 1.5 })
|
|
4377
4496
|
});
|
|
4378
4497
|
}
|
|
4379
4498
|
return layers;
|
|
@@ -5478,7 +5597,7 @@ var PADDING = 80;
|
|
|
5478
5597
|
var CANVAS_PADDING = PADDING;
|
|
5479
5598
|
var CANVAS_TITLE_LINE_HEIGHT = 1.15;
|
|
5480
5599
|
var CANVAS_TITLE_MAX_LINES = 2;
|
|
5481
|
-
var CANVAS_TITLE_GAP_PX =
|
|
5600
|
+
var CANVAS_TITLE_GAP_PX = 60;
|
|
5482
5601
|
var CANVAS_DESCRIPTION_LINE_HEIGHT = 1.35;
|
|
5483
5602
|
var CANVAS_DESCRIPTION_MAX_LINES = 3;
|
|
5484
5603
|
var CANVAS_DESCRIPTION_GAP_PX = 28;
|
|
@@ -5782,6 +5901,16 @@ function diagramBlock(input, context) {
|
|
|
5782
5901
|
}
|
|
5783
5902
|
const containers = resolved.nodes.filter((n) => n.isContainer).sort((a, b) => a.depth - b.depth || a.y - b.y || a.x - b.x);
|
|
5784
5903
|
const leaves = resolved.nodes.filter((n) => !n.isContainer);
|
|
5904
|
+
const build = getMotionProfile(context).diagramBuild;
|
|
5905
|
+
const leafOrder = /* @__PURE__ */ new Map();
|
|
5906
|
+
[...leaves].sort((a, b) => a.y - b.y || a.x - b.x).forEach((node, index) => leafOrder.set(node.id, index));
|
|
5907
|
+
const containerDepth = new Map(containers.map((node) => [node.id, node.depth]));
|
|
5908
|
+
const nodeDelay = (id) => {
|
|
5909
|
+
const order = leafOrder.get(id);
|
|
5910
|
+
if (order !== void 0) return Number(Math.min(2, 0.2 + order * 0.12).toFixed(3));
|
|
5911
|
+
return Number((0.05 + (containerDepth.get(id) ?? 0) * 0.08).toFixed(3));
|
|
5912
|
+
};
|
|
5913
|
+
const at = (animation) => build ? { animation } : {};
|
|
5785
5914
|
for (const node of containers) {
|
|
5786
5915
|
const t = transform(node);
|
|
5787
5916
|
const card = {
|
|
@@ -5795,7 +5924,8 @@ function diagramBlock(input, context) {
|
|
|
5795
5924
|
strokeWidth: Math.max(1, strokeW - 1),
|
|
5796
5925
|
borderRadius: 10
|
|
5797
5926
|
},
|
|
5798
|
-
position: { x: t.x, y: t.y, width: t.w, height: t.h }
|
|
5927
|
+
position: { x: t.x, y: t.y, width: t.w, height: t.h },
|
|
5928
|
+
...at({ type: "fadeIn", duration: 0.5, delay: nodeDelay(node.id) })
|
|
5799
5929
|
};
|
|
5800
5930
|
layers.push(card);
|
|
5801
5931
|
}
|
|
@@ -5812,6 +5942,9 @@ function diagramBlock(input, context) {
|
|
|
5812
5942
|
const b = positions.get(edge.target);
|
|
5813
5943
|
if (!a || !b) continue;
|
|
5814
5944
|
const endMarker = edge.directed ? configuredEnd : "none";
|
|
5945
|
+
const edgeDelay = Number(
|
|
5946
|
+
(Math.max(nodeDelay(edge.source), nodeDelay(edge.target)) + 0.3).toFixed(3)
|
|
5947
|
+
);
|
|
5815
5948
|
const snapped = snapEndpoints(a, b);
|
|
5816
5949
|
const start = edge.sourceAnchor ? anchorPoint(a, edge.sourceAnchor) : snapped.start;
|
|
5817
5950
|
const end = edge.targetAnchor ? anchorPoint(b, edge.targetAnchor) : snapped.end;
|
|
@@ -5827,7 +5960,8 @@ function diagramBlock(input, context) {
|
|
|
5827
5960
|
...startMarker !== "none" ? { startMarker } : {},
|
|
5828
5961
|
...endMarker !== "none" ? { endMarker } : {}
|
|
5829
5962
|
},
|
|
5830
|
-
position: { x: 0, y: 0, width: "100%", height: "100%" }
|
|
5963
|
+
position: { x: 0, y: 0, width: "100%", height: "100%" },
|
|
5964
|
+
...at({ type: "drawOn", duration: 0.6, delay: edgeDelay })
|
|
5831
5965
|
};
|
|
5832
5966
|
layers.push(pathLayer);
|
|
5833
5967
|
if (edge.label) {
|
|
@@ -5846,7 +5980,8 @@ function diagramBlock(input, context) {
|
|
|
5846
5980
|
textAlign: "center"
|
|
5847
5981
|
}
|
|
5848
5982
|
},
|
|
5849
|
-
position: { x: mx, y: my - labelFontSize * 0.9, anchor: "center" }
|
|
5983
|
+
position: { x: mx, y: my - labelFontSize * 0.9, anchor: "center" },
|
|
5984
|
+
...at({ type: "fadeIn", duration: 0.4, delay: Number((edgeDelay + 0.5).toFixed(3)) })
|
|
5850
5985
|
};
|
|
5851
5986
|
layers.push(labelLayer);
|
|
5852
5987
|
}
|
|
@@ -5863,7 +5998,8 @@ function diagramBlock(input, context) {
|
|
|
5863
5998
|
strokeWidth: strokeW,
|
|
5864
5999
|
borderRadius: input.nodeShape === "pill" ? t.h / 2 : 10
|
|
5865
6000
|
},
|
|
5866
|
-
position: { x: t.x, y: t.y, width: t.w, height: t.h }
|
|
6001
|
+
position: { x: t.x, y: t.y, width: t.w, height: t.h },
|
|
6002
|
+
...at({ type: "grow", origin: "center", duration: 0.45, delay: nodeDelay(node.id) })
|
|
5867
6003
|
};
|
|
5868
6004
|
layers.push(card);
|
|
5869
6005
|
const preferredFontSize = themedFontSize(Math.round(22 * fontAdj), context, false);
|
|
@@ -5887,7 +6023,12 @@ function diagramBlock(input, context) {
|
|
|
5887
6023
|
y: t.y + t.h / 2 + fit.firstLineOffset,
|
|
5888
6024
|
anchor: "center",
|
|
5889
6025
|
width: fit.textWidth
|
|
5890
|
-
}
|
|
6026
|
+
},
|
|
6027
|
+
...at({
|
|
6028
|
+
type: "fadeIn",
|
|
6029
|
+
duration: 0.3,
|
|
6030
|
+
delay: Number((nodeDelay(node.id) + 0.15).toFixed(3))
|
|
6031
|
+
})
|
|
5891
6032
|
};
|
|
5892
6033
|
layers.push(label);
|
|
5893
6034
|
}
|
|
@@ -5907,7 +6048,8 @@ function diagramBlock(input, context) {
|
|
|
5907
6048
|
textAlign: "center"
|
|
5908
6049
|
}
|
|
5909
6050
|
},
|
|
5910
|
-
position: { x: t.x + t.w / 2, y: t.y + fontSize, anchor: "center", width: t.w }
|
|
6051
|
+
position: { x: t.x + t.w / 2, y: t.y + fontSize, anchor: "center", width: t.w },
|
|
6052
|
+
...at({ type: "fadeIn", duration: 0.4, delay: nodeDelay(node.id) })
|
|
5911
6053
|
};
|
|
5912
6054
|
layers.push(label);
|
|
5913
6055
|
}
|
|
@@ -6073,7 +6215,7 @@ function coerceLinks(raw, eventIds) {
|
|
|
6073
6215
|
}
|
|
6074
6216
|
return links;
|
|
6075
6217
|
}
|
|
6076
|
-
function diamondLayer(id, x, y, radius, color, delay) {
|
|
6218
|
+
function diamondLayer(id, x, y, radius, color, delay, build) {
|
|
6077
6219
|
return {
|
|
6078
6220
|
type: "path",
|
|
6079
6221
|
id,
|
|
@@ -6084,7 +6226,7 @@ function diamondLayer(id, x, y, radius, color, delay) {
|
|
|
6084
6226
|
strokeWidth: 2
|
|
6085
6227
|
},
|
|
6086
6228
|
position: { x: x - radius, y: y - radius, width: radius * 2, height: radius * 2 },
|
|
6087
|
-
animation: { type: "zoomIn", duration: 0.35, delay }
|
|
6229
|
+
animation: build ? { type: "grow", origin: "center", duration: 0.35, delay } : { type: "zoomIn", duration: 0.35, delay }
|
|
6088
6230
|
};
|
|
6089
6231
|
}
|
|
6090
6232
|
function branchPath(source, target, bend) {
|
|
@@ -6102,10 +6244,22 @@ function timelineBlock(input, context) {
|
|
|
6102
6244
|
const colors = resolveColorScheme(context, input.colorScheme);
|
|
6103
6245
|
const tracks = coerceTracks(input.tracks);
|
|
6104
6246
|
const layers = [createBackgroundLayer("bg", themedSurfaceGradient(context, 165))];
|
|
6105
|
-
const
|
|
6106
|
-
const
|
|
6107
|
-
const
|
|
6108
|
-
const
|
|
6247
|
+
const build = getMotionProfile(context).diagramBuild;
|
|
6248
|
+
const strokeIn = (duration, delay, fallbackDuration) => build ? { type: "drawOn", duration, delay } : { type: "fadeIn", duration: fallbackDuration, delay };
|
|
6249
|
+
const titleFontSize = themedFontSize(52, context, true);
|
|
6250
|
+
const trackFontSize = themedFontSize(26, context, false);
|
|
6251
|
+
const baseEventFontSize = themedFontSize(28, context, false);
|
|
6252
|
+
const baseDescriptionFontSize = themedFontSize(20, context, false);
|
|
6253
|
+
const trackCount = Math.max(1, tracks.length);
|
|
6254
|
+
const viewportScale = Math.min(viewport.width, viewport.height) / 1080;
|
|
6255
|
+
const calloutExtent = 78 + Math.min(baseEventFontSize, 28 * viewportScale) * 1.4 + Math.min(baseDescriptionFontSize, 20 * viewportScale) * 1.4 * 2 + 28;
|
|
6256
|
+
const naturalBand = calloutExtent * 2 + 24;
|
|
6257
|
+
const titleBlock2 = input.title ? titleFontSize * 1.3 + 40 : 0;
|
|
6258
|
+
const maxTracksHeight = viewport.height * 0.82 - titleBlock2;
|
|
6259
|
+
const trackBand = Math.max(120, Math.min(naturalBand, maxTracksHeight / trackCount));
|
|
6260
|
+
const groupHeight = titleBlock2 + trackBand * trackCount;
|
|
6261
|
+
const groupTop = Math.max(viewport.height * 0.06, (viewport.height - groupHeight) / 2);
|
|
6262
|
+
const contentTop = groupTop + titleBlock2;
|
|
6109
6263
|
if (input.title) {
|
|
6110
6264
|
layers.push({
|
|
6111
6265
|
type: "text",
|
|
@@ -6121,8 +6275,8 @@ function timelineBlock(input, context) {
|
|
|
6121
6275
|
shadow: shouldUseShadow(context)
|
|
6122
6276
|
}
|
|
6123
6277
|
},
|
|
6124
|
-
position: { x: "50%", y:
|
|
6125
|
-
animation: { type: "fadeIn", duration: 0.7 }
|
|
6278
|
+
position: { x: "50%", y: groupTop + titleFontSize * 0.65, width: "82%", anchor: "center" },
|
|
6279
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.7 })
|
|
6126
6280
|
});
|
|
6127
6281
|
}
|
|
6128
6282
|
if (tracks.length === 0) {
|
|
@@ -6148,10 +6302,6 @@ function timelineBlock(input, context) {
|
|
|
6148
6302
|
const axisStartX = outerMargin + labelWidth;
|
|
6149
6303
|
const axisEndX = viewport.width - outerMargin;
|
|
6150
6304
|
const axisWidth = Math.max(1, axisEndX - axisStartX);
|
|
6151
|
-
const contentTop = input.title ? Math.max(titleFontSize * 2.2, viewport.height * 0.2) : viewport.height * 0.09;
|
|
6152
|
-
const contentBottom = viewport.height * 0.91;
|
|
6153
|
-
const availableHeight = Math.max(1, contentBottom - contentTop);
|
|
6154
|
-
const trackBand = availableHeight / tracks.length;
|
|
6155
6305
|
const markerRadius = Math.max(6, Math.min(11, Math.min(viewport.width, viewport.height) / 105));
|
|
6156
6306
|
const trackColor = withAlpha(colors.text ?? theme.colors.primary, 0.72);
|
|
6157
6307
|
const accentColor = colors.accent ?? theme.colors.primary;
|
|
@@ -6166,8 +6316,8 @@ function timelineBlock(input, context) {
|
|
|
6166
6316
|
Math.min(330, axisWidth / Math.min(maxCalloutEvents, 4) * 0.86)
|
|
6167
6317
|
);
|
|
6168
6318
|
const minViewportScale = Math.min(viewport.width, viewport.height) / 1080;
|
|
6169
|
-
const eventFontSize = Math.min(baseEventFontSize,
|
|
6170
|
-
const descriptionFontSize = Math.min(baseDescriptionFontSize,
|
|
6319
|
+
const eventFontSize = Math.min(baseEventFontSize, 28 * minViewportScale);
|
|
6320
|
+
const descriptionFontSize = Math.min(baseDescriptionFontSize, 20 * minViewportScale);
|
|
6171
6321
|
const trackMarkerRadii = tracks.map((track) => {
|
|
6172
6322
|
const positions = track.events.map((event) => clamp012(event.position)).sort((a, b) => a - b);
|
|
6173
6323
|
let minGapPx = Number.POSITIVE_INFINITY;
|
|
@@ -6193,7 +6343,7 @@ function timelineBlock(input, context) {
|
|
|
6193
6343
|
endMarker: "arrow"
|
|
6194
6344
|
},
|
|
6195
6345
|
position: { x: axisStartX, y: y - markerRadius, width: axisWidth, height: markerRadius * 2 },
|
|
6196
|
-
animation:
|
|
6346
|
+
animation: strokeIn(0.9, trackDelay, 0.65)
|
|
6197
6347
|
};
|
|
6198
6348
|
layers.push(line);
|
|
6199
6349
|
if (track.label) {
|
|
@@ -6216,7 +6366,7 @@ function timelineBlock(input, context) {
|
|
|
6216
6366
|
width: Math.max(1, labelWidth - 32),
|
|
6217
6367
|
anchor: "center"
|
|
6218
6368
|
},
|
|
6219
|
-
animation: { type: "fadeIn", duration: 0.5, delay: trackDelay }
|
|
6369
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.5, delay: trackDelay })
|
|
6220
6370
|
};
|
|
6221
6371
|
layers.push(label);
|
|
6222
6372
|
}
|
|
@@ -6240,7 +6390,7 @@ function timelineBlock(input, context) {
|
|
|
6240
6390
|
width: Math.max(48, outerMargin - markerRadius * 2),
|
|
6241
6391
|
anchor: "top-left"
|
|
6242
6392
|
},
|
|
6243
|
-
animation: { type: "fadeIn", duration: 0.5, delay: trackDelay }
|
|
6393
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.5, delay: trackDelay })
|
|
6244
6394
|
});
|
|
6245
6395
|
}
|
|
6246
6396
|
track.events.forEach((event, eventIndex) => {
|
|
@@ -6272,7 +6422,7 @@ function timelineBlock(input, context) {
|
|
|
6272
6422
|
endMarker: "arrow"
|
|
6273
6423
|
},
|
|
6274
6424
|
position: { x: 0, y: 0, width: "100%", height: "100%" },
|
|
6275
|
-
animation:
|
|
6425
|
+
animation: strokeIn(0.6, 0.45 + linkIndex * 0.08, 0.6)
|
|
6276
6426
|
});
|
|
6277
6427
|
if (link.label) {
|
|
6278
6428
|
const sameTrack = source.trackIndex === target.trackIndex;
|
|
@@ -6330,7 +6480,11 @@ function timelineBlock(input, context) {
|
|
|
6330
6480
|
height: linkLabelHeight,
|
|
6331
6481
|
anchor: "center"
|
|
6332
6482
|
},
|
|
6333
|
-
animation:
|
|
6483
|
+
animation: motionEntrance(context, {
|
|
6484
|
+
type: "fadeIn",
|
|
6485
|
+
duration: 0.5,
|
|
6486
|
+
delay: 0.55 + linkIndex * 0.08
|
|
6487
|
+
})
|
|
6334
6488
|
});
|
|
6335
6489
|
}
|
|
6336
6490
|
});
|
|
@@ -6360,7 +6514,7 @@ function timelineBlock(input, context) {
|
|
|
6360
6514
|
width: Math.max(2, Math.abs(calloutX - x)),
|
|
6361
6515
|
height: Math.max(2, Math.abs(endY - y))
|
|
6362
6516
|
},
|
|
6363
|
-
animation:
|
|
6517
|
+
animation: strokeIn(0.35, stemDelay, 0.4)
|
|
6364
6518
|
});
|
|
6365
6519
|
};
|
|
6366
6520
|
if (event.callout !== false) {
|
|
@@ -6384,7 +6538,8 @@ function timelineBlock(input, context) {
|
|
|
6384
6538
|
y,
|
|
6385
6539
|
pointMarkerRadius,
|
|
6386
6540
|
accentColor,
|
|
6387
|
-
delay
|
|
6541
|
+
delay,
|
|
6542
|
+
build
|
|
6388
6543
|
)
|
|
6389
6544
|
);
|
|
6390
6545
|
} else {
|
|
@@ -6403,7 +6558,7 @@ function timelineBlock(input, context) {
|
|
|
6403
6558
|
width: pointMarkerRadius * 2,
|
|
6404
6559
|
height: pointMarkerRadius * 2
|
|
6405
6560
|
},
|
|
6406
|
-
animation: { type: "zoomIn", duration: 0.35, delay }
|
|
6561
|
+
animation: build ? { type: "grow", origin: "center", duration: 0.35, delay } : { type: "zoomIn", duration: 0.35, delay }
|
|
6407
6562
|
};
|
|
6408
6563
|
layers.push(dot);
|
|
6409
6564
|
}
|
|
@@ -6437,7 +6592,7 @@ function timelineBlock(input, context) {
|
|
|
6437
6592
|
}
|
|
6438
6593
|
},
|
|
6439
6594
|
position: { x: calloutX, y: labelY, width: calloutWidth, anchor: "center" },
|
|
6440
|
-
animation: { type: "fadeIn", duration: 0.5, delay: delay + 0.08 }
|
|
6595
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.5, delay: delay + 0.08 })
|
|
6441
6596
|
});
|
|
6442
6597
|
if (event.description) {
|
|
6443
6598
|
const descriptionSide = event.descriptionSide ?? side;
|
|
@@ -6486,7 +6641,11 @@ function timelineBlock(input, context) {
|
|
|
6486
6641
|
}
|
|
6487
6642
|
},
|
|
6488
6643
|
position: { x: calloutX, y: descriptionY, width: calloutWidth, anchor: "center" },
|
|
6489
|
-
animation:
|
|
6644
|
+
animation: motionEntrance(context, {
|
|
6645
|
+
type: "fadeIn",
|
|
6646
|
+
duration: 0.5,
|
|
6647
|
+
delay: delay + 0.14
|
|
6648
|
+
})
|
|
6490
6649
|
});
|
|
6491
6650
|
}
|
|
6492
6651
|
}
|
|
@@ -7699,12 +7858,13 @@ function stackSeries(series) {
|
|
|
7699
7858
|
})
|
|
7700
7859
|
);
|
|
7701
7860
|
}
|
|
7861
|
+
var CHART_CHAR_WIDTH_EM = 0.62;
|
|
7702
7862
|
function layoutLegend(labels, fontSize, maxWidth) {
|
|
7703
7863
|
const swatchSize = fontSize * 0.9;
|
|
7704
|
-
const gap = fontSize *
|
|
7864
|
+
const gap = fontSize * 2.2;
|
|
7705
7865
|
const rowHeight = fontSize * 2;
|
|
7706
7866
|
const widths = labels.map(
|
|
7707
|
-
(label) => swatchSize + fontSize * 0.5 + label.length * fontSize *
|
|
7867
|
+
(label) => swatchSize + fontSize * 0.5 + label.length * fontSize * CHART_CHAR_WIDTH_EM
|
|
7708
7868
|
);
|
|
7709
7869
|
const rows = [];
|
|
7710
7870
|
let current = [];
|
|
@@ -7758,10 +7918,10 @@ function renderChart(kind, input, context) {
|
|
|
7758
7918
|
const { theme, viewport } = context;
|
|
7759
7919
|
const templateId = TEMPLATE_ID[kind];
|
|
7760
7920
|
const title = (input.title ?? "").trim();
|
|
7761
|
-
const titleFontSize = themedFontSize(
|
|
7762
|
-
const axisFontSize = themedFontSize(
|
|
7763
|
-
const labelFontSize = themedFontSize(
|
|
7764
|
-
const legendFontSize = themedFontSize(
|
|
7921
|
+
const titleFontSize = themedFontSize(52, context, true);
|
|
7922
|
+
const axisFontSize = themedFontSize(24, context, false);
|
|
7923
|
+
const labelFontSize = themedFontSize(26, context, false);
|
|
7924
|
+
const legendFontSize = themedFontSize(26, context, false);
|
|
7765
7925
|
const tableFontSize = themedFontSize(20, context, false);
|
|
7766
7926
|
const bodyFont = getThemeFont(context, "body");
|
|
7767
7927
|
const isRadial = kind === "pie" || kind === "donut";
|
|
@@ -7790,11 +7950,55 @@ function renderChart(kind, input, context) {
|
|
|
7790
7950
|
tableFontSize
|
|
7791
7951
|
});
|
|
7792
7952
|
const entranceHint = getTemplateHint(context, templateId, "entrance", "staggered");
|
|
7953
|
+
const markDelay = (index) => entranceHint === "subtle" ? 0.1 : Math.min(1.2, 0.2 + index * 0.08);
|
|
7793
7954
|
const entrance = (index) => ({
|
|
7794
7955
|
type: "fadeIn",
|
|
7795
7956
|
duration: 0.6,
|
|
7796
|
-
delay:
|
|
7957
|
+
delay: markDelay(index)
|
|
7797
7958
|
});
|
|
7959
|
+
const motion = getMotionProfile(context);
|
|
7960
|
+
const growDuration = motion.chartGrowthDuration;
|
|
7961
|
+
const growEasing = motion.textEntrance.easing;
|
|
7962
|
+
const eased = (animation) => growEasing ? { ...animation, easing: growEasing } : animation;
|
|
7963
|
+
const mark = (index, kind2, along = 0) => {
|
|
7964
|
+
if (!motion.chartGrowth) return entrance(index);
|
|
7965
|
+
const delay = motionDelay(context, markDelay(index));
|
|
7966
|
+
switch (kind2) {
|
|
7967
|
+
case "bar":
|
|
7968
|
+
return eased({ type: "grow", origin: "left", duration: growDuration, delay });
|
|
7969
|
+
case "bar-negative":
|
|
7970
|
+
return eased({ type: "grow", origin: "right", duration: growDuration, delay });
|
|
7971
|
+
case "column":
|
|
7972
|
+
return eased({ type: "grow", origin: "bottom", duration: growDuration, delay });
|
|
7973
|
+
case "column-negative":
|
|
7974
|
+
return eased({ type: "grow", origin: "top", duration: growDuration, delay });
|
|
7975
|
+
case "line":
|
|
7976
|
+
return { type: "drawOn", duration: growDuration * 1.4, delay };
|
|
7977
|
+
case "area":
|
|
7978
|
+
return { type: "reveal", origin: "left", duration: growDuration * 1.4, delay };
|
|
7979
|
+
case "point":
|
|
7980
|
+
return {
|
|
7981
|
+
type: "grow",
|
|
7982
|
+
origin: "center",
|
|
7983
|
+
duration: 0.35,
|
|
7984
|
+
delay: Number((delay + growDuration * 1.4 * along).toFixed(3))
|
|
7985
|
+
};
|
|
7986
|
+
case "wedge":
|
|
7987
|
+
return eased({
|
|
7988
|
+
type: "grow",
|
|
7989
|
+
origin: "center",
|
|
7990
|
+
duration: Math.max(0.4, growDuration * 0.6),
|
|
7991
|
+
delay
|
|
7992
|
+
});
|
|
7993
|
+
case "dot":
|
|
7994
|
+
return eased({ type: "grow", origin: "center", duration: 0.4, delay });
|
|
7995
|
+
}
|
|
7996
|
+
};
|
|
7997
|
+
const labelAnimation = (index, fallback, along = 0) => {
|
|
7998
|
+
if (!motion.chartGrowth) return fallback;
|
|
7999
|
+
const settled = motionDelay(context, markDelay(index)) + growDuration * (along > 0 ? 1.4 * along : 1);
|
|
8000
|
+
return { type: "fadeIn", duration: 0.4, delay: Number(settled.toFixed(3)) };
|
|
8001
|
+
};
|
|
7798
8002
|
const paint = {
|
|
7799
8003
|
kind,
|
|
7800
8004
|
input,
|
|
@@ -7807,7 +8011,9 @@ function renderChart(kind, input, context) {
|
|
|
7807
8011
|
bodyFont,
|
|
7808
8012
|
gridColor: withAlpha(theme.colors.text, 0.12),
|
|
7809
8013
|
axisTextColor: theme.colors.textMuted,
|
|
7810
|
-
entrance
|
|
8014
|
+
entrance,
|
|
8015
|
+
mark,
|
|
8016
|
+
labelAnimation
|
|
7811
8017
|
};
|
|
7812
8018
|
const layers = [createBackgroundLayer("bg", themedSurfaceGradient(context, 170))];
|
|
7813
8019
|
if (title && frame.titleBand) {
|
|
@@ -7831,7 +8037,7 @@ function renderChart(kind, input, context) {
|
|
|
7831
8037
|
width: frame.titleBand.width,
|
|
7832
8038
|
anchor: "center"
|
|
7833
8039
|
},
|
|
7834
|
-
animation: { type: "fadeIn", duration: 0.8 }
|
|
8040
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.8 })
|
|
7835
8041
|
});
|
|
7836
8042
|
}
|
|
7837
8043
|
switch (kind) {
|
|
@@ -8005,7 +8211,7 @@ function paintCategoryAxisX(paint, xForCenter) {
|
|
|
8005
8211
|
return layers;
|
|
8006
8212
|
}
|
|
8007
8213
|
function paintColumns(paint) {
|
|
8008
|
-
const { frame, data, colors, input,
|
|
8214
|
+
const { frame, data, colors, input, mark, labelAnimation } = paint;
|
|
8009
8215
|
const scale = valueTicks("column", data, input);
|
|
8010
8216
|
const yFor = (v) => frame.plot.y + frame.plot.height * (1 - (v - scale.niceMin) / (scale.niceMax - scale.niceMin));
|
|
8011
8217
|
const layers = paintValueAxisY(paint, scale, yFor);
|
|
@@ -8030,7 +8236,7 @@ function paintColumns(paint) {
|
|
|
8030
8236
|
id: `mark-${s}-${i}`,
|
|
8031
8237
|
content: { shape: "rect", fill: colors[s], borderRadius: stacked ? 0 : 3 },
|
|
8032
8238
|
position: { x, y: top, width: barWidth, height },
|
|
8033
|
-
animation:
|
|
8239
|
+
animation: mark(i + s, extent.y1 <= 0 ? "column-negative" : "column")
|
|
8034
8240
|
});
|
|
8035
8241
|
if (input.showValues === true && value !== null && !stacked) {
|
|
8036
8242
|
layers.push(
|
|
@@ -8039,7 +8245,8 @@ function paintColumns(paint) {
|
|
|
8039
8245
|
`val-${s}-${i}`,
|
|
8040
8246
|
value,
|
|
8041
8247
|
x + barWidth / 2,
|
|
8042
|
-
value >= 0 ? top - paint.axisFontSize * 0.9 : top + height + paint.axisFontSize * 0.9
|
|
8248
|
+
value >= 0 ? top - paint.axisFontSize * 0.9 : top + height + paint.axisFontSize * 0.9,
|
|
8249
|
+
labelAnimation(i + s)
|
|
8043
8250
|
)
|
|
8044
8251
|
);
|
|
8045
8252
|
}
|
|
@@ -8053,7 +8260,8 @@ function paintBars(paint) {
|
|
|
8053
8260
|
data,
|
|
8054
8261
|
colors,
|
|
8055
8262
|
input,
|
|
8056
|
-
|
|
8263
|
+
mark,
|
|
8264
|
+
labelAnimation,
|
|
8057
8265
|
labelFontSize,
|
|
8058
8266
|
axisFontSize,
|
|
8059
8267
|
bodyFont,
|
|
@@ -8062,7 +8270,7 @@ function paintBars(paint) {
|
|
|
8062
8270
|
} = paint;
|
|
8063
8271
|
const scale = valueTicks("bar", data, input);
|
|
8064
8272
|
const labelGap = axisFontSize * 0.6;
|
|
8065
|
-
const labelWidthPx = (value) => formatChartValue(value, input.unit).length * axisFontSize *
|
|
8273
|
+
const labelWidthPx = (value) => formatChartValue(value, input.unit).length * axisFontSize * CHART_CHAR_WIDTH_EM;
|
|
8066
8274
|
const showValueLabels = input.showValues === true && !(input.stacked === true);
|
|
8067
8275
|
const reservedForLabels = showValueLabels ? data.series.flatMap((series) => series.values).filter((v) => v !== null).reduce((max, v) => Math.max(max, labelWidthPx(v)), 0) + labelGap : 0;
|
|
8068
8276
|
const axisWidth = Math.max(20, frame.plot.width - reservedForLabels);
|
|
@@ -8140,19 +8348,28 @@ function paintBars(paint) {
|
|
|
8140
8348
|
id: `mark-${s}-${i}`,
|
|
8141
8349
|
content: { shape: "rect", fill: colors[s], borderRadius: stacked ? 0 : 3 },
|
|
8142
8350
|
position: { x: left, y, width, height: barHeight },
|
|
8143
|
-
animation:
|
|
8351
|
+
animation: mark(i + s, extent.y1 <= 0 ? "bar-negative" : "bar")
|
|
8144
8352
|
});
|
|
8145
8353
|
if (showValueLabels && value !== null) {
|
|
8146
8354
|
const half = labelWidthPx(value) / 2;
|
|
8147
8355
|
const labelX = value >= 0 ? left + width + labelGap + half : left - labelGap - half;
|
|
8148
|
-
layers.push(
|
|
8356
|
+
layers.push(
|
|
8357
|
+
valueLabel(
|
|
8358
|
+
paint,
|
|
8359
|
+
`val-${s}-${i}`,
|
|
8360
|
+
value,
|
|
8361
|
+
labelX,
|
|
8362
|
+
y + barHeight / 2,
|
|
8363
|
+
labelAnimation(i + s)
|
|
8364
|
+
)
|
|
8365
|
+
);
|
|
8149
8366
|
}
|
|
8150
8367
|
});
|
|
8151
8368
|
});
|
|
8152
8369
|
return layers;
|
|
8153
8370
|
}
|
|
8154
8371
|
function paintRadial(paint) {
|
|
8155
|
-
const { kind, frame, data, colors, input, entrance, context } = paint;
|
|
8372
|
+
const { kind, frame, data, colors, input, entrance, mark, labelAnimation, context } = paint;
|
|
8156
8373
|
const slices = data.labels.map((label, index) => ({ label, value: data.series[0].values[index], index })).filter(
|
|
8157
8374
|
(s) => s.value !== null && Number.isFinite(s.value) && s.value > 0
|
|
8158
8375
|
);
|
|
@@ -8175,7 +8392,7 @@ function paintRadial(paint) {
|
|
|
8175
8392
|
strokeWidth: 2
|
|
8176
8393
|
},
|
|
8177
8394
|
position: { x: cx - rOuter, y: cy - rOuter, width: rOuter * 2, height: rOuter * 2 },
|
|
8178
|
-
animation:
|
|
8395
|
+
animation: mark(order, "wedge")
|
|
8179
8396
|
});
|
|
8180
8397
|
if (input.showValues === true && sweep >= 14) {
|
|
8181
8398
|
const mid = startDeg + sweep / 2;
|
|
@@ -8200,7 +8417,7 @@ function paintRadial(paint) {
|
|
|
8200
8417
|
y: cy + rLabel * Math.sin(rad),
|
|
8201
8418
|
anchor: "center"
|
|
8202
8419
|
},
|
|
8203
|
-
animation: entrance(order)
|
|
8420
|
+
animation: labelAnimation(order, entrance(order))
|
|
8204
8421
|
});
|
|
8205
8422
|
}
|
|
8206
8423
|
startDeg += sweep;
|
|
@@ -8208,7 +8425,7 @@ function paintRadial(paint) {
|
|
|
8208
8425
|
return layers;
|
|
8209
8426
|
}
|
|
8210
8427
|
function paintLines(paint) {
|
|
8211
|
-
const { kind, frame, data, colors, input,
|
|
8428
|
+
const { kind, frame, data, colors, input, mark, labelAnimation } = paint;
|
|
8212
8429
|
const scale = valueTicks(kind, data, input);
|
|
8213
8430
|
const yFor = (v) => frame.plot.y + frame.plot.height * (1 - (v - scale.niceMin) / (scale.niceMax - scale.niceMin));
|
|
8214
8431
|
const n = data.labels.length;
|
|
@@ -8249,7 +8466,7 @@ function paintLines(paint) {
|
|
|
8249
8466
|
width: frame.plot.width,
|
|
8250
8467
|
height: frame.plot.height
|
|
8251
8468
|
},
|
|
8252
|
-
animation:
|
|
8469
|
+
animation: mark(s, "area")
|
|
8253
8470
|
});
|
|
8254
8471
|
}
|
|
8255
8472
|
if (segment.length > 1) {
|
|
@@ -8263,7 +8480,7 @@ function paintLines(paint) {
|
|
|
8263
8480
|
width: frame.plot.width,
|
|
8264
8481
|
height: frame.plot.height
|
|
8265
8482
|
},
|
|
8266
|
-
animation:
|
|
8483
|
+
animation: mark(s, "line")
|
|
8267
8484
|
});
|
|
8268
8485
|
}
|
|
8269
8486
|
});
|
|
@@ -8276,7 +8493,7 @@ function paintLines(paint) {
|
|
|
8276
8493
|
id: `pt-${s}-${i}`,
|
|
8277
8494
|
content: { shape: "circle", fill: colors[s] },
|
|
8278
8495
|
position: { x: xForCenter(i) - r, y: yFor(value) - r, width: r * 2, height: r * 2 },
|
|
8279
|
-
animation:
|
|
8496
|
+
animation: mark(s, "point", i / Math.max(1, n - 1))
|
|
8280
8497
|
});
|
|
8281
8498
|
if (input.showValues === true) {
|
|
8282
8499
|
layers.push(
|
|
@@ -8285,7 +8502,8 @@ function paintLines(paint) {
|
|
|
8285
8502
|
`val-${s}-${i}`,
|
|
8286
8503
|
value,
|
|
8287
8504
|
xForCenter(i),
|
|
8288
|
-
yFor(value) - paint.axisFontSize
|
|
8505
|
+
yFor(value) - paint.axisFontSize,
|
|
8506
|
+
labelAnimation(s, void 0, i / Math.max(1, n - 1))
|
|
8289
8507
|
)
|
|
8290
8508
|
);
|
|
8291
8509
|
}
|
|
@@ -8295,7 +8513,7 @@ function paintLines(paint) {
|
|
|
8295
8513
|
return layers;
|
|
8296
8514
|
}
|
|
8297
8515
|
function paintScatter(paint) {
|
|
8298
|
-
const { frame, data, colors, input,
|
|
8516
|
+
const { frame, data, colors, input, mark } = paint;
|
|
8299
8517
|
const scale = valueTicks("scatter", data, input);
|
|
8300
8518
|
const yFor = (v) => frame.plot.y + frame.plot.height * (1 - (v - scale.niceMin) / (scale.niceMax - scale.niceMin));
|
|
8301
8519
|
const layers = paintValueAxisY(paint, scale, yFor);
|
|
@@ -8353,7 +8571,7 @@ function paintScatter(paint) {
|
|
|
8353
8571
|
id: `mark-${s}-${i}`,
|
|
8354
8572
|
content: { shape: "circle", fill: colors[s], fillOpacity: 0.85 },
|
|
8355
8573
|
position: { x: x - r, y: yFor(value) - r, width: r * 2, height: r * 2 },
|
|
8356
|
-
animation:
|
|
8574
|
+
animation: mark(Math.floor(i / 3) + s, "dot")
|
|
8357
8575
|
});
|
|
8358
8576
|
});
|
|
8359
8577
|
});
|
|
@@ -8390,7 +8608,7 @@ function paintLegend(paint, legend, band, fontSize) {
|
|
|
8390
8608
|
});
|
|
8391
8609
|
return layers;
|
|
8392
8610
|
}
|
|
8393
|
-
function valueLabel(paint, id, value, x, y) {
|
|
8611
|
+
function valueLabel(paint, id, value, x, y, animation) {
|
|
8394
8612
|
return {
|
|
8395
8613
|
type: "text",
|
|
8396
8614
|
id,
|
|
@@ -8404,7 +8622,8 @@ function valueLabel(paint, id, value, x, y) {
|
|
|
8404
8622
|
textAlign: "center"
|
|
8405
8623
|
}
|
|
8406
8624
|
},
|
|
8407
|
-
position: { x, y, anchor: "center" }
|
|
8625
|
+
position: { x, y, anchor: "center" },
|
|
8626
|
+
...animation ? { animation } : {}
|
|
8408
8627
|
};
|
|
8409
8628
|
}
|
|
8410
8629
|
function tableLayer(table, band, fontSize, input, context) {
|
|
@@ -8729,6 +8948,25 @@ function avatarLayers(idPrefix, name, imageSrc, x, y, context) {
|
|
|
8729
8948
|
}
|
|
8730
8949
|
|
|
8731
8950
|
// src/doc/templates/registry.ts
|
|
8951
|
+
var GEOMETRY_BOUND_TEMPLATES = /* @__PURE__ */ new Set([
|
|
8952
|
+
"barChart",
|
|
8953
|
+
"columnChart",
|
|
8954
|
+
"lineChart",
|
|
8955
|
+
"areaChart",
|
|
8956
|
+
"pieChart",
|
|
8957
|
+
"donutChart",
|
|
8958
|
+
"scatterChart",
|
|
8959
|
+
"comparisonBar",
|
|
8960
|
+
"timeline",
|
|
8961
|
+
"diagram",
|
|
8962
|
+
"drawing",
|
|
8963
|
+
"tree",
|
|
8964
|
+
"map",
|
|
8965
|
+
"dataTable"
|
|
8966
|
+
]);
|
|
8967
|
+
function isGeometryBoundTemplate(template) {
|
|
8968
|
+
return template !== void 0 && GEOMETRY_BOUND_TEMPLATES.has(template);
|
|
8969
|
+
}
|
|
8732
8970
|
var templateRegistry = {
|
|
8733
8971
|
title: titleBlock,
|
|
8734
8972
|
sectionHeader,
|
|
@@ -9412,7 +9650,7 @@ function materializeBlockLayersWithRuntime(block, options, runtime) {
|
|
|
9412
9650
|
source: layers.length > 0 ? "rich-content" : "empty"
|
|
9413
9651
|
};
|
|
9414
9652
|
}
|
|
9415
|
-
const context = runtime.templateContext ? cloneData(runtime.templateContext) : createTemplateContext(theme, blockIndex, totalBlocks, viewport);
|
|
9653
|
+
const context = runtime.templateContext ? cloneData(runtime.templateContext) : createTemplateContext(theme, blockIndex, totalBlocks, viewport, { motion: options.motion });
|
|
9416
9654
|
context.block = cloneData(block);
|
|
9417
9655
|
const execution = executeTemplateMaterialization(block, context, runtime.registry);
|
|
9418
9656
|
if (execution.status === "ok") {
|
|
@@ -10297,8 +10535,9 @@ function coverBlock(input, context) {
|
|
|
10297
10535
|
anchor: "center",
|
|
10298
10536
|
width: layout.maxTextWidth
|
|
10299
10537
|
},
|
|
10300
|
-
// No animation delay - shown immediately at rest
|
|
10301
|
-
|
|
10538
|
+
// No animation delay - shown immediately at rest. Word-by-word reveal is
|
|
10539
|
+
// a profile opt-in (off by default: the cover doubles as the poster).
|
|
10540
|
+
animation: getMotionProfile(context).coverWordReveal ? { type: "wordReveal", duration: 0.5, delay: 0.1, stagger: 0.12 } : { type: "fadeIn", duration: 0.8 }
|
|
10302
10541
|
});
|
|
10303
10542
|
if (subtitle) {
|
|
10304
10543
|
layers.push({
|
|
@@ -10321,7 +10560,7 @@ function coverBlock(input, context) {
|
|
|
10321
10560
|
anchor: "center",
|
|
10322
10561
|
width: layout.maxTextWidth
|
|
10323
10562
|
},
|
|
10324
|
-
animation: { type: "fadeIn", duration: 0.8, delay: 0.2 }
|
|
10563
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.8, delay: 0.2 })
|
|
10325
10564
|
});
|
|
10326
10565
|
}
|
|
10327
10566
|
return layers;
|
|
@@ -10416,7 +10655,7 @@ function expandCoverBlock(config, context, template = "cover") {
|
|
|
10416
10655
|
}
|
|
10417
10656
|
|
|
10418
10657
|
// src/doc/templates/index.ts
|
|
10419
|
-
function materializeScheduledBlock(sourceBlock, blockIndex, totalBlocks, theme, viewport, persistentLayers, expandedPersistentLayers, registry, failureMode, onDiagnostic) {
|
|
10658
|
+
function materializeScheduledBlock(sourceBlock, blockIndex, totalBlocks, theme, viewport, persistentLayers, expandedPersistentLayers, registry, failureMode, onDiagnostic, motion) {
|
|
10420
10659
|
const materialized = materializeBlockLayersWithRuntime(
|
|
10421
10660
|
sourceBlock,
|
|
10422
10661
|
{
|
|
@@ -10425,7 +10664,8 @@ function materializeScheduledBlock(sourceBlock, blockIndex, totalBlocks, theme,
|
|
|
10425
10664
|
persistentLayers: persistentLayers ?? false,
|
|
10426
10665
|
blockIndex,
|
|
10427
10666
|
totalBlocks,
|
|
10428
|
-
failureMode
|
|
10667
|
+
failureMode,
|
|
10668
|
+
motion
|
|
10429
10669
|
},
|
|
10430
10670
|
{ registry, expandedPersistentLayers }
|
|
10431
10671
|
);
|
|
@@ -10461,7 +10701,8 @@ function expandDocBlocks(blocks, options = {}) {
|
|
|
10461
10701
|
failureMode = "fallback",
|
|
10462
10702
|
onDiagnostic,
|
|
10463
10703
|
splitLongBlocks = true,
|
|
10464
|
-
mergeShortBlocks = true
|
|
10704
|
+
mergeShortBlocks = true,
|
|
10705
|
+
motion
|
|
10465
10706
|
} = opts;
|
|
10466
10707
|
const totalBlocks = blocks.length;
|
|
10467
10708
|
const registry = customTemplates && customTemplates.length > 0 ? buildRegistry(customTemplates) : templateRegistry;
|
|
@@ -10483,7 +10724,8 @@ function expandDocBlocks(blocks, options = {}) {
|
|
|
10483
10724
|
expandedPersistentLayers,
|
|
10484
10725
|
registry,
|
|
10485
10726
|
failureMode,
|
|
10486
|
-
onDiagnostic
|
|
10727
|
+
onDiagnostic,
|
|
10728
|
+
motion
|
|
10487
10729
|
);
|
|
10488
10730
|
expandedBlock.startTime = currentTime;
|
|
10489
10731
|
currentTime += expandedBlock.duration;
|
|
@@ -10515,7 +10757,8 @@ function expandDocBlocks(blocks, options = {}) {
|
|
|
10515
10757
|
expandedPersistentLayers,
|
|
10516
10758
|
registry,
|
|
10517
10759
|
failureMode,
|
|
10518
|
-
onDiagnostic
|
|
10760
|
+
onDiagnostic,
|
|
10761
|
+
motion
|
|
10519
10762
|
);
|
|
10520
10763
|
expandedBlock.startTime = offsetTime;
|
|
10521
10764
|
offsetTime += expandedBlock.duration;
|
|
@@ -10553,7 +10796,8 @@ function expandDocBlocks(blocks, options = {}) {
|
|
|
10553
10796
|
expandedPersistentLayers,
|
|
10554
10797
|
registry,
|
|
10555
10798
|
failureMode,
|
|
10556
|
-
onDiagnostic
|
|
10799
|
+
onDiagnostic,
|
|
10800
|
+
motion
|
|
10557
10801
|
);
|
|
10558
10802
|
const templateBlock = block;
|
|
10559
10803
|
expandedInfos.push({
|
|
@@ -11669,6 +11913,7 @@ function markdownToDoc(markdownDoc, options) {
|
|
|
11669
11913
|
const customTemplates = readCustomTemplatesFromFrontmatter(markdownDoc.frontmatter);
|
|
11670
11914
|
const customThemes = readCustomThemesFromFrontmatter(markdownDoc.frontmatter);
|
|
11671
11915
|
const themeId = readFrontmatterThemeId(markdownDoc.frontmatter);
|
|
11916
|
+
const motion = readFrontmatterMotion(markdownDoc.frontmatter);
|
|
11672
11917
|
const doc = {
|
|
11673
11918
|
articleId,
|
|
11674
11919
|
duration: currentTime,
|
|
@@ -11679,6 +11924,7 @@ function markdownToDoc(markdownDoc, options) {
|
|
|
11679
11924
|
...captions ? { captions } : {},
|
|
11680
11925
|
...markdownDoc.frontmatter ? { frontmatter: markdownDoc.frontmatter } : {},
|
|
11681
11926
|
...themeId ? { themeId } : {},
|
|
11927
|
+
...motion ? { motion } : {},
|
|
11682
11928
|
...customTemplates ? { customTemplates } : {},
|
|
11683
11929
|
...customThemes ? { customThemes } : {},
|
|
11684
11930
|
...diagnostics.length > 0 ? { diagnostics } : {},
|
|
@@ -11987,6 +12233,9 @@ export {
|
|
|
11987
12233
|
scaleAnimationDuration,
|
|
11988
12234
|
getDefaultAnimation,
|
|
11989
12235
|
themedEntrance,
|
|
12236
|
+
getMotionProfile,
|
|
12237
|
+
motionEntrance,
|
|
12238
|
+
motionDelay,
|
|
11990
12239
|
shouldUseShadow,
|
|
11991
12240
|
getOverlayOpacity,
|
|
11992
12241
|
themedImageTreatment,
|
|
@@ -12028,6 +12277,10 @@ export {
|
|
|
12028
12277
|
autoTemplatePreservesContent,
|
|
12029
12278
|
deriveTemplateInputs,
|
|
12030
12279
|
contentBlock,
|
|
12280
|
+
parseStatNumber,
|
|
12281
|
+
countUpSpecFor,
|
|
12282
|
+
formatCountValue,
|
|
12283
|
+
formatCountUp,
|
|
12031
12284
|
statHighlight,
|
|
12032
12285
|
quoteBlock,
|
|
12033
12286
|
factCard,
|
|
@@ -12065,6 +12318,8 @@ export {
|
|
|
12065
12318
|
drawingBlock,
|
|
12066
12319
|
computeLayoutLayers,
|
|
12067
12320
|
layoutBlock,
|
|
12321
|
+
GEOMETRY_BOUND_TEMPLATES,
|
|
12322
|
+
isGeometryBoundTemplate,
|
|
12068
12323
|
templateRegistry,
|
|
12069
12324
|
buildRegistry,
|
|
12070
12325
|
themeWantsAmbientMotion,
|