Animate Shapes
Morph between two SVG shapes and export as a self-contained animated SVG.
From two SVG files
use Atelier\Svg\Svg;
use Atelier\Svg\Path\Path;
use Atelier\Svg\Morphing\Morph;
use Atelier\Svg\Morphing\AnimationExporter;
$star = Svg::load('star.svg')->getDocument()->querySelector('path');
$circle = Svg::load('circle.svg')->getDocument()->querySelector('path');
$frames = Morph::frames(
Path::parse($star->getAttribute('d'))->getData(),
Path::parse($circle->getAttribute('d'))->getData(),
60,
'ease-in-out',
);
$animated = AnimationExporter::toAnimatedSVG($frames, [
'duration' => 2,
'repeatCount' => 'indefinite',
]);
From path strings
use Atelier\Svg\Path\Data;
use Atelier\Svg\Morphing\Morph;
$start = Data::parse('M 0 0 L 100 0 L 100 100 L 0 100 Z');
$end = Data::parse('M 50 0 L 100 50 L 50 100 L 0 50 Z');
// Single interpolated frame
$mid = Morph::between($start, $end, 0.5);
// All frames for animation
$frames = Morph::frames($start, $end, 60, 'ease-in-out');
Export formats
use Atelier\Svg\Morphing\AnimationExporter;
// Self-contained SVG with SMIL animation
$doc = AnimationExporter::toAnimatedSVG($frames, ['duration' => 3]);
// CSS @keyframes
$css = AnimationExporter::toCSSKeyframes($frames, 'my-morph');
// JavaScript array for manual animation
$js = AnimationExporter::toJavaScript($frames, 'morphFrames');
// Web Animations API
$waapi = AnimationExporter::toWebAnimationsAPI($frames, ['duration' => 2]);
// JSON for interchange
$json = AnimationExporter::toJSON($frames, ['name' => 'star-to-circle']);
// Individual SVG files for sprite sheets
AnimationExporter::toSpriteSheet($frames, 'output/frames/');
Using the builder
$frames = Morph::create()
->from($start)
->to($end)
->withDuration(2000, 60) // 2s at 60fps
->withEasing('ease-in-out')
->generate();
See also
- Morphing overview: easing functions, interpolation details
- Animation elements: SMIL animation builder
- Animation export: export format reference