finished docs, demo updates for Time-based component foregrounds with ArchieML
This commit is contained in:
parent
69b08e65c9
commit
346827ef65
4 changed files with 201 additions and 189 deletions
|
|
@ -118,7 +118,7 @@ The `autoplay` option combines the autoplay and scrollytelling experience. If se
|
|||
|
||||
## Time-based text foregrounds with ArchieML
|
||||
|
||||
The `ScrollyVideo` component can also be used to display text as foregrounds at specific times in the video. To do so, use the `ScrollyVideoForeground` component.
|
||||
The `ScrollyVideo` component can also be used to display text as foregrounds at specific times in the video. To do so, use the `text` prop in `ScrollyVideoForeground` component.
|
||||
|
||||
[Demo](?path=/story/components-graphics-scrollyvideo--archie-ml-foregrounds)
|
||||
|
||||
|
|
@ -127,15 +127,6 @@ With the graphics kit, you'll likely get your text and prop values from an Archi
|
|||
```yaml
|
||||
# ArchieML doc
|
||||
|
||||
# Headline
|
||||
hed: The Alps
|
||||
[authors]
|
||||
* Jane Doe
|
||||
[]
|
||||
publishTime: 2020-01-01T00:00:00Z
|
||||
startTime: 0 # When in the video to start showing the headline
|
||||
endTime: 2 # When to stop showing the headline
|
||||
|
||||
[blocks]
|
||||
type: scrolly-video
|
||||
id: alps-scrolly
|
||||
|
|
@ -188,49 +179,91 @@ endTime: 2 # When to stop showing the headline
|
|||
} from '@reuters-graphics/graphics-components';
|
||||
import { assets } from '$app/paths'; // 👈 If using in the graphics kit...
|
||||
</script>
|
||||
|
||||
{#if block.type == 'scrolly-video'}
|
||||
<ScrollyVideo id={block.id} src={`${assets}/${block.src}}`} height={block.height}>
|
||||
|
||||
<!-- You can wrap components, such as `Headline`, inside `ScrollyVideoForeground` and make them appear/disappear at specific times -->
|
||||
<ScrollyVideoForeground startTime={parseFloat(content.startTime)} endTime={parseFloat(content.endTime)}>
|
||||
<Headline
|
||||
hed={content.hed}
|
||||
authors={content.authors}
|
||||
publishTime={content.publishedDate}
|
||||
/>
|
||||
</ScrollyVideoForeground>
|
||||
|
||||
<!-- Loop through foregrounds to add text blurbs that appear/disappear at specific times -->
|
||||
{#each block.foregrounds as foreground}
|
||||
<ScrollyVideoForeground
|
||||
startTime={parseFloat(foreground.startTime)}
|
||||
endTime={parseFloat(foreground.endTime)}
|
||||
width={foreground.width}
|
||||
position={foreground.position}
|
||||
backgroundColour={foreground.backgroundColour}
|
||||
text={foreground.text}
|
||||
/>
|
||||
{/each}
|
||||
</ScrollyVideo>
|
||||
{/if}
|
||||
{#each content.blocks as block}
|
||||
<!-- Inside the content.blocks for loop... -->
|
||||
{#if block.type == 'scrolly-video'}
|
||||
<ScrollyVideo id={block.id} src={`${assets}/${block.src}}`} height={block.height}>
|
||||
<!-- Loop through foregrounds to add text blurbs that appear/disappear at specific times -->
|
||||
{#each block.foregrounds as foreground}
|
||||
<ScrollyVideoForeground
|
||||
startTime={parseFloat(foreground.startTime)}
|
||||
endTime={parseFloat(foreground.endTime)}
|
||||
width={foreground.width}
|
||||
position={foreground.position}
|
||||
backgroundColour={foreground.backgroundColour}
|
||||
text={foreground.text}
|
||||
/>
|
||||
{/each}
|
||||
</ScrollyVideo>
|
||||
{/if}
|
||||
{/each}
|
||||
```
|
||||
|
||||
|
||||
## Time-based component foregrounds with ArchieML
|
||||
|
||||
The `ScrollyVideo` component can also be used to display components, such as `Headline` or ai2svelte files, as foregrounds at specific times in the video. To do so, use the `ScrollyVideoForeground` component.
|
||||
The `ScrollyVideo` component can also be used to display components, such as `Headline` or ai2svelte files, as foregrounds at specific times in the video. To do so, use the `Foreground` prop in `ScrollyVideoForeground` component.
|
||||
|
||||
> **IMPORTANT❗**: When layering ai2svelte files over a video, the aspect ratio of the ai2svelte graphics should match that of the video. If the ai2svelte graphic is responsive and has, for example, small, medium and large verisons — which is generally the case — make sure to also render small, medium and large versions of the video at the appropriate screen sizes. See [Responsive videos](#responsive-videos) for more details.
|
||||
|
||||
[Demo](?path=/story/components-graphics-scrollyvideo--component-archie-ml-foregrounds)
|
||||
|
||||
With the graphics kit, you'll likely get your text and prop values from an ArchieML doc...
|
||||
|
||||
```yaml
|
||||
# ArchieML doc
|
||||
|
||||
# Headline
|
||||
hed: Wind and waves
|
||||
[authors]
|
||||
* Jane Doe
|
||||
[]
|
||||
publishTime: 2020-01-01T00:00:00Z
|
||||
startTime: 0 # When in the video to start showing the headline
|
||||
endTime: 0.3 # When to stop showing the headline
|
||||
|
||||
[blocks]
|
||||
type: scrolly-video
|
||||
id: my-scrolly-video
|
||||
height: 800svh
|
||||
|
||||
# Adjust prop names as needed
|
||||
srcSm: videos/my-video-sm.mp4
|
||||
srcMd: videos/my-video-md.mp4
|
||||
srcLg: videos/my-video-lg.mp4
|
||||
|
||||
# Array of foregrounds
|
||||
[.foregrounds]
|
||||
startTime: 0.3 # When in the video to start showing the foreground
|
||||
endTime: 2.2 # When to stop showing the foreground
|
||||
width: fluid # foreground container width
|
||||
Foreground: Foreground1 # Name of the ai2svelte component to render
|
||||
|
||||
startTime: 2.2
|
||||
endTime: 3.2
|
||||
width: fluid
|
||||
Foreground: Foreground2
|
||||
|
||||
startTime: 3.2
|
||||
endTime: 4.5
|
||||
width: fluid
|
||||
Foreground: Foreground3
|
||||
|
||||
startTime: 6.5
|
||||
endTime: 8
|
||||
width: fluid
|
||||
Foreground: Foreground4
|
||||
[]
|
||||
[]
|
||||
```
|
||||
|
||||
... which you'll parse out of a ArchieML block object before passing to the `ScrollyVideo` and `ScrollyVideoForeground` components.
|
||||
|
||||
|
||||
```svelte
|
||||
<script lang="ts">
|
||||
// Graphics kit only
|
||||
import { assets } from '$app/paths'; // 👈 If using in the graphics kit...
|
||||
import { truthy } from '$utils/propValidators'; // 👈 If using in the graphics kit...
|
||||
|
||||
=
|
||||
import {
|
||||
Headline,
|
||||
GraphicBlock,
|
||||
|
|
@ -239,80 +272,72 @@ With the graphics kit, you'll likely get your text and prop values from an Archi
|
|||
} from '@reuters-graphics/graphics-components';
|
||||
|
||||
// Foreground ai2svelte components
|
||||
import Annotation1 from './ai2svelte/annotation1.svelte';
|
||||
import Annotation2 from './ai2svelte/annotation2.svelte';
|
||||
import Annotation3 from './ai2svelte/annotation3.svelte';
|
||||
import Annotation4 from './ai2svelte/annotation4.svelte';
|
||||
import Foreground1 from './ai2svelte/foreground1.svelte';
|
||||
import Foreground2 from './ai2svelte/foreground2.svelte';
|
||||
import Foreground3 from './ai2svelte/foreground3.svelte';
|
||||
import Foreground4 from './ai2svelte/foreground4.svelte';
|
||||
|
||||
// Foreground ai2svelte graphics components
|
||||
// Add your imported foreground ai2svelte charts to this object
|
||||
const aiChartsForeground = {
|
||||
Annotation1,
|
||||
Annotation2,
|
||||
Annotation3,
|
||||
Annotation4,
|
||||
Foreground1,
|
||||
Foreground2,
|
||||
Foreground3,
|
||||
Foreground4,
|
||||
};
|
||||
|
||||
// Window width for responsive videos
|
||||
let width = $state(1);
|
||||
</script>
|
||||
|
||||
<svelte:window bind:innerWidth={width} />
|
||||
|
||||
{#snippet ScrollForeground()}
|
||||
<Foreground startTime={0} endTime={0.3}>
|
||||
<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={0.3} endTime={2.2}>
|
||||
<GraphicBlock title="" description="" width="fluid">
|
||||
<Annotation1 />
|
||||
</GraphicBlock>
|
||||
</Foreground>
|
||||
<Foreground startTime={2.2} endTime={3.2}>
|
||||
<GraphicBlock title="" description="" width="fluid">
|
||||
<Annotation2 />
|
||||
</GraphicBlock>
|
||||
</Foreground>
|
||||
<Foreground startTime={3.2} endTime={4.5}>
|
||||
<GraphicBlock title="" description="" width="fluid">
|
||||
<Annotation3 />
|
||||
</GraphicBlock>
|
||||
</Foreground>
|
||||
<Foreground startTime={6.5} endTime={8}>
|
||||
<GraphicBlock title="" description="" width="fluid">
|
||||
<Annotation4 />
|
||||
</GraphicBlock>
|
||||
</Foreground>
|
||||
{/snippet}
|
||||
<!-- Loop through content blocks... -->
|
||||
{#each content.blocks as block}
|
||||
|
||||
{#snippet ScrollVideo(height: string, VideoSrc: string)}
|
||||
<ScrollyVideo {height} src={VideoSrc} useWebCodecs={true} showDebugInfo>
|
||||
{@render ScrollForeground()}
|
||||
</ScrollyVideo>
|
||||
{/snippet}
|
||||
{#if block.type == 'scrolly-video'}
|
||||
|
||||
{#if width < 600}
|
||||
{@render ScrollVideo('800svh', `${assets}/videos/sm.mp4`)}
|
||||
{:else if width < 1200}
|
||||
{@render ScrollVideo('800svh', `${assets}/videos/md.mp4`)}
|
||||
{:else}
|
||||
{@render ScrollVideo('800svh', `${assets}/videos/lg.mp4`)}
|
||||
{/if}
|
||||
<!-- ScrollVideo snippet to render responsive videos -->
|
||||
{#snippet ScrollVideo(height: string, src: string)}
|
||||
<ScrollyVideo
|
||||
id={block.id}
|
||||
{height}
|
||||
{src}
|
||||
>
|
||||
<!-- Headline component as foreground -->
|
||||
<ScrollyVideoForeground
|
||||
startTime={parseFloat(content.startTime)}
|
||||
endTime={parseFloat(content.endTime)}
|
||||
>
|
||||
<Headline
|
||||
hed={content.hed}
|
||||
authors={content.authors}
|
||||
publishTime={new Date(content.publishTime).toISOString()}
|
||||
/>
|
||||
</ScrollyVideoForeground>
|
||||
|
||||
<style lang="scss">
|
||||
:global(.custom-headline *) {
|
||||
color: white;
|
||||
}
|
||||
<!-- Loop through block.foregrounds to render each foreground component -->
|
||||
{#each block.foregrounds as foreground}
|
||||
<ScrollyVideoForeground
|
||||
startTime={parseFloat(foreground.startTime)}
|
||||
endTime={parseFloat(foreground.endTime)}
|
||||
width={foreground.width}
|
||||
Foreground={aiChartsForeground[
|
||||
foreground.foreground as keyof typeof aiChartsForeground
|
||||
]}
|
||||
/>
|
||||
{/each}
|
||||
</ScrollyVideo>
|
||||
{/snippet}
|
||||
|
||||
:global(.scrolly-video-foreground) {
|
||||
filter: drop-shadow(0 0 4px rgba(0, 0, 0, 0.85));
|
||||
}
|
||||
</style>
|
||||
<!-- Render the ScrollVideo snippet for different screen sizes -->
|
||||
{#if width < 600}
|
||||
{@render ScrollVideo({block.height}, `${assets}/${block.srcSm}`)}
|
||||
{:else if width < 1200}
|
||||
{@render ScrollVideo({block.height}, `${assets}/${block.srcMd}`)}
|
||||
{:else}
|
||||
{@render ScrollVideo({block.height}, `${assets}/${block.srcLg}`)}
|
||||
{/if}
|
||||
{/each}
|
||||
```
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,8 @@
|
|||
backgroundColour?: string;
|
||||
width?: ContainerWidth;
|
||||
position?: ScrollyVideoForegroundPosition | string;
|
||||
foreground?: string | Component;
|
||||
text?: string;
|
||||
Foreground?: Component;
|
||||
}
|
||||
|
||||
let {
|
||||
|
|
@ -33,7 +34,8 @@
|
|||
backgroundColour = '#000',
|
||||
width = 'normal',
|
||||
position = 'center center',
|
||||
foreground,
|
||||
text,
|
||||
Foreground,
|
||||
}: ForegroundProps = $props();
|
||||
|
||||
let componentState: ScrollyVideoState = getContext('scrollyVideoState');
|
||||
|
|
@ -46,27 +48,31 @@
|
|||
in:fade={{ delay: 100, duration: 200 }}
|
||||
out:fade={{ delay: 0, duration: 100 }}
|
||||
>
|
||||
<div class="scrolly-video-foreground-item">
|
||||
{#if children}
|
||||
{@render children()}
|
||||
{/if}
|
||||
</div>
|
||||
{#if foreground}
|
||||
{#if typeof foreground === 'string'}
|
||||
<Block
|
||||
class="scrolly-video-foreground-text {position.split(' ')[1]}"
|
||||
{width}
|
||||
<!-- Text blurb foreground -->
|
||||
{#if text}
|
||||
<Block
|
||||
class="scrolly-video-foreground-text {position.split(' ')[1]}"
|
||||
{width}
|
||||
>
|
||||
<div
|
||||
style="background-color: {backgroundColour};"
|
||||
class="foreground-text {position.split(' ')[0]}"
|
||||
>
|
||||
<div
|
||||
style="background-color: {backgroundColour};"
|
||||
class="foreground-text {position.split(' ')[0]}"
|
||||
>
|
||||
<Markdown source={foreground} />
|
||||
</div>
|
||||
<Markdown source={text} />
|
||||
</div>
|
||||
</Block>
|
||||
<!-- Render children snippet -->
|
||||
{:else if children}
|
||||
<div class="scrolly-video-foreground-item">
|
||||
{@render children()}
|
||||
</div>
|
||||
<!-- Render Foreground component -->
|
||||
{:else if Foreground}
|
||||
<div class="scrolly-video-foreground-item">
|
||||
<Block width="fluid">
|
||||
<Foreground />
|
||||
</Block>
|
||||
{:else}
|
||||
{foreground}
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
|
|
|
|||
|
|
@ -5,13 +5,20 @@
|
|||
import MD from '../videos/waves_md.mp4';
|
||||
import LG from '../videos/waves_lg.mp4';
|
||||
import Headline from '../../Headline/Headline.svelte';
|
||||
import Block from '../../Block/Block.svelte';
|
||||
|
||||
// Foreground ai2svelte components
|
||||
import Annotation1 from './graphic/ai2svelte/annotation1.svelte';
|
||||
import Annotation2 from './graphic/ai2svelte/annotation2.svelte';
|
||||
import Annotation3 from './graphic/ai2svelte/annotation3.svelte';
|
||||
import Annotation4 from './graphic/ai2svelte/annotation4.svelte';
|
||||
import Foreground1 from './graphic/ai2svelte/annotation1.svelte';
|
||||
import Foreground2 from './graphic/ai2svelte/annotation2.svelte';
|
||||
import Foreground3 from './graphic/ai2svelte/annotation3.svelte';
|
||||
import Foreground4 from './graphic/ai2svelte/annotation4.svelte';
|
||||
|
||||
// Foreground ai2svelte graphics components
|
||||
const aiChartsForeground = {
|
||||
Foreground1,
|
||||
Foreground2,
|
||||
Foreground3,
|
||||
Foreground4,
|
||||
};
|
||||
|
||||
const content = {
|
||||
hed: 'Wind and waves',
|
||||
|
|
@ -29,19 +36,25 @@
|
|||
startTime: '0.3',
|
||||
endTime: '2.2',
|
||||
width: 'fluid',
|
||||
foregroud: 'Annotation1',
|
||||
foreground: 'Foreground1',
|
||||
},
|
||||
{
|
||||
startTime: '7',
|
||||
endTime: '12',
|
||||
startTime: '2.2',
|
||||
endTime: '3.2',
|
||||
width: 'fluid',
|
||||
foreground: 'Annotation2',
|
||||
foreground: 'Foreground2',
|
||||
},
|
||||
{
|
||||
startTime: '14',
|
||||
endTime: '20',
|
||||
startTime: '3.2',
|
||||
endTime: '4.5',
|
||||
width: 'fluid',
|
||||
foreground: 'Annotation3',
|
||||
foreground: 'Foreground3',
|
||||
},
|
||||
{
|
||||
startTime: '6.5',
|
||||
endTime: '8',
|
||||
width: 'fluid',
|
||||
foreground: 'Foreground4',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
|
@ -50,62 +63,49 @@
|
|||
const scrollyVideoBlock = content.blocks[0];
|
||||
|
||||
let width = $state(1);
|
||||
|
||||
let src = $derived(() => {
|
||||
if (width < 600) return '../videos/waves_sm.mp4';
|
||||
else if (width < 1200) return '../videos/waves_md.mp4';
|
||||
else return '../videos/waves_lg.mp4';
|
||||
});
|
||||
</script>
|
||||
|
||||
<svelte:window bind:innerWidth={width} />
|
||||
|
||||
{#snippet ScrollVideo(height: string, VideoSrc: string)}
|
||||
{#snippet ScrollVideo(height: string, src: string)}
|
||||
<ScrollyVideo
|
||||
class="surf-scrolly"
|
||||
id={scrollyVideoBlock.id}
|
||||
{height}
|
||||
src={VideoSrc}
|
||||
{src}
|
||||
useWebCodecs={true}
|
||||
showDebugInfo
|
||||
>
|
||||
<ScrollyVideoForeground startTime={0} endTime={0.3}>
|
||||
<ScrollyVideoForeground
|
||||
startTime={parseFloat(content.startTime)}
|
||||
endTime={parseFloat(content.endTime)}
|
||||
>
|
||||
<Headline
|
||||
class="custom-headline"
|
||||
hed="Wind and waves"
|
||||
authors={['Jane Doe']}
|
||||
publishTime={new Date('2020-01-01').toISOString()}
|
||||
hed={content.hed}
|
||||
authors={content.authors}
|
||||
publishTime={new Date(content.publishTime).toISOString()}
|
||||
/>
|
||||
</ScrollyVideoForeground>
|
||||
|
||||
{#each scrollyVideoBlock.foregrounds as foreground, idx}
|
||||
{#if foreground.foreground}
|
||||
<ScrollyVideoForeground
|
||||
startTime={parseFloat(foreground.startTime)}
|
||||
endTime={parseFloat(foreground.endTime)}
|
||||
>
|
||||
<Block width="fluid">
|
||||
{#if idx === 0}
|
||||
<Annotation1 />
|
||||
{:else if idx === 1}
|
||||
<Annotation2 />
|
||||
{:else if idx === 2}
|
||||
<Annotation3 />
|
||||
{:else if idx === 3}
|
||||
<Annotation4 />
|
||||
{/if}
|
||||
</Block>
|
||||
</ScrollyVideoForeground>
|
||||
{/if}
|
||||
{#each scrollyVideoBlock.foregrounds as foreground}
|
||||
<ScrollyVideoForeground
|
||||
startTime={parseFloat(foreground.startTime)}
|
||||
endTime={parseFloat(foreground.endTime)}
|
||||
width={foreground.width as 'fluid'}
|
||||
Foreground={aiChartsForeground[
|
||||
foreground.foreground as keyof typeof aiChartsForeground
|
||||
]}
|
||||
/>
|
||||
{/each}
|
||||
</ScrollyVideo>
|
||||
{/snippet}
|
||||
|
||||
{#if width < 600}
|
||||
{@render ScrollVideo('800svh', SM)}
|
||||
{@render ScrollVideo(scrollyVideoBlock.height, SM)}
|
||||
{:else if width < 1200}
|
||||
{@render ScrollVideo('800svh', MD)}
|
||||
{@render ScrollVideo(scrollyVideoBlock.height, MD)}
|
||||
{:else}
|
||||
{@render ScrollVideo('800svh', LG)}
|
||||
{@render ScrollVideo(scrollyVideoBlock.height, LG)}
|
||||
{/if}
|
||||
|
||||
<style lang="scss">
|
||||
|
|
|
|||
|
|
@ -2,15 +2,9 @@
|
|||
import ScrollyVideo from '../ScrollyVideo.svelte';
|
||||
import ScrollyVideoForeground from '../ScrollyVideoForeground.svelte';
|
||||
import Drone from '../videos/drone.mp4';
|
||||
import Headline from '../../Headline/Headline.svelte';
|
||||
import type { ContainerWidth } from '../../@types/global';
|
||||
|
||||
const content = {
|
||||
hed: 'The Alps',
|
||||
authors: ['Jane Doe'],
|
||||
publishTime: '2020-01-01T00:00:00Z',
|
||||
startTime: '0',
|
||||
endTime: '2',
|
||||
blocks: [
|
||||
{
|
||||
type: 'scrolly-video',
|
||||
|
|
@ -57,19 +51,6 @@
|
|||
useWebCodecs={true}
|
||||
showDebugInfo
|
||||
>
|
||||
<!-- <ScrollyVideoForeground
|
||||
startTime={parseFloat(content.startTime)}
|
||||
endTime={parseFloat(content.endTime)}
|
||||
>
|
||||
<Headline
|
||||
class="custom-headline"
|
||||
hed={content.hed}
|
||||
authors={content.authors}
|
||||
publishTime={new Date(content.publishTime).toISOString()}
|
||||
hedSize="bigger"
|
||||
/>
|
||||
</ScrollyVideoForeground> -->
|
||||
|
||||
{#each scrollyVideoBlock.foregrounds as foreground}
|
||||
<ScrollyVideoForeground
|
||||
startTime={parseFloat(foreground.startTime)}
|
||||
|
|
@ -77,7 +58,7 @@
|
|||
width={foreground.width as ContainerWidth}
|
||||
position={foreground.position}
|
||||
backgroundColour={foreground.backgroundColour}
|
||||
foreground={foreground.text}
|
||||
text={foreground.text}
|
||||
/>
|
||||
{/each}
|
||||
</ScrollyVideo>
|
||||
|
|
|
|||
Loading…
Reference in a new issue