
Security News
New Study Identifies 53 Slopsquatting Targets Across 5 Frontier LLMs
Five frontier LLMs generated the same nonexistent package names, leaving 53 available for potential slopsquatting across PyPI and npm.
aminofx-kit
Advanced tools
一个强大、灵活的Web动画播放器SDK,支持基于关键帧的复杂动画制作和播放。
{{variable}}语法的动态内容渲染npm install @yqg-max/click-gate
动画元素配置接口,定义了动画中每个元素的基本信息和样式。
interface IAnimationElement {
/** 元素唯一标识符 */
id: string;
/** 元素关联的数据,用于模板渲染 */
data?: Record<string, any>;
/** 元素内容配置 */
content: {
/** HTML内容模板,支持 {{variable}} 语法 */
html?: string;
/** 自定义CSS样式 */
style?: Record<string, string | number>;
};
}
CSS属性接口,定义了动画中常用的CSS变换属性。
interface IPropertieCss {
/** X轴位置 (px) */
x: number;
/** Y轴位置 (px) */
y: number;
/** 宽度 (px) */
width: number;
/** 高度 (px) */
height: number;
/** 旋转角度 (deg) */
rotation: number;
/** 透明度 (0-1) */
opacity: number;
/** 缩放比例 */
scale: number;
}
动画关键帧接口,定义了某个时间点上元素的属性状态。
interface IAnimationKeyframe {
/** 关键帧唯一标识符 */
id: string;
/** 关联的元素ID */
elementId: string;
/** 时间点 (毫秒) */
time: number;
/** 该时间点的CSS属性值 */
properties: Partial<IPropertieCss> & Record<string, any>;
}
动画配置模式接口,定义了完整的动画配置。
interface IAnimationSchema {
/** 动画中的所有元素 */
elements: IAnimationElement[];
/** 动画中的所有关键帧 */
keyframes: IAnimationKeyframe[];
/** 全局数据,用于模板渲染 */
data?: Record<string, any>;
}
动画信息接口,提供动画的统计信息。
interface IAnimationInfo {
/** 总时长 (毫秒) */
totalDuration: number;
/** 最大关键帧时间 */
maxKeyframeTime: number;
/** 关键帧数量 */
keyframeCount: number;
/** 元素数量 */
elementCount: number;
/** 是否自动计算时长 */
isAutoCalculated: boolean;
}
动画缓动函数类型。
type EasingFunction =
| 'linear' // 线性
| 'ease-in' // 缓慢开始
| 'ease-out' // 缓慢结束
| 'ease-in-out' // 缓慢开始和结束
| 'ease-in-cubic' // 三次方缓入
| 'ease-out-cubic' // 三次方缓出
| 'bounce-out' // 弹跳结束
| 'elastic-out'; // 弹性结束
动画状态类型。
type AnimationState = 'idle' | 'playing' | 'paused' | 'completed';
事件监听器回调函数类型。
type ElementEventCallback = (event: Event, element: HTMLElement) => void;
动画播放器主类,负责管理和控制动画的播放。
constructor(container: HTMLElement, schema: IAnimationSchema)
| 方法 | 描述 | 参数 | 返回值 |
|---|---|---|---|
play() | 开始播放动画 | - | void |
pause() | 暂停动画 | - | void |
stop() | 停止动画并重置到初始状态 | - | void |
seek(time: number) | 跳转到指定时间 | time: 目标时间(毫秒) | void |
| 方法 | 描述 | 返回值 |
|---|---|---|
getCurrentTime() | 获取当前播放时间 | number |
getDuration() | 获取动画总时长 | number |
getProgress() | 获取播放进度(0-1) | number |
getState() | 获取当前状态 | AnimationState |
isPlaying() | 检查是否正在播放 | boolean |
getSchema() | 获取动画配置的副本 | IAnimationSchema |
getAnimationInfo() | 获取动画统计信息 | IAnimationInfo |
| 方法 | 描述 | 参数 |
|---|---|---|
updateData(newData) | 更新动画数据 | newData: 新数据对象 |
updateSchema(newSchema) | 更新动画配置 | newSchema: 新配置对象 |
| 方法 | 描述 | 参数 |
|---|---|---|
onTimeChange(callback) | 监听时间变化 | callback: (time: number) => void |
onAnimationComplete(callback) | 监听动画完成 | callback: () => void |
onStateChange(callback) | 监听状态变化 | callback: (state: AnimationState) => void |
onListen(elementId, eventType, callback) | 监听元素事件 | 详见下表 |
| 参数 | 类型 | 描述 |
|---|---|---|
elementId | string | 元素ID |
eventType | string | 事件类型('click', 'mouseover'等) |
callback | ElementEventCallback | 事件回调函数 |
| 返回值 | () => void | 取消监听的函数 |
| 方法 | 描述 | 参数 |
|---|---|---|
removeAllListeners(elementId) | 移除指定元素的所有事件监听器 | elementId: 元素ID |
removeAllElementListeners() | 移除所有事件监听器 | - |
destroy() | 销毁动画播放器 | - |
模板引擎类,负责解析和渲染模板字符串。
| 方法 | 描述 | 参数 | 返回值 |
|---|---|---|---|
render(template, data) | 渲染模板字符串 | template: 模板字符串data: 渲染数据 | string |
CSS动画生成器类,负责生成CSS关键帧动画代码。
| 方法 | 描述 | 参数 | 返回值 |
|---|---|---|---|
generateKeyframes(elementId, keyframes) | 生成CSS关键帧动画 | elementId: 元素IDkeyframes: 关键帧数组 | string |
generateAnimationCSS(elementId, duration, easing) | 生成元素动画CSS | elementId: 元素IDduration: 动画时长easing: 缓动函数 | string |
easingToCSSFunction(easing) | 转换缓动函数为CSS | easing: 缓动函数名 | string |
根据容器ID创建动画播放器。
function createAnimationPlayer(
containerId: string,
schema: IAnimationSchema,
): AnimationPlayer;
直接使用DOM元素创建动画播放器。
function createAnimationPlayerFromElement(
container: HTMLElement,
schema: IAnimationSchema,
): AnimationPlayer;
import { createAnimationPlayer, IAnimationSchema } from '@yqg-max/click-gate';
// 1. 定义动画配置
const schema: IAnimationSchema = {
elements: [
{
id: 'box1',
content: {
html: '<div style="width: 100px; height: 100px; background: #3b82f6;"></div>',
style: {
borderRadius: '8px',
},
},
},
],
keyframes: [
{
id: 'kf1',
elementId: 'box1',
time: 0,
properties: { x: 0, y: 0, opacity: 1, scale: 1 },
},
{
id: 'kf2',
elementId: 'box1',
time: 1000,
properties: { x: 200, y: 100, opacity: 0.5, scale: 1.5 },
},
{
id: 'kf3',
elementId: 'box1',
time: 2000,
properties: { x: 0, y: 0, opacity: 1, scale: 1, rotation: 360 },
},
],
};
// 2. 创建播放器
const player = createAnimationPlayer('animation-container', schema);
// 3. 播放动画
player.play();
const schema: IAnimationSchema = {
data: {
title: '欢迎使用动画播放器',
subtitle: '强大而灵活的动画解决方案',
},
elements: [
{
id: 'text1',
data: {
content: '{{title}}',
},
content: {
html: '<h2>{{content}}</h2>',
style: {
color: '#1f2937',
fontFamily: 'Arial, sans-serif',
},
},
},
{
id: 'text2',
content: {
html: '<p>{{subtitle}}</p>',
style: {
color: '#6b7280',
},
},
},
],
keyframes: [
// 标题动画
{
id: 'title-start',
elementId: 'text1',
time: 0,
properties: { x: -200, opacity: 0 },
},
{
id: 'title-end',
elementId: 'text1',
time: 800,
properties: { x: 0, opacity: 1 },
},
// 副标题动画
{
id: 'subtitle-start',
elementId: 'text2',
time: 400,
properties: { x: 200, opacity: 0 },
},
{
id: 'subtitle-end',
elementId: 'text2',
time: 1200,
properties: { x: 0, opacity: 1 },
},
],
};
// 创建播放器
const player = createAnimationPlayer('container', schema);
// 监听元素点击事件
const removeClickListener = player.onListen(
'button1',
'click',
(event, element) => {
console.log('按钮被点击了!', element);
// 可以执行自定义逻辑
player.seek(1500); // 跳转到1.5秒
},
);
// 监听元素悬停事件
player.onListen('image1', 'mouseover', (event, element) => {
element.style.transform = 'scale(1.1)';
});
player.onListen('image1', 'mouseout', (event, element) => {
element.style.transform = 'scale(1)';
});
// 监听动画状态变化
player.onStateChange((state) => {
console.log('动画状态:', state);
});
// 监听播放进度
player.onTimeChange((time) => {
console.log('当前时间:', time);
});
// 监听动画完成
player.onAnimationComplete(() => {
console.log('动画播放完成!');
});
// 创建包含动态数据的动画
const schema: IAnimationSchema = {
data: {
username: 'User',
score: 0,
},
elements: [
{
id: 'scoreDisplay',
content: {
html: '<div class="score">{{username}}的分数: {{score}}</div>',
},
},
],
keyframes: [
{
id: 'score-anim',
elementId: 'scoreDisplay',
time: 0,
properties: { scale: 1 },
},
{
id: 'score-bounce',
elementId: 'scoreDisplay',
time: 500,
properties: { scale: 1.2 },
},
{
id: 'score-normal',
elementId: 'scoreDisplay',
time: 1000,
properties: { scale: 1 },
},
],
};
const player = createAnimationPlayer('container', schema);
// 动态更新数据
function updateScore(newScore: number) {
player.updateData({ score: newScore });
player.seek(0); // 重新播放动画
player.play();
}
// 使用示例
updateScore(100);
updateScore(250);
const complexSchema: IAnimationSchema = {
elements: [
{ id: 'circle', content: { html: '<div class="circle"></div>' } },
{ id: 'square', content: { html: '<div class="square"></div>' } },
{ id: 'triangle', content: { html: '<div class="triangle"></div>' } },
],
keyframes: [
// 圆形动画序列
{
id: 'c1',
elementId: 'circle',
time: 0,
properties: { x: 0, y: 0, opacity: 0 },
},
{
id: 'c2',
elementId: 'circle',
time: 500,
properties: { x: 100, y: 0, opacity: 1 },
},
{
id: 'c3',
elementId: 'circle',
time: 1000,
properties: { x: 100, y: 100, rotation: 180 },
},
{
id: 'c4',
elementId: 'circle',
time: 1500,
properties: { x: 0, y: 100, scale: 1.5 },
},
{
id: 'c5',
elementId: 'circle',
time: 2000,
properties: { x: 0, y: 0, scale: 1, rotation: 360 },
},
// 方形动画序列(延迟启动)
{
id: 's1',
elementId: 'square',
time: 300,
properties: { x: 200, y: 0, opacity: 0 },
},
{
id: 's2',
elementId: 'square',
time: 800,
properties: { x: 300, y: 0, opacity: 1 },
},
{
id: 's3',
elementId: 'square',
time: 1300,
properties: { x: 300, y: 100, rotation: 90 },
},
{
id: 's4',
elementId: 'square',
time: 1800,
properties: { x: 200, y: 100, scale: 0.8 },
},
// 三角形动画序列(更晚启动)
{
id: 't1',
elementId: 'triangle',
time: 600,
properties: { x: 400, y: 50, opacity: 0 },
},
{
id: 't2',
elementId: 'triangle',
time: 1100,
properties: { x: 450, y: 50, opacity: 1 },
},
{
id: 't3',
elementId: 'triangle',
time: 1600,
properties: { x: 450, y: 100, rotation: 120 },
},
{
id: 't4',
elementId: 'triangle',
time: 2100,
properties: { x: 400, y: 100, scale: 1.2 },
},
],
};
// 使用不同的缓动函数创建丰富的动画效果
const bounceSchema: IAnimationSchema = {
elements: [{ id: 'bouncer', content: { html: '<div class="ball"></div>' } }],
keyframes: [
{
id: 'bounce-start',
elementId: 'bouncer',
time: 0,
properties: { y: 0 },
},
{
id: 'bounce-drop',
elementId: 'bouncer',
time: 1000,
properties: { y: 200 }, // 使用 bounce-out 缓动
},
{
id: 'bounce-up',
elementId: 'bouncer',
time: 1500,
properties: { y: 50 }, // 弹起
},
{
id: 'bounce-settle',
elementId: 'bouncer',
time: 2000,
properties: { y: 200 }, // 最终落地
},
],
};
play() - 播放动画pause() - 暂停动画stop() - 停止动画seek(time: number) - 跳转到指定时间getCurrentTime(): number - 当前播放时间getDuration(): number - 动画总时长getProgress(): number - 播放进度 (0-1)getState(): AnimationState - 当前状态isPlaying(): boolean - 是否正在播放updateData(data: Record<string, any>) - 更新动画数据updateSchema(schema: IAnimationSchema) - 更新动画配置getSchema(): IAnimationSchema - 获取当前配置getAnimationInfo(): IAnimationInfo - 获取动画信息onTimeChange(callback) - 时间变化事件onAnimationComplete(callback) - 动画完成事件onStateChange(callback) - 状态变化事件onListen(elementId, eventType, callback) - 元素事件监听removeAllListeners(elementId) - 移除指定元素的监听器removeAllElementListeners() - 移除所有监听器destroy() - 销毁播放器// 避免过多的关键帧
// ❌ 不好的做法
const badSchema = {
keyframes: [
{ time: 0, properties: { x: 0 } },
{ time: 10, properties: { x: 1 } },
{ time: 20, properties: { x: 2 } },
// ... 每10ms一个关键帧
],
};
// ✅ 好的做法
const goodSchema = {
keyframes: [
{ time: 0, properties: { x: 0 } },
{ time: 500, properties: { x: 50 } },
{ time: 1000, properties: { x: 100 } },
],
};
// 在组件卸载时清理播放器
const player = createAnimationPlayer('container', schema);
// 在适当的时候销毁
function cleanup() {
player.destroy(); // 清理所有事件监听器和DOM引用
}
// React 示例
useEffect(() => {
return () => {
cleanup();
};
}, []);
try {
const player = createAnimationPlayer('container', schema);
player.play();
} catch (error) {
console.error('动画初始化失败:', error);
// 处理错误情况
}
destroy()方法清理资源A: 检查以下几点:
A: 确保:
{{variableName}}updateData()后重新渲染A: 检查:
MIT License
欢迎提交 Issue 和 Pull Request!
如有疑问,请查看源码注释或提交 Issue。
FAQs
YQG AminoFX CSS animation kit - Core animation utilities and effects
The npm package aminofx-kit receives a total of 2 weekly downloads. As such, aminofx-kit popularity was classified as not popular.
We found that aminofx-kit demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Five frontier LLMs generated the same nonexistent package names, leaving 53 available for potential slopsquatting across PyPI and npm.

Security News
The White House’s Gold Eagle Initiative aims to coordinate AI-discovered vulnerabilities, validate findings, and accelerate patching across critical software.

Security News
A Shai-Hulud infection exposed Suno's source code, which shows the AI music startup stream-ripped tracks to train its models.