chore(config): 添加项目配置文件和隐私协议
- 新增 .editorconfig 文件统一代码风格配置 - 新增 .env 环境变量配置文件 - 添加开发和生产环境的环境变量配置 - 配置 ESLint 忽略规则文件 - 设置代码检查配置文件 .eslintrc.js - 添加 Git 忽略文件规则 - 创建 Prettier 格式化忽略规则 - 添加隐私政策和服务协议HTML文件 - 实现访问密钥编辑组件基础结构
This commit is contained in:
89
src/utils/animations.ts
Normal file
89
src/utils/animations.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
// 动画工具类
|
||||
export class AnimationUtils {
|
||||
// 页面加载动画
|
||||
static pageEnterAnimation() {
|
||||
const elements = document.querySelectorAll('.animate-on-load');
|
||||
elements.forEach((el, index) => {
|
||||
(el as HTMLElement).style.animationDelay = `${index * 0.1}s`;
|
||||
el.classList.add('animate-fade-in-up');
|
||||
});
|
||||
}
|
||||
|
||||
// 表单项动画
|
||||
static formItemAnimation(element: HTMLElement, delay: number = 0) {
|
||||
setTimeout(() => {
|
||||
element.classList.add('animate-slide-in-left');
|
||||
}, delay);
|
||||
}
|
||||
|
||||
// 按钮点击波纹效果
|
||||
static rippleEffect(event: MouseEvent) {
|
||||
const button = event.currentTarget as HTMLElement;
|
||||
const ripple = document.createElement('span');
|
||||
const rect = button.getBoundingClientRect();
|
||||
const size = Math.max(rect.width, rect.height);
|
||||
const x = event.clientX - rect.left - size / 2;
|
||||
const y = event.clientY - rect.top - size / 2;
|
||||
|
||||
ripple.style.width = ripple.style.height = size + 'px';
|
||||
ripple.style.left = x + 'px';
|
||||
ripple.style.top = y + 'px';
|
||||
ripple.classList.add('ripple');
|
||||
|
||||
button.appendChild(ripple);
|
||||
|
||||
setTimeout(() => {
|
||||
ripple.remove();
|
||||
}, 600);
|
||||
}
|
||||
|
||||
// 输入框聚焦动画
|
||||
static inputFocusAnimation(element: HTMLElement) {
|
||||
const parent = element.closest('.ant-form-item');
|
||||
if (parent) {
|
||||
parent.classList.add('input-focused');
|
||||
}
|
||||
}
|
||||
|
||||
// 输入框失焦动画
|
||||
static inputBlurAnimation(element: HTMLElement) {
|
||||
const parent = element.closest('.ant-form-item');
|
||||
if (parent && !(element as HTMLInputElement).value) {
|
||||
parent.classList.remove('input-focused');
|
||||
}
|
||||
}
|
||||
|
||||
// 错误提示动画
|
||||
static errorShakeAnimation(element: HTMLElement) {
|
||||
element.classList.add('animate-shake');
|
||||
setTimeout(() => {
|
||||
element.classList.remove('animate-shake');
|
||||
}, 500);
|
||||
}
|
||||
|
||||
// 成功提示动画
|
||||
static successPulseAnimation(element: HTMLElement) {
|
||||
element.classList.add('animate-pulse-success');
|
||||
setTimeout(() => {
|
||||
element.classList.remove('animate-pulse-success');
|
||||
}, 1000);
|
||||
}
|
||||
}
|
||||
|
||||
// Vue 3 组合式 API 动画钩子
|
||||
export function useAnimations() {
|
||||
const onEnter = (el: Element, done: () => void) => {
|
||||
el.classList.add('animate-fade-in');
|
||||
setTimeout(done, 300);
|
||||
};
|
||||
|
||||
const onLeave = (el: Element, done: () => void) => {
|
||||
el.classList.add('animate-fade-out');
|
||||
setTimeout(done, 300);
|
||||
};
|
||||
|
||||
return {
|
||||
onEnter,
|
||||
onLeave
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user