### Canvas Setup and Resizing
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/color-trail-canvas.html
Initializes the canvas context and sets up a resize handler to ensure the canvas scales correctly with the window. Handles device pixel ratio for sharper rendering.
```javascript
const canvas = document.getElementById('stage');
const ctx = canvas.getContext('2d');
const dpr = window.devicePixelRatio || 1;
function resize() {
const w = canvas.clientWidth;
const h = canvas.clientHeight;
canvas.width = w * dpr;
canvas.height = h * dpr;
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
}
resize();
window.addEventListener('resize', resize);
```
--------------------------------
### Basic HTML and CSS Setup
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/threejs/color-trail/index.html
Sets up the basic HTML structure and CSS styling for the canvas and page elements. Ensures proper layout and background for the visual effect.
```html
html, body {
margin: 0;
padding: 0;
height: 100%;
background: #111;
overflow: hidden;
font-family: system-ui, sans-serif;
}
canvas {
display: block;
}
.label {
position: absolute;
top: 12px;
left: 12px;
color: #888;
font-size: 12px;
pointer-events: none;
}
```
--------------------------------
### Three.js and Anime.js Setup for Color Comparison
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/threejs/color-compare/index.html
Initializes the Three.js scene, camera, renderer, and loads the anime.js adapter. Sets up the canvas and event listeners for resizing. This code is essential for rendering the visual comparison.
```javascript
import { Scene, WebGLRenderer, PerspectiveCamera, Mesh, BoxGeometry, MeshBasicMaterial, Color, SRGBColorSpace, LinearSRGBColorSpace, } from 'three';
import { utils } from '../../../../dist/modules/index.js';
import '../../../../dist/modules/adapters/three/index.js';
const swatches = [
'#ff3b30',
'#ff8800',
'#ffcc00',
'#34c759',
'#0a84ff',
'#5e5ce6',
'#bf5af2',
'#ff2d55',
'#ffffff',
'#cccccc',
'#888888',
'#444444',
'#111111',
];
const scene = new Scene();
scene.background = new Color(0x111111);
const camera = new PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 100);
camera.position.z = 18;
const renderer = new WebGLRenderer({
antialias: true,
});
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
renderer.setSize(innerWidth, innerHeight);
renderer.outputColorSpace = SRGBColorSpace;
document.body.appendChild(renderer.domElement);
addEventListener('resize', () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
```
--------------------------------
### Basic CSS Setup for Three.js Canvas
Source: https://github.com/juliangarnier/anime/blob/master/examples/threejs/transforms/index.html
Sets up basic styling for the HTML document and the canvas element to ensure proper rendering of the Three.js scene.
```html
html, body {
margin: 0;
padding: 0;
height: 100%;
background: var(--bg-1);
overflow: hidden;
}
canvas {
display: block;
}
```
--------------------------------
### Anime.js Staggering: Easing from Center and Reversed
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/advanced-staggering-demos.html
Demonstrates staggering animations with custom easing functions, starting from the center. Allows for more nuanced animation curves.
```javascript
.add('.ease span', {
translateY: stagger(['2rem', '-2rem'], {from: 'center', ease: 'easeOutQuad'}),
color: red,
delay: stagger([0, 600], {from: 'center', ease: 'easeOutExpo'})
}, 0)
.add('.ease-reversed span', {
translateY: stagger(['2rem', '-2rem'], {from: 'center', reversed: true , ease: 'easeOutQuad'}),
color: red,
delay: stagger([0, 600], {from: 'center', reversed: true , ease: 'easeOutExpo'}),
}, 0)
```
--------------------------------
### Setup Anime.js Animations with Stagger and Loop
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/tween-composition.html
Initializes staggered animations for elements with the 'loop' class and sets up hover and click event handlers for elements with the 'hover' class. Requires Anime.js to be imported.
```javascript
import { animate, stagger, utils } from '../../../dist/modules/index.js';
const black = '#252423';
const white = '#F6F4F2';
const red = '#FF4B4B';
const orange = '#FF8F42';
const lightorange = '#FFC730';
const yellow = '#F6FF56';
const citrus = '#A4FF4F';
const green = '#18FF74';
const darkgreen = '#00D672';
const turquoise = '#3CFFEC';
const blue = '#61C3FF';
const kingblue = '#5A87FF';
const lavender = '#8453E3';
const purple = '#C26EFF';
const pink = '#FB89FB';
const $hovereds = utils.$('.hover');
const $loopeds = utils.$('.loop');
const staggered = animate($loopeds, {
autoplay: false,
x: [
{ to: ['-50%', 50], delay: stagger(120, {grid: [5, 5], from: 14}) },
{ to: '-50%', delay: stagger(120, {grid: [5, 5], from: 10}) },
],
ease: 'inOutQuart',
duration: 2000,
loop: true,
});
// animate($loopeds, {
// scale: [0, 1],
// ease: 'inOutQuad',
// duration: 500,
// delay: stagger(120, {grid: [5, 5], from: 'center', start: 240}),
// });
for (let i = 0, l = $hovereds.length; i < l; i++) {
const el = $hovereds[i];
el.onmouseenter = () => {
staggered.play();
animate(el, {
scale: [{ from: 1.4, to: .5, duration: 4000 }, { to: 1.6, duration: 2000 }],
rotate: [{ to: 45, duration: 2000 }],
zIndex: { to: 999, modifier: utils.round(0), ease: 'linear', duration: 25 },
color: { to: el.dataset.clicked ? blue : orange, duration: 300, ease: 'out(4)' },
boxShadow: '0 0 10px 0 rgba(0, 0, 0, .3)',
duration: 900,
onBegin() {
el.dataset.hover = true;
},
})
}
el.onmousedown = () => {
animate(el, {
scale: { to: 1, ease: 'outElastic' },
zIndex: { to: 1, modifier: utils.round(0), ease: 'linear', duration: 25 },
color: { to: el.dataset.clicked ? red : kingblue, duration: 800 },
duration: 400,
onBegin() {
el.dataset.clicked ? el.removeAttribute('data-clicked') : el.dataset.clicked = true;
},
})
}
el.onmouseleave = () => {
animate(el, {
scale: 1,
rotate: { to: 0, duration: 1200 },
zIndex: { to: 1, modifier: utils.round(0), ease: 'linear' },
color: { to: el.dataset.clicked ? kingblue : red },
boxShadow: { to: '0 0 0 0 rgba(0, 0, 0, 0)', ease: 'linear' },
duration: 500,
onBegin() {
el.removeAttribute('data-hover');
},
// complete() {
// el.style.color = 'green';
// },
})
}
el.onmouseup = () => {
animate(el, {
scale: el.dataset.clicked ? 1 : (el.dataset.hover ? 1.2 : 1),
zIndex: { to: el.dataset.hover ? 999 : 1, modifier: utils.round(0), ease: 'linear', duration: 25 },
color: { to: el.dataset.clicked ? kingblue : (el.dataset.hover ? orange : red), duration: 500 },
duration: 500
})
}
}
```
--------------------------------
### Anime.js V2 Logo Animation Setup and Timeline
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/animejs-v2-logo-animation.html
Sets up the Anime.js timeline for the logo animation. It imports necessary modules, defines default easing, and chains multiple animation sequences for different elements.
```javascript
import { createTimeline, utils, stagger, svg } from '../../../dist/modules/index.js';
utils.set(['.fill.out', '.line.out'], { opacity: 0 });
const fillDraggable = svg.createDrawable('.fill');
const logoTimeline = createTimeline({
alternate: true,
loop: 1,
defaults: {
ease: 'outElastic(1, .5)',
},
})
.add('.dot-e', {
translateX: [
{ to: -600, duration: 520, delay: 200, ease: 'inQuart' },
{ to: [-100, 0], duration: 500, delay: 1000, ease: 'outQuart' }
],
scale: [
{ to: [0, 1], duration: 200, ease: 'outBack' },
{ to: [0, 0], duration: 100, delay: 500, ease: 'inQuart' },
{ to: 1, duration: 200, delay: 1000, ease: 'outQuart' },
{ to: 0, duration: 400, delay: 500, ease: 'inBack' }
]
}, 0)
.add('.dot-i', {
translateY: { to: [-200, 0], duration: 500, ease: 'outElastic(1, .8)' },
scale: [
{ to: [0, 1], duration: 100, ease: 'outQuart' },
{ to: 0, duration: 400, delay: 1400, ease: 'inBack' }
],
delay: 1200
}, 0)
.add(fillDraggable, {
draw: { to: '0 1', duration: 600, ease: 'outQuart' },
stroke: {
to: ['#FFF', el => utils.get(el.parentNode, 'stroke')],
duration: 350,
ease: 'inOutQuart',
},
}, stagger(60, { start: 700 }))
.add(fillDraggable, {
draw: { to: '1 1', duration: 800, ease: 'inQuart' }
}, stagger(80, { start: 2000 }))
.add(svg.createDrawable('.line.out'), {
opacity: { to: 1, duration: 100 },
draw: {
to: ['0 1', '1 1'],
duration: 1200,
delay: stagger(100, { start: 500 }),
ease: 'inQuart'
},
strokeWidth: {
to: [0, 2],
delay: stagger(100),
duration: 200,
ease: 'linear'
}
}, 2000)
.add('.icon', {
opacity: { to: 1, duration: 10, delay: 2800, ease: 'linear' },
translateY: { to: 60, duration: 800 },
ease: 'outElastic(1, .5)',
delay: 4200
}, 0)
.add(svg.createDrawable('.icon-line'), {
draw: { to: '0 1', duration: 1200, ease: 'inOutQuart' },
strokeWidth: { to: [8, 2], duration: 800, ease: 'inQuad' },
stroke: { from: '#FFF', duration: 800, delay: 400, ease: 'inQuad' }
}, 3000)
.add(['.icon-text path', '.icon-text polygon'], {
translateY: { to: [50, 0] },
opacity: { to: 1, duration: 100, ease: 'linear' },
ease: 'outElastic(1, .5)',
delay: stagger(20),
}, 4200)
.init();
// logoTimeline.seek(660);
// logoTimeline.seek(660);
document.body.classList.add('ready');
// logoTimeline.play();
```
--------------------------------
### Import and Use Anime.js ES Modules
Source: https://github.com/juliangarnier/anime/blob/master/README.md
Import necessary functions from Anime.js and use them to create animations. This example demonstrates animating an element with specific properties and delays.
```javascript
import {
animate,
stagger,
} from 'animejs';
animate('.square', {
x: 320,
rotate: { from: -180 },
duration: 1250,
delay: stagger(65, { from: 'center' }),
ease: 'inOutQuint',
loop: true,
alternate: true
});
```
--------------------------------
### Anime.js Staggering: From Index and Reversed
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/advanced-staggering-demos.html
Starts staggering animations from a specific index. Useful for targeting particular elements in a sequence.
```javascript
.add('.from-index span', {
translateY: stagger('-.5em', {from: 3}),
color: red,
delay: stagger(100, {from: 3})
}, 0)
.add('.from-index-reversed span', {
translateY: stagger('-.5em', { from: 3, reversed: true }),
color: red,
delay: stagger(100, { from: 3, reversed: true }),
}, 0)
```
--------------------------------
### CSS for WAAPI values stress test
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/waapi/values/index.html
Basic CSS for layout and styling of the stress test elements. No specific setup is required beyond including this CSS.
```css
body { display: flex; align-items: flex-start; justify-content: flex-start; flex-direction: row; width: 100%; height: 100vh; }
.container { font-size: 2vw; pointer-events: none; display: flex; align-items: center; justify-content: center; flex-direction: row; flex-wrap: wrap; width: 10em; height: 10em; }
.square { position: relative; width: 1em; height: 1em; border-radius: 0px; background-color: currentColor; color: var(--red-1); }
```
--------------------------------
### Layered Animations CSS Setup
Source: https://github.com/juliangarnier/anime/blob/master/examples/layered-css-transforms/index.html
This CSS sets up a container for layered animations, defining styles for the main container and individual shapes within it. It uses flexbox for centering and absolute positioning for layering.
```css
body {
display: flex;
flex-wrap: wrap;
justify-content: center;
align-items: center;
height: 100vh;
}
.layered-animations {
position: relative;
display: flex;
justify-content: center;
align-items: center;
width: 16rem;
height: 16rem;
transform: scale(1.75);
}
.layered-animations .shape {
position: absolute;
overflow: visible;
width: 8rem;
height: 8rem;
stroke: currentColor;
fill: transparent;
}
.layered-animations .small.shape {
width: 1.5rem;
height: 1.5rem;
stroke: currentColor;
stroke-width: 2px;
fill: currentColor;
}
```
--------------------------------
### Anime.js Staggering: From Last and Reversed
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/advanced-staggering-demos.html
Applies staggering animations starting from the last element in the selection. Useful for effects that build backward.
```javascript
.add('.from-last span', {
translateY: stagger('-.5em', {from: 'last'}),
color: red,
delay: stagger(100, {from: 'last'})
}, 0)
.add('.from-last-reversed span', {
translateY: stagger('-.5em', { from: 'last', reversed: true }),
color: red,
delay: stagger(100, { from: 'last', reversed: true }),
}, 0)
```
--------------------------------
### CSS Keyframes Animation
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/keyframes/index.html
Defines a CSS animation sequence using `@keyframes`. This example animates the position and rotation of an element over time.
```css
:root { --test: 2em; --from: calc(100px - var(--test)); --to: calc(100px + var(--test)); }
body { display: flex; flex-wrap: wrap; justify-content: center; align-items: center; height: 100vh; }
.playground { position: relative; display: flex; flex-direction: column; justify-content: center; align-items: center; flex-wrap: wrap; }
.square { --d: 4rem; position: relative; width: var(--d); height: var(--d); margin-top: calc(var(--d) * -.5); margin-left: calc(var(--d) * -.5); border-radius: calc(var(--d) * .125); margin: 2px; cursor: pointer; font-size: 100px; }
@keyframes css {
0% { left: 0rem; top: 0rem; }
30% { left: 0rem; top: -2.5rem; rotate: 45deg; animation-timing-function: ease-out }
40% { left: 17rem; top: -2.5rem; }
50% { left: 17rem; top: 2.5rem; rotate: 90deg; }
70% { left: 0rem; top: 2.5rem; }
100% { left: 0rem; top: 0rem; rotate: 180deg; }
}
.css { background-color: var(--yellow-1); }
.css.is-animated { animation: css 4s linear forwards infinite; }
```
--------------------------------
### Anime.js Staggering: Range from Center and Reversed
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/advanced-staggering-demos.html
Applies staggering animations over a range, starting from the center. Creates a ripple or expanding effect from the middle.
```javascript
.add('.range-from-center span', {
translateY: stagger(['-2em', '2em'], {from: 'center'}),
color: red,
delay: stagger([0, 600], {from: 'center'})
}, 0)
.add('.range-from-center-reversed span', {
translateY: stagger(['-2em', '2em'], { from: 'center', reversed: true }),
color: red,
delay: stagger([0, 600], { from: 'center', reversed: true }),
}, 0)
```
--------------------------------
### Creating Timelines
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
Timelines are now initialized using the createTimeline import.
```diff
- const tl = anime.timeline(),
+ const tl = createTimeline(),
```
--------------------------------
### Initialize Three.js Scene and Objects
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/threejs/color-trail/index.html
Sets up the basic Three.js scene, camera, renderer, and initial meshes including stations and a ring outline. Ensure Three.js and the animation adapter are imported.
```javascript
import { Scene, WebGLRenderer, PerspectiveCamera, Mesh, SphereGeometry, MeshBasicMaterial, Color, BufferGeometry, LineBasicMaterial, LineLoop, BufferAttribute, } from 'three';
import { animate, createTimeline, createTimer } from '../../../../dist/modules/index.js';
import '../../../../dist/modules/adapters/three/index.js';
const colors = [
'#ff3b30',
'#ffcc00',
'#34c759',
'#0a84ff',
];
const scene = new Scene();
scene.background = new Color(0x111111);
const camera = new PerspectiveCamera(50, innerWidth / innerHeight, 0.1, 1000);
camera.position.z = 18;
const renderer = new WebGLRenderer({
antialias: true,
});
renderer.setPixelRatio(Math.min(devicePixelRatio, 2));
renderer.setSize(innerWidth, innerHeight);
document.body.appendChild(renderer.domElement);
addEventListener('resize', () => {
camera.aspect = innerWidth / innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(innerWidth, innerHeight);
});
const ringRadius = 6;
const stationRadius = 0.8;
const ballRadius = 0.55;
// Station meshes at the cardinal points; Y is negated so the layout matches the canvas demo (canvas Y goes down, three.js Y goes up).
const stations = [];
for (let i = 0; i < 4; i++) {
const a = -Math.PI * 0.5 + (Math.PI * 2 * i) / 4;
const mesh = new Mesh(
new SphereGeometry(stationRadius, 24, 16),
new MeshBasicMaterial({
color: colors[i],
})
);
mesh.position.set(Math.cos(a) * ringRadius, -Math.sin(a) * ringRadius, 0);
scene.add(mesh);
stations.push(mesh);
}
// Ring outline
{
const segments = 128;
const positions = new Float32Array(segments * 3);
for (let i = 0; i < segments; i++) {
const a = (i / segments) * Math.PI * 2;
positions[i * 3] = Math.cos(a) * ringRadius;
positions[i * 3 + 1] = Math.sin(a) * ringRadius;
positions[i * 3 + 2] = 0;
}
const geo = new BufferGeometry();
geo.setAttribute('position', new BufferAttribute(positions, 3));
scene.add(
new LineLoop(
geo,
new LineBasicMaterial({
color: 0xffffff,
transparent: true,
opacity: 0.08,
})
)
);
}
```
--------------------------------
### Anime.js Staggering: Range from Last and Reversed
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/advanced-staggering-demos.html
Applies staggering animations over a range, starting from the last element. Combines range-based animation with backward sequencing.
```javascript
.add('.range-from-last span', {
translateY: stagger(['-2em', '2em'], {from: 'last'}),
color: red,
delay: stagger([0, 600], {from: 'last'})
}, 0)
.add('.range-from-last-reversed span', {
translateY: stagger(['-2em', '2em'], { from: 'last', reversed: true }),
color: red,
delay: stagger([0, 600], { from: 'last', reversed: true }),
}, 0)
```
--------------------------------
### Migrate utility functions to utils module
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
Utility functions are now accessed via the utils import.
```diff
- animation.remove(targets),
+ utils.remove(targets),
```
```diff
- animation.get(target, 'property'),
+ utils.get(target, 'property'),
```
```diff
- animation.set(target, { prop1: value, prop2: value }),
+ utils.set(target, { prop1: value, prop2: value }),
```
```diff
- animation.random(50, 100),
+ utils.random(50, 100),
```
--------------------------------
### Timeline Creation and Configuration
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/color-trail-canvas.html
Sets up two Anime.js timelines for managing animations. `tl` is configured for a looping animation with overlapping tweens, while `tl2` is for sequential, non-overlapping adds.
```javascript
const tl = createTimeline({
autoplay: true,
loop: true,
defaults: { ease: 'linear', duration: 1000 },
});
const tl2 = createTimeline({
autoplay: true,
loop: true,
defaults: { ease: 'linear', duration: 800 },
});
```
--------------------------------
### Rendering Cubes with Native Three.js and Anime.js Adapter
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/threejs/color-compare/index.html
Creates two rows of cubes. The top row uses native Three.js `material.color.set()` to apply colors, while the bottom row uses the anime.js adapter `utils.set()` for the same purpose. This visually demonstrates the equivalence of both methods.
```javascript
const cubeSize = 1.4;
const stride = cubeSize;
const rowOffset = cubeSize * 0.5;
const xStart = -((swatches.length - 1) * stride) / 2;
const nativeMeshes = [];
const animeMeshes = [];
const geometry = new BoxGeometry(cubeSize, cubeSize, cubeSize);
for (let i = 0; i < swatches.length; i++) {
const native = new Mesh(geometry, new MeshBasicMaterial());
native.material.color.set(swatches[i]);
native.position.set(xStart + i * stride, rowOffset, 0);
scene.add(native);
nativeMeshes.push(native);
const anime = new Mesh(geometry, new MeshBasicMaterial());
anime.position.set(xStart + i * stride, -rowOffset, 0);
scene.add(anime);
utils.set(anime, { color: swatches[i] });
animeMeshes.push(anime);
}
```
--------------------------------
### Anime.js Staggering: Normal and Reversed
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/advanced-staggering-demos.html
Demonstrates basic forward and reversed staggering animations for elements. Use for simple sequential animations.
```javascript
import { createTimeline, stagger } from '../../../dist/modules/index.js';
const red = '#F64E4D';
const animations = createTimeline({
ease: 'expo.out',
alternate: true,
loop: true
})
.add('.normal span', {
translateY: stagger('-.5em'),
color: red,
delay: stagger(100)
}, 0)
.add('.normal-reversed span', {
translateY: stagger('-.5em', { reversed: true }),
color: red,
delay: stagger(100, { reversed: true }),
}, 0)
```
--------------------------------
### Test Wrapper Styling
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/timeline/test/index.html
Styles the wrapper for test elements, using flexbox for vertical centering and column layout with padding.
```css
#test-wrapper {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
padding: 2rem;
max-width: 32rem;
}
```
--------------------------------
### Updating Callback Prefixes
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
All callback parameters now require the on prefix.
```diff
- update: () => {},
+ onUpdate: () => {},
- begin: () => {},
+ onBegin: () => {},
- complete: () => {},
+ onComplete: () => {},
```
--------------------------------
### CSS for Stagger Grid Layout
Source: https://github.com/juliangarnier/anime/blob/master/examples/stagger/index.html
Basic CSS to set up a full-screen container and style individual grid items (dots).
```css
body {
overflow: hidden;
width: 100vw;
height: 100vh;
}
.dot {
position: absolute;
width: 16px;
height: 16px;
background-color: var(--color-1);
}
```
--------------------------------
### Importing Anime
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
Replaces the global anime object with a named import.
```diff
- import anime from 'animejs';
+ import { animate } from 'animejs';
```
--------------------------------
### Configure Grid Staggering with Axis and Reversal
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/advanced-staggering-demos.html
Applies grid-based staggering to translate and color properties with axis-specific constraints and reversal logic.
```javascript
from: 38, axis: 'y'}), color: red, delay: stagger(100, {grid: [10, 5], from: 38}) }, 0) .add('.grid-axis-reversed span', { translateX: stagger('.5rem', {grid: [10, 5], from: 38, axis: 'x', reversed: true }), translateY: stagger('.5rem', {grid: [10, 5], from: 38, axis: 'y', reversed: true }), color: red, delay: stagger(100, {grid: [10, 5], from: 38, reversed: true }) }, 0);
```
--------------------------------
### Interactive Sphere Creation on Pointer Down
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/additive-animations-2.html
Handles user interaction by creating new spheres on pointer down events. It manages the number of spheres and cycles through available colors for new creations.
```javascript
document.onpointerdown = e => {
const x = e.clientX - (window.innerWidth / 2);
const y = e.clientY - (window.innerHeight / 2);
if (spheres.length >= colors.length) {
spheres[curIndex].init(x, y);
} else {
new Sphere(x, y);
}
curIndex++;
if (curIndex >= colors.length) curIndex = 0;
}
```
--------------------------------
### Updating Loop Callbacks
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
Replaces loopBegin and loopComplete with a single onLoop callback.
```diff
- loopBegin: () => {},
- loopComplete: () => {},
+ onLoop: () => {},
```
--------------------------------
### Render Loop and Trail Generation
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/threejs/color-trail/index.html
Sets up a recurring timer to spawn trail ghosts at the current positions of both animated balls and render the scene. This creates the continuous color trail effect.
```javascript
// Render loop: spawn one ghost per frame at each ball's current position/color, then render.
// Ghosts fade themselves out via their own opacity animations.
createTimer({
autoplay: true,
onUpdate: () => {
spawnGhost(outer.position.x, outer.position.y, outer.material.color, 1);
spawnGhost(inner.position.x, inner.position.y, inner.material.color, 0.65);
renderer.render(scene, camera);
},
});
```
--------------------------------
### Apply 3D Word Rotation with Anime.js
Source: https://github.com/juliangarnier/anime/blob/master/examples/text/hover-effects/index.html
Use this CSS to set up the 3D perspective and positioning for word rotation effects. Ensure the HTML structure includes elements for each face of the 3D word.
```css
body {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
min-height: 100svh;
font-family: "Noto Sans JP", sans-serif;
font-kerning: none;
font-variant-ligatures: none;
text-rendering: optimizeSpeed;
}
main {
margin: 0 auto;
padding: 20px;
width: 100%;
max-width: 1200px;
display: grid;
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
gap: 20px;
justify-content: center;
container-type: inline-size;
}
article {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
min-height: 200px;
padding: 20px;
container-type: inline-size;
border-radius: 1cqw;
background: #2A2A2A;
color: #D0D0D0;
transition: background-color .25s ease-out;
}
article:has(p) {
/*justify-content: flex-start;*/
align-items: flex-start;
}
article:hover {
cursor: default;
background: #303030;
}
article h2 {
text-align: center;
font-size: clamp(20px, 8cqw, 30px);
will-change: transform;
}
.word-3d {
perspective: 1000px;
position: relative;
transform-style: preserve-3d;
transform-origin: 50% 50% 1rem;
}
.face {
position: absolute;
left: 0;
opacity: 0;
}
.face-front {
opacity: 1;
}
.face-bottom {
top: 100%;
transform-origin: 50% 0%;
transform: rotateX(90deg);
}
.face-top {
bottom: 100%;
transform-origin: 50% 100%;
transform: rotateX(-90deg);
}
.face-back {
top: 0;
transform-origin: 50% 50%;
transform: translateZ(2.5rem) rotateX(-180deg);
}
```
--------------------------------
### Migrate SVG helpers to svg module
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
SVG-related utilities have been moved to the dedicated svg module.
```diff
- anime.path(),
+ svg.createMotionPath(),
- anime.setDashoffset(),
+ svg.createDrawable(),
```
```diff
- const { x, y, angle } = anime.path(el),
+ const { translateX, translateY, rotate } = createMotionPath(el);
```
```diff
- anime({
- targets: 'path',
- strokeDashoffset: [anime.setDashoffset, 0],
- });
+ animate(createDrawable('path'), {
+ draw: '0 1',
+ });
```
--------------------------------
### Toggling Output Color Space (SRGB vs. Linear)
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/threejs/color-compare/index.html
Provides functionality to switch the renderer's output color space between `SRGBColorSpace` (default) and `LinearSRGBColorSpace`. This demonstrates how different color spaces affect perceived brightness and ensures color consistency between native and adapter methods.
```javascript
const srgbBtn = document.getElementById('srgb');
const linearBtn = document.getElementById('linear');
function setSpace(space, activeBtn, inactiveBtn) {
renderer.outputColorSpace = space;
// Materials cache their compiled shaders; re-set the colors so the
// cached uniforms refresh against the new output space.
for (let i = 0; i < swatches.length; i++) {
nativeMeshes[i].material.color.set(swatches[i]);
utils.set(animeMeshes[i], { color: swatches[i] });
}
activeBtn.classList.add('active');
inactiveBtn.classList.remove('active');
}
srgbBtn.onclick = () => setSpace(SRGBColorSpace, srgbBtn, linearBtn);
linearBtn.onclick = () => setSpace(LinearSRGBColorSpace, linearBtn, srgbBtn);
```
--------------------------------
### Implement manual animation tick
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
The tick() method is replaced by a global manual engine update system.
```javascript
import { engine } from 'animejs';
// Prevents Anime.js from using its own loop
engine.useDefaultMainLoop = false;
function render() {
engine.update(); // Manually update Anime.js engine
}
// Calls the builtin Three.js animation loop
renderer.setAnimationLoop(render);
```
--------------------------------
### Animate Color Transitions with Anime.js
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/color-conversion.html
This script iterates through elements with the class 'color-test', creates a new div for displaying color, and animates its background color between two specified values. It uses the 'animate' function from Anime.js, supporting various color formats and animation properties like ease, duration, loop, alternate, and direction.
```javascript
import { animate } from '../../../dist/modules/index.js'; const colorTestEls = document.querySelectorAll('.color-test'); function createTest(el) { const testHtml = el.innerHTML; const testValues = testHtml.split('
▾
'); const colorEl = document.createElement('div'); colorEl.classList.add('color-el'); el.appendChild(colorEl); const animation = animate(colorEl, { backgroundColor: [testValues[0], testValues[1]], scale: 1, ease: 'inOut', duration: 4000, loop: true, alternate: true, }); } for (var i = 0; i < colorTestEls.length; i++) { createTest(colorTestEls[i]); }
```
--------------------------------
### CSS Styles for Anime.js Starlings
Source: https://github.com/juliangarnier/anime/blob/master/examples/timeline-refresh-starlings/index.html
Sets up a full-screen viewport with a gradient background and a centered, responsive element.
```css
body { overflow: hidden; position: absolute; width: 100%; height: 100dvh; background: linear-gradient( to top, #DCB697 0%, #9BA5AE 35%, #3E5879 100% ); } div { position: absolute; top: 50%; left: 50%; width: 1em; height: 1em; margin: -.5em 0 0 -.5em; font-size: clamp(3px, 2vw, 4px); border-radius: 1em; background-color: currentColor; }
```
--------------------------------
### Basic Body Styling for Timeline Tests
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/timeline/test/index.html
Applies flexbox properties to center content and sets absolute positioning for full-screen overflow.
```css
body {
display: flex;
align-items: center;
justify-content: center;
flex-direction: column;
position: absolute;
overflow: hidden;
width: 100%;
height: 100%;
}
```
--------------------------------
### Animation Loop for Three.js Scene
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/threejs/color-compare/index.html
Sets up the main animation loop using `requestAnimationFrame` to continuously render the scene. This ensures that the cubes are displayed and updated.
```javascript
function loop() {
requestAnimationFrame(loop);
renderer.render(scene, camera);
}
loop();
```
--------------------------------
### Updating Change Callback
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
Replaces the change callback with onRender.
```diff
- change: () => {},
+ onRender: () => {},
```
--------------------------------
### Stagger Grid Animation with Anime.js
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/stagger-grid-demo.html
This snippet sets up a grid of divs and animates them using Anime.js's createTimeline and stagger utilities. It includes complex animations for translation, rotation, scaling, and background color changes.
```javascript
import { animate, createTimeline, utils, stagger, svg } from '../../../dist/modules/index.js';
const staggerVisualizerEl = document.querySelector('.stagger-visualizer');
const fragment = document.createDocumentFragment();
const grid = [24, 24];
const col = grid[0];
const row = grid[1];
const numberOfElements = col * row;
for (let i = 0; i < numberOfElements; i++) {
fragment.appendChild(document.createElement('div'));
}
staggerVisualizerEl.appendChild(fragment);
const staggersAnimation = createTimeline({
defaults: {
ease: 'inOutSine',
delay: stagger(50),
},
loop: true,
})
.add('.stagger-visualizer div', {
translateX: [
{ to: stagger('-.1rem', {grid, from: 'center', axis: 'x'}) },
{ to: stagger('.1rem', {grid, from: 'center', axis: 'x'}) }
],
translateY: [
{ to: stagger('-.1rem', {grid, from: 'center', axis: 'y'}) },
{ to: stagger('.1rem', {grid, from: 'center', axis: 'y'}) }
],
backgroundColor: {
from: '#FFF'
},
duration: 1000,
scale: .5,
delay: stagger(100, {grid, from: 'center'})
})
.add('.stagger-visualizer div', {
translateX: () => utils.random(-10, 10),
translateY: () => utils.random(-10, 10),
delay: stagger(8, {from: 'last'})
})
.add('.stagger-visualizer div', {
translateX: stagger('.25rem', {grid, from: 'center', axis: 'x'}),
translateY: stagger('.25rem', {grid, from: 'center', axis: 'y'}),
rotate: 0,
scaleX: 4,
scaleY: .25,
delay: stagger(4, {from: 'center'}),
})
.add('.stagger-visualizer div', {
rotate: stagger([180, 0], {grid, from: 'center'}),
delay: stagger(50, {grid, from: 'center'})
})
.add('.stagger-visualizer div', {
backgroundColor: '#FFF',
translateX: 0,
translateY: 0,
scale: .5,
scaleX: 1,
rotate: 0,
duration: 1000,
delay: stagger(100, {grid, from: 'center'})
})
.add('.stagger-visualizer div', {
scaleY: 1,
scale: 1,
delay: stagger(20, {grid, from: 'center'})
})
.init()
```
--------------------------------
### CSS Styling for Anime.js Tests
Source: https://github.com/juliangarnier/anime/blob/master/tests/index.html
Contains CSS rules for styling elements used in Anime.js test cases. Includes styles for squares, staggering animations, and grid layouts.
```css
#tests #square {
position: absolute;
left: 0;
top: 0;
width: 1rem;
height: 1rem;
margin-left: -.5rem;
margin-top: -.5rem;
background-color: white;
}
#tests #stagger div {
width: 1rem;
height: 1rem;
background-color: var(--color-citrus);
border: 1px solid var(--color-black);
}
#tests #grid {
display: flex;
flex-wrap: wrap;
}
#tests #grid div {
width: 20%;
height: 1.675rem;
background-color: var(--color-darkgreen);
border: 1px solid var(--color-black);
}
@media (min-width: 600px) {
#mocha, #tests {
width: 50%;
}
#tests {
opacity: 1;
top: 40px;
}
}
```
--------------------------------
### CSS for grid staggering visualizer
Source: https://github.com/juliangarnier/anime/blob/master/examples/advanced-grid-staggering/index.html
Defines the layout and sizing for the grid container, individual dots, and the cursor element.
```css
body { --rows: 41; display: flex; flex-wrap: wrap; justify-content: center; align-items: center; height: 100vh; } .stagger-visualizer { position: relative; display: flex; flex-wrap: wrap; justify-content: center; align-items: center; width: calc(var(--rows) * 1rem); height: calc(var(--rows) * 1rem); } .stagger-visualizer .dot { position: relative; width: .25rem; height: .25rem; margin: .375rem; background-color: currentColor; border-radius: 50%; } .stagger-visualizer .cursor { position: absolute; z-index: 1; top: 0; left: 0; width: 1rem; height: 1rem; background-color: currentColor; border-radius: 50%; }
```
--------------------------------
### Update Easing parameters
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
Easing function names have been shortened by removing the 'ease' prefix, and the 'easing' parameter is now 'ease'.
```diff
- easing: 'easeOutQuad',
+ ease: 'outQuad',
```
```diff
- easing: 'spring(1, 80, 10, 0)',
+ ease: createSpring({ mass: 1, stiffness: 80, damping: 10, velocity: 0 }),
```
```diff
- easing: () => t => 1 - Math.sqrt(1 - t * t),
+ ease: t => 1 - Math.sqrt(1 - t * t),
```
--------------------------------
### Import Three.js Modules
Source: https://github.com/juliangarnier/anime/blob/master/tests/playground/threejs/adapters/index.html
Import the core Three.js library and specific modules for TSL and WebGPU rendering. These imports are essential for setting up Three.js scenes and utilizing its advanced features.
```javascript
{
"imports": {
"three": "https://unpkg.com/three@0.184.0/build/three.module.js",
"three/tsl": "https://unpkg.com/three@0.184.0/build/three.tsl.js",
"three/webgpu": "https://unpkg.com/three@0.184.0/build/three.webgpu.js"
}
}
```
--------------------------------
### Updating Property Parameters
Source: https://github.com/juliangarnier/anime/wiki/Migrating-from-v3-to-v4
The value parameter in object syntax is now named to.
```diff
- opacity: { value: .5, duration: 250 },
+ opacity: { to: 1, duration: 250 },
```
--------------------------------
### Define Auto Layout and Navigation Styles
Source: https://github.com/juliangarnier/anime/blob/master/examples/auto-layout/nav/index.html
Applies flexbox layout for centering content and styling the navigation bar with scrollable overflow and active state handling.
```css
body { display: flex; flex-direction: row; justify-content: center; align-items: center; width: 100%; padding: 6rem 1rem; min-height: 100lvh; } nav { overflow-x: scroll; display: flex; width: 100%; border-top-left-radius: 1rem; border-top-right-radius: 1rem; background-color: var(--bg-2); } nav ul { position: relative; display: flex; flex-shrink: 0; padding: 1rem; list-style: none; } nav button { flex: 1; position: relative; z-index: 1; background: transparent; color: var(--fg-2); } nav button:not(:disabled):focus-visible, nav button:not(:disabled):hover, nav button:has(.button-bg) { z-index: 0; color: var(--color-1); background: transparent; outline: none; } nav button .button-bg { position: absolute; z-index: 0; top: 0; left: 0; right: 0; bottom: 0; background-color: var(--color-4); border-radius: .25rem; border: 1px solid var(--color-2); } nav button .button-txt { position: relative; z-index: 1; } .container { width: 100%; max-width: 42rem; border-radius: 1rem; background: var(--bg-3); } .content { width: 100%; padding: 2rem; } .content h1 { color: var(--color-1); margin-bottom: 1em; } .content section { display: none; } .content section.is-active { display: block; }
```
--------------------------------
### Module Imports for Three.js and Anime.js
Source: https://github.com/juliangarnier/anime/blob/master/examples/threejs/transforms/index.html
Defines the necessary module imports for Three.js and its addons, as well as Anime.js and its GUI component, using unpkg CDN and local paths.
```javascript
{
"imports": {
"three": "https://unpkg.com/three@0.184.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.184.0/examples/jsm/",
"tweaks": "../../../node_modules/tweaks/tweaks.js",
"tweaks/gui": "../../../node_modules/tweaks/gui/index.js"
}
}
```