updated docs

This commit is contained in:
MinamiFunakoshiTR 2025-12-03 14:26:01 -05:00
parent 675860a4b8
commit 4f2d8d996c
Failed to extract signature
5 changed files with 163 additions and 183 deletions

View file

@ -47,6 +47,8 @@ If importing the Lottie file directly into a Svelte component, make sure to appe
## Using with ArchieML ## Using with ArchieML
If you are using `Lottie` with ArchieML, store your Lottie zip file in the `src/statics/lottie/` folder.
With the graphics kit, you'll likely get your text and prop values from an ArchieML doc... With the graphics kit, you'll likely get your text and prop values from an ArchieML doc...
```yaml ```yaml
@ -98,12 +100,18 @@ With the graphics kit, you'll likely get your text and prop values from an Archi
# ArchieML doc # ArchieML doc
[blocks] [blocks]
type: lottie type: lottie
src: LottieFile.zip showDebugInfo: true
loop: true
# Optionally, set playback speed
speed: 0.5
# Lottie file stored in `src/statics/lottie/` folder
src: lottie/LottieFile.zip
[.segment] [.segment]
start: 0 start: 0
end: 20 end: 20
[] []
:end
[] []
``` ```
@ -112,18 +120,21 @@ With the graphics kit, you'll likely get your text and prop values from an Archi
```svelte ```svelte
<script lang="ts"> <script lang="ts">
import { Lottie } from '@reuters-graphics/graphics-components'; import { Lottie } from '@reuters-graphics/graphics-components';
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...
</script> </script>
{#each content.blocks as block} {#each content.blocks as block}
<!-- Inside the content.blocks for loop... --> <!-- Inside the content.blocks for loop... -->
{#if block.type == 'lottie'} {#if block.type == 'lottie'}
<Lottie <Lottie
src={`${assets}/animations/${block.src}`} src={`${assets}/${block.src}`}
segment={[block.segment.start, block.segment.end]} segment={[parseInt(block.segment.start), parseInt(block.segment.end)]}
autoplay showDebugInfo={truthy(block.showDebugInfo)}
loop loop={truthy(block.loop)}
showDebugInfo speed={parseInt(block.speed)}
/> />
{/if} {/if}
{/each} {/each}
@ -155,60 +166,25 @@ When setting markers in AfterEffects, ensure that the **Comment** section of the
## Switching themes ## Switching themes
[Lottie Creator](https://lottiefiles.com/theming) allows you to define multiple color themes for your animation. You can switch between these themes using the `theme` prop. [Lottie Creator](https://lottiefiles.com/theming) allows you to define multiple colour themes for your animation. You can switch between these themes using the `theme` prop.
Available themes can be found in the debug info when `showDebugInfo` prop is enabled. Available themes can be found in the debug info when the `showDebugInfo` prop is set to `true`.
With the graphics kit, you'll likely get your text and prop values from an ArchieML doc... You can set multiple themes and switch between them dynamically -- for example, based on the `progress` of the animation.
```yaml
# ArchieML doc
[blocks]
type: lottie
src: LottieFile.zip
theme: myTheme
:end
[]
```
... which you'll parse out of a ArchieML block object before passing to the `Lottie` component.
```svelte
<script lang="ts">
import { Lottie } from '@reuters-graphics/graphics-components';
import { assets } from '$app/paths';
</script>
{#each content.blocks as block}
<!-- Inside the content.blocks for loop... -->
{#if block.type == 'lottie'}
<Lottie
src={`${assets}/animations/${block.src}`}
theme={block.theme}
autoplay
loop
showDebugInfo
/>
{/if}
{/each}
```
It is also possible to switch themes dynamically based on the `progress` prop by binding a variable to it.
[Demo](?path=/story/components-graphics-scrollerlottie--themes) [Demo](?path=/story/components-graphics-scrollerlottie--themes)
```svelte ```svelte
<script lang="ts"> <script lang="ts">
import { Lottie } from '@reuters-graphics/graphics-components'; import { Lottie } from '@reuters-graphics/graphics-components';
// make a folder named 'data' and place the .zip lottie file inside it import MyLottie from './lottie/my-lottie.zip?url';
// append ?url to the import statement
import LottieSrc from './data/lottie-example.zip?url';
// Set a bindable `progress` variable to pass into `<Lottie />`
let progress = $state(0); let progress = $state(0);
</script> </script>
<Lottie <Lottie
src={LottieSrc} src={MyLottie}
bind:progress bind:progress
themeId={progress < 0.33 ? 'water' themeId={progress < 0.33 ? 'water'
: progress < 0.66 ? 'air' : progress < 0.66 ? 'air'
@ -218,16 +194,14 @@ It is also possible to switch themes dynamically based on the `progress` prop by
/> />
``` ```
## With ScrollerBase ## Using with `ScrollerBase`
The `Lottie` component can be used in conjunction with the `ScrollerBase` component to create a more complex scrolling experience. The `ScrollerBase` component provides a scrollable container that can hold the `Lottie` component as a background. The `Lottie` component can be used with the `ScrollerBase` component to create a more complex scrolling experience. `ScrollerBase` provides a scrollable container sets the `Lottie` component as a background.
```svelte ```svelte
<script lang="ts"> <script lang="ts">
import { Lottie } from '@reuters-graphics/graphics-components'; import { Lottie, ScrollerBase } from '@reuters-graphics/graphics-components';
// make a folder named 'data' and place the .zip lottie file inside it import MyLottie from './lottie/my-lottie.zip?url';
// append ?url to the import statement
import LottieSrc from './data/lottie-example.zip?url';
// Pass `progress` as `videoPercentage` to Lottie // Pass `progress` as `videoPercentage` to Lottie
let progress = $state(0); let progress = $state(0);
@ -236,12 +210,9 @@ The `Lottie` component can be used in conjunction with the `ScrollerBase` compon
<ScrollerBase bind:progress query="div.step-foreground-container"> <ScrollerBase bind:progress query="div.step-foreground-container">
{#snippet backgroundSnippet()} {#snippet backgroundSnippet()}
<!-- Pass bindable prop `progress` as `progress` --> <!-- Pass bindable prop `progress` as `progress` -->
<div class="lottie-container"> <Lottie src={MyLottie} {progress} showDebugInfo />
<Lottie src={LottieSrc} {progress} showDebugInfo />
</div>
{/snippet} {/snippet}
{#snippet foregroundSnippet()} {#snippet foregroundSnippet()}
<!-- Add custom foreground HTML or component -->
<div class="step-foreground-container"> <div class="step-foreground-container">
<h3 class="text-center">Step 1</h3> <h3 class="text-center">Step 1</h3>
</div> </div>
@ -255,23 +226,14 @@ The `Lottie` component can be used in conjunction with the `ScrollerBase` compon
</ScrollerBase> </ScrollerBase>
<style lang="scss"> <style lang="scss">
.lottie-container {
width: 100%;
height: 100lvh;
}
.step-foreground-container { .step-foreground-container {
height: 100lvh; height: 100lvh;
width: 50%; width: 50%;
padding: 1em; margin: 0 auto;
margin: auto;
h3 { h3 {
display: flex; background-color: antiquewhite;
align-items: center; text-align: center;
justify-content: center;
height: 100%;
color: white;
} }
} }
</style> </style>
@ -279,41 +241,90 @@ The `Lottie` component can be used in conjunction with the `ScrollerBase` compon
## With foregrounds ## With foregrounds
The `Lottie` component can also be used to display captions or even components, such as `Headline` or ai2svelte files, as foregrounds at specific times in the animation. To do so, add LottieForeground components as children of the Lottie component. The `Lottie` component can also be used with the `LottieForeground` component to display foreground elements at specific times in the animation.
[Demo](?path=/story/components-graphics-scrollerlottie--with-foregrounds) [Demo](?path=/story/components-graphics-scrollerlottie--with-foregrounds).
```svelte
<script lang="ts">
import { Lottie, ScrollerBase } from '@reuters-graphics/graphics-components';
import MyLottie from './lottie/my-lottie.zip?url';
</script>
<Lottie src={MyLottie} autoplay >
<!-- Foreground 1: Headline component as foreground -->
<LottieForeground
startFrame={0}
endFrame={50}
position="center center"
backgroundColour="rgba(0, 0, 0)"
>
<div class="headline-container">
<Theme base="dark">
<Headline
hed="Headline"
dek="This is an example of using a Svelte component as the foreground."
authors={['Jane Doe', 'John Doe']}
/>
</Theme>
</div>
</LottieForeground>
<!-- Foreground 2: Text only -->
<LottieForeground
startFrame={50}
endFrame={100}
text="Foreground caption between frames 50 and 100."
position="bottom center"
backgroundColour="rgba(0, 0, 0)"
width="wide"
/>
</Lottie>
```
### Using with ArchieML
With the graphics kit, you'll likely get your text and prop values from an ArchieML doc... With the graphics kit, you'll likely get your text and prop values from an ArchieML doc...
```yaml ```yaml
# ArchieML doc # ArchieML doc
[blocks] [blocks]
type: lottie type: lottie
src: LottieFile.zip
# Lottie file stored in `src/statics/lottie/` folder
src: lottie/LottieFile.zip
# Array of foregrounds # Array of foregrounds
[.foregrounds] [.foregrounds]
# Foreground 1: Headline component
startFrame: 0 # When in the animation to start showing the foreground startFrame: 0 # When in the animation to start showing the foreground
endFrame: 50 # When to stop showing the foreground endFrame: 50 # When to stop showing the foreground
type: text
{.foregroundProps}
text: Some text for the foreground
{}
startFrame: 50 # When in the animation to start showing the foreground # Set foreground type
endFrame: 100 # When to stop showing the foreground type: component
type: component
{.foregroundProps} # Set props to pass into `LottieForeground`
componentType: Headline {.foregroundProps}
hed: Some headline text componentName: Headline
dek: Some deck text hed: Headline
[.authors] dek: Some deck text
* Jane Doe [.authors]
* John Smith * Jane Doe
[] * John Smith
{} []
[] {}
:end
# Foreground 2: Text only
startFrame: 50
endFrame: 100
# Set foreground type
type: text
# If the foreground type is `text`, set text prop here
{.foregroundProps}
text: Some text for the foreground
{}
[] []
``` ```
@ -328,35 +339,29 @@ With the graphics kit, you'll likely get your text and prop values from an Archi
} from '@reuters-graphics/graphics-components'; } from '@reuters-graphics/graphics-components';
import { assets } from '$app/paths'; import { assets } from '$app/paths';
// Make an object of components to use as foregrounds
const Components = $state({ const Components = $state({
Headline, Headline,
Video,
}); });
</script> </script>
{#each content.blocks as block} {#each content.blocks as block}
<!-- Inside the content.blocks for loop... --> <!-- Inside the content.blocks for loop... -->
{#if block.type == 'lottie'} {#if block.type == 'lottie'}
<Lottie <Lottie src={`${assets}/${block.src}`} >
src={`${assets}/animations/${block.src}`}
theme={block.theme}
autoplay
loop
showDebugInfo
>
{#each block.foregrounds as foreground} {#each block.foregrounds as foreground}
{#if foreground.type == 'text'} {#if foreground.type == 'text'}
<LottieForeground <LottieForeground
endFrame={parseInt(foreground.endFrame)}
startFrame={parseInt(foreground.startFrame)} startFrame={parseInt(foreground.startFrame)}
endFrame={parseInt(foreground.endFrame)}
text={foreground.foregroundProps.text} text={foreground.foregroundProps.text}
/> />
{:else if foreground.type == 'component'} {:else if foreground.type == 'component'}
{@const Component = {@const Component =
Components[foreground.foregroundProps.componentType]} Components[foreground.foregroundProps.componentName]}
<LottieForeground <LottieForeground
endFrame={parseInt(foreground.endFrame)}
startFrame={parseInt(foreground.startFrame)} startFrame={parseInt(foreground.startFrame)}
endFrame={parseInt(foreground.endFrame)}
> >
<Component {...foreground.foregroundProps} /> <Component {...foreground.foregroundProps} />
</LottieForeground> </LottieForeground>

View file

@ -1,5 +1,7 @@
<script module lang="ts"> <script module lang="ts">
import { defineMeta } from '@storybook/addon-svelte-csf'; import { defineMeta } from '@storybook/addon-svelte-csf';
// Components
import Lottie from './Lottie.svelte'; import Lottie from './Lottie.svelte';
import LottieForeground from './LottieForeground.svelte'; import LottieForeground from './LottieForeground.svelte';
import Headline from '../Headline/Headline.svelte'; import Headline from '../Headline/Headline.svelte';
@ -42,17 +44,6 @@
<Lottie src={DemoLottie} autoplay={true} showDebugInfo={true} /> <Lottie src={DemoLottie} autoplay={true} showDebugInfo={true} />
</Story> </Story>
<Story name="Marker">
<Lottie
src={MarkerSample}
showDebugInfo
autoplay
marker="ballerina"
loop
mode="bounce"
/>
</Story>
<Story name="Segment"> <Story name="Segment">
<Lottie <Lottie
src={DemoLottie} src={DemoLottie}
@ -64,6 +55,17 @@
/> />
</Story> </Story>
<Story name="Marker">
<Lottie
src={MarkerSample}
showDebugInfo
autoplay
marker="ballerina"
loop
mode="bounce"
/>
</Story>
<Story name="Themes"> <Story name="Themes">
<Lottie <Lottie
src={ThemesSample} src={ThemesSample}
@ -81,39 +83,32 @@
</Story> </Story>
<Story name="With foregrounds"> <Story name="With foregrounds">
<Lottie <Lottie src={ForegroundSample} autoplay }>
src={ForegroundSample} <LottieForeground
showDebugInfo startFrame={0}
autoplay endFrame={50}
speed={0.5} position="center center"
loop backgroundColour="rgba(0, 0, 0)"
mode="bounce" >
> <div class="headline-container">
<Theme base="dark">
<Headline
hed="Headline"
dek="This is an example of using a Svelte component as the foreground."
authors={['Jane Doe', 'John Doe']}
/>
</Theme>
</div>
</LottieForeground>
<LottieForeground <LottieForeground
startFrame={50} startFrame={50}
endFrame={100} endFrame={100}
text="Foreground caption between frames 50 and 100." text="Foreground caption between frames 50 and 100."
position="bottom center" position="bottom center"
backgroundColour="rgba(0, 0, 0)" backgroundColour="rgba(0, 0, 0)"
width="normal" width="wide"
/> />
<LottieForeground
startFrame={0}
endFrame={50}
position="center center"
backgroundColour="rgba(0, 0, 0)"
width="normal"
>
<Theme base="dark">
<Headline
hed="Lottie with foreground component"
dek="This is an example of using a Svelte component as the foreground."
width="normal"
authors={['Jane Doe', 'John Doe']}
/>
</Theme>
</LottieForeground>
</Lottie> </Lottie>
</Story> </Story>
@ -132,4 +127,13 @@
} }
} }
} }
.headline-container {
width: 100%;
height: 100%;
position: absolute;
display: flex;
justify-content: center;
align-items: center;
}
</style> </style>

View file

@ -38,14 +38,14 @@
speed = 1, speed = 1,
data = undefined, data = undefined,
backgroundColor = '#ffffff', backgroundColor = '#ffffff',
segment = undefined, segment,
renderConfig = undefined, renderConfig,
dotLottieRefCallback = () => {}, dotLottieRefCallback = () => {},
useFrameInterpolation = true, useFrameInterpolation = true,
themeId = '', themeId = '',
themeData = '', themeData = '',
playOnHover = false, playOnHover = false,
marker = undefined, marker,
layout = { fit: 'contain', align: [0.5, 0.5] }, layout = { fit: 'contain', align: [0.5, 0.5] },
animationId = '', animationId = '',
lottiePlayer = $bindable(undefined), lottiePlayer = $bindable(undefined),

View file

@ -5,7 +5,7 @@
import { Markdown } from '@reuters-graphics/svelte-markdown'; import { Markdown } from '@reuters-graphics/svelte-markdown';
// Types // Types
import type { Component, Snippet } from 'svelte'; import type { Snippet } from 'svelte';
import type { LottieState } from './ts/lottieState.svelte'; import type { LottieState } from './ts/lottieState.svelte';
import type { import type {
ContainerWidth, ContainerWidth,
@ -22,12 +22,11 @@
width?: ContainerWidth; width?: ContainerWidth;
position?: LottieForegroundPosition | string; position?: LottieForegroundPosition | string;
text?: string; text?: string;
Foreground?: Component;
} }
let { let {
id = '', id,
class: cls = '', class: cls,
startFrame = 0, startFrame = 0,
endFrame = 10, endFrame = 10,
children, children,
@ -35,7 +34,6 @@
width = 'normal', width = 'normal',
position = 'center center', position = 'center center',
text, text,
Foreground,
}: ForegroundProps = $props(); }: ForegroundProps = $props();
let componentState: LottieState | null = $state(getContext('lottieState')); let componentState: LottieState | null = $state(getContext('lottieState'));
@ -67,16 +65,7 @@
</Block> </Block>
<!-- Render children snippet --> <!-- Render children snippet -->
{:else if children} {:else if children}
<div class="scroller-lottie-foreground-item"> {@render children()}
{@render children()}
</div>
<!-- Render Foreground component -->
{:else if Foreground}
<div class="scroller-lottie-foreground-item">
<Block width="fluid">
<Foreground />
</Block>
</div>
{/if} {/if}
</div> </div>
{/if} {/if}

View file

@ -24,44 +24,26 @@
query="div.step-foreground-container" query="div.step-foreground-container"
> >
{#snippet backgroundSnippet()} {#snippet backgroundSnippet()}
<!-- Add custom background HTML or component --> <Lottie src={LottieSample} {progress} showDebugInfo />
<div class="lottie-container">
<Lottie src={LottieSample} showDebugInfo {progress} />
</div>
{/snippet} {/snippet}
{#snippet foregroundSnippet()} {#snippet foregroundSnippet()}
<!-- Add custom foreground HTML or component --> <div class="step-foreground-container"><h3>Step 1</h3></div>
<div class="step-foreground-container"><p>Step 1</p></div> <div class="step-foreground-container"><h3>Step 2</h3></div>
<div class="step-foreground-container"><p>Step 2</p></div> <div class="step-foreground-container"><h3>Step 3</h3></div>
<div class="step-foreground-container"><p>Step 3</p></div> <div class="step-foreground-container"><h3>Step 4</h3></div>
<div class="step-foreground-container"><p>Step 4</p></div> <div class="step-foreground-container"><h3>Step 5</h3></div>
<div class="step-foreground-container"><p>Step 5</p></div>
{/snippet} {/snippet}
</ScrollerBase> </ScrollerBase>
<style lang="scss"> <style lang="scss">
@use '../../../scss/mixins' as mixins; @use '../../../scss/mixins' as mixins;
.lottie-container {
// border: 2px solid red;
width: 100%;
height: 100lvh;
}
.step-foreground-container { .step-foreground-container {
height: 100lvh; height: 100lvh;
width: 50%; width: 50%;
background-color: rgba(0, 0, 0, 0);
padding: 1em;
margin: 0 auto; margin: 0 auto;
position: relative;
margin-bottom: 2rem;
p { h3 {
position: relative;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
background-color: antiquewhite; background-color: antiquewhite;
text-align: center; text-align: center;
} }