A lightweight micro-animation engine for smooth UI motion — without external libraries.
MicroMotion is a zero-dependency JavaScript animation engine designed for building smooth, performant micro-animations directly in the browser. It provides 30+ easing functions, spring physics, timeline sequencing, scroll-triggered animations, stagger systems, and color interpolation — all in a single lightweight file.
Built as part of a B.Sc. Computer Science final year project at Weldios University of Management and Technology.
- 30+ Easing Functions — Full Robert Penner easing suite
- Spring Physics — Damped harmonic oscillator with 6 presets
- Timeline Sequencing — Chain and overlap animations with offset control
- Scroll Animations — IntersectionObserver-based reveals and scroll-scrubbed progress
- Stagger System — Cascade delays from start, end, center, or random
- Color Interpolation — Hex, RGB, RGBA, HSL, and named color blending
- Promise-based — Every animation returns a promise for easy chaining
- Transform Shorthand — Use
x,y,scale,rotateinstead of verbose CSS - Zero Dependencies — No npm install, no build step, just one JS file
- TypeScript Support — Full type definitions included
- Theme Customizer — Live theme customization with CSS variable export
micro-animation-engine/
├── micromotion.js # Core engine (38KB source)
├── micromotion.min.js # Minified build (17KB / 5.5KB gzipped)
├── micromotion.d.ts # TypeScript definitions
├── index.html # Interactive demo website
├── style.css # Demo stylesheet (CSS custom properties)
├── demo.js # Demo interactions & theme customizer
├── benchmark.html # Performance stress-test page
├── tests/
│ └── micromotion.test.html # Browser-based unit test suite (70+ tests)
├── report.html # Academic report (APA 7th ed.)
├── obs.pdf # Generated PDF report
└── README.md
<!-- Use the minified version for production -->
<script src="micromotion.min.js"></script>
<script>
// Animate to values
MicroMotion.to('.box', {
x: 200,
opacity: 1,
rotate: 45,
duration: 600,
easing: 'easeOutCubic'
});
// Spring physics
MicroMotion.spring('.ball', { x: 300 }, 'wobbly');
// Timeline
MicroMotion.timeline()
.add('.step-1', { x: 100 }, { duration: 300 })
.add('.step-2', { y: -50 }, { duration: 200, offset: '-=100' })
.play();
// Stagger
MicroMotion.stagger('.items', {
opacity: 1, y: 0, duration: 400
}, { stagger: 80, from: 'center' });
// Scroll reveal
MicroMotion.scroll('.reveal', {
opacity: 1, y: 0, duration: 600
}, { threshold: 0.2, once: true });
</script>| Method | Description |
|---|---|
MicroMotion.to(targets, props) |
Animate to specified values |
MicroMotion.from(targets, props) |
Animate from specified values |
MicroMotion.fromTo(targets, from, to, opts) |
Animate between two states |
MicroMotion.spring(targets, props, config) |
Spring physics animation |
MicroMotion.timeline(opts) |
Create sequenced animations |
MicroMotion.stagger(targets, props, opts) |
Staggered group animation |
MicroMotion.scroll(targets, props, opts) |
Scroll-triggered animation |
MicroMotion.set(targets, props) |
Set values immediately |
| Option | Type | Default | Description |
|---|---|---|---|
duration |
number | 400 | Duration in ms |
delay |
number | 0 | Delay before start |
easing |
string/function | 'easeOutCubic' |
Easing curve |
loop |
number | 0 | Loop count (-1 = infinite) |
alternate |
boolean | false | Reverse on each loop |
autoplay |
boolean | true | Start immediately |
onStart |
function | null | Called on first frame |
onUpdate |
function | null | Called each frame |
onComplete |
function | null | Called on completion |
linear, easeInQuad, easeOutQuad, easeInOutQuad, easeInCubic, easeOutCubic, easeInOutCubic, easeInQuart, easeOutQuart, easeInOutQuart, easeInQuint, easeOutQuint, easeInOutQuint, easeInSine, easeOutSine, easeInOutSine, easeInExpo, easeOutExpo, easeInOutExpo, easeInCirc, easeOutCirc, easeInOutCirc, easeInBack, easeOutBack, easeInOutBack, easeInElastic, easeOutElastic, easeInOutElastic, easeOutBounce, easeInBounce, easeInOutBounce
| Preset | Stiffness | Damping | Mass |
|---|---|---|---|
default |
100 | 10 | 1 |
gentle |
120 | 14 | 1 |
wobbly |
180 | 12 | 1 |
stiff |
210 | 20 | 1 |
slow |
280 | 60 | 1 |
molasses |
280 | 120 | 1 |
Open tests/micromotion.test.html in a browser. Tests cover:
- Module exports (13 tests)
- Easing functions — boundary values, symmetry (18 tests)
- Spring presets (7 tests)
.to()— animation object, controls, seek behavior (10 tests).from(),.fromTo(),.set()(5 tests).spring()— object & preset configs (2 tests).timeline()— chaining, offset, duration tracking (9 tests).stagger(),.scroll()(3 tests)- Transform animations — x, scale, rotate (3 tests)
- Color animation (1 test)
- Callbacks — onStart, onUpdate (2 tests)
- Edge cases — missing targets, invalid easing, duration 0, infinite loop (4 tests)
Open benchmark.html to stress-test the engine. Configurable parameters:
- 50–1000 concurrent animations
- Custom duration and easing
- Real-time FPS, dropped frames, and memory metrics
Typical results on modern hardware:
- 100 concurrent animations: 60 FPS sustained
- 500 concurrent animations: 55–60 FPS
- 1000 concurrent animations: 45–55 FPS
| Browser | Minimum Version | Status |
|---|---|---|
| Chrome | 60+ | ✅ Tested |
| Firefox | 55+ | ✅ Tested |
| Safari | 12+ | ✅ Tested |
| Edge | 79+ (Chromium) | ✅ Tested |
| Mobile Chrome | 60+ | ✅ Tested |
| Mobile Safari | 12+ | ✅ Tested |
Requires: Promise, WeakMap, IntersectionObserver, requestAnimationFrame
# Minify (requires Node.js)
npx terser micromotion.js -c -m -o micromotion.min.jsObaje Josephine — HEIM/2023/CSC/0006
Department of Computer Science
Faculty of Pure and Applied Science
Weldios University of Management and Technology
Supervisor: Dr. Kona
MIT