### 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" } } ```