Documentation Index
Fetch the complete documentation index at: https://mintlify.com/juliangarnier/anime/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Scope module creates isolated animation contexts with their own defaults, lifecycle management, and automatic cleanup. Perfect for component-based architectures, SPAs, and managing animations across different UI sections.
Importing
import { createScope, Scope } from 'animejs';
Creating Scopes
createScope()
Create an isolated animation scope:
const scope = createScope(parameters);
Parameters:
parameters - Scope configuration object (optional)
Basic Example
import { createScope } from 'animejs';
const scope = createScope({
defaults: {
duration: 800,
ease: 'outExpo'
}
});
Scope Parameters
root
string | element | ref
default:"document"
Root element for scoped selector queries
Default animation parameters for all animations in this scope
Named media queries for responsive behavior
const scope = createScope({
root: '.app',
defaults: {
duration: 600,
ease: 'outQuad'
},
mediaQueries: {
mobile: '(max-width: 768px)',
desktop: '(min-width: 769px)',
prefersReducedMotion: '(prefers-reduced-motion: reduce)'
}
});
Framework Integration
React
import { useRef, useEffect } from 'react';
import { createScope } from 'animejs';
function Component() {
const rootRef = useRef(null);
const scopeRef = useRef(null);
useEffect(() => {
scopeRef.current = createScope({
root: rootRef, // React ref
defaults: { duration: 800 }
});
return () => scopeRef.current.revert();
}, []);
return <div ref={rootRef}>...</div>;
}
Angular
import { Component, ElementRef, ViewChild } from '@angular/core';
import { createScope } from 'animejs';
@Component({...})
export class MyComponent {
@ViewChild('root') rootRef: ElementRef;
scope: any;
ngAfterViewInit() {
this.scope = createScope({
root: this.rootRef, // Angular ref
defaults: { duration: 800 }
});
}
ngOnDestroy() {
this.scope.revert();
}
}
Vue
import { ref, onMounted, onUnmounted } from 'vue';
import { createScope } from 'animejs';
export default {
setup() {
const root = ref(null);
let scope;
onMounted(() => {
scope = createScope({
root: root.value,
defaults: { duration: 800 }
});
});
onUnmounted(() => {
scope.revert();
});
return { root };
}
}
Adding Constructors
.add()
Add animation constructors that execute within the scope:
const scope = createScope({
root: '.section',
defaults: { duration: 1000 }
});
scope.add((scope) => {
// Animations automatically use scope defaults
const anim = animate('.box', {
translateX: 250
// duration: 1000 inherited from scope
});
// Return cleanup function
return () => {
anim.revert();
};
});
Named Methods
Create named methods on the scope:
scope.add('slideIn', (element) => {
return animate(element, {
translateX: [100, 0],
opacity: [0, 1]
});
});
// Call the method
scope.methods.slideIn('.card');
Reactive Updates
.refresh()
Refresh all animations in the scope:
let offset = 100;
scope.add(() => {
animate('.box', {
translateX: () => offset // Function-based value
});
});
offset = 200;
scope.refresh(); // Re-evaluates function
Scope automatically refreshes when media queries change:
const scope = createScope({
mediaQueries: {
mobile: '(max-width: 768px)'
}
});
scope.add((scope) => {
const isMobile = scope.matches.mobile;
animate('.menu', {
translateX: isMobile ? 0 : 250
});
});
// Automatically refreshes when viewport changes
Single Execution
.addOnce()
Execute constructor only once, even after refresh:
scope.addOnce(constructor)
scope.add(() => {
console.log('Runs on every refresh');
});
scope.addOnce(() => {
console.log('Runs only once');
// Good for initialization
});
scope.refresh(); // First constructor runs again, second doesn't
Time Preservation
.keepTime()
Preserve animation state across refreshes:
scope.keepTime(constructor)
let isActive = false;
const animation = scope.keepTime(() => {
return animate('.box', {
rotate: isActive ? 360 : 0,
duration: 1000
});
});
isActive = true;
scope.refresh();
// Animation preserves current time instead of restarting
Executing Code in Scope
.execute()
Run code within the scope context:
const scope = createScope({
root: '.section',
defaults: { duration: 1200 }
});
scope.execute(() => {
// Queries scoped to .section
// Uses scope defaults
const animation = animate('.box', {
scale: 2
});
return animation;
});
Scope Properties
Root element for scoped queries
Default animation parameters
Named methods added with .add(name, method)
Current media query match states
MediaQueryList objects for each media query
const scope = createScope({
defaults: { duration: 800 },
mediaQueries: {
mobile: '(max-width: 768px)'
}
});
console.log(scope.defaults.duration); // 800
console.log(scope.matches.mobile); // true/false
// Store custom data
scope.data.theme = 'dark';
scope.data.count = 0;
Cleanup
.revert()
Cleanup all animations and remove event listeners:
const scope = createScope();
scope.add(() => {
return animate('.box', { scale: 2 });
});
// Later, cleanup everything
scope.revert();
Advanced Examples
Component Scope
class AnimatedComponent {
constructor(element) {
this.scope = createScope({
root: element,
defaults: {
duration: 600,
ease: 'outQuad'
}
});
this.scope.add(() => {
this.timeline = createTimeline();
this.timeline.add('.title', { opacity: [0, 1] })
.add('.content', { translateY: [20, 0] });
return () => this.timeline.revert();
});
}
destroy() {
this.scope.revert();
}
}
Responsive Animations
const scope = createScope({
mediaQueries: {
mobile: '(max-width: 768px)',
tablet: '(min-width: 769px) and (max-width: 1024px)',
desktop: '(min-width: 1025px)'
}
});
scope.add((s) => {
const { mobile, tablet, desktop } = s.matches;
const duration = mobile ? 400 : tablet ? 600 : 800;
const offset = mobile ? 50 : tablet ? 100 : 150;
return animate('.card', {
translateX: offset,
duration: duration
});
});
// Auto-refreshes on viewport change
Shared Scope Configuration
// Shared across components
const appScope = createScope({
defaults: {
duration: 800,
ease: 'outExpo'
},
mediaQueries: {
mobile: '(max-width: 768px)',
prefersReducedMotion: '(prefers-reduced-motion: reduce)'
}
});
// Method library
appScope.add('fadeIn', (element, options = {}) => {
const shouldAnimate = !appScope.matches.prefersReducedMotion;
return animate(element, {
opacity: [0, 1],
duration: shouldAnimate ? undefined : 0,
...options
});
});
appScope.add('slideUp', (element) => {
return animate(element, {
translateY: [30, 0],
opacity: [0, 1]
});
});
// Use anywhere
appScope.methods.fadeIn('.modal');
appScope.methods.slideUp('.notification');
Dynamic Scope Data
const scope = createScope();
scope.data.theme = 'light';
scope.data.animationSpeed = 1;
scope.add((s) => {
const speed = s.data.animationSpeed;
const color = s.data.theme === 'dark' ? '#fff' : '#000';
return animate('.element', {
color: color,
duration: 1000 / speed
});
});
// Update and refresh
scope.data.theme = 'dark';
scope.data.animationSpeed = 2;
scope.refresh();
Best Practices
Always call .revert() when components unmount to prevent memory leaks.
Use scopes to isolate animation contexts in component-based applications.
Avoid creating scopes in loops or on every render. Create once per component instance.
// Good: One scope per component
class Component {
constructor() {
this.scope = createScope({ root: this.element });
}
destroy() {
this.scope.revert();
}
}
// Bad: Creating scope on every update
function update() {
const scope = createScope(); // Don't do this!
}