SVG animation features including motion path following, path morphing, and drawable path animations for scalable vector graphics.
Create drawable SVG path animation with stroke-dasharray technique for revealing paths progressively.
/**
* Create drawable SVG path animation
* Prepares SVG paths for animated drawing effect
* @param selector - SVG path element(s) to make drawable
* @param start - Start position (0-1, default: 0)
* @param end - End position (0-1, default: 1)
* @returns Array of drawable SVG geometry objects
*/
function createDrawable(
selector: TargetsParam,
start?: number,
end?: number
): Array<DrawableSVGGeometry>;Usage Example:
import { animate, createDrawable } from "animejs";
// Make path drawable
const drawable = createDrawable("path", 0, 0);
// Animate drawing from 0 to 1
animate(drawable, {
draw: [0, 1],
duration: 2000,
ease: "outQuad",
});Animate SVG path drawing from start to end:
import { animate, createDrawable } from "animejs";
// Setup drawable paths
const paths = createDrawable(".svg-path");
// Draw paths in sequence
animate(paths, {
draw: [0, 1], // Draw from 0% to 100%
duration: 1500,
stagger: 200,
ease: "inOutQuad",
});
// Draw backwards
animate(paths, {
draw: [1, 0], // Erase from 100% to 0%
duration: 1000,
});
// Partial drawing
animate(paths, {
draw: [0.2, 0.8], // Draw middle 60%
duration: 1000,
});Drawable path object with animatable properties:
/**
* Drawable SVG geometry object
*/
interface DrawableSVGGeometry {
/** SVG path element */
element: SVGPathElement;
/** Total path length */
totalLength: number;
/** Current draw progress (0-1) */
draw: number;
/** Start offset (0-1) */
start: number;
/** End offset (0-1) */
end: number;
}Usage Example:
const drawable = createDrawable("path")[0];
console.log(drawable.totalLength); // Path length in pixels
console.log(drawable.draw); // Current progress
// Manually set draw progress
drawable.draw = 0.5; // 50% drawnCreate motion path following animation for moving elements along SVG paths.
/**
* Create motion path following animation
* @param path - SVG path element to follow
* @param offset - Offset along path (default: 0)
* @returns Object with translateX, translateY, rotate properties as FunctionValues
*/
function createMotionPath(
path: TargetsParam,
offset?: number
): {
translateX: FunctionValue;
translateY: FunctionValue;
rotate: FunctionValue;
};Usage Example:
import { animate, createMotionPath } from "animejs";
// Create motion path
const motionPath = createMotionPath("#path");
// Animate element along path
animate(".ball", {
...motionPath,
duration: 3000,
ease: "inOutQuad",
});Animate elements along SVG paths:
import { animate, createMotionPath } from "animejs";
// Basic motion path
const path = createMotionPath("#curved-path");
animate(".dot", {
translateX: path.translateX,
translateY: path.translateY,
duration: 2000,
ease: "linear",
loop: true,
});
// With rotation to follow path direction
animate(".arrow", {
translateX: path.translateX,
translateY: path.translateY,
rotate: path.rotate, // Auto-rotate to face path direction
duration: 3000,
ease: "inOutCubic",
});
// With offset
const offsetPath = createMotionPath("#path", 50); // 50px offset
animate(".follower", {
...offsetPath,
duration: 2500,
});Control motion path animation precisely:
import { animate, createMotionPath } from "animejs";
const path = createMotionPath("#path");
// Create animation without autoplay
const anim = animate(
".element",
{
...path,
duration: 5000,
},
{ autoplay: false }
);
// Scrub through motion path
anim.seek(2500); // Move to halfway point
anim.progress = 0.75; // Move to 75% along pathCreate path morphing animation value for smooth shape transitions.
/**
* Create path morphing animation value
* Smoothly transitions from one SVG path to another
* @param path2 - Target path to morph into
* @param precision - Morphing precision (default: auto)
* @returns FunctionValue for path morphing
*/
function morphTo(path2: TargetsParam, precision?: number): FunctionValue;Usage Example:
import { animate, morphTo } from "animejs";
// Morph from one path to another
animate("#path1", {
d: morphTo("#path2"),
duration: 1500,
ease: "inOutQuad",
});Smoothly transition between different SVG path shapes:
import { animate, morphTo } from "animejs";
// Morph circle to star
animate("#shape", {
d: morphTo("#star-path"),
duration: 1000,
ease: "outElastic",
});
// Morph through multiple shapes
const tl = createTimeline();
tl.add("#shape", {
d: morphTo("#shape2"),
duration: 800,
})
.add("#shape", {
d: morphTo("#shape3"),
duration: 800,
})
.add("#shape", {
d: morphTo("#shape1"),
duration: 800,
});
// Custom precision for complex paths
animate("#complex-path", {
d: morphTo("#target-path", 100), // Higher precision
duration: 2000,
});Animate any SVG attribute:
import { animate } from "animejs";
// Basic attributes
animate("circle", {
r: [10, 50], // Radius
cx: [50, 200], // Center X
cy: [50, 100], // Center Y
fill: ["#ff0000", "#0000ff"], // Color
opacity: [0, 1],
duration: 1500,
});
// Rectangle
animate("rect", {
x: [0, 100],
y: [0, 50],
width: [50, 150],
height: [50, 100],
rx: [0, 20], // Border radius
fill: "#ff6b6b",
});
// Polygon points
animate("polygon", {
points: "0,0 100,0 100,100 0,100", // Target points
duration: 1000,
});
// Stroke properties
animate("path", {
stroke: "#ff0000",
strokeWidth: [1, 5],
strokeDasharray: "10 5",
strokeOpacity: [0.5, 1],
});Animate SVG transform attributes:
import { animate } from "animejs";
// Transform individual values
animate("rect", {
translateX: 100,
translateY: 50,
rotate: 360,
scale: [1, 1.5],
skewX: 10,
duration: 1500,
});
// Group animations
animate("g", {
translateX: [-100, 100],
rotate: [0, 180],
scale: [0.5, 1],
duration: 2000,
ease: "outElastic",
});import { animate, createDrawable, createTimeline } from "animejs";
const paths = createDrawable(".logo path");
const tl = createTimeline();
// Draw all paths
tl.add(paths, {
draw: [0, 1],
stagger: 100,
duration: 1500,
ease: "outQuad",
})
// Fill with color
.add(
".logo path",
{
fill: ["transparent", "#000"],
duration: 800,
},
"-=500"
);import { animate, createDrawable, createMotionPath } from "animejs";
// Draw the path first
const drawable = createDrawable("#track-path");
animate(drawable, {
draw: [0, 1],
duration: 2000,
}).then(() => {
// Then move element along the drawn path
const path = createMotionPath("#track-path");
animate(".vehicle", {
...path,
duration: 3000,
loop: true,
ease: "linear",
});
});import { animate, morphTo, createTimeline } from "animejs";
const tl = createTimeline({
loop: true,
direction: "alternate",
});
tl.add("#morph-shape", {
d: morphTo("#shape1"),
duration: 1000,
ease: "inOutQuad",
})
.add("#morph-shape", {
d: morphTo("#shape2"),
duration: 1000,
ease: "inOutQuad",
})
.add("#morph-shape", {
d: morphTo("#shape3"),
duration: 1000,
ease: "inOutQuad",
});import { animate, createDrawable, createMotionPath } from "animejs";
const drawable = createDrawable("#trail");
const path = createMotionPath("#trail");
// Draw path while moving element
animate(".tracer", {
...path,
duration: 3000,
ease: "linear",
update: (anim) => {
// Sync path drawing with motion
drawable[0].draw = anim.progress;
},
});import { animate } from "animejs";
document.querySelectorAll(".icon").forEach((icon) => {
icon.addEventListener("mouseenter", () => {
animate(icon.querySelector("path"), {
scale: 1.2,
rotate: 10,
duration: 300,
ease: "outBack",
});
});
icon.addEventListener("mouseleave", () => {
animate(icon.querySelector("path"), {
scale: 1,
rotate: 0,
duration: 300,
ease: "outQuad",
});
});
});import { animate, createDrawable } from "animejs";
const paths = createDrawable(".diagram path");
animate(paths, {
draw: [0, 1],
stagger: {
value: 200,
from: "center", // Start from center outward
},
duration: 1500,
ease: "outCubic",
});import { animate, createDrawable } from "animejs";
const progressBar = createDrawable("#progress-path")[0];
function updateProgress(percent) {
animate(progressBar, {
draw: percent / 100,
duration: 500,
ease: "outQuad",
});
}
updateProgress(75); // Animate to 75%import { animate, morphTo } from "animejs";
const button = document.querySelector(".morph-button");
const shape = button.querySelector("path");
button.addEventListener("click", () => {
animate(shape, {
d: morphTo("#checkmark"),
fill: ["#007bff", "#28a745"],
duration: 400,
ease: "outBack",
});
});Animate SVG filter properties:
import { animate } from "animejs";
// Blur animation
animate("#blur-filter feGaussianBlur", {
stdDeviation: [0, 10],
duration: 1000,
});
// Color matrix
animate("#filter feColorMatrix", {
values:
"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0", // Target color matrix
duration: 1500,
});Animate gradients:
import { animate } from "animejs";
// Gradient colors
animate("#gradient stop", {
stopColor: ["#ff0000", "#0000ff"],
duration: 2000,
stagger: 500,
});
// Gradient position
animate("#gradient", {
x1: "0%",
y1: "0%",
x2: "100%",
y2: "100%",
duration: 3000,
});/**
* Drawable SVG geometry object
*/
interface DrawableSVGGeometry {
/** SVG path element */
element: SVGPathElement;
/** Total path length in pixels */
totalLength: number;
/** Current draw progress (0-1) */
draw: number;
/** Start offset (0-1) */
start: number;
/** End offset (0-1) */
end: number;
}
/**
* Motion path return object
*/
interface MotionPathValues {
/** X translation function value */
translateX: FunctionValue;
/** Y translation function value */
translateY: FunctionValue;
/** Rotation function value (follows path direction) */
rotate: FunctionValue;
}
/**
* Function value type for dynamic animations
*/
type FunctionValue = (
target: any,
index: number,
total: number
) => string | number;
/**
* Target parameter type
*/
type TargetsParam =
| string
| HTMLElement
| SVGElement
| NodeList
| Array<HTMLElement | SVGElement>
| object;