SVG Line Drawing
Create elegant line drawing animations using thesvg.createDrawable() function:
import { svg, createTimeline, stagger } from 'animejs';
// Generate SVG lines
function generateLines(numberOfLines) {
const svgWidth = 1100;
const svgHeight = 1100;
const margin = 50;
const spacing = (svgWidth - margin * 2) / (numberOfLines - 1);
let svgContent = `<svg width="${svgWidth}" height="${svgHeight}" viewBox="0 0 ${svgWidth} ${svgHeight}">
<g id="lines" fill="none">`;
for (let i = 0; i < numberOfLines; i++) {
const x = margin + i * spacing;
svgContent += `<line x1="${x}" y1="${margin}" x2="${x}" y2="${svgHeight - margin}" class="line" stroke="#A4FF4F"></line>`;
}
svgContent += `</g></svg>`;
return svgContent;
}
document.body.innerHTML += generateLines(50);
// Animate line drawing
createTi timeline({
defaults: {
ease: 'inOut(4)',
duration: 10000,
loop: true
}
})
.add(svg.createDrawable('.line'), {
draw: [
'0.5 0.5', // Start from center
'0 1', // Draw full line
'0.5 0.5' // Return to center
],
stroke: '#FF4B4B'
}, stagger(100, { from: 'first' }));
The Draw Property
Thedraw property controls how much of an SVG path is visible:
import { animate, svg } from 'animejs';
// Draw from 0% to 100%
animate(svg.createDrawable('.path'), {
draw: '0 1', // start end (0 to 1)
duration: 2000
});
// Draw from center
animate(svg.createDrawable('.path'), {
draw: ['0.5 0.5', '0 1'],
duration: 1500
});
// Multiple steps with keyframes
animate(svg.createDrawable('.path'), {
draw: [
'0 0', // Hidden
'0 0.5', // Draw first half
'0.5 1', // Draw second half
'0 1' // Full path visible
],
duration: 3000
});
Animating Circles
Create radial drawing effects:import { svg, createTimeline, stagger, utils } from 'animejs';
function generateCircles(numberOfCircles) {
const svgWidth = 1100;
const centerX = svgWidth / 2;
const centerY = svgWidth / 2;
const maxRadius = 500;
const step = maxRadius / numberOfCircles;
let svgContent = `<svg width="${svgWidth}" height="${svgWidth}" viewBox="0 0 ${svgWidth} ${svgWidth}">
<g id="circles" fill="none">`;
for (let i = 0; i < numberOfCircles; i++) {
const radius = (i + 1) * step;
svgContent += `<circle class="circle" stroke="#A4FF4F" cx="${centerX}" cy="${centerY}" r="${radius}"></circle>`;
}
svgContent += `</g></svg>`;
return svgContent;
}
document.body.innerHTML += generateCircles(50);
creatTimeline({
defaults: {
ease: 'inOut(4)',
duration: 8000,
loop: true
}
})
.add(svg.createDrawable('.circle'), {
draw: [
() => {
const v = utils.random(-1, -0.5, 2);
return `${v} ${v}`;
},
() => `${utils.random(0, 0.25, 2)} ${utils.random(0.5, 0.75, 2)}`,
() => {
const v = utils.random(1, 1.5, 2);
return `${v} ${v}`;
}
],
stroke: '#FF4B4B'
}, stagger(100));
SVG Transform Animations
Animate standard SVG transforms:import { animate } from 'animejs';
// Rotate SVG element
animate('svg .shape', {
rotate: 360,
duration: 2000,
loop: true,
ease: 'linear'
});
// Scale and move
animate('svg .icon', {
scale: [1, 1.5, 1],
x: [0, 50, 0],
y: [0, -30, 0],
duration: 1500,
loop: true
});
SVG Attributes
Animate native SVG attributes:import { animate } from 'animejs';
// Animate stroke properties
animate('.path', {
strokeDashoffset: [1000, 0],
strokeWidth: [1, 10, 1],
stroke: ['#FF4B4B', '#A4FF4F'],
duration: 2000
});
// Animate circle radius
animate('circle', {
r: [0, 100],
fill: ['#FF4B4B', '#FFC730'],
duration: 1500,
ease: 'outElastic'
});
// Animate polygon points
animate('polygon', {
points: [
'50,0 100,100 0,100',
'50,50 75,100 25,100'
],
duration: 1000
});
Morphing Paths
Transform between different path shapes:import { animate } from 'animejs';
const circle = 'M50,50 m-40,0 a40,40 0 1,0 80,0 a40,40 0 1,0 -80,0';
const square = 'M10,10 L90,10 L90,90 L10,90 Z';
animate('path', {
d: [circle, square, circle],
duration: 2000,
loop: true,
ease: 'inOutQuad'
});
Complex SVG Timeline
Combine multiple SVG animations:import { createTimeline, svg, stagger } from 'animejs';
const tl = createTimeline({
defaults: {
duration: 1500,
ease: 'outQuad'
}
});
// Draw paths in sequence
tl.add(svg.createDrawable('.path-1'), {
draw: '0 1'
}, 0)
.add(svg.createDrawable('.path-2'), {
draw: '0 1'
}, 500)
.add(svg.createDrawable('.path-3'), {
draw: '0 1'
}, 1000)
// Then fill colors
.add(['.path-1', '.path-2', '.path-3'], {
fill: ['transparent', '#FF4B4B'],
stroke: ['#A4FF4F', 'transparent'],
duration: 1000
}, 2000);
SVG Filter Animations
Animate SVG filter effects:import { animate } from 'animejs';
// Animate blur filter
animate('feGaussianBlur', {
stdDeviation: [0, 10, 0],
duration: 2000,
loop: true
});
// Animate color matrix
animate('feColorMatrix', {
values: [
'1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 1 0',
'0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 0 0 0 1 0'
],
duration: 3000
});
Random Drawing Effects
Create organic, randomized animations:import { animate, svg, utils, stagger } from 'animejs';
animate(svg.createDrawable('.line'), {
draw: [
'0.5 0.5',
() => {
const length = utils.random(0.05, 0.45, 2);
return `${0.5 - length} ${0.5 + length}`;
},
'0.5 0.5'
],
stroke: '#FF4B4B',
duration: 10000,
loop: true
}, stagger(150, { from: 'random' }));
Performance Tips
- Use
will-change: transformon frequently animated SVG elements - Keep SVG markup clean and optimized
- Use
createDrawable()for path animations instead of manual strokeDasharray - Consider using
composition: 'replace'for better performance with many elements
Next Steps
Canvas Animations
Learn canvas-based animations
Basic Animations
Review animation fundamentals