iife封装动画引擎并用闭包实现状态机驱动的动画单元,避免全局污染与外部依赖,每个动画独立维护生命周期,支持按需扩展与单独控制。

用IIFE封装动画引擎,避免全局污染
把整个动画引擎包在立即执行函数里,外部无法访问内部变量和函数,只暴露必要的接口。比如启动、暂停、注册动画这些方法,其他细节都藏在里面:
```js(function (global) {
let animations = [];
let isRunning = false;
let lastTime = 0;
// 核心循环
function tick(timestamp) {
if (!isRunning) return;
const delta = timestamp - lastTime;
lastTime = timestamp;
for (let i = animations.length - 1; i >= 0; i--) {
const anim = animations[i];
if (anim.update && !anim.paused) anim.update(delta);
if (anim.removed) animations.splice(i, 1);
}
if (isRunning) requestAnimationFrame(tick);
}
// 对外暴露的 API
global.AnimEngine = {
start() {
if (!isRunning) {
isRunning = true;
lastTime = performance.now();
requestAnimationFrame(tick);
}
},
stop() { isRunning = false; },
add(anim) { animations.push(anim); },
remove(anim) { anim.removed = true; }
};
})(typeof window !== 'undefined' ? window : globalThis);
用闭包实现状态机驱动的动画单元
每个动画实例应自带生命周期和状态(如 playing / paused / ended),不依赖外部控制变量。用闭包保存私有状态,只通过方法操作:
```jsfunction createTween({ from, to, duration, ease = t => t, onUpdate, onEnd }) {
let startTime = 0;
let elapsed = 0;
let isPlaying = false;
let isEnded = false;
return {
update(delta) {
if (!isPlaying || isEnded) return;
elapsed += delta;
if (elapsed >= duration) {
elapsed = duration;
isEnded = true;
}
const t = ease(elapsed / duration);
const value = from + (to - from) * t;
if (onUpdate) onUpdate(value);
if (isEnded && onEnd) onEnd();
},
play() {
if (isEnded) {
elapsed = 0;
isEnded = false;
}
isPlaying = true;
},
pause() { isPlaying = false; },
reset() { elapsed = 0; isEnded = false; isPlaying = false; },
getProgress() { return Math.min(elapsed / duration, 1); },
isPlaying: () => isPlaying,
isEnded: () => isEnded
};
}
组合使用:注册动画并控制状态流转
把闭包生成的动画单元加进引擎,靠 IIFE 隔离的全局状态统一调度。每个动画独立维护自己的时间线,互不干扰:
```js// 创建两个独立动画
const fadeAnim = createTween({
from: 0, to: 1, duration: 800,
onUpdate: v => el.style.opacity = v,
onEnd: () => console.log('fade done')
});
const moveAnim = createTween({
from: 0, to: 200, duration: 1200,
ease: t => t * t * (3 - 2 * t), // easeInOutCubic
onUpdate: v => el.style.transform = `translateX(${v}px)`
});
// 加入引擎并启动
AnimEngine.add(fadeAnim);
AnimEngine.add(moveAnim);
AnimEngine.start();
// 可随时单独控制
setTimeout(() => moveAnim.pause(), 500);
setTimeout(() => moveAnim.play(), 1000);
轻量关键:零依赖、无类、按需扩展
这个设计不基于 class 或 this,避免原型链开销;所有状态都在闭包里,没有属性反射或 getter/setter;新增功能只需扩展现有闭包返回对象,比如加一个 repeat 模式:
- 添加 repeat 字段后,在 update 中检测 isEnded 就重置 elapsed 并继续
- 加 delay 参数,让 startTime 延后,首次 update 前跳过更新逻辑
- 支持链式调用?在返回对象上挂 .then(cb) 方法,内部用 onEnd 触发
- 需要销毁资源?在 remove 时调用 anim.destroy() —— 只要你在闭包里预留了 destroy 函数
不复杂但容易忽略
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











