working on ai2svelte foregrouds

This commit is contained in:
MinamiFunakoshiTR 2025-07-21 10:44:08 -04:00
parent 096026a7eb
commit 69b08e65c9
Failed to extract signature
6 changed files with 121 additions and 72 deletions

View file

@ -116,9 +116,9 @@ The `autoplay` option combines the autoplay and scrollytelling experience. If se
/>
```
## Time-based foregrounds with ArchieML
## Time-based text foregrounds with ArchieML
The `ScrollyVideo` component can also be used to display foregrounds, such as headlines, blurbs, or ai2svelte components, 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 `ScrollyVideoForeground` component.
[Demo](?path=/story/components-graphics-scrollyvideo--archie-ml-foregrounds)
@ -217,15 +217,19 @@ endTime: 2 # When to stop showing the headline
```
## Time based Foregrounds
## Time-based component foregrounds with ArchieML
The `ScrollyVideo` component can also be used to display different foregrounds based on the current time in the video. This is useful for creating interactive experiences where the content changes as the video progresses. To throw off some ideas, one could add `Headline`, `GraphicBlock`, `FeaturePhoto` or any other component to the foreground based on the current time in the video. This can be achieved by adding `Foreground` components, along with their **startTime** and **endTime**, as a child to the main `ScrollyVideo` 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 `ScrollyVideoForeground` component.
[Demo](?path=/story/components-graphics-scrollyvideo--ai-2-svelte-foregrounds)
[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...
```svelte
<script lang="ts">
import { assets } from '$app/paths';
// 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,
@ -233,11 +237,21 @@ The `ScrollyVideo` component can also be used to display different foregrounds b
ScrollyVideo,
Foreground,
} 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';
// Foreground ai2svelte graphics components
const aiChartsForeground = {
Annotation1,
Annotation2,
Annotation3,
Annotation4,
};
let width = $state(1);
</script>

View file

@ -194,8 +194,8 @@
</Story>
<Story
name="Time-based ai2svelte foregrounds"
exportName="Ai2svelteForegrounds"
name="Time-based component foregrounds with ArchieML"
exportName="ComponentArchieMLForegrounds"
{args}
>
<WithAi2svelteForegrounds />

View file

@ -115,14 +115,6 @@
...embeddedProps,
};
console.log(
'embedded',
embedded,
'embeddedSrc:',
embeddedSrc,
'restProps:',
restProps.src
);
$effect(() => {
if (scrollyVideoContainer) {
if (JSON.stringify(restProps) !== lastPropsString) {

View file

@ -1,11 +1,11 @@
<script lang="ts">
import type { Snippet } from 'svelte';
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 { Component, Snippet } from 'svelte';
import type { ScrollyVideoState } from './ts/state.svelte';
import type {
ContainerWidth,
@ -21,7 +21,7 @@
backgroundColour?: string;
width?: ContainerWidth;
position?: ScrollyVideoForegroundPosition | string;
text?: string | undefined;
foreground?: string | Component;
}
let {
@ -33,7 +33,7 @@
backgroundColour = '#000',
width = 'normal',
position = 'center center',
text,
foreground,
}: ForegroundProps = $props();
let componentState: ScrollyVideoState = getContext('scrollyVideoState');
@ -51,18 +51,22 @@
{@render children()}
{/if}
</div>
{#if typeof text === 'string' && text.trim() !== ''}
<Block
class="scrolly-video-foreground-text {position.split(' ')[1]}"
{width}
>
<div
style="background-color: {backgroundColour};"
class="foreground-text {position.split(' ')[0]}"
{#if foreground}
{#if typeof foreground === 'string'}
<Block
class="scrolly-video-foreground-text {position.split(' ')[1]}"
{width}
>
<Markdown source={text} />
</div>
</Block>
<div
style="background-color: {backgroundColour};"
class="foreground-text {position.split(' ')[0]}"
>
<Markdown source={foreground} />
</div>
</Block>
{:else}
{foreground}
{/if}
{/if}
</div>
{/if}

View file

@ -4,51 +4,62 @@
import SM from '../videos/waves_sm.mp4';
import MD from '../videos/waves_md.mp4';
import LG from '../videos/waves_lg.mp4';
import GraphicBlock from '../../GraphicBlock/GraphicBlock.svelte';
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';
const content = {
hed: 'Wind and waves',
authors: ['Jane Doe'],
publishTime: '2020-01-01T00:00:00Z',
startTime: '0',
endTime: '0.3',
blocks: [
{
type: 'scrolly-video',
id: 'surf-scrolly',
height: '800svh',
foregrounds: [
{
startTime: '0.3',
endTime: '2.2',
width: 'fluid',
foregroud: 'Annotation1',
},
{
startTime: '7',
endTime: '12',
width: 'fluid',
foreground: 'Annotation2',
},
{
startTime: '14',
endTime: '20',
width: 'fluid',
foreground: 'Annotation3',
},
],
},
],
};
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 ScrollForeground()}
<ScrollyVideoForeground 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()}
/>
</ScrollyVideoForeground>
<ScrollyVideoForeground startTime={0.3} endTime={2.2}>
<GraphicBlock title="" description="" width="fluid">
<Annotation1 />
</GraphicBlock>
</ScrollyVideoForeground>
<ScrollyVideoForeground startTime={2.2} endTime={3.2}>
<GraphicBlock title="" description="" width="fluid">
<Annotation2 />
</GraphicBlock>
</ScrollyVideoForeground>
<ScrollyVideoForeground startTime={3.2} endTime={4.5}>
<GraphicBlock title="" description="" width="fluid">
<Annotation3 />
</GraphicBlock>
</ScrollyVideoForeground>
<ScrollyVideoForeground startTime={6.5} endTime={8}>
<GraphicBlock title="" description="" width="fluid">
<Annotation4 />
</GraphicBlock>
</ScrollyVideoForeground>
{/snippet}
{#snippet ScrollVideo(height: string, VideoSrc: string)}
<ScrollyVideo
class="surf-scrolly"
@ -57,7 +68,35 @@
useWebCodecs={true}
showDebugInfo
>
{@render ScrollForeground()}
<ScrollyVideoForeground startTime={0} endTime={0.3}>
<Headline
class="custom-headline"
hed="Wind and waves"
authors={['Jane Doe']}
publishTime={new Date('2020-01-01').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}
</ScrollyVideo>
{/snippet}

View file

@ -19,15 +19,15 @@
height: '800svh',
foregrounds: [
{
startTime: '3',
endTime: '7',
startTime: '0',
endTime: '5',
width: 'normal',
position: 'bottom center',
backgroundColour: '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).',
},
{
startTime: '9',
startTime: '7',
endTime: '12',
width: 'normal',
position: 'bottom center',
@ -35,7 +35,7 @@
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.",
},
{
startTime: '16',
startTime: '14',
endTime: '20',
width: 'normal',
position: 'bottom center',
@ -57,7 +57,7 @@
useWebCodecs={true}
showDebugInfo
>
<ScrollyVideoForeground
<!-- <ScrollyVideoForeground
startTime={parseFloat(content.startTime)}
endTime={parseFloat(content.endTime)}
>
@ -68,7 +68,7 @@
publishTime={new Date(content.publishTime).toISOString()}
hedSize="bigger"
/>
</ScrollyVideoForeground>
</ScrollyVideoForeground> -->
{#each scrollyVideoBlock.foregrounds as foreground}
<ScrollyVideoForeground
@ -76,8 +76,8 @@
endTime={parseFloat(foreground.endTime)}
width={foreground.width as ContainerWidth}
position={foreground.position}
text={foreground.text}
backgroundColour={foreground.backgroundColour}
foreground={foreground.text}
/>
{/each}
</ScrollyVideo>