@bendyline/squisq-react 1.4.2 → 2.0.1
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/README.md +30 -3
- package/dist/index.d.ts +177 -28
- package/dist/index.js +1330 -611
- package/dist/index.js.map +1 -1
- package/dist/squisq-player.css +1 -1
- package/dist/squisq-player.css.map +1 -1
- package/dist/squisq-player.global.js +57 -37
- package/dist/squisq-player.global.js.map +1 -1
- package/dist/standalone-source.js +1 -1
- package/dist/styles/index.css +28 -0
- package/package.json +2 -2
- package/src/BlockRenderer.tsx +54 -17
- package/src/DocControlsSlideshow.tsx +222 -5
- package/src/DocPlayer.tsx +367 -183
- package/src/DocPlayerWithSidebar.tsx +4 -0
- package/src/DocProgressBar.tsx +40 -1
- package/src/LinearDocView.tsx +138 -62
- package/src/MarkdownRenderer.tsx +40 -97
- package/src/MediaClipLayer.tsx +12 -2
- package/src/__tests__/BlockRenderer.test.tsx +138 -8
- package/src/__tests__/DocControlsSlideshow.test.tsx +94 -1
- package/src/__tests__/DocPlayer.test.tsx +505 -0
- package/src/__tests__/DocProgressBar.test.tsx +28 -2
- package/src/__tests__/LinearDocView.test.tsx +104 -11
- package/src/__tests__/MapLayer.test.tsx +63 -0
- package/src/__tests__/MarkdownRenderer.test.tsx +16 -5
- package/src/__tests__/MediaClipLayer.test.tsx +70 -0
- package/src/__tests__/MediaContext.test.tsx +51 -0
- package/src/__tests__/PathLayer.test.tsx +12 -1
- package/src/__tests__/VideoLayer.test.tsx +94 -0
- package/src/__tests__/fillStyle.test.tsx +50 -2
- package/src/__tests__/standaloneEntry.test.tsx +103 -0
- package/src/__tests__/useAudioSync.test.ts +49 -0
- package/src/__tests__/useDocPlayback.transition.test.ts +48 -5
- package/src/__tests__/useViewportOrientation.test.ts +22 -0
- package/src/hooks/MediaContext.tsx +12 -3
- package/src/hooks/useAudioSync.ts +61 -12
- package/src/hooks/useDocPlayback.ts +40 -12
- package/src/hooks/useViewportOrientation.ts +2 -4
- package/src/index.ts +5 -2
- package/src/layers/ImageLayer.tsx +106 -1
- package/src/layers/MapLayer.tsx +7 -6
- package/src/layers/PathLayer.tsx +20 -11
- package/src/layers/ShapeLayer.tsx +33 -9
- package/src/layers/TextLayer.tsx +4 -3
- package/src/layers/TreeLayer.tsx +167 -0
- package/src/layers/VideoLayer.tsx +20 -6
- package/src/standalone-entry.tsx +91 -14
- package/src/styles/doc-animations.css +36 -0
- package/src/types.ts +13 -13
|
@@ -178,6 +178,26 @@
|
|
|
178
178
|
}
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
+
/* Portrait framing for dominant cover photos. Animating object-position scans
|
|
182
|
+
exactly across the crop overflow without adding another scale transform. */
|
|
183
|
+
@keyframes portraitCoverPanRight {
|
|
184
|
+
from {
|
|
185
|
+
object-position: left center;
|
|
186
|
+
}
|
|
187
|
+
to {
|
|
188
|
+
object-position: right center;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
@keyframes portraitCoverPanLeft {
|
|
193
|
+
from {
|
|
194
|
+
object-position: right center;
|
|
195
|
+
}
|
|
196
|
+
to {
|
|
197
|
+
object-position: left center;
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
181
201
|
@keyframes slideInLeft {
|
|
182
202
|
from {
|
|
183
203
|
transform: translateX(-100%);
|
|
@@ -2170,6 +2190,18 @@
|
|
|
2170
2190
|
forwards;
|
|
2171
2191
|
}
|
|
2172
2192
|
|
|
2193
|
+
.squisq-image--portrait-pan-right {
|
|
2194
|
+
animation: portraitCoverPanRight var(--portrait-pan-duration, 12s)
|
|
2195
|
+
var(--portrait-pan-easing, ease-in-out) var(--portrait-pan-delay, 0s) forwards;
|
|
2196
|
+
will-change: object-position;
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2199
|
+
.squisq-image--portrait-pan-left {
|
|
2200
|
+
animation: portraitCoverPanLeft var(--portrait-pan-duration, 12s)
|
|
2201
|
+
var(--portrait-pan-easing, ease-in-out) var(--portrait-pan-delay, 0s) forwards;
|
|
2202
|
+
will-change: object-position;
|
|
2203
|
+
}
|
|
2204
|
+
|
|
2173
2205
|
.anim-typewriter {
|
|
2174
2206
|
animation: typewriter var(--anim-duration, 2s) var(--anim-easing, steps(40, end))
|
|
2175
2207
|
var(--anim-delay, 0s) forwards;
|
|
@@ -2369,6 +2401,10 @@
|
|
|
2369
2401
|
.anim-slowZoom-out,
|
|
2370
2402
|
.anim-slowZoom-panLeft,
|
|
2371
2403
|
.anim-slowZoom-panRight,
|
|
2404
|
+
.anim-panLeft,
|
|
2405
|
+
.anim-panRight,
|
|
2406
|
+
.squisq-image--portrait-pan-left,
|
|
2407
|
+
.squisq-image--portrait-pan-right,
|
|
2372
2408
|
.anim-drift {
|
|
2373
2409
|
animation: none;
|
|
2374
2410
|
}
|
package/src/types.ts
CHANGED
|
@@ -33,8 +33,12 @@ export type ControlsLayout = 'overlay' | 'sidebar' | 'bottom';
|
|
|
33
33
|
* `markdownDocToPlainHtml` export produces. No SquisqPlayer, no SVG
|
|
34
34
|
* cards — just `<h1>`/`<p>`/`<ul>` etc. inside a sandboxed iframe.
|
|
35
35
|
* Use when you want a WYSIWYG view of the simple HTML export.
|
|
36
|
+
* - `'narrate'` — Teleprompter/performance surface. DocPlayer does not
|
|
37
|
+
* implement this mode; it is owned by the editor package
|
|
38
|
+
* (`@bendyline/squisq-editor-react`), which renders its own
|
|
39
|
+
* voice-paced teleprompter view for it.
|
|
36
40
|
*/
|
|
37
|
-
export type DisplayMode = 'video' | 'slideshow' | 'linear' | 'page';
|
|
41
|
+
export type DisplayMode = 'video' | 'slideshow' | 'linear' | 'page' | 'narrate';
|
|
38
42
|
|
|
39
43
|
/**
|
|
40
44
|
* Caption display style.
|
|
@@ -68,6 +72,8 @@ export interface PlaybackState {
|
|
|
68
72
|
isPlaying: boolean;
|
|
69
73
|
currentTime: number;
|
|
70
74
|
totalDuration: number;
|
|
75
|
+
/** Whether the managed cover is the visual currently shown. */
|
|
76
|
+
isCoverVisible?: boolean;
|
|
71
77
|
currentBlockIndex: number;
|
|
72
78
|
totalBlocks: number;
|
|
73
79
|
docProgress: number;
|
|
@@ -146,15 +152,15 @@ export interface RenderChapterInfo {
|
|
|
146
152
|
}
|
|
147
153
|
|
|
148
154
|
/**
|
|
149
|
-
* API
|
|
150
|
-
*
|
|
155
|
+
* Instance-scoped API created in render mode and debug mode.
|
|
156
|
+
* React hosts receive it via `DocPlayer.onRenderAPIReady`; standalone hosts
|
|
157
|
+
* receive it from their mount handle.
|
|
151
158
|
*
|
|
152
159
|
* @example
|
|
153
160
|
* ```ts
|
|
154
|
-
*
|
|
155
|
-
* const
|
|
156
|
-
* await
|
|
157
|
-
* const blocks = w.getBlocks!();
|
|
161
|
+
* const handle = SquisqPlayer.getHandle(rootElement);
|
|
162
|
+
* const api = await handle?.renderAPI;
|
|
163
|
+
* await api?.seekTo(5.0);
|
|
158
164
|
* ```
|
|
159
165
|
*/
|
|
160
166
|
export interface SquisqRenderAPI {
|
|
@@ -169,12 +175,6 @@ export interface SquisqRenderAPI {
|
|
|
169
175
|
hasCoverBlock: () => boolean;
|
|
170
176
|
}
|
|
171
177
|
|
|
172
|
-
/**
|
|
173
|
-
* Window augmented with optional SquisqRenderAPI properties.
|
|
174
|
-
* Each property is optional because they're only present in render/debug mode.
|
|
175
|
-
*/
|
|
176
|
-
export type SquisqWindow = Window & typeof globalThis & Partial<SquisqRenderAPI>;
|
|
177
|
-
|
|
178
178
|
/** Format time in seconds to MM:SS string */
|
|
179
179
|
export function formatTime(seconds: number): string {
|
|
180
180
|
const mins = Math.floor(seconds / 60);
|