feat: animated SVG output from anim_save(".svg") - #143
Merged
Conversation
anim_save() gains a third format alongside GIF and APNG: writing to a `.svg` path emits a single animated SVG (via vellum's format = "svg") -- every frame as vector markup, shown in turn by a CSS step animation. It is resolution-independent and honours prefers-reduced-motion (both handled inside the SVG by the engine). Because an animated SVG emits every frame in full, its size grows with marks x frames where a raster format does not. So anim_save() advises switching to a raster format when a `.svg` scene is dense enough (> ~800 drawn elements per keyframe) that GIF/APNG would be smaller -- "choose by mark count, not preference". The frame-schedule + encode path is factored into `.anim_render()` so the widget's animated-SVG embed (vellumwidget) drives identical frames. Consumes vellum >= 0.6.5 (already required), which provides format = "svg". Docs: NEWS, an Animation-article section, inst/examples/28-animation.R (an animated-SVG wave), tests in test-animate.R. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
WI-11 (vellumplot half). Adds a third
anim_save()output format on top of the existing keyframe-animation feature.What
Writing an animation to a
.svgpath emits a single animated SVG — every frame as vector markup, shown in turn by a CSS step animation (vellum'sformat = "svg", in the required vellum ≥ 0.6.5). It is resolution-independent (crisp at any size, print, retina) and honoursprefers-reduced-motion(both handled inside the SVG by the engine).Mark-count policy
An animated SVG emits every frame in full, so its size grows with marks × frames where a raster format does not.
anim_save()therefore advises switching to a raster format when a.svgscene is dense (> ~800 drawn elements per keyframe) — "choose by mark count, not preference", the decision vellum left to vellumplot. The schedule + encode path is factored into.anim_render()so vellumwidget's animated-SVG embed drives identical frames.Note on branching
The prior
feat-animatebranch turned out to be a stale parallel copy of the animation feature (which already landed onmainseparately). This PR re-applies the animated-SVG work cleanly on top of currentmain;feat-animateshould not be merged.Verification (WI-0)
Rendered an animated SVG and looked at it in real Chrome (chromote) — panel, marks, axes, legends all embed and the frames animate (vellum's own example confirmed frames become visible; forcing all frames visible confirmed my scatter's content).
inst/examples/28-animation.Rgains a wave SVG and runs end to end.Tests:
test-animate.R(+3). Full suite[ FAIL 0 | WARN 1 pre-existing | SKIP 0 | PASS 2886 ].🤖 Generated with Claude Code