renderer handles

Adapters

The same Chop character projection animated with GSAP, Anime.js, Motion, and CSS keyframes.

All demos

One split, four renderers

Chop owns the projection. The animation engine is swappable.

GSAP gsap.to(chars)

Split once animate anywhere

Timeline-grade control over the same Chop character handles.

Anime.js animate(chars)

Split once animate anywhere

Millisecond timing with native stagger helpers.

Motion animate(char)

Split once animate anywhere

Per-handle playback controls using seconds-based timing.

CSS animation @keyframes

Split once animate anywhere

Plain keyframes driven by Chop index variables.

Same Chop handles, different renderers


                    
                      1
                    
                    import { chop } from '@tonybonet/chop'
                  
                    
                      2
                    
                    import { gsap } from 'gsap'
                  
                    
                      3
                    
                    import { animate as animeAnimate } from 'animejs/animation'
                  
                    
                      4
                    
                    import { cubicBezier as animeEase } from 'animejs/easings/cubic-bezier'
                  
                    
                      5
                    
                    import { stagger } from 'animejs/utils'
                  
                    
                      6
                    
                    import { animate as motionAnimate } from 'motion/mini'
                  
                    
                      7
                    
                    
                  
                    
                      8
                    
                    const split = chop(title)
                  
                    
                      9
                    
                    const chars = split.chars
                  
                    
                      10
                    
                    
                  
                    
                      11
                    
                    gsap.set(chars, { y: 16, opacity: 0, filter: 'blur(12px)' })
                  
                    
                      12
                    
                    gsap.to(chars, {
                  
                    
                      13
                    
                      y: 0,
                  
                    
                      14
                    
                      opacity: 1,
                  
                    
                      15
                    
                      filter: 'blur(0px)',
                  
                    
                      16
                    
                      duration: 0.9,
                  
                    
                      17
                    
                      stagger: 0.025,
                  
                    
                      18
                    
                      ease: 'power3.out'
                  
                    
                      19
                    
                    })
                  
                    
                      20
                    
                    
                  
                    
                      21
                    
                    animeAnimate(chars, {
                  
                    
                      22
                    
                      translateY: [16, 0],
                  
                    
                      23
                    
                      opacity: [0, 1],
                  
                    
                      24
                    
                      filter: ['blur(12px)', 'blur(0px)'],
                  
                    
                      25
                    
                      duration: 900,
                  
                    
                      26
                    
                      delay: stagger(25),
                  
                    
                      27
                    
                      ease: animeEase(0.22, 1, 0.36, 1)
                  
                    
                      28
                    
                    })
                  
                    
                      29
                    
                    
                  
                    
                      30
                    
                    chars.forEach((char, index) => {
                  
                    
                      31
                    
                      motionAnimate(char, {
                  
                    
                      32
                    
                        opacity: [0, 1],
                  
                    
                      33
                    
                        transform: ['translate3d(0, 16px, 0)', 'translate3d(0, 0, 0)'],
                  
                    
                      34
                    
                        filter: ['blur(12px)', 'blur(0px)']
                  
                    
                      35
                    
                      }, {
                  
                    
                      36
                    
                        delay: index * 0.025,
                  
                    
                      37
                    
                        duration: 0.9,
                  
                    
                      38
                    
                        ease: [0.22, 1, 0.36, 1]
                  
                    
                      39
                    
                      })
                  
                    
                      40
                    
                    })
                  
                    
                      41
                    
                    
                  
                    
                      42
                    
                    chars.forEach((char, index) => char.style.setProperty('--adapter-index', String(index)))
                  
                    
                      43
                    
                    card.classList.add('is-running')