Two rpic extensions delegate presentation to the host
document that embeds the SVG: class attaches CSS class
names to shapes, and animate emits a timing manifest a
player can drive. Neither changes rpic’s own rendering — classic output
stays byte-identical — but together they make diagrams that respond to
the page they live in.
class: CSS hooks on shapes
class has two forms writing to the same hook — inline at
creation, and a statement form that reuses pic’s object references
(labels, last line, 2nd box), which also
reaches shapes drawn inside macros:
library(rpic)
svg <- rpic_svg('
boxht = 0.4; boxwid = 0.9
box class "service" "api"
arrow
box class "service hot" "billing"
arrow
box class "storage" "database"
class last arrow "dataflow"
')Each class lands on the shape’s SVG group
(<g id="sN" class="…">). The names are validated
([A-Za-z_][A-Za-z0-9_-]* only), so there is no
attribute-injection surface.
Styling happens in the host page. This very vignette embeds the SVG
inline below and styles it with a
<style> block — the “billing” box is hot, services
get a blue border, and the last arrow is dashed. That is live CSS, not
something rpic drew:
Note the delegation contract: CSS only reaches
inline-embedded SVG. An
<img src="…svg"> reference isolates the document, and
raster (PNG/PDF) output ignores classes entirely — there, the diagram
renders exactly as if no class existed.
animate: a timing manifest
animate schedules an effect (draw,
fade, pop) per shape, again without touching
the static rendering:
bundle <- rpic_manifest('
boxht = 0.35; boxwid = 0.8
A: box "build"
arrow
box "test"
arrow
box "ship"
animate A with "pop"
animate 2nd box with "fade"
animate 3rd box with "draw" for 0.8
')The drawing itself is the ordinary static SVG:
and the bundle carries an animations array — shape ids
(the same stable s<N> ids the class hooks ride on),
effect names and a resolved timeline:
"animations":[{"id":"s0","effect":"pop","start":0,"duration":0.6},
{"id":"s2","effect":"fade","start":0.6,"duration":0.6},
{"id":"s4","effect":"draw","start":1.2,"duration":0.8}]
Playing it is the host’s job. In the browser, the @strategicprojects/rpic
npm package ships a GSAP player:
animate(stage, animations, gsap) builds the timeline
(draw traces strokes, pop scales in,
fade fades). The animate extension
page shows it running live.
Unknown effect names are accepted but reported: the bundle’s
warnings array flags them
(unknown_animation_effect, with the supported list), the
same structured-diagnostic shape used by compile errors.
Both layers together
Class hooks and animation target the same shape groups, so a diagram
can be styled by the page and animated by the player at once —
the classes ride on <g id="sN" class="…"> while the
manifest addresses sN. Everything stays a plain, portable
SVG for any consumer that ignores them.