import { Meta } from '@storybook/blocks';
import * as ScrollyVideoStories from './ScrollyVideo.stories.svelte';
# ScrollyVideo
The `ScrollyVideo` component is a powerful tool for creating engaging, interactive video experiences that respond to user scrolling. It allows for precise control over video playback, including the ability to sync video progress with scroll position.
The `ScrollyVideo` component is built on top of the [ScrollyVideo.js](https://scrollyvideo.js.org/), and is designed to work seamlessly with Svelte's reactivity model.
> For embedded version, toggle the `embedded` prop to **true** and provide video src to `embeddedSrc` prop. If `embeddedSrc` is not used, it will default to using the original `src` prop. If other elements are used in conjunction with the `ScrollyVideo` component, such as `ScrollerBase`, it is recommended to screen record the desktop output using [Scroll Capture](https://chromewebstore.google.com/detail/scroll-capture/egmhoeaacclmanaimofoooiamhpkimkk?hl=en) and use that video instead.
> To optimise videos for use with the `ScrollyVideo` component, it is recommended to minimise the file size and ensure that the video is encoded in a format that is widely supported across browsers. Videos encoded at higher frames per second (FPS) are bound to crash on phone devices, so it is recommended to use 24 FPS for most videos (or atleast for the phone devices). Toggle showDebugInfo to check on video encoding information.
>
> In case of doubt, fire away this command with the video file in question:
>
> ```bash
> npx ffmpeg -y -i .mp4 -c:v libx264 -movflags faststart -crf 20 -r 24 -vf scale=720:-1 -profile:v high -preset veryslow -level:v 4.1 -color_primaries 1 -color_trc 1 -colorspace 1 -an .mp4
> ```
>
> This will convert the video to a format that is optimised for web playback, with a resolution of 720p and a frame rate of 24 FPS. Adjust the `-crf` value to control the quality (lower values mean higher quality, with 20 being a good balance).
> Refer to the [Testing Media Capabilities](https://cconcolato.github.io/media-mime-support/mediacapabilities.html) for more details on the encoding formats to use.
## Basic usage
To use the `ScrollyVideo` component, simply import it and provide the video source. Set height prop to any valid CSS height value, such as `1200px`, `50vh`, or `500svh` to set the scrolling height.
[Demo](?path=/story/components-graphics-scrollyvideo--basic)
```svelte
```
## Mutliple videos
It can also be used to display multiple different videos based on the viewport width. This is useful for responsive designs where your subject in the video is not in the center. After Effects can be usd to maintain a crop with a focus on the subject, and the `ScrollyVideo` component can be used to display the appropriate video based on the viewport width.
[Demo](?path=/story/components-graphics-scrollyvideo--multiple-videos)
```svelte
{#if width < 600}
{:else if width < 1200}
{:else}
{/if}
```
## Autoplay
Autoplay can be enabled by setting the `autoplay` prop to `true`. This will start the video playback automatically when the component is mounted. Upon interruption by manual scroll, the video will resume playback on scroll. The height is altered to remaining portion of the video.
[Demo](?path=/story/components-graphics-scrollyvideo--autoplay)
```svelte
```
## Inside ScrollerBase
The `ScrollyVideo` component can also be used inside the `ScrollerBase` component to create a scroller-based layout. This allows for more complex interactions and layouts, such as combining ai2svelte components with scrolly video content.
[Demo](?path=/story/components-graphics-scrollyvideo--inside-scroller-base)
```svelte
{#snippet backgroundSnippet()}
Current step: {index + 1}/{count}
Offset in current step
Total progress
{/snippet}
{#snippet foregroundSnippet()}
Step 2
Step 4
Step 5
{/snippet}
```
## Time based Foregrounds
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.
[Demo](?path=/story/components-graphics-scrollyvideo--time-based-foregrounds)
```svelte
{#snippet ScrollForeground()}
{/snippet}
{#snippet ScrollVideo(height: string, VideoSrc: string)}
{@render ScrollForeground()}
{/snippet}
{#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}
```
## 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
{#if block.type == 'scrolly-video'}
{#each block.foregrounds as caption}
{/each}
{/if}
```
## 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.
```js
scrollyVideo.setVideoPercentage(0.5, {
jump: false,
transitionSpeed: 12,
easing: d3.easeLinear,
});
```
This will set the video to 50% progress, with a smooth transition at a playback rate of 12, using a linear easing function.