@bendyline/squisq 2.11.9 → 2.11.11
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-DmElSKmg.d.ts → Doc-BWtfp7dT.d.ts} +207 -3
- package/dist/{ImageEditDoc-Dm_BETxC.d.ts → ImageEditDoc-CYRQK8so.d.ts} +1 -1
- package/dist/{chunk-YNO6JV36.js → chunk-2SRF5III.js} +4 -4
- package/dist/{chunk-QOVINAB2.js → chunk-42IU2SJY.js} +383 -114
- package/dist/{chunk-DTM4FG7S.js → chunk-7WN7DDMI.js} +1 -1
- package/dist/{chunk-2PGC4JDT.js → chunk-BR7ZMDWW.js} +1 -1
- package/dist/{chunk-CCRBHFNO.js → chunk-EWO2VLOS.js} +2 -2
- package/dist/{chunk-B5STNW6C.js → chunk-HVJ6VFDX.js} +2 -2
- package/dist/{chunk-PCCQLD3G.js → chunk-PFH3WV6J.js} +143 -3
- package/dist/{chunk-VRTXPGP7.js → chunk-S4427XKY.js} +98 -4
- package/dist/{chunk-QDA7NXDO.js → chunk-X2TDC4E5.js} +2 -2
- package/dist/doc/index.d.ts +103 -6
- 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 +47 -9
- package/dist/jsonForm/index.d.ts +1 -1
- package/dist/jsonForm/index.js +4 -4
- package/dist/{materializePageSection-BfttC9Zj.d.ts → materializePageSection-Db7pABI0.d.ts} +1 -1
- 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 +15 -3
- package/dist/{themeLibrary-ChnTImby.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
|
}
|
|
@@ -6010,6 +6152,13 @@ function treeBlock(input, context) {
|
|
|
6010
6152
|
return layers;
|
|
6011
6153
|
}
|
|
6012
6154
|
|
|
6155
|
+
// src/doc/utils/textMetrics.ts
|
|
6156
|
+
var AVERAGE_CHAR_WIDTH_EM = 0.62;
|
|
6157
|
+
var BOLD_CHAR_WIDTH_EM = 0.66;
|
|
6158
|
+
function estimateTextWidth(text, fontSize, charWidthEm = AVERAGE_CHAR_WIDTH_EM) {
|
|
6159
|
+
return text.length * fontSize * charWidthEm;
|
|
6160
|
+
}
|
|
6161
|
+
|
|
6013
6162
|
// src/doc/templates/timelineBlock.ts
|
|
6014
6163
|
var clamp012 = (value) => Math.max(0, Math.min(1, value));
|
|
6015
6164
|
var clamp = (value, min, max) => Math.max(min, Math.min(max, value));
|
|
@@ -6073,7 +6222,7 @@ function coerceLinks(raw, eventIds) {
|
|
|
6073
6222
|
}
|
|
6074
6223
|
return links;
|
|
6075
6224
|
}
|
|
6076
|
-
function diamondLayer(id, x, y, radius, color, delay) {
|
|
6225
|
+
function diamondLayer(id, x, y, radius, color, delay, build) {
|
|
6077
6226
|
return {
|
|
6078
6227
|
type: "path",
|
|
6079
6228
|
id,
|
|
@@ -6084,7 +6233,7 @@ function diamondLayer(id, x, y, radius, color, delay) {
|
|
|
6084
6233
|
strokeWidth: 2
|
|
6085
6234
|
},
|
|
6086
6235
|
position: { x: x - radius, y: y - radius, width: radius * 2, height: radius * 2 },
|
|
6087
|
-
animation: { type: "zoomIn", duration: 0.35, delay }
|
|
6236
|
+
animation: build ? { type: "grow", origin: "center", duration: 0.35, delay } : { type: "zoomIn", duration: 0.35, delay }
|
|
6088
6237
|
};
|
|
6089
6238
|
}
|
|
6090
6239
|
function branchPath(source, target, bend) {
|
|
@@ -6102,10 +6251,22 @@ function timelineBlock(input, context) {
|
|
|
6102
6251
|
const colors = resolveColorScheme(context, input.colorScheme);
|
|
6103
6252
|
const tracks = coerceTracks(input.tracks);
|
|
6104
6253
|
const layers = [createBackgroundLayer("bg", themedSurfaceGradient(context, 165))];
|
|
6105
|
-
const
|
|
6106
|
-
const
|
|
6107
|
-
const
|
|
6108
|
-
const
|
|
6254
|
+
const build = getMotionProfile(context).diagramBuild;
|
|
6255
|
+
const strokeIn = (duration, delay, fallbackDuration) => build ? { type: "drawOn", duration, delay } : { type: "fadeIn", duration: fallbackDuration, delay };
|
|
6256
|
+
const titleFontSize = themedFontSize(52, context, true);
|
|
6257
|
+
const trackFontSize = themedFontSize(26, context, false);
|
|
6258
|
+
const baseEventFontSize = themedFontSize(28, context, false);
|
|
6259
|
+
const baseDescriptionFontSize = themedFontSize(20, context, false);
|
|
6260
|
+
const trackCount = Math.max(1, tracks.length);
|
|
6261
|
+
const viewportScale = Math.min(viewport.width, viewport.height) / 1080;
|
|
6262
|
+
const calloutExtent = 78 + Math.min(baseEventFontSize, 28 * viewportScale) * 1.4 + Math.min(baseDescriptionFontSize, 20 * viewportScale) * 1.4 * 2 + 28;
|
|
6263
|
+
const naturalBand = calloutExtent * 2 + 24;
|
|
6264
|
+
const titleBlock2 = input.title ? titleFontSize * 1.3 + 40 : 0;
|
|
6265
|
+
const maxTracksHeight = viewport.height * 0.82 - titleBlock2;
|
|
6266
|
+
const trackBand = Math.max(120, Math.min(naturalBand, maxTracksHeight / trackCount));
|
|
6267
|
+
const groupHeight = titleBlock2 + trackBand * trackCount;
|
|
6268
|
+
const groupTop = Math.max(viewport.height * 0.06, (viewport.height - groupHeight) / 2);
|
|
6269
|
+
const contentTop = groupTop + titleBlock2;
|
|
6109
6270
|
if (input.title) {
|
|
6110
6271
|
layers.push({
|
|
6111
6272
|
type: "text",
|
|
@@ -6121,8 +6282,8 @@ function timelineBlock(input, context) {
|
|
|
6121
6282
|
shadow: shouldUseShadow(context)
|
|
6122
6283
|
}
|
|
6123
6284
|
},
|
|
6124
|
-
position: { x: "50%", y:
|
|
6125
|
-
animation: { type: "fadeIn", duration: 0.7 }
|
|
6285
|
+
position: { x: "50%", y: groupTop + titleFontSize * 0.65, width: "82%", anchor: "center" },
|
|
6286
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.7 })
|
|
6126
6287
|
});
|
|
6127
6288
|
}
|
|
6128
6289
|
if (tracks.length === 0) {
|
|
@@ -6144,14 +6305,17 @@ function timelineBlock(input, context) {
|
|
|
6144
6305
|
}
|
|
6145
6306
|
const hasTrackLabels = tracks.some((track) => !!track.label);
|
|
6146
6307
|
const outerMargin = Math.max(48, viewport.width * 0.065);
|
|
6147
|
-
const
|
|
6308
|
+
const labelGap = 32;
|
|
6309
|
+
const longestLabel = Math.max(
|
|
6310
|
+
0,
|
|
6311
|
+
...tracks.map(
|
|
6312
|
+
(track) => track.label ? estimateTextWidth(track.label, trackFontSize, BOLD_CHAR_WIDTH_EM) : 0
|
|
6313
|
+
)
|
|
6314
|
+
);
|
|
6315
|
+
const labelWidth = hasTrackLabels ? Math.min(Math.min(280, viewport.width * 0.18), Math.ceil(longestLabel) + labelGap) : 0;
|
|
6148
6316
|
const axisStartX = outerMargin + labelWidth;
|
|
6149
6317
|
const axisEndX = viewport.width - outerMargin;
|
|
6150
6318
|
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
6319
|
const markerRadius = Math.max(6, Math.min(11, Math.min(viewport.width, viewport.height) / 105));
|
|
6156
6320
|
const trackColor = withAlpha(colors.text ?? theme.colors.primary, 0.72);
|
|
6157
6321
|
const accentColor = colors.accent ?? theme.colors.primary;
|
|
@@ -6166,8 +6330,8 @@ function timelineBlock(input, context) {
|
|
|
6166
6330
|
Math.min(330, axisWidth / Math.min(maxCalloutEvents, 4) * 0.86)
|
|
6167
6331
|
);
|
|
6168
6332
|
const minViewportScale = Math.min(viewport.width, viewport.height) / 1080;
|
|
6169
|
-
const eventFontSize = Math.min(baseEventFontSize,
|
|
6170
|
-
const descriptionFontSize = Math.min(baseDescriptionFontSize,
|
|
6333
|
+
const eventFontSize = Math.min(baseEventFontSize, 28 * minViewportScale);
|
|
6334
|
+
const descriptionFontSize = Math.min(baseDescriptionFontSize, 20 * minViewportScale);
|
|
6171
6335
|
const trackMarkerRadii = tracks.map((track) => {
|
|
6172
6336
|
const positions = track.events.map((event) => clamp012(event.position)).sort((a, b) => a - b);
|
|
6173
6337
|
let minGapPx = Number.POSITIVE_INFINITY;
|
|
@@ -6193,7 +6357,7 @@ function timelineBlock(input, context) {
|
|
|
6193
6357
|
endMarker: "arrow"
|
|
6194
6358
|
},
|
|
6195
6359
|
position: { x: axisStartX, y: y - markerRadius, width: axisWidth, height: markerRadius * 2 },
|
|
6196
|
-
animation:
|
|
6360
|
+
animation: strokeIn(0.9, trackDelay, 0.65)
|
|
6197
6361
|
};
|
|
6198
6362
|
layers.push(line);
|
|
6199
6363
|
if (track.label) {
|
|
@@ -6211,12 +6375,12 @@ function timelineBlock(input, context) {
|
|
|
6211
6375
|
}
|
|
6212
6376
|
},
|
|
6213
6377
|
position: {
|
|
6214
|
-
x: outerMargin + labelWidth / 2
|
|
6378
|
+
x: outerMargin + (labelWidth - labelGap) / 2,
|
|
6215
6379
|
y,
|
|
6216
|
-
width: Math.max(1, labelWidth -
|
|
6380
|
+
width: Math.max(1, labelWidth - labelGap),
|
|
6217
6381
|
anchor: "center"
|
|
6218
6382
|
},
|
|
6219
|
-
animation: { type: "fadeIn", duration: 0.5, delay: trackDelay }
|
|
6383
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.5, delay: trackDelay })
|
|
6220
6384
|
};
|
|
6221
6385
|
layers.push(label);
|
|
6222
6386
|
}
|
|
@@ -6240,7 +6404,7 @@ function timelineBlock(input, context) {
|
|
|
6240
6404
|
width: Math.max(48, outerMargin - markerRadius * 2),
|
|
6241
6405
|
anchor: "top-left"
|
|
6242
6406
|
},
|
|
6243
|
-
animation: { type: "fadeIn", duration: 0.5, delay: trackDelay }
|
|
6407
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.5, delay: trackDelay })
|
|
6244
6408
|
});
|
|
6245
6409
|
}
|
|
6246
6410
|
track.events.forEach((event, eventIndex) => {
|
|
@@ -6272,7 +6436,7 @@ function timelineBlock(input, context) {
|
|
|
6272
6436
|
endMarker: "arrow"
|
|
6273
6437
|
},
|
|
6274
6438
|
position: { x: 0, y: 0, width: "100%", height: "100%" },
|
|
6275
|
-
animation:
|
|
6439
|
+
animation: strokeIn(0.6, 0.45 + linkIndex * 0.08, 0.6)
|
|
6276
6440
|
});
|
|
6277
6441
|
if (link.label) {
|
|
6278
6442
|
const sameTrack = source.trackIndex === target.trackIndex;
|
|
@@ -6330,7 +6494,11 @@ function timelineBlock(input, context) {
|
|
|
6330
6494
|
height: linkLabelHeight,
|
|
6331
6495
|
anchor: "center"
|
|
6332
6496
|
},
|
|
6333
|
-
animation:
|
|
6497
|
+
animation: motionEntrance(context, {
|
|
6498
|
+
type: "fadeIn",
|
|
6499
|
+
duration: 0.5,
|
|
6500
|
+
delay: 0.55 + linkIndex * 0.08
|
|
6501
|
+
})
|
|
6334
6502
|
});
|
|
6335
6503
|
}
|
|
6336
6504
|
});
|
|
@@ -6360,7 +6528,7 @@ function timelineBlock(input, context) {
|
|
|
6360
6528
|
width: Math.max(2, Math.abs(calloutX - x)),
|
|
6361
6529
|
height: Math.max(2, Math.abs(endY - y))
|
|
6362
6530
|
},
|
|
6363
|
-
animation:
|
|
6531
|
+
animation: strokeIn(0.35, stemDelay, 0.4)
|
|
6364
6532
|
});
|
|
6365
6533
|
};
|
|
6366
6534
|
if (event.callout !== false) {
|
|
@@ -6384,7 +6552,8 @@ function timelineBlock(input, context) {
|
|
|
6384
6552
|
y,
|
|
6385
6553
|
pointMarkerRadius,
|
|
6386
6554
|
accentColor,
|
|
6387
|
-
delay
|
|
6555
|
+
delay,
|
|
6556
|
+
build
|
|
6388
6557
|
)
|
|
6389
6558
|
);
|
|
6390
6559
|
} else {
|
|
@@ -6403,7 +6572,7 @@ function timelineBlock(input, context) {
|
|
|
6403
6572
|
width: pointMarkerRadius * 2,
|
|
6404
6573
|
height: pointMarkerRadius * 2
|
|
6405
6574
|
},
|
|
6406
|
-
animation: { type: "zoomIn", duration: 0.35, delay }
|
|
6575
|
+
animation: build ? { type: "grow", origin: "center", duration: 0.35, delay } : { type: "zoomIn", duration: 0.35, delay }
|
|
6407
6576
|
};
|
|
6408
6577
|
layers.push(dot);
|
|
6409
6578
|
}
|
|
@@ -6437,7 +6606,7 @@ function timelineBlock(input, context) {
|
|
|
6437
6606
|
}
|
|
6438
6607
|
},
|
|
6439
6608
|
position: { x: calloutX, y: labelY, width: calloutWidth, anchor: "center" },
|
|
6440
|
-
animation: { type: "fadeIn", duration: 0.5, delay: delay + 0.08 }
|
|
6609
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.5, delay: delay + 0.08 })
|
|
6441
6610
|
});
|
|
6442
6611
|
if (event.description) {
|
|
6443
6612
|
const descriptionSide = event.descriptionSide ?? side;
|
|
@@ -6486,7 +6655,11 @@ function timelineBlock(input, context) {
|
|
|
6486
6655
|
}
|
|
6487
6656
|
},
|
|
6488
6657
|
position: { x: calloutX, y: descriptionY, width: calloutWidth, anchor: "center" },
|
|
6489
|
-
animation:
|
|
6658
|
+
animation: motionEntrance(context, {
|
|
6659
|
+
type: "fadeIn",
|
|
6660
|
+
duration: 0.5,
|
|
6661
|
+
delay: delay + 0.14
|
|
6662
|
+
})
|
|
6490
6663
|
});
|
|
6491
6664
|
}
|
|
6492
6665
|
}
|
|
@@ -7699,12 +7872,13 @@ function stackSeries(series) {
|
|
|
7699
7872
|
})
|
|
7700
7873
|
);
|
|
7701
7874
|
}
|
|
7875
|
+
var CHART_CHAR_WIDTH_EM = 0.62;
|
|
7702
7876
|
function layoutLegend(labels, fontSize, maxWidth) {
|
|
7703
7877
|
const swatchSize = fontSize * 0.9;
|
|
7704
|
-
const gap = fontSize *
|
|
7878
|
+
const gap = fontSize * 2.2;
|
|
7705
7879
|
const rowHeight = fontSize * 2;
|
|
7706
7880
|
const widths = labels.map(
|
|
7707
|
-
(label) => swatchSize + fontSize * 0.5 + label.length * fontSize *
|
|
7881
|
+
(label) => swatchSize + fontSize * 0.5 + label.length * fontSize * CHART_CHAR_WIDTH_EM
|
|
7708
7882
|
);
|
|
7709
7883
|
const rows = [];
|
|
7710
7884
|
let current = [];
|
|
@@ -7758,10 +7932,10 @@ function renderChart(kind, input, context) {
|
|
|
7758
7932
|
const { theme, viewport } = context;
|
|
7759
7933
|
const templateId = TEMPLATE_ID[kind];
|
|
7760
7934
|
const title = (input.title ?? "").trim();
|
|
7761
|
-
const titleFontSize = themedFontSize(
|
|
7762
|
-
const axisFontSize = themedFontSize(
|
|
7763
|
-
const labelFontSize = themedFontSize(
|
|
7764
|
-
const legendFontSize = themedFontSize(
|
|
7935
|
+
const titleFontSize = themedFontSize(52, context, true);
|
|
7936
|
+
const axisFontSize = themedFontSize(24, context, false);
|
|
7937
|
+
const labelFontSize = themedFontSize(26, context, false);
|
|
7938
|
+
const legendFontSize = themedFontSize(26, context, false);
|
|
7765
7939
|
const tableFontSize = themedFontSize(20, context, false);
|
|
7766
7940
|
const bodyFont = getThemeFont(context, "body");
|
|
7767
7941
|
const isRadial = kind === "pie" || kind === "donut";
|
|
@@ -7790,11 +7964,55 @@ function renderChart(kind, input, context) {
|
|
|
7790
7964
|
tableFontSize
|
|
7791
7965
|
});
|
|
7792
7966
|
const entranceHint = getTemplateHint(context, templateId, "entrance", "staggered");
|
|
7967
|
+
const markDelay = (index) => entranceHint === "subtle" ? 0.1 : Math.min(1.2, 0.2 + index * 0.08);
|
|
7793
7968
|
const entrance = (index) => ({
|
|
7794
7969
|
type: "fadeIn",
|
|
7795
7970
|
duration: 0.6,
|
|
7796
|
-
delay:
|
|
7971
|
+
delay: markDelay(index)
|
|
7797
7972
|
});
|
|
7973
|
+
const motion = getMotionProfile(context);
|
|
7974
|
+
const growDuration = motion.chartGrowthDuration;
|
|
7975
|
+
const growEasing = motion.textEntrance.easing;
|
|
7976
|
+
const eased = (animation) => growEasing ? { ...animation, easing: growEasing } : animation;
|
|
7977
|
+
const mark = (index, kind2, along = 0) => {
|
|
7978
|
+
if (!motion.chartGrowth) return entrance(index);
|
|
7979
|
+
const delay = motionDelay(context, markDelay(index));
|
|
7980
|
+
switch (kind2) {
|
|
7981
|
+
case "bar":
|
|
7982
|
+
return eased({ type: "grow", origin: "left", duration: growDuration, delay });
|
|
7983
|
+
case "bar-negative":
|
|
7984
|
+
return eased({ type: "grow", origin: "right", duration: growDuration, delay });
|
|
7985
|
+
case "column":
|
|
7986
|
+
return eased({ type: "grow", origin: "bottom", duration: growDuration, delay });
|
|
7987
|
+
case "column-negative":
|
|
7988
|
+
return eased({ type: "grow", origin: "top", duration: growDuration, delay });
|
|
7989
|
+
case "line":
|
|
7990
|
+
return { type: "drawOn", duration: growDuration * 1.4, delay };
|
|
7991
|
+
case "area":
|
|
7992
|
+
return { type: "reveal", origin: "left", duration: growDuration * 1.4, delay };
|
|
7993
|
+
case "point":
|
|
7994
|
+
return {
|
|
7995
|
+
type: "grow",
|
|
7996
|
+
origin: "center",
|
|
7997
|
+
duration: 0.35,
|
|
7998
|
+
delay: Number((delay + growDuration * 1.4 * along).toFixed(3))
|
|
7999
|
+
};
|
|
8000
|
+
case "wedge":
|
|
8001
|
+
return eased({
|
|
8002
|
+
type: "grow",
|
|
8003
|
+
origin: "center",
|
|
8004
|
+
duration: Math.max(0.4, growDuration * 0.6),
|
|
8005
|
+
delay
|
|
8006
|
+
});
|
|
8007
|
+
case "dot":
|
|
8008
|
+
return eased({ type: "grow", origin: "center", duration: 0.4, delay });
|
|
8009
|
+
}
|
|
8010
|
+
};
|
|
8011
|
+
const labelAnimation = (index, fallback, along = 0) => {
|
|
8012
|
+
if (!motion.chartGrowth) return fallback;
|
|
8013
|
+
const settled = motionDelay(context, markDelay(index)) + growDuration * (along > 0 ? 1.4 * along : 1);
|
|
8014
|
+
return { type: "fadeIn", duration: 0.4, delay: Number(settled.toFixed(3)) };
|
|
8015
|
+
};
|
|
7798
8016
|
const paint = {
|
|
7799
8017
|
kind,
|
|
7800
8018
|
input,
|
|
@@ -7807,7 +8025,9 @@ function renderChart(kind, input, context) {
|
|
|
7807
8025
|
bodyFont,
|
|
7808
8026
|
gridColor: withAlpha(theme.colors.text, 0.12),
|
|
7809
8027
|
axisTextColor: theme.colors.textMuted,
|
|
7810
|
-
entrance
|
|
8028
|
+
entrance,
|
|
8029
|
+
mark,
|
|
8030
|
+
labelAnimation
|
|
7811
8031
|
};
|
|
7812
8032
|
const layers = [createBackgroundLayer("bg", themedSurfaceGradient(context, 170))];
|
|
7813
8033
|
if (title && frame.titleBand) {
|
|
@@ -7831,7 +8051,7 @@ function renderChart(kind, input, context) {
|
|
|
7831
8051
|
width: frame.titleBand.width,
|
|
7832
8052
|
anchor: "center"
|
|
7833
8053
|
},
|
|
7834
|
-
animation: { type: "fadeIn", duration: 0.8 }
|
|
8054
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.8 })
|
|
7835
8055
|
});
|
|
7836
8056
|
}
|
|
7837
8057
|
switch (kind) {
|
|
@@ -8005,7 +8225,7 @@ function paintCategoryAxisX(paint, xForCenter) {
|
|
|
8005
8225
|
return layers;
|
|
8006
8226
|
}
|
|
8007
8227
|
function paintColumns(paint) {
|
|
8008
|
-
const { frame, data, colors, input,
|
|
8228
|
+
const { frame, data, colors, input, mark, labelAnimation } = paint;
|
|
8009
8229
|
const scale = valueTicks("column", data, input);
|
|
8010
8230
|
const yFor = (v) => frame.plot.y + frame.plot.height * (1 - (v - scale.niceMin) / (scale.niceMax - scale.niceMin));
|
|
8011
8231
|
const layers = paintValueAxisY(paint, scale, yFor);
|
|
@@ -8030,7 +8250,7 @@ function paintColumns(paint) {
|
|
|
8030
8250
|
id: `mark-${s}-${i}`,
|
|
8031
8251
|
content: { shape: "rect", fill: colors[s], borderRadius: stacked ? 0 : 3 },
|
|
8032
8252
|
position: { x, y: top, width: barWidth, height },
|
|
8033
|
-
animation:
|
|
8253
|
+
animation: mark(i + s, extent.y1 <= 0 ? "column-negative" : "column")
|
|
8034
8254
|
});
|
|
8035
8255
|
if (input.showValues === true && value !== null && !stacked) {
|
|
8036
8256
|
layers.push(
|
|
@@ -8039,7 +8259,8 @@ function paintColumns(paint) {
|
|
|
8039
8259
|
`val-${s}-${i}`,
|
|
8040
8260
|
value,
|
|
8041
8261
|
x + barWidth / 2,
|
|
8042
|
-
value >= 0 ? top - paint.axisFontSize * 0.9 : top + height + paint.axisFontSize * 0.9
|
|
8262
|
+
value >= 0 ? top - paint.axisFontSize * 0.9 : top + height + paint.axisFontSize * 0.9,
|
|
8263
|
+
labelAnimation(i + s)
|
|
8043
8264
|
)
|
|
8044
8265
|
);
|
|
8045
8266
|
}
|
|
@@ -8053,7 +8274,8 @@ function paintBars(paint) {
|
|
|
8053
8274
|
data,
|
|
8054
8275
|
colors,
|
|
8055
8276
|
input,
|
|
8056
|
-
|
|
8277
|
+
mark,
|
|
8278
|
+
labelAnimation,
|
|
8057
8279
|
labelFontSize,
|
|
8058
8280
|
axisFontSize,
|
|
8059
8281
|
bodyFont,
|
|
@@ -8062,7 +8284,7 @@ function paintBars(paint) {
|
|
|
8062
8284
|
} = paint;
|
|
8063
8285
|
const scale = valueTicks("bar", data, input);
|
|
8064
8286
|
const labelGap = axisFontSize * 0.6;
|
|
8065
|
-
const labelWidthPx = (value) => formatChartValue(value, input.unit).length * axisFontSize *
|
|
8287
|
+
const labelWidthPx = (value) => formatChartValue(value, input.unit).length * axisFontSize * CHART_CHAR_WIDTH_EM;
|
|
8066
8288
|
const showValueLabels = input.showValues === true && !(input.stacked === true);
|
|
8067
8289
|
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
8290
|
const axisWidth = Math.max(20, frame.plot.width - reservedForLabels);
|
|
@@ -8140,19 +8362,28 @@ function paintBars(paint) {
|
|
|
8140
8362
|
id: `mark-${s}-${i}`,
|
|
8141
8363
|
content: { shape: "rect", fill: colors[s], borderRadius: stacked ? 0 : 3 },
|
|
8142
8364
|
position: { x: left, y, width, height: barHeight },
|
|
8143
|
-
animation:
|
|
8365
|
+
animation: mark(i + s, extent.y1 <= 0 ? "bar-negative" : "bar")
|
|
8144
8366
|
});
|
|
8145
8367
|
if (showValueLabels && value !== null) {
|
|
8146
8368
|
const half = labelWidthPx(value) / 2;
|
|
8147
8369
|
const labelX = value >= 0 ? left + width + labelGap + half : left - labelGap - half;
|
|
8148
|
-
layers.push(
|
|
8370
|
+
layers.push(
|
|
8371
|
+
valueLabel(
|
|
8372
|
+
paint,
|
|
8373
|
+
`val-${s}-${i}`,
|
|
8374
|
+
value,
|
|
8375
|
+
labelX,
|
|
8376
|
+
y + barHeight / 2,
|
|
8377
|
+
labelAnimation(i + s)
|
|
8378
|
+
)
|
|
8379
|
+
);
|
|
8149
8380
|
}
|
|
8150
8381
|
});
|
|
8151
8382
|
});
|
|
8152
8383
|
return layers;
|
|
8153
8384
|
}
|
|
8154
8385
|
function paintRadial(paint) {
|
|
8155
|
-
const { kind, frame, data, colors, input, entrance, context } = paint;
|
|
8386
|
+
const { kind, frame, data, colors, input, entrance, mark, labelAnimation, context } = paint;
|
|
8156
8387
|
const slices = data.labels.map((label, index) => ({ label, value: data.series[0].values[index], index })).filter(
|
|
8157
8388
|
(s) => s.value !== null && Number.isFinite(s.value) && s.value > 0
|
|
8158
8389
|
);
|
|
@@ -8175,7 +8406,7 @@ function paintRadial(paint) {
|
|
|
8175
8406
|
strokeWidth: 2
|
|
8176
8407
|
},
|
|
8177
8408
|
position: { x: cx - rOuter, y: cy - rOuter, width: rOuter * 2, height: rOuter * 2 },
|
|
8178
|
-
animation:
|
|
8409
|
+
animation: mark(order, "wedge")
|
|
8179
8410
|
});
|
|
8180
8411
|
if (input.showValues === true && sweep >= 14) {
|
|
8181
8412
|
const mid = startDeg + sweep / 2;
|
|
@@ -8200,7 +8431,7 @@ function paintRadial(paint) {
|
|
|
8200
8431
|
y: cy + rLabel * Math.sin(rad),
|
|
8201
8432
|
anchor: "center"
|
|
8202
8433
|
},
|
|
8203
|
-
animation: entrance(order)
|
|
8434
|
+
animation: labelAnimation(order, entrance(order))
|
|
8204
8435
|
});
|
|
8205
8436
|
}
|
|
8206
8437
|
startDeg += sweep;
|
|
@@ -8208,7 +8439,7 @@ function paintRadial(paint) {
|
|
|
8208
8439
|
return layers;
|
|
8209
8440
|
}
|
|
8210
8441
|
function paintLines(paint) {
|
|
8211
|
-
const { kind, frame, data, colors, input,
|
|
8442
|
+
const { kind, frame, data, colors, input, mark, labelAnimation } = paint;
|
|
8212
8443
|
const scale = valueTicks(kind, data, input);
|
|
8213
8444
|
const yFor = (v) => frame.plot.y + frame.plot.height * (1 - (v - scale.niceMin) / (scale.niceMax - scale.niceMin));
|
|
8214
8445
|
const n = data.labels.length;
|
|
@@ -8249,7 +8480,7 @@ function paintLines(paint) {
|
|
|
8249
8480
|
width: frame.plot.width,
|
|
8250
8481
|
height: frame.plot.height
|
|
8251
8482
|
},
|
|
8252
|
-
animation:
|
|
8483
|
+
animation: mark(s, "area")
|
|
8253
8484
|
});
|
|
8254
8485
|
}
|
|
8255
8486
|
if (segment.length > 1) {
|
|
@@ -8263,7 +8494,7 @@ function paintLines(paint) {
|
|
|
8263
8494
|
width: frame.plot.width,
|
|
8264
8495
|
height: frame.plot.height
|
|
8265
8496
|
},
|
|
8266
|
-
animation:
|
|
8497
|
+
animation: mark(s, "line")
|
|
8267
8498
|
});
|
|
8268
8499
|
}
|
|
8269
8500
|
});
|
|
@@ -8276,7 +8507,7 @@ function paintLines(paint) {
|
|
|
8276
8507
|
id: `pt-${s}-${i}`,
|
|
8277
8508
|
content: { shape: "circle", fill: colors[s] },
|
|
8278
8509
|
position: { x: xForCenter(i) - r, y: yFor(value) - r, width: r * 2, height: r * 2 },
|
|
8279
|
-
animation:
|
|
8510
|
+
animation: mark(s, "point", i / Math.max(1, n - 1))
|
|
8280
8511
|
});
|
|
8281
8512
|
if (input.showValues === true) {
|
|
8282
8513
|
layers.push(
|
|
@@ -8285,7 +8516,8 @@ function paintLines(paint) {
|
|
|
8285
8516
|
`val-${s}-${i}`,
|
|
8286
8517
|
value,
|
|
8287
8518
|
xForCenter(i),
|
|
8288
|
-
yFor(value) - paint.axisFontSize
|
|
8519
|
+
yFor(value) - paint.axisFontSize,
|
|
8520
|
+
labelAnimation(s, void 0, i / Math.max(1, n - 1))
|
|
8289
8521
|
)
|
|
8290
8522
|
);
|
|
8291
8523
|
}
|
|
@@ -8295,7 +8527,7 @@ function paintLines(paint) {
|
|
|
8295
8527
|
return layers;
|
|
8296
8528
|
}
|
|
8297
8529
|
function paintScatter(paint) {
|
|
8298
|
-
const { frame, data, colors, input,
|
|
8530
|
+
const { frame, data, colors, input, mark } = paint;
|
|
8299
8531
|
const scale = valueTicks("scatter", data, input);
|
|
8300
8532
|
const yFor = (v) => frame.plot.y + frame.plot.height * (1 - (v - scale.niceMin) / (scale.niceMax - scale.niceMin));
|
|
8301
8533
|
const layers = paintValueAxisY(paint, scale, yFor);
|
|
@@ -8353,7 +8585,7 @@ function paintScatter(paint) {
|
|
|
8353
8585
|
id: `mark-${s}-${i}`,
|
|
8354
8586
|
content: { shape: "circle", fill: colors[s], fillOpacity: 0.85 },
|
|
8355
8587
|
position: { x: x - r, y: yFor(value) - r, width: r * 2, height: r * 2 },
|
|
8356
|
-
animation:
|
|
8588
|
+
animation: mark(Math.floor(i / 3) + s, "dot")
|
|
8357
8589
|
});
|
|
8358
8590
|
});
|
|
8359
8591
|
});
|
|
@@ -8390,7 +8622,7 @@ function paintLegend(paint, legend, band, fontSize) {
|
|
|
8390
8622
|
});
|
|
8391
8623
|
return layers;
|
|
8392
8624
|
}
|
|
8393
|
-
function valueLabel(paint, id, value, x, y) {
|
|
8625
|
+
function valueLabel(paint, id, value, x, y, animation) {
|
|
8394
8626
|
return {
|
|
8395
8627
|
type: "text",
|
|
8396
8628
|
id,
|
|
@@ -8404,7 +8636,8 @@ function valueLabel(paint, id, value, x, y) {
|
|
|
8404
8636
|
textAlign: "center"
|
|
8405
8637
|
}
|
|
8406
8638
|
},
|
|
8407
|
-
position: { x, y, anchor: "center" }
|
|
8639
|
+
position: { x, y, anchor: "center" },
|
|
8640
|
+
...animation ? { animation } : {}
|
|
8408
8641
|
};
|
|
8409
8642
|
}
|
|
8410
8643
|
function tableLayer(table, band, fontSize, input, context) {
|
|
@@ -8729,6 +8962,25 @@ function avatarLayers(idPrefix, name, imageSrc, x, y, context) {
|
|
|
8729
8962
|
}
|
|
8730
8963
|
|
|
8731
8964
|
// src/doc/templates/registry.ts
|
|
8965
|
+
var GEOMETRY_BOUND_TEMPLATES = /* @__PURE__ */ new Set([
|
|
8966
|
+
"barChart",
|
|
8967
|
+
"columnChart",
|
|
8968
|
+
"lineChart",
|
|
8969
|
+
"areaChart",
|
|
8970
|
+
"pieChart",
|
|
8971
|
+
"donutChart",
|
|
8972
|
+
"scatterChart",
|
|
8973
|
+
"comparisonBar",
|
|
8974
|
+
"timeline",
|
|
8975
|
+
"diagram",
|
|
8976
|
+
"drawing",
|
|
8977
|
+
"tree",
|
|
8978
|
+
"map",
|
|
8979
|
+
"dataTable"
|
|
8980
|
+
]);
|
|
8981
|
+
function isGeometryBoundTemplate(template) {
|
|
8982
|
+
return template !== void 0 && GEOMETRY_BOUND_TEMPLATES.has(template);
|
|
8983
|
+
}
|
|
8732
8984
|
var templateRegistry = {
|
|
8733
8985
|
title: titleBlock,
|
|
8734
8986
|
sectionHeader,
|
|
@@ -9412,7 +9664,7 @@ function materializeBlockLayersWithRuntime(block, options, runtime) {
|
|
|
9412
9664
|
source: layers.length > 0 ? "rich-content" : "empty"
|
|
9413
9665
|
};
|
|
9414
9666
|
}
|
|
9415
|
-
const context = runtime.templateContext ? cloneData(runtime.templateContext) : createTemplateContext(theme, blockIndex, totalBlocks, viewport);
|
|
9667
|
+
const context = runtime.templateContext ? cloneData(runtime.templateContext) : createTemplateContext(theme, blockIndex, totalBlocks, viewport, { motion: options.motion });
|
|
9416
9668
|
context.block = cloneData(block);
|
|
9417
9669
|
const execution = executeTemplateMaterialization(block, context, runtime.registry);
|
|
9418
9670
|
if (execution.status === "ok") {
|
|
@@ -10297,8 +10549,9 @@ function coverBlock(input, context) {
|
|
|
10297
10549
|
anchor: "center",
|
|
10298
10550
|
width: layout.maxTextWidth
|
|
10299
10551
|
},
|
|
10300
|
-
// No animation delay - shown immediately at rest
|
|
10301
|
-
|
|
10552
|
+
// No animation delay - shown immediately at rest. Word-by-word reveal is
|
|
10553
|
+
// a profile opt-in (off by default: the cover doubles as the poster).
|
|
10554
|
+
animation: getMotionProfile(context).coverWordReveal ? { type: "wordReveal", duration: 0.5, delay: 0.1, stagger: 0.12 } : { type: "fadeIn", duration: 0.8 }
|
|
10302
10555
|
});
|
|
10303
10556
|
if (subtitle) {
|
|
10304
10557
|
layers.push({
|
|
@@ -10321,7 +10574,7 @@ function coverBlock(input, context) {
|
|
|
10321
10574
|
anchor: "center",
|
|
10322
10575
|
width: layout.maxTextWidth
|
|
10323
10576
|
},
|
|
10324
|
-
animation: { type: "fadeIn", duration: 0.8, delay: 0.2 }
|
|
10577
|
+
animation: motionEntrance(context, { type: "fadeIn", duration: 0.8, delay: 0.2 })
|
|
10325
10578
|
});
|
|
10326
10579
|
}
|
|
10327
10580
|
return layers;
|
|
@@ -10416,7 +10669,7 @@ function expandCoverBlock(config, context, template = "cover") {
|
|
|
10416
10669
|
}
|
|
10417
10670
|
|
|
10418
10671
|
// src/doc/templates/index.ts
|
|
10419
|
-
function materializeScheduledBlock(sourceBlock, blockIndex, totalBlocks, theme, viewport, persistentLayers, expandedPersistentLayers, registry, failureMode, onDiagnostic) {
|
|
10672
|
+
function materializeScheduledBlock(sourceBlock, blockIndex, totalBlocks, theme, viewport, persistentLayers, expandedPersistentLayers, registry, failureMode, onDiagnostic, motion) {
|
|
10420
10673
|
const materialized = materializeBlockLayersWithRuntime(
|
|
10421
10674
|
sourceBlock,
|
|
10422
10675
|
{
|
|
@@ -10425,7 +10678,8 @@ function materializeScheduledBlock(sourceBlock, blockIndex, totalBlocks, theme,
|
|
|
10425
10678
|
persistentLayers: persistentLayers ?? false,
|
|
10426
10679
|
blockIndex,
|
|
10427
10680
|
totalBlocks,
|
|
10428
|
-
failureMode
|
|
10681
|
+
failureMode,
|
|
10682
|
+
motion
|
|
10429
10683
|
},
|
|
10430
10684
|
{ registry, expandedPersistentLayers }
|
|
10431
10685
|
);
|
|
@@ -10461,7 +10715,8 @@ function expandDocBlocks(blocks, options = {}) {
|
|
|
10461
10715
|
failureMode = "fallback",
|
|
10462
10716
|
onDiagnostic,
|
|
10463
10717
|
splitLongBlocks = true,
|
|
10464
|
-
mergeShortBlocks = true
|
|
10718
|
+
mergeShortBlocks = true,
|
|
10719
|
+
motion
|
|
10465
10720
|
} = opts;
|
|
10466
10721
|
const totalBlocks = blocks.length;
|
|
10467
10722
|
const registry = customTemplates && customTemplates.length > 0 ? buildRegistry(customTemplates) : templateRegistry;
|
|
@@ -10483,7 +10738,8 @@ function expandDocBlocks(blocks, options = {}) {
|
|
|
10483
10738
|
expandedPersistentLayers,
|
|
10484
10739
|
registry,
|
|
10485
10740
|
failureMode,
|
|
10486
|
-
onDiagnostic
|
|
10741
|
+
onDiagnostic,
|
|
10742
|
+
motion
|
|
10487
10743
|
);
|
|
10488
10744
|
expandedBlock.startTime = currentTime;
|
|
10489
10745
|
currentTime += expandedBlock.duration;
|
|
@@ -10515,7 +10771,8 @@ function expandDocBlocks(blocks, options = {}) {
|
|
|
10515
10771
|
expandedPersistentLayers,
|
|
10516
10772
|
registry,
|
|
10517
10773
|
failureMode,
|
|
10518
|
-
onDiagnostic
|
|
10774
|
+
onDiagnostic,
|
|
10775
|
+
motion
|
|
10519
10776
|
);
|
|
10520
10777
|
expandedBlock.startTime = offsetTime;
|
|
10521
10778
|
offsetTime += expandedBlock.duration;
|
|
@@ -10553,7 +10810,8 @@ function expandDocBlocks(blocks, options = {}) {
|
|
|
10553
10810
|
expandedPersistentLayers,
|
|
10554
10811
|
registry,
|
|
10555
10812
|
failureMode,
|
|
10556
|
-
onDiagnostic
|
|
10813
|
+
onDiagnostic,
|
|
10814
|
+
motion
|
|
10557
10815
|
);
|
|
10558
10816
|
const templateBlock = block;
|
|
10559
10817
|
expandedInfos.push({
|
|
@@ -11669,6 +11927,7 @@ function markdownToDoc(markdownDoc, options) {
|
|
|
11669
11927
|
const customTemplates = readCustomTemplatesFromFrontmatter(markdownDoc.frontmatter);
|
|
11670
11928
|
const customThemes = readCustomThemesFromFrontmatter(markdownDoc.frontmatter);
|
|
11671
11929
|
const themeId = readFrontmatterThemeId(markdownDoc.frontmatter);
|
|
11930
|
+
const motion = readFrontmatterMotion(markdownDoc.frontmatter);
|
|
11672
11931
|
const doc = {
|
|
11673
11932
|
articleId,
|
|
11674
11933
|
duration: currentTime,
|
|
@@ -11679,6 +11938,7 @@ function markdownToDoc(markdownDoc, options) {
|
|
|
11679
11938
|
...captions ? { captions } : {},
|
|
11680
11939
|
...markdownDoc.frontmatter ? { frontmatter: markdownDoc.frontmatter } : {},
|
|
11681
11940
|
...themeId ? { themeId } : {},
|
|
11941
|
+
...motion ? { motion } : {},
|
|
11682
11942
|
...customTemplates ? { customTemplates } : {},
|
|
11683
11943
|
...customThemes ? { customThemes } : {},
|
|
11684
11944
|
...diagnostics.length > 0 ? { diagnostics } : {},
|
|
@@ -11987,6 +12247,9 @@ export {
|
|
|
11987
12247
|
scaleAnimationDuration,
|
|
11988
12248
|
getDefaultAnimation,
|
|
11989
12249
|
themedEntrance,
|
|
12250
|
+
getMotionProfile,
|
|
12251
|
+
motionEntrance,
|
|
12252
|
+
motionDelay,
|
|
11990
12253
|
shouldUseShadow,
|
|
11991
12254
|
getOverlayOpacity,
|
|
11992
12255
|
themedImageTreatment,
|
|
@@ -12028,6 +12291,10 @@ export {
|
|
|
12028
12291
|
autoTemplatePreservesContent,
|
|
12029
12292
|
deriveTemplateInputs,
|
|
12030
12293
|
contentBlock,
|
|
12294
|
+
parseStatNumber,
|
|
12295
|
+
countUpSpecFor,
|
|
12296
|
+
formatCountValue,
|
|
12297
|
+
formatCountUp,
|
|
12031
12298
|
statHighlight,
|
|
12032
12299
|
quoteBlock,
|
|
12033
12300
|
factCard,
|
|
@@ -12065,6 +12332,8 @@ export {
|
|
|
12065
12332
|
drawingBlock,
|
|
12066
12333
|
computeLayoutLayers,
|
|
12067
12334
|
layoutBlock,
|
|
12335
|
+
GEOMETRY_BOUND_TEMPLATES,
|
|
12336
|
+
isGeometryBoundTemplate,
|
|
12068
12337
|
templateRegistry,
|
|
12069
12338
|
buildRegistry,
|
|
12070
12339
|
themeWantsAmbientMotion,
|