HTML Loop Render
Render self-contained HTML animations to GIF by freezing the page at many time offsets and stitching the frames with ffmpeg.
Workflow
- Build or edit a self-contained HTML file.
- Add the freeze-time query-param pattern from
references/freeze-time-pattern.md. - Test a still frame first with headless Chrome at one timestamp.
- Render the full loop with
scripts/render_html_loop.sh. - If the asset is for LinkedIn, prefer square layout and calmer motion.
Quick start
Test one still frame first:
google-chrome --headless=new --disable-gpu \
--screenshot=/tmp/preview.png \
--window-size=1080,1080 \
"file:///absolute/path/to/animation.html?t=3"
Render the full GIF:
bash skills/html-loop-render/scripts/render_html_loop.sh \
/absolute/path/to/animation.html \
/absolute/path/to/output.gif \
6 8 1080 1080
Arguments are:
- input HTML
- output GIF
- duration seconds, default
6 - fps, default
12 - width, default
1200 - height, default
675
LinkedIn guidance
Use square 1080x1080 unless the user explicitly wants landscape.
Prefer:
- one strong headline
- one central focal element
- balanced left/right groups
- large text, minimal copy
- slow, obvious motion
Avoid:
- tiny labels
- too many simultaneous animated elements
- thin low-contrast lines
- complex backgrounds that dither badly in GIFs
Good starting render settings for LinkedIn:
- duration:
4to6 - fps:
6to8 - size:
1080 1080
Troubleshooting
If the GIF is blank or static:
- confirm the HTML reads
?t=and pauses/seeks animations correctly - render a still frame first with
?t=3 - ensure all assets are local or embedded, not blocked remote URLs
If the render is too slow:
- reduce fps first
- shorten duration
- reduce canvas size only as a last resort
If the GIF looks noisy:
- reduce motion complexity
- increase contrast
- remove subtle gradients or tiny text
Resources
- Freeze-time implementation:
references/freeze-time-pattern.md - Renderer script:
scripts/render_html_loop.sh
