adds quick caption prop

This commit is contained in:
Sudev Kiyada 2025-06-04 18:26:04 +05:30
parent 73285cd91b
commit fbc8d24467
Failed to extract signature
7 changed files with 287 additions and 9 deletions

View file

@ -56,3 +56,14 @@ export type ForegroundPosition =
| 'right'
| 'left opposite'
| 'right opposite';
export type ScrollyVideoForegroundPosition =
| 'top center'
| 'top left'
| 'top right'
| 'bottom center'
| 'bottom left'
| 'bottom right'
| 'center center'
| 'center left'
| 'center right';

View file

@ -3,7 +3,14 @@
import Block from '../Block/Block.svelte';
import { fade } from 'svelte/transition';
import { getContext } from 'svelte';
import { Markdown } from '@reuters-graphics/svelte-markdown';
// Types
import type { ScrollyVideoState } from './js/state.svelte';
import type {
ContainerWidth,
ScrollyVideoForegroundPosition,
} from '../@types/global';
interface ForegroundProps {
id?: string;
@ -11,6 +18,10 @@
startTime?: number;
endTime?: number;
children?: Snippet;
backgroundColor?: string;
width?: ContainerWidth;
position?: ScrollyVideoForegroundPosition | string;
text?: string | undefined;
}
let {
@ -19,29 +30,57 @@
startTime = 0,
endTime = 1,
children,
backgroundColor = '#000',
width = 'normal',
position = 'center center',
text,
}: ForegroundProps = $props();
let componentState: ScrollyVideoState = getContext('scrollyVideoState');
</script>
<Block width="fluid">
<Block class={`scrolly-video-foreground ${cls}`} {id}>
{#if componentState.generalData.currentTime >= startTime && componentState.generalData.currentTime <= endTime}
<div
{id}
class={`scrolly-video-foreground ${cls}`}
class="scrolly-foreground"
in:fade={{ delay: 100, duration: 200 }}
out:fade={{ delay: 0, duration: 100 }}
>
{@render children?.()}
<div class="scrolly-video-foreground-item">
{#if children}
{@render children()}
{/if}
</div>
{#if typeof text === 'string' && text.trim() !== ''}
<Block
class="scrolly-video-foreground-text {position.split(' ')[1]}"
{width}
>
<div
style="background-color: {backgroundColor};"
class="foreground-text {position.split(' ')[0]}"
>
<Markdown source={text} />
</div>
</Block>
{/if}
</div>
{/if}
</Block>
<style lang="scss">
.scrolly-video-foreground {
@use './../../scss/mixins' as mixins;
.scrolly-foreground {
width: 100%;
height: 100%;
}
:global(.scrolly-video-foreground) {
position: absolute;
top: 0;
left: 0;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
width: 100%;
height: 100%;
display: flex;
@ -50,4 +89,68 @@
justify-content: center;
z-index: 2;
}
.scrolly-video-foreground-item {
width: 100%;
height: 100%;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
}
:global {
.scrolly-video-foreground-text {
position: absolute;
width: 100%;
max-width: calc(mixins.$column-width-normal * 0.9);
height: 100%;
@media (max-width: 1200px) {
left: 50%;
transform: translateX(-50%);
}
&.left {
left: 0;
}
&.right {
right: 0;
}
&.center {
left: 50%;
transform: translateX(-50%);
}
}
.foreground-text {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 0.25rem;
background-color: white;
width: 100%;
@include mixins.fpy-5;
@include mixins.fpx-4;
@include mixins.fm-0;
:global(*) {
margin: 0;
padding: 0;
}
&.center {
top: 50%;
}
&.top {
top: 0;
transform: translate(-50%, 50%);
}
&.bottom {
top: 100%;
transform: translate(-50%, -150%);
}
}
}
</style>

View file

@ -365,6 +365,94 @@ The `ScrollyVideo` component can also be used to display different foregrounds b
</style>
```
## With Captions
The `ScrollyVideo` component can also be used to display captions at specific times in the video. This is useful for providing additional context or information to the viewer. To add captions, you can use the `Foreground` component and pass on the caption as **text** prop.
To quickly set it up using ArchieML, you can use the following format on your RNGS doc or Google doc:
```yaml
# ArchieML doc
[blocks]
type: scrolly-video
id: alps-scrolly
src: videos/alps.mp4
height: 800svh
# Array of foregrounds
[.foregrounds]
startTime: 3
endTime: 7
text: "#### The Alps\n\nThe Alps stretch across eight countries: France, Switzerland, Italy, Monaco, Liechtenstein, Austria, Germany, and Slovenia, covering about 1,200 kilometers (750 miles)."
:end
startTime: 9
endTime: 12
text: "Mont Blanc, standing at 4,809 meters (15,777 feet), is the highest peak in the Alps and Western Europe, though there's ongoing debate between France and Italy about exactly where the summit lies."
:end
startTime: 16
endTime: 20
text: "#### History\n\nThe Alps were formed around **65 million years** ago when the African and Eurasian tectonic plates collided, pushing the land upward.Over 14 million people live in the Alpine region, with tourism supporting approximately 120 million visitors annually."
:end
[]
:end
[]
```
Then add the following code to your App.svelte or the component where you want to display the scrolly video:
```svelte
<script lang="ts">
import {
ScrollyVideo,
Foreground,
} from '@reuters-graphics/graphics-components';
import { assets } from '$app/paths';
</script>
{#if block.type == 'scrolly-video'}
<ScrollyVideo id={block.id} src={block.src} height={block.height}>
<Foreground startTime={0} endTime={2}>
<Headline
class="custom-headline"
hed={content.hed}
dek={content.dek}
section={content.section}
sectionUrl={content.sectionUrl}
authors={content.authors}
publishTime={content.publishedDate}
updateTime={content.updatedDate}
/>
</Foreground>
{#each block.foregrounds as caption}
<Foreground
startTime={parseFloat(caption.startTime)}
endTime={parseFloat(caption.endTime)}
text={caption.text}
/>
{/each}
</ScrollyVideo>
{/if}
<style lang="scss">
:global {
.custom-headline * {
color: white;
text-shadow: 0 0 10px black;
}
#alps-scrolly .foreground-text {
* {
color: white;
}
}
}
</style>
```
## Advanced usecases
For advanced use cases such as looping a particular section of the video, or jumping to a specific time in the video, you can bind `scrollyVideo` prop and take benefits of methods such as `setVideoPercentage` or bindable methods such as `onReady` and `onChange`. This allows for fine-grained control over the video playback and interaction with the scroll position.

View file

@ -3,6 +3,7 @@
import ScrollyVideo from './ScrollyVideo.svelte';
import WithScrollerBase from './demo/WithScrollerBase.svelte';
import WithTimeline from './demo/WithTimeline.svelte';
import BasicTextBoxes from './demo/BasicTextBoxes.svelte';
const { Story } = defineMeta({
title: 'Components/Graphics/ScrollyVideo',
@ -197,3 +198,11 @@
{/key}
{/snippet}
</Story>
<Story name="Basic text foreground" {args}>
{#snippet children(args)}
{#key args}
<BasicTextBoxes />
{/key}
{/snippet}
</Story>

View file

@ -0,0 +1,61 @@
<script lang="ts">
import ScrollyVideo from '../ScrollyVideo.svelte';
import Foreground from '../Foreground.svelte';
import Drone from '../videos/drone.mp4';
import Headline from '../../Headline/Headline.svelte';
</script>
<ScrollyVideo
id="alps-scrolly"
height="800svh"
src={Drone}
useWebCodecs={true}
showDebugInfo
>
<Foreground startTime={0} endTime={2}>
<Headline
class="custom-headline"
hed="ScrollyVideo inside ScrollerBase"
dek="This is a demo of ScrollyVideo inside ScrollerBase component."
section={'Reuters Graphics'}
authors={['Jane Doe']}
publishTime={new Date('2020-01-01').toISOString()}
/>
</Foreground>
<Foreground
startTime={3}
endTime={7}
backgroundColor="rgba(0, 0, 0, 0.8)"
text={'#### The Alps\n\nThe Alps stretch across eight countries: France, Switzerland, Italy, Monaco, Liechtenstein, Austria, Germany, and Slovenia, covering about 1,200 kilometers (750 miles).'}
position="bottom center"
></Foreground>
<Foreground
startTime={9}
endTime={12}
backgroundColor="rgba(0, 0, 0, 0.8)"
text={"Mont Blanc, standing at 4,809 meters (15,777 feet), is the highest peak in the Alps and Western Europe, though there's ongoing debate between France and Italy about exactly where the summit lies."}
position="bottom center"
></Foreground>
<Foreground
startTime={16}
endTime={20}
backgroundColor="rgba(0, 0, 0, 0.8)"
text={'#### History\n\nThe Alps were formed around **65 million years** ago when the African and Eurasian tectonic plates collided, pushing the land upward.Over 14 million people live in the Alpine region, with tourism supporting approximately 120 million visitors annually.'}
position="bottom center"
></Foreground>
</ScrollyVideo>
<style lang="scss">
:global(.custom-headline *) {
color: white;
text-shadow: 0 0 10px black;
}
:global {
#alps-scrolly .foreground-text {
* {
color: white;
}
}
}
</style>

View file

@ -50,7 +50,13 @@
{/snippet}
{#snippet ScrollVideo(height: string, VideoSrc: string)}
<ScrollyVideo {height} src={VideoSrc} useWebCodecs={true} showDebugInfo>
<ScrollyVideo
class="surf-scrolly"
{height}
src={VideoSrc}
useWebCodecs={true}
showDebugInfo
>
{@render ScrollForeground()}
</ScrollyVideo>
{/snippet}
@ -68,7 +74,7 @@
color: white;
}
:global(.scrolly-video-foreground) {
:global(.surf-scrolly .scrolly-video-foreground) {
filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.85));
}
</style>

Binary file not shown.