How to use it
1. Put your pictures in a folder
Number them in order, with leading zeros: f-001.jpg, f-002.jpg, and so on. The download has 48 example pictures.
2. Add one section
Write the path with ### where the number is. Three # mean three digits.
<section data-scroll-sequence="frames/f-###.jpg" data-frames="48"></section> <script src="sequence.js" defer></script>
That is all. The section becomes three screens tall, the picture pins to the screen, and the scrollbar plays the frames.
Texts that appear on time
Everything you put inside the section lies on top of the pictures. With data-seq-show an element is only visible in one part of the scroll. The numbers go from 0 (start) to 1 (end).
<section data-scroll-sequence="frames/f-###.jpg" data-frames="48" data-length="4">
<div class="caption" data-seq-show="0-0.2"> <h2>One phone.</h2> </div>
<div class="caption" data-seq-show="0.3-0.55"> <h2>Five layers.</h2> </div>
<div class="caption" data-seq-show="0.8-1"> <h2>Order now</h2> </div>
</section>
<style>
.caption { position: absolute; left: 0; right: 0; bottom: 15%; text-align: center; color: #fff; }
</style>Options
| Attribute | Default | What it does |
|---|---|---|
data-scroll-sequence | Path of the pictures, with ### for the number. | |
data-frames | How many pictures there are. | |
data-start | 1 | Number of the first file. Use 0 if your files start at 000. |
data-length | 3 | Height of the section in screens. A bigger number means slower playback. |
data-fit | cover | cover fills the screen and crops the edges. contain shows the whole picture. |
data-smooth | 0.18 | How softly the frames follow the scrollbar. 1 follows exactly, 0.08 is very soft. |
data-label | a general text | What screen readers say about the animation. Describe what is shown. |
How to make the pictures
From a video
The free tool ffmpeg turns a video into numbered pictures. This line makes pictures 1280 pixels wide, 15 per second.
ffmpeg -i product.mp4 -vf "fps=15,scale=1280:-2" -q:v 5 frames/f-%03d.jpg
From a 3D program
Blender, Cinema 4D, Spline and After Effects can all export an "image sequence". Choose JPG or WebP and a fixed number of digits.
How many, and how big?
| Good value | Why | |
|---|---|---|
| Number of pictures | 40 to 120 | Under 40 looks choppy. Over 150 loads long on phones. |
| Width | 1280 px | Sharp enough full screen. 1920 px only for very detailed products. |
| File size | 15 to 40 KB each | JPG quality 70 or WebP quality 60. The whole set should stay under 3 MB. |
| Background | One flat colour | Give the section the same background colour, then no edge is visible. |
Why pictures and not a video?
- Videos jump when you scrub them. A video stores only some full pictures. Jumping to a point in between is slow, so the animation stutters, most of all on iPhones.
- Pictures are exact. Every scroll position has its own picture. Forwards and backwards look the same.
- They load in order. The first picture shows at once. The others load when the section comes close, a few at a time.
What the script takes care of
- Missing frames. If a picture has not loaded yet, the closest loaded one is shown. The visitor never sees an empty box.
- Sharp on every screen. The canvas follows the screen size and pixel density, also when the phone is turned.
- No wasted work. It draws only when the frame changes. While nobody scrolls, it does nothing.
- Reduced motion. For visitors who switched off animations the soft follow is off. The pictures still change with the scrollbar, because that is their own movement.
Use it from JavaScript
var seq = ScrollSequence(document.querySelector('#product'), {
src: 'frames/f-###.jpg', frames: 48, length: 4
});
seq.progress; // 0 to 1, where the visitor is
seq.frame; // the picture that is shown now
seq.set('fit', 'contain');
seq.refresh(); // call after you add texts with data-seq-showThe section also gets the CSS variable --seq-progress. Use it for a progress bar: width: calc(var(--seq-progress) * 100%).
Common questions
The picture does not stay pinned.
A parent element has overflow: hidden, overflow: auto or a transform. Pinning does not work inside such a box. Remove it from the parents, or move the section out of them.
It plays too fast.
Make the section taller with data-length="5". More scroll distance means slower playback.
On phones the sides are cut off.
With cover a wide picture is cropped on a tall screen. Keep the product in the middle of the picture, or use data-fit="contain".
Does it hurt my page speed score?
Only the first picture loads with the page. The rest load later, so the first paint is not slowed down. Keep the first picture small.
What is in the download
sequence.jsthe script, about 8 KB with comments. The styles are included.frames/48 example pictures of the phone from the demo, to try it at onceindex.htmlanddemo.cssthe demo page you see aboveREADME.txtandLICENSE.txtthe short guide and the MIT licence
Licence
MIT licence. Use it in personal and commercial projects, change it as you like. A link back is welcome and not required.