chore: v2.0.1 - 精简dead code + 版本升级
- utils.js: 950行→180行,移除30+未使用函数 - styles.js: 1800行→650行,移除未使用组件样式和重复规则 - animations.js: 850行→120行,移除Web Animations API dead code - 全项目版本号升级到 2.0.1 - 测试同步清理,134/134通过
This commit is contained in:
+48
-793
@@ -1,856 +1,111 @@
|
||||
/**
|
||||
* MetonaToast Animations - 动画管理
|
||||
* MetonaToast Animations - 动画管理(精简版 v2.0.1)
|
||||
* @module animations
|
||||
* @version 2.0.0
|
||||
* @description 动画效果管理和自定义
|
||||
* @description 动画注册与管理,移除未使用的 Web Animations API dead code
|
||||
*/
|
||||
|
||||
import { ANIMATIONS } from './constants.js';
|
||||
|
||||
// 动画缓存
|
||||
const animationCache = new Map();
|
||||
const animationMap = new Map();
|
||||
|
||||
/**
|
||||
* 动画管理器类
|
||||
* 注册默认动画
|
||||
*/
|
||||
class AnimationManager {
|
||||
constructor() {
|
||||
this.animations = new Map();
|
||||
this.activeAnimations = new Map();
|
||||
this.animationId = 0;
|
||||
|
||||
// 注册默认动画
|
||||
this._registerDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册默认动画
|
||||
*/
|
||||
_registerDefaults() {
|
||||
Object.entries(ANIMATIONS).forEach(([name, config]) => {
|
||||
this.register(name, config);
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册动画
|
||||
* @param {string} name - 动画名称
|
||||
* @param {Object} config - 动画配置
|
||||
*/
|
||||
register(name, config) {
|
||||
const animation = {
|
||||
name,
|
||||
enter: config.enter || {},
|
||||
leave: config.leave || {},
|
||||
duration: config.duration || 300,
|
||||
easing: config.easing || 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
delay: config.delay || 0,
|
||||
iterations: config.iterations || 1,
|
||||
direction: config.direction || 'normal',
|
||||
fillMode: config.fillMode || 'forwards',
|
||||
};
|
||||
|
||||
this.animations.set(name, animation);
|
||||
animationCache.set(name, animation);
|
||||
}
|
||||
|
||||
/**
|
||||
* 注销动画
|
||||
* @param {string} name - 动画名称
|
||||
*/
|
||||
unregister(name) {
|
||||
this.animations.delete(name);
|
||||
animationCache.delete(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取动画配置
|
||||
* @param {string} name - 动画名称
|
||||
* @returns {Object|null} 动画配置
|
||||
*/
|
||||
get(name) {
|
||||
return this.animations.get(name) || ANIMATIONS[name] || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
* @param {string} animationName - 动画名称
|
||||
* @param {Object} options - 额外选项
|
||||
* @returns {Promise} 动画完成Promise
|
||||
*/
|
||||
apply(element, animationName, options = {}) {
|
||||
return new Promise((resolve, reject) => {
|
||||
const animation = this.get(animationName);
|
||||
if (!animation) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
const config = { ...animation, ...options };
|
||||
const animId = ++this.animationId;
|
||||
|
||||
// 设置初始状态
|
||||
Object.assign(element.style, config.enter);
|
||||
|
||||
// 强制重绘
|
||||
element.offsetHeight;
|
||||
|
||||
// 创建动画
|
||||
const keyframes = [
|
||||
{ ...config.enter },
|
||||
{ ...config.leave },
|
||||
];
|
||||
|
||||
const animationOptions = {
|
||||
duration: config.duration,
|
||||
easing: config.easing,
|
||||
delay: config.delay,
|
||||
iterations: config.iterations,
|
||||
direction: config.direction,
|
||||
fill: config.fillMode,
|
||||
};
|
||||
|
||||
// 应用动画
|
||||
const anim = element.animate(keyframes, animationOptions);
|
||||
|
||||
// 存储活动动画
|
||||
this.activeAnimations.set(animId, {
|
||||
element,
|
||||
animation: anim,
|
||||
config,
|
||||
});
|
||||
|
||||
// 动画完成处理
|
||||
anim.onfinish = () => {
|
||||
Object.assign(element.style, config.leave);
|
||||
this.activeAnimations.delete(animId);
|
||||
resolve();
|
||||
};
|
||||
|
||||
// 动画取消处理 — reject 让调用者感知取消
|
||||
anim.oncancel = () => {
|
||||
this.activeAnimations.delete(animId);
|
||||
reject(new Error(`Animation "${animationName}" was cancelled`));
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用进入动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
* @param {string} animationName - 动画名称
|
||||
* @param {Object} options - 额外选项
|
||||
* @returns {Promise} 动画完成Promise
|
||||
*/
|
||||
enter(element, animationName, options = {}) {
|
||||
const animation = this.get(animationName);
|
||||
if (!animation) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return this.apply(element, animationName, {
|
||||
...options,
|
||||
direction: 'normal',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用离开动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
* @param {string} animationName - 动画名称
|
||||
* @param {Object} options - 额外选项
|
||||
* @returns {Promise} 动画完成Promise
|
||||
*/
|
||||
leave(element, animationName, options = {}) {
|
||||
const animation = this.get(animationName);
|
||||
if (!animation) {
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
return this.apply(element, animationName, {
|
||||
...options,
|
||||
direction: 'reverse',
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消所有动画
|
||||
*/
|
||||
cancelAll() {
|
||||
this.activeAnimations.forEach(({ animation }) => {
|
||||
animation.cancel();
|
||||
});
|
||||
|
||||
this.activeAnimations.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消元素动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
*/
|
||||
cancel(element) {
|
||||
this.activeAnimations.forEach(({ element: el, animation }, id) => {
|
||||
if (el === element) {
|
||||
animation.cancel();
|
||||
this.activeAnimations.delete(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停所有动画
|
||||
*/
|
||||
pauseAll() {
|
||||
this.activeAnimations.forEach(({ animation }) => {
|
||||
animation.pause();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复所有动画
|
||||
*/
|
||||
resumeAll() {
|
||||
this.activeAnimations.forEach(({ animation }) => {
|
||||
animation.play();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停元素动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
*/
|
||||
pause(element) {
|
||||
this.activeAnimations.forEach(({ element: el, animation }) => {
|
||||
if (el === element) {
|
||||
animation.pause();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复元素动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
*/
|
||||
resume(element) {
|
||||
this.activeAnimations.forEach(({ element: el, animation }) => {
|
||||
if (el === element) {
|
||||
animation.play();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取活动动画数量
|
||||
* @returns {number} 动画数量
|
||||
*/
|
||||
getActiveCount() {
|
||||
return this.activeAnimations.size;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所有活动动画
|
||||
* @returns {Map} 活动动画映射
|
||||
*/
|
||||
getActiveAnimations() {
|
||||
return new Map(this.activeAnimations);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查元素是否有活动动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
* @returns {boolean} 是否有活动动画
|
||||
*/
|
||||
hasActiveAnimation(element) {
|
||||
for (const { element: el } of this.activeAnimations.values()) {
|
||||
if (el === element) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取动画配置
|
||||
* @returns {Object} 动画配置
|
||||
*/
|
||||
getConfig() {
|
||||
return {
|
||||
animations: Array.from(this.animations.keys()),
|
||||
activeCount: this.getActiveCount(),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置动画管理器
|
||||
*/
|
||||
reset() {
|
||||
this.cancelAll();
|
||||
this.animations.clear();
|
||||
this._registerDefaults();
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁动画管理器
|
||||
*/
|
||||
destroy() {
|
||||
this.cancelAll();
|
||||
this.animations.clear();
|
||||
this.activeAnimations.clear();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 预设动画效果
|
||||
*/
|
||||
const presetAnimations = {
|
||||
bounce: {
|
||||
enter: { transform: 'translateY(-80px)', opacity: 0 },
|
||||
leave: { transform: 'translateY(20px)', opacity: 1 },
|
||||
duration: 650,
|
||||
easing: 'ease',
|
||||
},
|
||||
slideUp: {
|
||||
enter: { transform: 'translateY(60px)', opacity: 0 },
|
||||
leave: { transform: 'translateY(0)', opacity: 1 },
|
||||
duration: 400,
|
||||
easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
||||
},
|
||||
slideDown: {
|
||||
enter: { transform: 'translateY(-60px)', opacity: 0 },
|
||||
leave: { transform: 'translateY(0)', opacity: 1 },
|
||||
duration: 400,
|
||||
easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
||||
},
|
||||
slideLeft: {
|
||||
enter: { transform: 'translateX(-90px)', opacity: 0 },
|
||||
leave: { transform: 'translateX(0)', opacity: 1 },
|
||||
duration: 400,
|
||||
easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
||||
},
|
||||
slideRight: {
|
||||
enter: { transform: 'translateX(90px)', opacity: 0 },
|
||||
leave: { transform: 'translateX(0)', opacity: 1 },
|
||||
duration: 400,
|
||||
easing: 'cubic-bezier(0.25, 0.46, 0.45, 0.94)',
|
||||
},
|
||||
|
||||
};
|
||||
|
||||
// 注册预设动画
|
||||
Object.entries(presetAnimations).forEach(([name, config]) => {
|
||||
ANIMATIONS[name] = config;
|
||||
Object.entries(ANIMATIONS).forEach(([name, config]) => {
|
||||
animationMap.set(name, config);
|
||||
});
|
||||
|
||||
/**
|
||||
* 创建动画管理器实例
|
||||
* @returns {AnimationManager} 动画管理器实例
|
||||
*/
|
||||
export const createAnimationManager = () => {
|
||||
return new AnimationManager();
|
||||
};
|
||||
|
||||
// 创建默认实例
|
||||
const defaultAnimationManager = createAnimationManager();
|
||||
|
||||
/**
|
||||
* 动画工具函数
|
||||
*/
|
||||
export const animationUtils = {
|
||||
/**
|
||||
* 应用动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
* @param {string} animationName - 动画名称
|
||||
* @param {Object} options - 额外选项
|
||||
* @returns {Promise} 动画完成Promise
|
||||
*/
|
||||
apply(element, animationName, options = {}) {
|
||||
return defaultAnimationManager.apply(element, animationName, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* 应用进入动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
* @param {string} animationName - 动画名称
|
||||
* @param {Object} options - 额外选项
|
||||
* @returns {Promise} 动画完成Promise
|
||||
*/
|
||||
enter(element, animationName, options = {}) {
|
||||
return defaultAnimationManager.enter(element, animationName, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* 应用离开动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
* @param {string} animationName - 动画名称
|
||||
* @param {Object} options - 额外选项
|
||||
* @returns {Promise} 动画完成Promise
|
||||
*/
|
||||
leave(element, animationName, options = {}) {
|
||||
return defaultAnimationManager.leave(element, animationName, options);
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消所有动画
|
||||
*/
|
||||
cancelAll() {
|
||||
defaultAnimationManager.cancelAll();
|
||||
},
|
||||
|
||||
/**
|
||||
* 取消元素动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
*/
|
||||
cancel(element) {
|
||||
defaultAnimationManager.cancel(element);
|
||||
},
|
||||
|
||||
/**
|
||||
* 暂停所有动画
|
||||
*/
|
||||
pauseAll() {
|
||||
defaultAnimationManager.pauseAll();
|
||||
},
|
||||
|
||||
/**
|
||||
* 恢复所有动画
|
||||
*/
|
||||
resumeAll() {
|
||||
defaultAnimationManager.resumeAll();
|
||||
},
|
||||
|
||||
/**
|
||||
* 暂停元素动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
*/
|
||||
pause(element) {
|
||||
defaultAnimationManager.pause(element);
|
||||
},
|
||||
|
||||
/**
|
||||
* 恢复元素动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
*/
|
||||
resume(element) {
|
||||
defaultAnimationManager.resume(element);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取活动动画数量
|
||||
* @returns {number} 动画数量
|
||||
*/
|
||||
getActiveCount() {
|
||||
return defaultAnimationManager.getActiveCount();
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查元素是否有活动动画
|
||||
* @param {HTMLElement} element - 目标元素
|
||||
* @returns {boolean} 是否有活动动画
|
||||
*/
|
||||
hasActiveAnimation(element) {
|
||||
return defaultAnimationManager.hasActiveAnimation(element);
|
||||
},
|
||||
|
||||
/**
|
||||
* 注册动画
|
||||
* 注册自定义动画
|
||||
* @param {string} name - 动画名称
|
||||
* @param {Object} config - 动画配置
|
||||
* @param {Object} config - 动画配置 { enter, leave, duration, easing }
|
||||
*/
|
||||
register(name, config) {
|
||||
defaultAnimationManager.register(name, config);
|
||||
animationMap.set(name, {
|
||||
name,
|
||||
enter: config.enter || {},
|
||||
leave: config.leave || {},
|
||||
duration: config.duration || 300,
|
||||
easing: config.easing || 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 注销动画
|
||||
* @param {string} name - 动画名称
|
||||
*/
|
||||
unregister(name) {
|
||||
defaultAnimationManager.unregister(name);
|
||||
animationMap.delete(name);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 获取动画配置
|
||||
* @param {string} name - 动画名称
|
||||
* @returns {Object|null} 动画配置
|
||||
*/
|
||||
get(name) {
|
||||
return defaultAnimationManager.get(name);
|
||||
return animationMap.get(name) || ANIMATIONS[name] || null;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 获取所有动画名称
|
||||
* @returns {Array} 动画名称数组
|
||||
*/
|
||||
getAnimationNames() {
|
||||
return Array.from(defaultAnimationManager.animations.keys());
|
||||
return Array.from(animationMap.keys());
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 获取动画配置
|
||||
* @returns {Object} 动画配置
|
||||
* 获取活动动画数量(兼容API,当前CSS动画不跟踪活动实例)
|
||||
* @returns {number} 动画数量
|
||||
*/
|
||||
getConfig() {
|
||||
return defaultAnimationManager.getConfig();
|
||||
getActiveCount() {
|
||||
return 0;
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 取消所有动画(兼容API,当前CSS动画由浏览器管理)
|
||||
*/
|
||||
cancelAll() {
|
||||
// CSS动画由浏览器原生管理,无需手动取消
|
||||
},
|
||||
|
||||
/**
|
||||
* 重置动画管理器
|
||||
*/
|
||||
reset() {
|
||||
defaultAnimationManager.reset();
|
||||
animationMap.clear();
|
||||
Object.entries(ANIMATIONS).forEach(([name, config]) => {
|
||||
animationMap.set(name, config);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* 销毁动画管理器
|
||||
*/
|
||||
destroy() {
|
||||
defaultAnimationManager.destroy();
|
||||
animationMap.clear();
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* 动画预设
|
||||
*/
|
||||
export const animationPresets = presetAnimations;
|
||||
export const animationPresets = {};
|
||||
|
||||
/**
|
||||
* 创建自定义动画
|
||||
* 创建自定义动画配置
|
||||
* @param {Object} config - 动画配置
|
||||
* @returns {Object} 动画配置
|
||||
*/
|
||||
export const createAnimation = (config) => {
|
||||
return {
|
||||
enter: config.enter || {},
|
||||
leave: config.leave || {},
|
||||
duration: config.duration || 300,
|
||||
easing: config.easing || 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
delay: config.delay || 0,
|
||||
iterations: config.iterations || 1,
|
||||
direction: config.direction || 'normal',
|
||||
fillMode: config.fillMode || 'forwards',
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* 组合动画
|
||||
* @param {Array} animations - 动画数组
|
||||
* @returns {Object} 组合后的动画配置
|
||||
*/
|
||||
export const combineAnimations = (animations) => {
|
||||
const combined = {
|
||||
enter: {},
|
||||
leave: {},
|
||||
duration: 0,
|
||||
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
delay: 0,
|
||||
iterations: 1,
|
||||
direction: 'normal',
|
||||
fillMode: 'forwards',
|
||||
};
|
||||
|
||||
animations.forEach((anim) => {
|
||||
if (anim.enter) {
|
||||
Object.assign(combined.enter, anim.enter);
|
||||
}
|
||||
if (anim.leave) {
|
||||
Object.assign(combined.leave, anim.leave);
|
||||
}
|
||||
if (anim.duration) {
|
||||
combined.duration = Math.max(combined.duration, anim.duration);
|
||||
}
|
||||
if (anim.easing) {
|
||||
combined.easing = anim.easing;
|
||||
}
|
||||
if (anim.delay) {
|
||||
combined.delay = Math.max(combined.delay, anim.delay);
|
||||
}
|
||||
});
|
||||
|
||||
return combined;
|
||||
};
|
||||
|
||||
/**
|
||||
* 链式动画
|
||||
* @param {Array} animations - 动画数组
|
||||
* @returns {Promise} 动画完成Promise
|
||||
*/
|
||||
export const chainAnimations = async (element, animations) => {
|
||||
for (const anim of animations) {
|
||||
await defaultAnimationManager.apply(element, anim.name, anim.options);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 并行动画
|
||||
* @param {Array} animations - 动画数组
|
||||
* @returns {Promise} 动画完成Promise
|
||||
*/
|
||||
export const parallelAnimations = (element, animations) => {
|
||||
return Promise.all(
|
||||
animations.map((anim) =>
|
||||
defaultAnimationManager.apply(element, anim.name, anim.options)
|
||||
)
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* 延迟动画
|
||||
* @param {number} delay - 延迟时间(毫秒)
|
||||
* @returns {Promise} Promise对象
|
||||
*/
|
||||
export const delayAnimation = (delay) => {
|
||||
return new Promise((resolve) => setTimeout(resolve, delay));
|
||||
};
|
||||
|
||||
/**
|
||||
* 动画队列
|
||||
*/
|
||||
export class AnimationQueue {
|
||||
constructor() {
|
||||
this.queue = [];
|
||||
this.isProcessing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加动画到队列
|
||||
* @param {Function} animationFn - 动画函数
|
||||
* @returns {Promise} 动画完成Promise
|
||||
*/
|
||||
add(animationFn) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.queue.push({
|
||||
fn: animationFn,
|
||||
resolve,
|
||||
reject,
|
||||
});
|
||||
|
||||
this._process();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理队列
|
||||
*/
|
||||
async _process() {
|
||||
if (this.isProcessing || this.queue.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.isProcessing = true;
|
||||
|
||||
while (this.queue.length > 0) {
|
||||
const { fn, resolve, reject } = this.queue.shift();
|
||||
|
||||
try {
|
||||
const result = await fn();
|
||||
resolve(result);
|
||||
} catch (error) {
|
||||
reject(error);
|
||||
}
|
||||
}
|
||||
|
||||
this.isProcessing = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 清空队列
|
||||
*/
|
||||
clear() {
|
||||
this.queue = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 暂停队列
|
||||
*/
|
||||
pause() {
|
||||
this.isProcessing = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 恢复队列
|
||||
*/
|
||||
resume() {
|
||||
this.isProcessing = false;
|
||||
this._process();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取队列长度
|
||||
* @returns {number} 队列长度
|
||||
*/
|
||||
get length() {
|
||||
return this.queue.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否正在处理
|
||||
* @returns {boolean} 是否正在处理
|
||||
*/
|
||||
get processing() {
|
||||
return this.isProcessing;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建动画队列
|
||||
* @returns {AnimationQueue} 动画队列实例
|
||||
*/
|
||||
export const createAnimationQueue = () => {
|
||||
return new AnimationQueue();
|
||||
};
|
||||
|
||||
/**
|
||||
* 动画性能监控
|
||||
*/
|
||||
export class AnimationPerformanceMonitor {
|
||||
constructor() {
|
||||
this.metrics = {
|
||||
totalAnimations: 0,
|
||||
activeAnimations: 0,
|
||||
averageDuration: 0,
|
||||
maxDuration: 0,
|
||||
minDuration: Infinity,
|
||||
};
|
||||
|
||||
this.history = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录动画开始
|
||||
* @param {string} animationName - 动画名称
|
||||
*/
|
||||
recordStart(animationName) {
|
||||
this.metrics.totalAnimations++;
|
||||
this.metrics.activeAnimations++;
|
||||
|
||||
this.history.push({
|
||||
name: animationName,
|
||||
startTime: performance.now(),
|
||||
endTime: null,
|
||||
duration: null,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 记录动画结束
|
||||
* @param {string} animationName - 动画名称
|
||||
*/
|
||||
recordEnd(animationName) {
|
||||
this.metrics.activeAnimations--;
|
||||
|
||||
const entry = this.history.find(
|
||||
(h) => h.name === animationName && h.endTime === null
|
||||
);
|
||||
|
||||
if (entry) {
|
||||
entry.endTime = performance.now();
|
||||
entry.duration = entry.endTime - entry.startTime;
|
||||
|
||||
// 更新统计
|
||||
this.metrics.maxDuration = Math.max(this.metrics.maxDuration, entry.duration);
|
||||
this.metrics.minDuration = Math.min(this.metrics.minDuration, entry.duration);
|
||||
|
||||
// 计算平均值
|
||||
const completed = this.history.filter((h) => h.duration !== null);
|
||||
this.metrics.averageDuration =
|
||||
completed.reduce((sum, h) => sum + h.duration, 0) / completed.length;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指标
|
||||
* @returns {Object} 性能指标
|
||||
*/
|
||||
getMetrics() {
|
||||
return { ...this.metrics };
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取历史记录
|
||||
* @returns {Array} 历史记录
|
||||
*/
|
||||
getHistory() {
|
||||
return [...this.history];
|
||||
}
|
||||
|
||||
/**
|
||||
* 重置监控
|
||||
*/
|
||||
reset() {
|
||||
this.metrics = {
|
||||
totalAnimations: 0,
|
||||
activeAnimations: 0,
|
||||
averageDuration: 0,
|
||||
maxDuration: 0,
|
||||
minDuration: Infinity,
|
||||
};
|
||||
|
||||
this.history = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建性能监控实例
|
||||
* @returns {AnimationPerformanceMonitor} 性能监控实例
|
||||
*/
|
||||
export const createPerformanceMonitor = () => {
|
||||
return new AnimationPerformanceMonitor();
|
||||
};
|
||||
|
||||
/**
|
||||
* 动画缓存管理
|
||||
*/
|
||||
export const animationCacheManager = {
|
||||
/**
|
||||
* 缓存动画
|
||||
* @param {string} key - 缓存键
|
||||
* @param {Object} animation - 动画配置
|
||||
*/
|
||||
set(key, animation) {
|
||||
animationCache.set(key, animation);
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取缓存动画
|
||||
* @param {string} key - 缓存键
|
||||
* @returns {Object|null} 动画配置
|
||||
*/
|
||||
get(key) {
|
||||
return animationCache.get(key) || null;
|
||||
},
|
||||
|
||||
/**
|
||||
* 检查缓存
|
||||
* @param {string} key - 缓存键
|
||||
* @returns {boolean} 是否存在
|
||||
*/
|
||||
has(key) {
|
||||
return animationCache.has(key);
|
||||
},
|
||||
|
||||
/**
|
||||
* 删除缓存
|
||||
* @param {string} key - 缓存键
|
||||
*/
|
||||
delete(key) {
|
||||
animationCache.delete(key);
|
||||
},
|
||||
|
||||
/**
|
||||
* 清空缓存
|
||||
*/
|
||||
clear() {
|
||||
animationCache.clear();
|
||||
},
|
||||
|
||||
/**
|
||||
* 获取缓存大小
|
||||
* @returns {number} 缓存大小
|
||||
*/
|
||||
size() {
|
||||
return animationCache.size;
|
||||
},
|
||||
};
|
||||
|
||||
export { AnimationManager, defaultAnimationManager };
|
||||
export const createAnimation = (config) => ({
|
||||
enter: config.enter || {},
|
||||
leave: config.leave || {},
|
||||
duration: config.duration || 300,
|
||||
easing: config.easing || 'cubic-bezier(0.4, 0, 0.2, 1)',
|
||||
});
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* MetonaToast Constants - 常量定义
|
||||
* @module constants
|
||||
* @version 2.0.0
|
||||
* @version 2.0.1
|
||||
* @description 默认配置、颜色、动画、主题等常量
|
||||
*/
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* MetonaToast Core - 核心Toast逻辑
|
||||
* @module core
|
||||
* @version 2.0.0
|
||||
* @version 2.0.1
|
||||
* @description 重构后的核心模块,包含Toast类的优化实现
|
||||
*/
|
||||
|
||||
@@ -621,7 +621,7 @@ const _actionHTML = (actions) => {
|
||||
const meToast = {
|
||||
_toasts: new Map(),
|
||||
_config: { ...DEFAULTS },
|
||||
version: '2.0.0',
|
||||
version: '2.0.1',
|
||||
|
||||
configure(opts) {
|
||||
if (!opts || typeof opts !== 'object') return this;
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* MetonaToast i18n - 国际化管理
|
||||
* @module i18n
|
||||
* @version 2.0.0
|
||||
* @version 2.0.1
|
||||
* @description 多语言支持、语言切换和翻译管理
|
||||
*/
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* MetonaToast Icons — 图标SVG定义
|
||||
* @module icons
|
||||
* @version 2.0.0
|
||||
* @version 2.0.1
|
||||
* @description 80+ 内置SVG图标
|
||||
*/
|
||||
|
||||
|
||||
+2
-2
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* MetonaToast - 轻量级Toast通知库
|
||||
* @module metona-toast
|
||||
* @version 2.0.0
|
||||
* @version 2.0.1
|
||||
* @author thzxx
|
||||
* @description 轻量、零依赖、精致美观的Toast通知库。单文件,开箱即用。
|
||||
* @license MIT
|
||||
@@ -15,7 +15,7 @@ import { pluginUtils, presetPlugins } from './plugins.js';
|
||||
import { DEFAULTS } from './constants.js';
|
||||
|
||||
// 版本信息
|
||||
const VERSION = '2.0.0';
|
||||
const VERSION = '2.0.1';
|
||||
|
||||
/**
|
||||
* 主对象增强
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* MetonaToast Locales — 国际化翻译数据
|
||||
* @module locales
|
||||
* @version 2.0.0
|
||||
* @version 2.0.1
|
||||
* @description 内置 zh-CN / en-US 完整翻译
|
||||
*/
|
||||
|
||||
|
||||
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* MetonaToast Plugins - 插件系统
|
||||
* @module plugins
|
||||
* @version 2.0.0
|
||||
* @version 2.0.1
|
||||
* @description 插件管理器 + 3 款预设插件 (keyboard / persistence / accessibility)
|
||||
*/
|
||||
|
||||
|
||||
+207
-1435
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* MetonaToast Themes - 主题管理
|
||||
* @module themes
|
||||
* @version 2.0.0
|
||||
* @version 2.0.1
|
||||
* @description 主题系统、自定义主题和主题切换
|
||||
*/
|
||||
|
||||
|
||||
+6
-1024
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user