A beautiful, performant scroll-driven video component for SvelteKit with smooth scrolling and optimized playback.
npm install
npm run dev
Open http://localhost:5174 in your browser.
npm run build
scrollyvideov2/
āāā src/
ā āāā lib/
ā ā āāā ScrollytellingSection.svelte # Complete scrollytelling component
ā ā āāā ScrollyVideo.svelte # Video playback component
ā ā āāā ScrollyVideo.js # Core video controller
ā ā āāā videoDecoder.js # WebCodecs implementation
ā ā āāā utils.js # Helper utilities
ā ā āāā LoremSection.svelte # Example section component
ā āāā routes/
ā ā āāā +layout.svelte # Global layout and styles
ā ā āāā +layout.js # SvelteKit layout config
ā ā āāā +page.svelte # Demo page
ā āāā app.html # HTML template
āāā static/
ā āāā output.mp4 # Demo video file
ā āāā poster.jpg # Video poster image
āāā VIDEO_ENCODING.md # Video encoding guide
āāā package.json
<script>
import ScrollyVideo from '$lib/ScrollyVideo.svelte';
</script>
<ScrollyVideo src="/path/to/video.mp4" />
<ScrollyVideo
src="/path/to/video.mp4"
transitionSpeed={12}
frameThreshold={0.05}
useWebCodecs={true}
/>
src (string) - Path to your video filetransitionSpeed (number, default: 8) - Controls scroll smoothness (higher = smoother)frameThreshold (number, default: 0.1) - Frame update sensitivity (lower = more updates)useWebCodecs (boolean, default: true) - Enable WebCodecs for better performancecover (boolean, default: true) - Video covers containersticky (boolean, default: true) - Video stays fixed while scrollingtrackScroll (boolean, default: true) - Sync video to scroll positionFor optimal performance, encode your videos using the provided ffmpeg command:
ffmpeg -i input.mp4 -c:v libx264 -preset medium -crf 25 \
-vf "scale='min(1280,iw)':'min(720,ih)':force_original_aspect_ratio=decrease" \
-g 30 -pix_fmt yuv420p -profile:v main -movflags +faststart -an output.mp4
See VIDEO_ENCODING.md for detailed encoding instructions and optimization tips.
will-change hints for smooth compositingThe demo includes 8 customizable content steps. Modify the steps array in src/lib/ScrollytellingSection.svelte:
export let steps = [
"Your first step description",
"Your second step description",
// Add more steps...
];
The scroll height automatically adjusts based on the number of steps.
All styles are in src/lib/ScrollytellingSection.svelte. Key classes:
.step - Individual step container.step-content - Content box styling.step-text - Text styling.foreground - Steps overlay container.video-scroll-container - Video containerFallback to standard video decoding on unsupported browsers.
Video not loading?
static/-movflags +faststartChoppy scrolling?
transitionSpeed (try 8 instead of 12)frameThreshold (try 0.1 instead of 0.05)Video not syncing with scroll?
trackScroll={true} is setMIT
Inspired by scrolly-video by @dkaoster
Built with Claude Code
Live Demo: View on GitHub Pages