Animation Libraries in Gameface
CSS transitions, CSS keyframes, SVG animations, WAAPI control, and sprite sheets should remain your default animation tools in Gameface. Animation libraries are useful when the UI needs designer-authored motion , complex timeline sequencing , or library-level callbacks that would be difficult to maintain with CSS alone.
Use CSS First
Section titled “Use CSS First”In browser UI development, it is common to install an animation library as soon as a screen needs motion. In a game UI, that habit needs more discipline. JavaScript animation libraries calculate values on the JavaScript thread, usually on every animation frame. That work competes with input handling, state updates, data-binding updates, and any other UI logic running in the same view.
Gameface already gives you several native animation tools:
- CSS transitions for simple state changes like hover, focus, selected, disabled, or expanded.
- CSS keyframes for looping or multi-step effects that do not need runtime sequencing.
- WAAPI control for pausing, reversing, seeking, or replaying CSS-authored animations from JavaScript.
- Sprite sheets for pre-rendered VFX where the final visual should come from an offline art tool.
Reach for an animation library only when the project needs behavior that those tools do not express cleanly. Common examples include a long end-of-match results sequence, an onboarding flow with multiple timed callouts, or an After Effects animation exported by the motion design team.
Choosing a Library
Section titled “Choosing a Library”The libraries below are documented as tested options that can run out of the box in Gameface, within the feature boundaries of the engine. Treat them as separate tools rather than interchangeable ways to move elements on screen.
- Use Lottie when the source of truth is an After Effects composition exported as JSON. It is best for designer-authored vector motion that should play back as an asset.
- Use GSAP when you need a maintained JavaScript timeline with sequencing, easing, callbacks, and runtime control across many DOM elements.
- Use AnimeJS when you need a lighter JavaScript animation library for DOM element tweening, simple sequencing, or staggered effects.
- Use Framer Motion when the UI is built in React and you want React-level animation primitives for components, variants, and transitions.
- Fallback to CSS or WAAPI when the animation is a simple UI state transition, an idle loop, a loading pulse, or a basic panel entrance.
Other animation libraries may also work, but they have not been explicitly tested in the same way. If a library almost works and only depends on a small missing DOM method, a narrow polyfill can be reasonable. If it depends on a larger unsupported rendering feature, choose a different approach instead.
The tabs below show a minimal setup for each tested library and the Gameface-specific rules that matter most when using it.
Lottie usually refers to two related pieces: a JSON animation exported from After Effects, often through the Bodymovin plugin, and the JavaScript library that renders that JSON at runtime. Gameface officially supports Lottie Light , which renders through SVG and does not support expressions or effects.
Use Lottie when the animation should be owned by motion design rather than recreated by hand in CSS. Level-up bursts, reward reveals, stylized loaders, and branded transition moments are good candidates.
Installation & Setup
Section titled “Installation & Setup”Install it through your package manager for project with bundlers (like Vite or Webpack):
npm i lottie-web-lightFor a direct script setup, download the Lottie Light build and serve it with the rest of your UI assets:
<script src="./vendor/lottie_light.js"></script><script src="./level-up-lottie.js"></script>Basic Usage
Section titled “Basic Usage”Start with a concrete container. Bodymovin usually generates an inline SVG with width="100%" and height="100%", so the parent element must
have an explicit size:
import { onMount } from 'solid-js';import Block from '@components/Layout/Block/Block';
const LevelUpLottie = () => { let containerRef!: HTMLElement;
onMount(() => { const container = document.getElementById("level-up-lottie");
const animation = bodymovin.loadAnimation({ container, path: "./assets/animations/level-up.json", renderer: "svg", loop: false, autoplay: true, });
// Snap playback to exported frames instead of interpolating subframes. animation.setSubframe(false); });
return <Block ref={containerRef} id="level-up-lottie" class="level-up-lottie" />;};<div id="level-up-lottie" class="level-up-lottie"></div>Then load the animation with the SVG renderer. The example below uses the global bodymovin object from lottie_light.js:
const container = document.getElementById("level-up-lottie");
const animation = bodymovin.loadAnimation({ container, path: "./assets/animations/level-up.json", renderer: "svg", loop: false, autoplay: true,});
// Snap playback to exported frames instead of interpolating subframes.animation.setSubframe(false);.level-up-lottie { width: 32vh; height: 32vh;}GSAP is useful when the UI needs a timeline rather than a single animation. A post-match screen, for example, might fade in the panel, count up rewards, stagger player rows, reveal buttons, and fire callbacks at specific points in the sequence.
Installation & Setup
Section titled “Installation & Setup”For project with bundlers (like Vite or Webpack):
npm i gsapFor a direct script setup, download the production build and serve it with the rest of your UI assets:
<script src="./vendor/gsap.min.js"></script><script src="./match-results.js"></script>Basic Usage
Section titled “Basic Usage”The markup can stay ordinary. The library controls the elements through selectors:
import { onMount } from 'solid-js';import Block from '@components/Layout/Block/Block';import TextBlock from '@components/Basic/TextBlock/TextBlock';import Button from '@components/Basic/Button/Button';
const MatchResults = () => { let fillRef!: HTMLElement;
onMount(() => { // gsap.to(fillRef, { width: '100%', duration: 1.5 }); });
return ( <Block class="match-results"> <TextBlock class="match-results__title">Victory</TextBlock> <Block class="match-results__xp-bar"> <Block ref={fillRef} class="match-results__xp-fill" /> </Block> <Button class="match-results__continue">Continue</Button> </Block> );};<section class="match-results"> <h2 class="match-results__title">Victory</h2> <div class="match-results__xp"> <div class="match-results__xp-fill"></div> </div> <button class="match-results__continue">Continue</button></section>A single tween is enough for a simple property change:
gsap.to(".match-results__xp-fill", { width: "100%", duration: 1.5, ease: "power2.out",});Timelines are where GSAP becomes more useful. They let you describe the order of a sequence in one place:
const resultsTimeline = gsap.timeline({ paused: true });
resultsTimeline .from(".match-results", { opacity: 0, y: 24, duration: 0.35, ease: "power2.out", }) .to(".match-results__xp-fill", { width: "100%", duration: 1.2, ease: "power2.out", }) .from(".match-results__continue", { opacity: 0, y: 12, duration: 0.25, });
resultsTimeline.play();AnimeJS is a smaller JavaScript animation library for DOM element tweening, sequencing, and staggered effects. It is a reasonable choice when a screen needs a little more orchestration than CSS provides , but the project does not need the full GSAP timeline feature set.
Installation & Setup
Section titled “Installation & Setup”For project with bundlers (like Vite or Webpack):
npm i animejsFor a direct script setup, download the browser build and serve it with the rest of your UI assets:
<script src="./vendor/anime.min.js"></script><script src="./loadout-menu.js"></script>Basic Usage
Section titled “Basic Usage”A common use case is a menu where items enter in order:
import { onMount } from 'solid-js';import Block from '@components/Layout/Block/Block';import Button from '@components/Basic/Button/Button';
const ITEMS = ['Sword', 'Shield', 'Bow', 'Staff'];
const LoadoutMenu = () => { let menuRef!: HTMLElement;
onMount(() => { // anime({ targets: menuRef.querySelectorAll('.loadout-item'), ... }); });
return ( <Block ref={menuRef} as="nav" class="loadout-menu"> {ITEMS.map((item) => ( <Button class="loadout-item">{item}</Button> ))} </Block> );};<nav class="loadout-menu"> <button class="loadout-menu__item">Weapons</button> <button class="loadout-menu__item">Armor</button> <button class="loadout-menu__item">Consumables</button> <button class="loadout-menu__item">Quest Items</button></nav>The configuration object defines the target elements, final values, timing, easing, and stagger:
anime({ targets: ".loadout-menu__item", opacity: [0, 1], translateX: ["-4vh", "0vh"], delay: anime.stagger(80), duration: 450, easing: "easeOutQuad",});Always include explicit units for dimensional values. For example, use top: "100px" rather than top: 100, and use "4vh" rather than 4
when the target property expects a length.
Framer Motion is a React animation library. Use it only when the UI screen is already built in React and the team wants component-level animation APIs such as variants, transitions, layout-aware component states, or declarative entrance and exit behavior.
Installation & Setup
Section titled “Installation & Setup”Install it in the React project that builds your Gameface view:
npm install framer-motionBasic Usage
Section titled “Basic Usage”The basic React pattern is to import motion and replace the element you want to animate with a motion-enabled element:
import { motion } from "framer-motion";
export function RewardPanel() { return ( <motion.section className="reward-panel" initial={{ opacity: 0, y: 24 }} animate={{ opacity: 1, y: 0 }} transition={{ duration: 0.35, ease: "easeOut" }} > <h2>Reward Unlocked</h2> <button>Continue</button> </motion.section> );}Gameface Constraints
Section titled “Gameface Constraints”Each library is limited by the same rendering and DOM capabilities as the rest of your Gameface UI. A library can provide timing, sequencing, easing, and callbacks, but it cannot make an unsupported CSS property, SVG feature, asset format, or browser API behave as if it were supported.
For GSAP, AnimeJS, and Framer Motion, the practical rule is simple: animate properties that Gameface already supports . Transforms, opacity, and supported dimensional properties are safer choices than library demos copied directly from browser-focused examples.
For Lottie, test the exported animation early in the Gameface Player. After Effects compositions can contain features that are valid in the Lottie ecosystem but outside the supported Gameface path, such as SVG filters, SVG blend modes, dynamic text, or unsupported embedded image formats.
For libraries not listed above, start with the smallest representative prototype. Test the exact property, SVG feature, DOM method, callback, or module format that your screen depends on. If the gap is small and local, such as a missing DOM convenience method, a focused polyfill may be enough. If the library depends on unsupported rendering behavior, a polyfill will not make that feature render correctly.
Learn More
Section titled “Learn More”© 2026 Coherent Labs. All rights reserved.