@bendyline/squisq-react 2.11.10 → 2.11.12
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/{chunk-X4I6Y3OP.js → chunk-7T26IKW2.js} +1 -1
- package/dist/{chunk-CLP3VWJ2.js → chunk-P3FJ3YKS.js} +6 -4
- package/dist/{chunk-4KBT2CXQ.js → chunk-QWUQNB4E.js} +116 -40
- package/dist/{chunk-MVJQL2W2.js → chunk-U2FIZWAL.js} +13 -2
- package/dist/{chunk-W6MKRWL6.js → chunk-WHVSQ42V.js} +193 -116
- package/dist/hooks/index.d.ts +14 -1
- package/dist/hooks/index.js +1 -1
- package/dist/index.d.ts +20 -3
- package/dist/index.js +5 -5
- package/dist/layers/index.js +1 -1
- package/dist/page/index.js +3 -3
- package/dist/player/index.d.ts +1 -1
- package/dist/player/index.js +4 -4
- package/dist/{player-5j10MhBq.d.ts → player-BCPc3Tv3.d.ts} +12 -1
- package/dist/squisq-player.full.global.js +428 -428
- package/dist/squisq-player.global.js +71 -71
- package/dist/standalone-source.js +1 -1
- package/dist/styles/index.css +236 -14
- package/package.json +2 -2
|
@@ -239,8 +239,16 @@ function remapToKenBurns(anim) {
|
|
|
239
239
|
}
|
|
240
240
|
|
|
241
241
|
// src/layers/TextLayer.tsx
|
|
242
|
-
import {
|
|
242
|
+
import {
|
|
243
|
+
Fragment,
|
|
244
|
+
useId,
|
|
245
|
+
useLayoutEffect,
|
|
246
|
+
useMemo,
|
|
247
|
+
useRef,
|
|
248
|
+
useState
|
|
249
|
+
} from "react";
|
|
243
250
|
import { DEFAULT_DOC_FONT } from "@bendyline/squisq/schemas";
|
|
251
|
+
import { formatCountUp, wordRevealDelay } from "@bendyline/squisq/doc";
|
|
244
252
|
import {
|
|
245
253
|
parseHtmlToNodes,
|
|
246
254
|
sanitizeHtmlNodes,
|
|
@@ -253,6 +261,16 @@ import {
|
|
|
253
261
|
iconClass
|
|
254
262
|
} from "@bendyline/squisq/icon-marker";
|
|
255
263
|
|
|
264
|
+
// src/utils/defsId.ts
|
|
265
|
+
function defsIdFor(reactId, layerId) {
|
|
266
|
+
const raw = `${reactId}-${layerId}`;
|
|
267
|
+
const safe = raw.replace(/[^A-Za-z0-9_-]/g, "_");
|
|
268
|
+
if (safe === raw.replace(/:/g, "_")) return safe.replace(/^_+/, "d");
|
|
269
|
+
let hash = 0;
|
|
270
|
+
for (let i = 0; i < raw.length; i++) hash = hash * 31 + raw.charCodeAt(i) >>> 0;
|
|
271
|
+
return `${safe.replace(/^_+/, "d")}-${hash.toString(36)}`;
|
|
272
|
+
}
|
|
273
|
+
|
|
256
274
|
// src/utils/fillStyle.tsx
|
|
257
275
|
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
258
276
|
function borderDashArray(style, strokeWidth) {
|
|
@@ -351,7 +369,7 @@ function resolveShapeFilter(layerId, filter) {
|
|
|
351
369
|
}
|
|
352
370
|
|
|
353
371
|
// src/layers/TextLayer.tsx
|
|
354
|
-
import { Fragment, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
372
|
+
import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
355
373
|
function TextLayer(props) {
|
|
356
374
|
if (props.layer.content.html?.trim()) return /* @__PURE__ */ jsx3(RichTextLayer, { ...props });
|
|
357
375
|
if (hasIconMarker(props.layer.content.text ?? "")) return /* @__PURE__ */ jsx3(IconTextLayer, { ...props });
|
|
@@ -401,37 +419,45 @@ function IconTextLayer({ layer, viewport, blockTime, textScale = 1 }) {
|
|
|
401
419
|
...style.shadow ? { textShadow: "0 2px 3px rgba(0,0,0,0.7)" } : {},
|
|
402
420
|
...animStyle.style
|
|
403
421
|
};
|
|
404
|
-
return /* @__PURE__ */ jsx3(
|
|
405
|
-
"
|
|
422
|
+
return /* @__PURE__ */ jsx3(
|
|
423
|
+
"g",
|
|
406
424
|
{
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
height: boxHeight,
|
|
411
|
-
style: { overflow: "visible" },
|
|
425
|
+
className: `block-layer block-layer--text ${animStyle.className}`,
|
|
426
|
+
style: animStyle.style,
|
|
427
|
+
"data-layer-id": layer.id,
|
|
412
428
|
children: /* @__PURE__ */ jsx3(
|
|
413
|
-
"
|
|
429
|
+
"foreignObject",
|
|
414
430
|
{
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
431
|
+
x: boxX,
|
|
432
|
+
y: boxY,
|
|
433
|
+
width: boxWidth,
|
|
434
|
+
height: boxHeight,
|
|
435
|
+
style: { overflow: "visible" },
|
|
419
436
|
children: /* @__PURE__ */ jsx3(
|
|
420
437
|
"div",
|
|
421
438
|
{
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
"
|
|
425
|
-
|
|
439
|
+
...{ xmlns: "http://www.w3.org/1999/xhtml" },
|
|
440
|
+
"data-squisq-text-fit": "html",
|
|
441
|
+
"data-squisq-base-font-size": style.fontSize,
|
|
442
|
+
style: boxStyle,
|
|
443
|
+
children: /* @__PURE__ */ jsx3(
|
|
444
|
+
"div",
|
|
445
|
+
{
|
|
446
|
+
"data-squisq-text-content": "true",
|
|
447
|
+
style: { width: "100%", whiteSpace: "pre-wrap", wordBreak: "break-word" },
|
|
448
|
+
"aria-label": plain,
|
|
449
|
+
dangerouslySetInnerHTML: { __html: html }
|
|
450
|
+
}
|
|
451
|
+
)
|
|
426
452
|
}
|
|
427
453
|
)
|
|
428
454
|
}
|
|
429
455
|
)
|
|
430
456
|
}
|
|
431
|
-
)
|
|
457
|
+
);
|
|
432
458
|
}
|
|
433
459
|
function PlainTextLayer({ layer, viewport, blockTime, textScale = 1 }) {
|
|
434
|
-
const defsId =
|
|
460
|
+
const defsId = defsIdFor(useId(), layer.id);
|
|
435
461
|
const { content, position, animation } = layer;
|
|
436
462
|
const { text, style } = content;
|
|
437
463
|
const rawX = resolveValue(position.x, viewport.width);
|
|
@@ -447,7 +473,10 @@ function PlainTextLayer({ layer, viewport, blockTime, textScale = 1 }) {
|
|
|
447
473
|
const fitWidth = boxWidth ?? (textAnchor === "middle" ? Math.max(0, Math.min(x, viewport.width - x) * 2) : textAnchor === "end" ? Math.max(0, x) : Math.max(0, viewport.width - x));
|
|
448
474
|
const fitHeight = boxHeight ?? (dominantBaseline === "middle" ? Math.max(0, Math.min(y, viewport.height - y) * 2) : dominantBaseline === "text-after-edge" ? Math.max(0, y) : Math.max(0, viewport.height - y));
|
|
449
475
|
const animStyle = getAnimationStyle(animation, blockTime);
|
|
450
|
-
const
|
|
476
|
+
const isCountUp = animation?.type === "countUp";
|
|
477
|
+
const isWordReveal = animation?.type === "wordReveal";
|
|
478
|
+
const displayText = isCountUp && animation ? formatCountUp(text ?? "", animation, blockTime) : text;
|
|
479
|
+
const rawLines = (displayText ?? "").split("\n");
|
|
451
480
|
let lines = maxWidth ? rawLines.reduce(
|
|
452
481
|
(acc, line) => acc.concat(wrapText(line, style.fontSize, maxWidth)),
|
|
453
482
|
[]
|
|
@@ -517,58 +546,78 @@ function PlainTextLayer({ layer, viewport, blockTime, textScale = 1 }) {
|
|
|
517
546
|
...animStyle.style
|
|
518
547
|
};
|
|
519
548
|
const filterId = style.shadow ? `shadow-${defsId}` : void 0;
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
549
|
+
let wordIndex = 0;
|
|
550
|
+
const renderLine = (line) => {
|
|
551
|
+
if (!isWordReveal || !animation || !line) return line || "\xA0";
|
|
552
|
+
const words = line.split(" ");
|
|
553
|
+
return words.map((word, w) => {
|
|
554
|
+
const delay = wordRevealDelay(animation, wordIndex++);
|
|
555
|
+
return /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
556
|
+
w > 0 ? " " : null,
|
|
557
|
+
/* @__PURE__ */ jsx3("tspan", { className: "anim-word", style: { "--anim-delay": `${delay}s` }, children: word })
|
|
558
|
+
] }, w);
|
|
559
|
+
});
|
|
560
|
+
};
|
|
561
|
+
return /* @__PURE__ */ jsxs2(
|
|
562
|
+
"g",
|
|
563
|
+
{
|
|
564
|
+
className: `block-layer block-layer--text ${animStyle.className}`,
|
|
565
|
+
style: animStyle.style,
|
|
566
|
+
"data-layer-id": layer.id,
|
|
567
|
+
children: [
|
|
568
|
+
style.shadow && /* @__PURE__ */ jsx3("defs", { children: /* @__PURE__ */ jsx3("filter", { id: filterId, x: "-20%", y: "-20%", width: "140%", height: "140%", children: /* @__PURE__ */ jsx3("feDropShadow", { dx: "0", dy: "2", stdDeviation: "3", floodColor: "rgba(0,0,0,0.7)" }) }) }),
|
|
569
|
+
/* @__PURE__ */ jsx3(
|
|
570
|
+
TextBox,
|
|
571
|
+
{
|
|
572
|
+
layerId: defsId,
|
|
573
|
+
style,
|
|
574
|
+
box: boxWidth != null && boxHeight != null ? {
|
|
575
|
+
x: rawX - anchorAxis(anchor, boxWidth, "x"),
|
|
576
|
+
y: rawY - anchorAxis(anchor, boxHeight, "y"),
|
|
577
|
+
width: boxWidth,
|
|
578
|
+
height: boxHeight
|
|
579
|
+
} : {
|
|
580
|
+
x: x - (style.padding || 16),
|
|
581
|
+
y: y - style.fontSize - (style.padding || 16),
|
|
582
|
+
width: getTextBoxWidth(lines, style) + (style.padding || 16) * 2,
|
|
583
|
+
height: lines.length * lineHeightPx + (style.padding || 16) * 2
|
|
584
|
+
}
|
|
585
|
+
}
|
|
586
|
+
),
|
|
587
|
+
/* @__PURE__ */ jsx3(
|
|
588
|
+
"g",
|
|
553
589
|
{
|
|
554
|
-
|
|
555
|
-
"data-squisq-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
590
|
+
"data-squisq-text-fit": "svg",
|
|
591
|
+
"data-squisq-fit-width": fitWidth,
|
|
592
|
+
"data-squisq-fit-height": fitHeight,
|
|
593
|
+
style: {
|
|
594
|
+
transform: `scale(${textScale})`,
|
|
595
|
+
transformOrigin: `${x}px ${y}px`,
|
|
596
|
+
transformBox: "view-box"
|
|
597
|
+
},
|
|
598
|
+
children: /* @__PURE__ */ jsx3(
|
|
599
|
+
"text",
|
|
600
|
+
{
|
|
601
|
+
ref: textRef,
|
|
602
|
+
"data-squisq-text-content": "true",
|
|
603
|
+
x,
|
|
604
|
+
y,
|
|
605
|
+
textAnchor,
|
|
606
|
+
dominantBaseline,
|
|
607
|
+
style: textStyles,
|
|
608
|
+
filter: filterId ? `url(#${filterId})` : void 0,
|
|
609
|
+
transform: fitTransform,
|
|
610
|
+
children: lines.map((line, i) => /* @__PURE__ */ jsxs2("tspan", { x, dy: i === 0 ? firstLineDy : lineHeightPx, children: [
|
|
611
|
+
renderLine(line),
|
|
612
|
+
" "
|
|
613
|
+
] }, i))
|
|
614
|
+
}
|
|
615
|
+
)
|
|
567
616
|
}
|
|
568
617
|
)
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
618
|
+
]
|
|
619
|
+
}
|
|
620
|
+
);
|
|
572
621
|
}
|
|
573
622
|
function RichTextLayer({ layer, viewport, blockTime, textScale = 1 }) {
|
|
574
623
|
const { content, position, animation } = layer;
|
|
@@ -618,48 +667,56 @@ function RichTextLayer({ layer, viewport, blockTime, textScale = 1 }) {
|
|
|
618
667
|
if (target?.closest?.("[data-squisq-table-scroll]")) event.stopPropagation();
|
|
619
668
|
};
|
|
620
669
|
const scopedCss = `.${cls}{margin:0}.${cls} p{margin:0 0 .4em}.${cls} h1,.${cls} h2,.${cls} h3,.${cls} h4,.${cls} h5,.${cls} h6{margin:0 0 .3em;line-height:1.2}.${cls} ul,.${cls} ol{margin:0 0 .7em;padding-left:1.2em;list-style-position:${listStylePosition}}.${cls} li{margin:0}.${cls} li>p{display:inline;margin:0}.${cls} [data-squisq-table-scroll]{width:100%;max-height:20em;margin:.35em 0;overflow:auto;overscroll-behavior:contain;box-sizing:border-box}.${cls} table{width:100%;min-width:48em;margin:0;border-collapse:separate;border-spacing:0;table-layout:fixed;font-size:.76em;line-height:1.2}.${cls} th,.${cls} td{box-sizing:border-box;padding:.28em .45em;border:1px solid rgba(127,127,127,.55);border-color:color-mix(in srgb,currentColor 32%,transparent);vertical-align:top;white-space:normal;overflow-wrap:anywhere}.${cls} th{position:sticky;top:0;z-index:1;background:rgba(127,127,127,.16);background:color-mix(in srgb,currentColor 12%,transparent);font-weight:600}.${cls} tbody tr:nth-child(even){background:rgba(127,127,127,.07);background:color-mix(in srgb,currentColor 5%,transparent)}.${cls} *:first-child{margin-top:0}.${cls} *:last-child{margin-bottom:0}.${cls} a{color:inherit;text-decoration:underline}`;
|
|
621
|
-
return /* @__PURE__ */ jsx3(
|
|
622
|
-
"
|
|
670
|
+
return /* @__PURE__ */ jsx3(
|
|
671
|
+
"g",
|
|
623
672
|
{
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
style: { color: style.color },
|
|
630
|
-
children: /* @__PURE__ */ jsxs2(
|
|
631
|
-
"div",
|
|
673
|
+
className: `block-layer block-layer--text ${animStyle.className}`,
|
|
674
|
+
style: animStyle.style,
|
|
675
|
+
"data-layer-id": layer.id,
|
|
676
|
+
children: /* @__PURE__ */ jsx3(
|
|
677
|
+
"foreignObject",
|
|
632
678
|
{
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
"
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
679
|
+
x: boxX,
|
|
680
|
+
y: boxY,
|
|
681
|
+
width: boxWidth,
|
|
682
|
+
height: boxHeight,
|
|
683
|
+
color: style.color,
|
|
684
|
+
style: { color: style.color },
|
|
685
|
+
children: /* @__PURE__ */ jsxs2(
|
|
686
|
+
"div",
|
|
687
|
+
{
|
|
688
|
+
...{ xmlns: "http://www.w3.org/1999/xhtml" },
|
|
689
|
+
"data-squisq-text-fit": "html",
|
|
690
|
+
"data-squisq-base-font-size": style.fontSize,
|
|
691
|
+
style: boxStyle,
|
|
692
|
+
onPointerDown: stopEmbeddedTableEvent,
|
|
693
|
+
onClick: stopEmbeddedTableEvent,
|
|
694
|
+
onWheel: stopEmbeddedTableEvent,
|
|
695
|
+
onKeyDown: stopEmbeddedTableEvent,
|
|
696
|
+
children: [
|
|
697
|
+
/* @__PURE__ */ jsx3("style", { children: scopedCss }),
|
|
698
|
+
/* @__PURE__ */ jsx3(
|
|
699
|
+
"div",
|
|
700
|
+
{
|
|
701
|
+
"data-squisq-text-content": "true",
|
|
702
|
+
className: cls,
|
|
703
|
+
"aria-label": content.text,
|
|
704
|
+
style: {
|
|
705
|
+
width: "100%",
|
|
706
|
+
color: style.color,
|
|
707
|
+
whiteSpace: "pre-wrap",
|
|
708
|
+
wordBreak: "break-word"
|
|
709
|
+
},
|
|
710
|
+
dangerouslySetInnerHTML: { __html: safeHtml }
|
|
711
|
+
}
|
|
712
|
+
)
|
|
713
|
+
]
|
|
714
|
+
}
|
|
715
|
+
)
|
|
659
716
|
}
|
|
660
717
|
)
|
|
661
718
|
}
|
|
662
|
-
)
|
|
719
|
+
);
|
|
663
720
|
}
|
|
664
721
|
function cssId(id) {
|
|
665
722
|
return id.replace(/[^a-zA-Z0-9_-]/g, "-");
|
|
@@ -674,7 +731,7 @@ function TextBox({
|
|
|
674
731
|
if (!hasFill && !hasBorder) return null;
|
|
675
732
|
const { fill, def } = resolveFill(layerId, style.background, style.backgroundGradient);
|
|
676
733
|
const dash = borderDashArray(style.borderStyle, style.borderWidth);
|
|
677
|
-
return /* @__PURE__ */ jsxs2(
|
|
734
|
+
return /* @__PURE__ */ jsxs2(Fragment2, { children: [
|
|
678
735
|
def && /* @__PURE__ */ jsx3("defs", { children: def }),
|
|
679
736
|
/* @__PURE__ */ jsx3(
|
|
680
737
|
"rect",
|
|
@@ -773,7 +830,7 @@ import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
|
773
830
|
var FULL_BLEED_OVERSCAN = 1;
|
|
774
831
|
function ShapeLayer({ layer, viewport, blockTime }) {
|
|
775
832
|
const { content, position, animation } = layer;
|
|
776
|
-
const defsId =
|
|
833
|
+
const defsId = defsIdFor(useId2(), layer.id);
|
|
777
834
|
const rawX = resolveValue(position.x, viewport.width);
|
|
778
835
|
const rawY = resolveValue(position.y, viewport.height);
|
|
779
836
|
const width = position.width ? resolveValue(position.width, viewport.width) : 100;
|
|
@@ -913,7 +970,7 @@ function effectiveMarker(explicit, legacyArrow, end) {
|
|
|
913
970
|
}
|
|
914
971
|
function PathLayer({ layer, viewport, blockTime }) {
|
|
915
972
|
const { content, animation, id } = layer;
|
|
916
|
-
const defsId =
|
|
973
|
+
const defsId = defsIdFor(useId3(), id);
|
|
917
974
|
const d = effectivePath(layer, viewport);
|
|
918
975
|
const stroke = content.stroke ?? "#1e293b";
|
|
919
976
|
const strokeWidth = content.strokeWidth ?? 2;
|
|
@@ -925,6 +982,9 @@ function PathLayer({ layer, viewport, blockTime }) {
|
|
|
925
982
|
const legacyArrow = readLegacyArrow(content);
|
|
926
983
|
const start = markerPath(effectiveMarker(content.startMarker, legacyArrow, "start"), "start");
|
|
927
984
|
const end = markerPath(effectiveMarker(content.endMarker, legacyArrow, "end"), "end");
|
|
985
|
+
const markerStart = start ? `url(#${startId})` : void 0;
|
|
986
|
+
const markerEnd = end ? `url(#${endId})` : void 0;
|
|
987
|
+
const drawOn = animation?.type === "drawOn";
|
|
928
988
|
return /* @__PURE__ */ jsxs4(
|
|
929
989
|
"g",
|
|
930
990
|
{
|
|
@@ -945,9 +1005,24 @@ function PathLayer({ layer, viewport, blockTime }) {
|
|
|
945
1005
|
strokeWidth,
|
|
946
1006
|
fill,
|
|
947
1007
|
fillOpacity: content.fillOpacity,
|
|
948
|
-
strokeDasharray: dash,
|
|
949
|
-
|
|
950
|
-
|
|
1008
|
+
strokeDasharray: drawOn ? void 0 : dash,
|
|
1009
|
+
pathLength: drawOn ? 1 : void 0,
|
|
1010
|
+
"data-squisq-draw": drawOn ? "stroke" : void 0,
|
|
1011
|
+
markerStart: drawOn ? void 0 : markerStart,
|
|
1012
|
+
markerEnd: drawOn ? void 0 : markerEnd
|
|
1013
|
+
}
|
|
1014
|
+
),
|
|
1015
|
+
drawOn && (markerStart || markerEnd) && /* @__PURE__ */ jsx5(
|
|
1016
|
+
"path",
|
|
1017
|
+
{
|
|
1018
|
+
d,
|
|
1019
|
+
stroke,
|
|
1020
|
+
strokeWidth,
|
|
1021
|
+
strokeOpacity: 0,
|
|
1022
|
+
fill: "none",
|
|
1023
|
+
"data-squisq-draw": "markers",
|
|
1024
|
+
markerStart,
|
|
1025
|
+
markerEnd
|
|
951
1026
|
}
|
|
952
1027
|
)
|
|
953
1028
|
]
|
|
@@ -1185,8 +1260,11 @@ import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
|
1185
1260
|
function MapLayer({ layer, basePath, viewport, blockTime }) {
|
|
1186
1261
|
const { content, position, animation } = layer;
|
|
1187
1262
|
const clipId = `map-clip-${useId4().replace(/:/g, "")}-${layer.id}`;
|
|
1188
|
-
const
|
|
1189
|
-
const [
|
|
1263
|
+
const staticSrc = useMediaUrl(content.staticSrc ?? "", basePath);
|
|
1264
|
+
const [mapImageUrl, setMapImageUrl] = useState2(
|
|
1265
|
+
() => content.staticSrc ? staticSrc || null : null
|
|
1266
|
+
);
|
|
1267
|
+
const [isLoading, setIsLoading] = useState2(!content.staticSrc);
|
|
1190
1268
|
const [error, setError] = useState2(null);
|
|
1191
1269
|
const [blockedByPolicy, setBlockedByPolicy] = useState2(false);
|
|
1192
1270
|
const x = resolveValue(position.x, viewport.width);
|
|
@@ -1196,7 +1274,6 @@ function MapLayer({ layer, basePath, viewport, blockTime }) {
|
|
|
1196
1274
|
const offset = getAnchorOffset(position.anchor, width, height);
|
|
1197
1275
|
const finalX = x + offset.x;
|
|
1198
1276
|
const finalY = y + offset.y;
|
|
1199
|
-
const staticSrc = useMediaUrl(content.staticSrc ?? "", basePath);
|
|
1200
1277
|
const resourcePolicy = useResourcePolicy();
|
|
1201
1278
|
useEffect(() => {
|
|
1202
1279
|
let cancelled = false;
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import { RefObject } from 'react';
|
|
3
|
-
import { AudioTrack, ScheduledClip, Theme, Doc, Block, MediaProvider, SurfaceScheme } from '@bendyline/squisq/schemas';
|
|
3
|
+
import { AudioTrack, ScheduledClip, Theme, MotionSpec, Doc, Block, MediaProvider, SurfaceScheme } from '@bendyline/squisq/schemas';
|
|
4
4
|
import { a as AudioController } from '../AudioController-DwMsPe38.js';
|
|
5
5
|
export { A as AudioActions, b as AudioState } from '../AudioController-DwMsPe38.js';
|
|
6
6
|
import { ViewportConfig, ViewportOrientation } from '@bendyline/squisq/doc';
|
|
@@ -127,6 +127,19 @@ interface UseDocPlaybackOptions {
|
|
|
127
127
|
* pacing rules.
|
|
128
128
|
*/
|
|
129
129
|
useAudioSegmentTiming?: boolean;
|
|
130
|
+
/**
|
|
131
|
+
* Derive the outgoing (exiting) block from block order instead of from the
|
|
132
|
+
* block rendered last. Offline capture seeks frames out of order (resume,
|
|
133
|
+
* dedupe, sampling), so the crossfade partner must be a pure function of
|
|
134
|
+
* time. Live playback keeps the render-history path so swipes and manual
|
|
135
|
+
* jumps crossfade from what the viewer actually saw.
|
|
136
|
+
*/
|
|
137
|
+
deterministicTransitions?: boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Motion profile override. Omitted → the doc's own `motion` / frontmatter
|
|
140
|
+
* `squisq-motion`, then the theme's `renderStyle.motionProfile`, then `calm`.
|
|
141
|
+
*/
|
|
142
|
+
motion?: MotionSpec | null;
|
|
130
143
|
}
|
|
131
144
|
declare function useDocPlayback(script: Doc | null, currentTime: number, options?: UseDocPlaybackOptions): PlaybackState & PlaybackActions;
|
|
132
145
|
|
package/dist/hooks/index.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { S as SquisqRenderAPI, V as VideoPresentation$1, P as PipSize, a as PipShape, b as PipPosition } from './player-
|
|
2
|
-
export { B as BlockMarker, c as BlockRenderer, C as CaptionMode, d as CaptionOverlay, e as CaptionPosition, f as CaptionStyle, g as ControlsLayout, D as DisplayMode, h as DocControlsBottom, i as DocControlsOverlay, j as DocControlsSidebar, k as DocControlsSlideshow, l as DocPlayer, m as DocPlayerProps, n as DocPlayerWithSidebar, o as DocProgressBar, F as FlashcardFaceView, p as FlashcardFaceViewProps, q as FlashcardView, r as FlashcardViewProps, I as InlineAudioPlayer, s as InlineAudioPlayerProps, t as InlineVideoPlayer, u as InlineVideoPlayerProps, M as MediaClipLayer, v as MediaClipLayerProps, w as PlaybackActions, x as PlaybackState, R as RenderAudioSegmentInfo, y as RenderBlockInfo, z as RenderCaptionInfo, A as RenderChapterInfo, E as RenderVideoFrameSelector, G as SlideNavActions, H as SocialCaptionOverlay, J as formatTime } from './player-
|
|
3
|
-
import { Theme, VideoPresentation, VideoPipSize, VideoPipShape, VideoPipPosition, Doc, ScheduledClip, MediaProvider } from '@bendyline/squisq/schemas';
|
|
1
|
+
import { S as SquisqRenderAPI, V as VideoPresentation$1, P as PipSize, a as PipShape, b as PipPosition } from './player-BCPc3Tv3.js';
|
|
2
|
+
export { B as BlockMarker, c as BlockRenderer, C as CaptionMode, d as CaptionOverlay, e as CaptionPosition, f as CaptionStyle, g as ControlsLayout, D as DisplayMode, h as DocControlsBottom, i as DocControlsOverlay, j as DocControlsSidebar, k as DocControlsSlideshow, l as DocPlayer, m as DocPlayerProps, n as DocPlayerWithSidebar, o as DocProgressBar, F as FlashcardFaceView, p as FlashcardFaceViewProps, q as FlashcardView, r as FlashcardViewProps, I as InlineAudioPlayer, s as InlineAudioPlayerProps, t as InlineVideoPlayer, u as InlineVideoPlayerProps, M as MediaClipLayer, v as MediaClipLayerProps, w as PlaybackActions, x as PlaybackState, R as RenderAudioSegmentInfo, y as RenderBlockInfo, z as RenderCaptionInfo, A as RenderChapterInfo, E as RenderVideoFrameSelector, G as SlideNavActions, H as SocialCaptionOverlay, J as formatTime } from './player-BCPc3Tv3.js';
|
|
3
|
+
import { Theme, VideoPresentation, VideoPipSize, VideoPipShape, VideoPipPosition, MotionSpec, Doc, ScheduledClip, MediaProvider } from '@bendyline/squisq/schemas';
|
|
4
4
|
import { DashboardStyleId, ViewportConfig, CoverSlideTemplate, CoverSlidePlayback } from '@bendyline/squisq/doc';
|
|
5
5
|
export { getAnimationStyle, getTransitionClass } from '@bendyline/squisq/doc';
|
|
6
6
|
import { C as CodeBlockCopyHandler } from './MarkdownRenderer-CC9dOc6b.js';
|
|
@@ -100,6 +100,23 @@ interface MountOptions {
|
|
|
100
100
|
* auto-play.
|
|
101
101
|
*/
|
|
102
102
|
renderMode?: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Viewport the player composes for, in CSS pixels. Render pages pass their
|
|
105
|
+
* export dimensions so portrait and custom sizes are laid out natively
|
|
106
|
+
* instead of letterboxed inside the landscape preset. Omit for live hosts
|
|
107
|
+
* (the player sizes to its element) and for dashboard mounts, which always
|
|
108
|
+
* fill the host box.
|
|
109
|
+
*/
|
|
110
|
+
viewport?: {
|
|
111
|
+
width: number;
|
|
112
|
+
height: number;
|
|
113
|
+
name?: string;
|
|
114
|
+
};
|
|
115
|
+
/**
|
|
116
|
+
* Motion profile override (`calm` | `documentary` | `vibrant`, or a spec
|
|
117
|
+
* with overrides). Omitted → the doc's own setting, then the theme's.
|
|
118
|
+
*/
|
|
119
|
+
motion?: MotionSpec | null;
|
|
103
120
|
/**
|
|
104
121
|
* Whether to render slide transitions and per-layer animations (default: true).
|
|
105
122
|
* Timed media continues to play when disabled.
|
package/dist/index.js
CHANGED
|
@@ -15,10 +15,10 @@ import {
|
|
|
15
15
|
formatTime,
|
|
16
16
|
resolveDocPlayerAppearance,
|
|
17
17
|
useMediaClipDurations
|
|
18
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-QWUQNB4E.js";
|
|
19
19
|
import {
|
|
20
20
|
PaginatedDocView
|
|
21
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-7T26IKW2.js";
|
|
22
22
|
import {
|
|
23
23
|
BlockRenderer,
|
|
24
24
|
CanvasSection,
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
PageSectionView,
|
|
27
27
|
PageViewContext,
|
|
28
28
|
usePageView
|
|
29
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-P3FJ3YKS.js";
|
|
30
30
|
import {
|
|
31
31
|
ImageLayer,
|
|
32
32
|
MapLayer,
|
|
@@ -39,7 +39,7 @@ import {
|
|
|
39
39
|
VideoLayer,
|
|
40
40
|
getAnimationStyle,
|
|
41
41
|
getTransitionClass
|
|
42
|
-
} from "./chunk-
|
|
42
|
+
} from "./chunk-WHVSQ42V.js";
|
|
43
43
|
import {
|
|
44
44
|
useModalDialog
|
|
45
45
|
} from "./chunk-65POMKHR.js";
|
|
@@ -48,7 +48,7 @@ import {
|
|
|
48
48
|
useDocPlayback,
|
|
49
49
|
useMediaSchedule,
|
|
50
50
|
useViewportOrientation
|
|
51
|
-
} from "./chunk-
|
|
51
|
+
} from "./chunk-U2FIZWAL.js";
|
|
52
52
|
import {
|
|
53
53
|
JsonView,
|
|
54
54
|
createJsonFormFenceRenderer
|
package/dist/layers/index.js
CHANGED
package/dist/page/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import {
|
|
2
2
|
PaginatedDocView
|
|
3
|
-
} from "../chunk-
|
|
3
|
+
} from "../chunk-7T26IKW2.js";
|
|
4
4
|
import {
|
|
5
5
|
CanvasSection,
|
|
6
6
|
LinearDocView,
|
|
7
7
|
PageSectionView,
|
|
8
8
|
PageViewContext,
|
|
9
9
|
usePageView
|
|
10
|
-
} from "../chunk-
|
|
11
|
-
import "../chunk-
|
|
10
|
+
} from "../chunk-P3FJ3YKS.js";
|
|
11
|
+
import "../chunk-WHVSQ42V.js";
|
|
12
12
|
import "../chunk-TT6ENR6T.js";
|
|
13
13
|
import "../chunk-6PUMLLJH.js";
|
|
14
14
|
import "../chunk-WLUZTUNZ.js";
|
package/dist/player/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { B as BlockMarker, c as BlockRenderer, C as CaptionMode, d as CaptionOverlay, f as CaptionStyle, g as ControlsLayout, D as DisplayMode, h as DocControlsBottom, i as DocControlsOverlay, j as DocControlsSidebar, k as DocControlsSlideshow, l as DocPlayer, m as DocPlayerProps, n as DocPlayerWithSidebar, o as DocProgressBar, F as FlashcardFaceView, p as FlashcardFaceViewProps, q as FlashcardView, r as FlashcardViewProps, I as InlineAudioPlayer, s as InlineAudioPlayerProps, t as InlineVideoPlayer, u as InlineVideoPlayerProps, M as MediaClipLayer, v as MediaClipLayerProps, b as PipPosition, a as PipShape, P as PipSize, w as PlaybackActions, x as PlaybackState, R as RenderAudioSegmentInfo, y as RenderBlockInfo, z as RenderCaptionInfo, A as RenderChapterInfo, G as SlideNavActions, H as SocialCaptionOverlay, S as SquisqRenderAPI, V as VideoPresentation, J as formatTime } from '../player-
|
|
1
|
+
export { B as BlockMarker, c as BlockRenderer, C as CaptionMode, d as CaptionOverlay, f as CaptionStyle, g as ControlsLayout, D as DisplayMode, h as DocControlsBottom, i as DocControlsOverlay, j as DocControlsSidebar, k as DocControlsSlideshow, l as DocPlayer, m as DocPlayerProps, n as DocPlayerWithSidebar, o as DocProgressBar, F as FlashcardFaceView, p as FlashcardFaceViewProps, q as FlashcardView, r as FlashcardViewProps, I as InlineAudioPlayer, s as InlineAudioPlayerProps, t as InlineVideoPlayer, u as InlineVideoPlayerProps, M as MediaClipLayer, v as MediaClipLayerProps, b as PipPosition, a as PipShape, P as PipSize, w as PlaybackActions, x as PlaybackState, R as RenderAudioSegmentInfo, y as RenderBlockInfo, z as RenderCaptionInfo, A as RenderChapterInfo, G as SlideNavActions, H as SocialCaptionOverlay, S as SquisqRenderAPI, V as VideoPresentation, J as formatTime } from '../player-BCPc3Tv3.js';
|
|
2
2
|
export { a as CodeBlockCopyContext, C as CodeBlockCopyHandler } from '../MarkdownRenderer-CC9dOc6b.js';
|
|
3
3
|
import 'react/jsx-runtime';
|
|
4
4
|
import '@bendyline/squisq/schemas';
|
package/dist/player/index.js
CHANGED
|
@@ -12,12 +12,12 @@ import {
|
|
|
12
12
|
MediaClipLayer,
|
|
13
13
|
SocialCaptionOverlay,
|
|
14
14
|
formatTime
|
|
15
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-QWUQNB4E.js";
|
|
16
16
|
import {
|
|
17
17
|
BlockRenderer
|
|
18
|
-
} from "../chunk-
|
|
19
|
-
import "../chunk-
|
|
20
|
-
import "../chunk-
|
|
18
|
+
} from "../chunk-P3FJ3YKS.js";
|
|
19
|
+
import "../chunk-WHVSQ42V.js";
|
|
20
|
+
import "../chunk-U2FIZWAL.js";
|
|
21
21
|
import "../chunk-TT6ENR6T.js";
|
|
22
22
|
import {
|
|
23
23
|
InlineAudioPlayer,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { Block, VideoPresentation as VideoPresentation$1, VideoPipSize, VideoPipShape, VideoPipPosition, Doc, MediaScheduleOptions, Theme, SurfaceScheme, Transition, CaptionTrack, ViewportConfig as ViewportConfig$1, CustomTemplateDefinition, ScheduledClip } from '@bendyline/squisq/schemas';
|
|
2
|
+
import { Block, VideoPresentation as VideoPresentation$1, VideoPipSize, VideoPipShape, VideoPipPosition, Doc, MediaScheduleOptions, Theme, MotionSpec, SurfaceScheme, Transition, CaptionTrack, ViewportConfig as ViewportConfig$1, CustomTemplateDefinition, ScheduledClip } from '@bendyline/squisq/schemas';
|
|
3
3
|
import { ViewportConfig, DashboardStyleId, CoverSlideTemplate, CoverSlidePlayback, FlashcardFace, FlashcardSourceMode } from '@bendyline/squisq/doc';
|
|
4
4
|
import { FenceRendererMap } from '@bendyline/squisq/fence';
|
|
5
5
|
import { a as AudioController } from './AudioController-DwMsPe38.js';
|
|
@@ -185,6 +185,11 @@ interface SquisqRenderAPI {
|
|
|
185
185
|
/** Timeline time most recently committed to the player DOM. */
|
|
186
186
|
getRenderedTime: () => number;
|
|
187
187
|
getDuration: () => number;
|
|
188
|
+
/** Viewport (CSS px) the blocks were composed for; capture hosts verify it matches their export size. */
|
|
189
|
+
getViewport: () => {
|
|
190
|
+
width: number;
|
|
191
|
+
height: number;
|
|
192
|
+
};
|
|
188
193
|
getBlocks: () => RenderBlockInfo[];
|
|
189
194
|
getAudioSegments: () => RenderAudioSegmentInfo[];
|
|
190
195
|
getCaptions: () => RenderCaptionInfo[];
|
|
@@ -255,6 +260,12 @@ interface DocPlayerProps {
|
|
|
255
260
|
onBlockMarkers?: (markers: BlockMarker[]) => void;
|
|
256
261
|
forceViewport?: ViewportConfig;
|
|
257
262
|
theme?: Theme;
|
|
263
|
+
/**
|
|
264
|
+
* Motion profile override (`calm` | `documentary` | `vibrant`, or a spec
|
|
265
|
+
* with overrides). Omitted → the doc's `motion` / frontmatter
|
|
266
|
+
* `squisq-motion`, then the theme's `renderStyle.motionProfile`, then `calm`.
|
|
267
|
+
*/
|
|
268
|
+
motion?: MotionSpec | null;
|
|
258
269
|
surface?: SurfaceScheme | 'auto';
|
|
259
270
|
/** Video, slideshow, page, dashboard, or flashcards rendition. */
|
|
260
271
|
displayMode?: DisplayMode;
|