vue封装gsap自定义动画指令

1、指令文件封装

javascript 复制代码
import { gsap } from 'gsap';

// 动画类型配置
const ANIMATION_TYPES = {
    // 缩放
	scale: {
		from: { scale: 0.5, opacity: 0 },
		to: { scale: 1, opacity: 1 },
		hide: { scale: 0.5, opacity: 0 },
	},
    // 透明度
	fade: {
		from: { opacity: 0 },
		to: { opacity: 1, ease: 'sine.out' },
		hide: { opacity: 0, ease: 'sine.in' },
	},
    // 向上滑出
	slideUp: {
		from: { y: 50, opacity: 0 },
		to: { y: 0, opacity: 1, ease: 'power2.out' },
		hide: { y: 50, opacity: 0, ease: 'power2.in' },
	},
    // 向下滑出
	slideDown: {
		from: { y: -50, opacity: 0 },
		to: { y: 0, opacity: 1, ease: 'power2.out' },
		hide: { y: -50, opacity: 0, ease: 'power2.in' },
	},
    // 向左滑出
	slideLeft: {
		from: { x: 50, opacity: 0 },
		to: { x: 0, opacity: 1, ease: 'power2.out' },
		hide: { x: 50, opacity: 0, ease: 'power2.in' },
	},
    // 向右滑出
	slideRight: {
		from: { x: -50, opacity: 0 },
		to: { x: 0, opacity: 1, ease: 'power2.out' },
		hide: { x: -50, opacity: 0, ease: 'power2.in' },
	},
    // 弹窗
	bounce: {
		from: { y: -100, opacity: 0 },
		to: {
			y: 0,
			opacity: 1,
			ease: 'bounce.out',
			duration: 1.5,
		},
		hide: {
			y: 100,
			opacity: 0,
			ease: 'power2.in',
			duration: 0.5,
		},
	},
    // 翻转折叠
	flip: {
		from: { rotationY: 90, opacity: 0 },
		to: { rotationY: 0, opacity: 1, ease: 'power2.out' },
		hide: { rotationY: -90, opacity: 0, ease: 'power2.in' },
	},
};

// 默认配置
const DEFAULT_CONFIG = {
	type: 'scale',
	duration: 0.3,
	delay: 0,
	origin: 'center',
	onComplete: null,
	onStart: null,
};

export const vGsapAnimation = {
	mounted(el, binding) {
		// 合并默认配置和绑定值
		const config = {
			...DEFAULT_CONFIG,
			...(typeof binding.value === 'object' ? binding.value : { value: binding.value }),
		};

		// 获取动画配置
		const animationConfig = ANIMATION_TYPES[config.type] || ANIMATION_TYPES.scale;

		// 设置变换原点
		el.style.transformOrigin = config.origin;
		el.style.willChange = 'transform, opacity';

		// 保存配置到元素
		el._gsapConfig = config;

		// 初始化动画时间轴
		el._gsapTimeline = gsap.timeline({
			paused: true,
			onComplete: config.onComplete,
			onStart: config.onStart,
		});

		// 创建显示动画
		el._gsapTimeline.fromTo(el, animationConfig.from, {
			...animationConfig.to,
			duration: config.duration,
			delay: config.delay,
		});

		// 初始状态
		if (config.value !== false) {
			el.style.visibility = 'visible';
			el._gsapTimeline.play();
		} else {
			el.style.visibility = 'hidden';
			gsap.set(el, animationConfig.from);
		}
	},

	updated(el, binding) {
		const oldConfig = el._gsapConfig;
		const newConfig = {
			...DEFAULT_CONFIG,
			...(typeof binding.value === 'object' ? binding.value : { value: binding.value }),
		};

		// 如果配置有变化
		if (JSON.stringify(oldConfig) !== JSON.stringify(newConfig)) {
			// 更新配置
			el._gsapConfig = newConfig;

			// 获取动画配置
			const animationConfig = ANIMATION_TYPES[newConfig.type] || ANIMATION_TYPES.scale;

			// 更新时间轴回调
			el._gsapTimeline.eventCallback('onComplete', newConfig.onComplete);
			el._gsapTimeline.eventCallback('onStart', newConfig.onStart);

			if (newConfig.value !== oldConfig?.value) {
				if (newConfig.value === false) {
					// 隐藏动画
					gsap.to(el, {
						...animationConfig.hide,
						duration: newConfig.duration,
						delay: newConfig.delay,
						onComplete: () => {
							el.style.visibility = 'hidden';
						},
					});
				} else {
					// 显示动画
					el.style.visibility = 'visible';
					el._gsapTimeline.restart();
				}
			}
		}
	},

	unmounted(el) {
		// 清理动画
		if (el._gsapTimeline) {
			el._gsapTimeline.kill();
		}
	},
};

2、main.ts注册

javascript 复制代码
// 引入文件
import { vGsapAnimation } from 'xxx'

// 注册指令
app.directive('gsap', vGsapAnimation)

3、使用

  • 基本使用
html 复制代码
<div v-gsap="isVisible">内容</div>
  • 指定动画类型
html 复制代码
<div v-gsap="{ type: 'fade', value: isVisible }">内容</div>
  • 完整配
html 复制代码
<div v-gsap="{
  type: 'bounce',
  value: isVisible,
  duration: 1,
  delay: 0.2,
  origin: 'top left',
  onComplete: handleComplete
}">内容</div>
相关推荐
陈随易1 小时前
Postman 被曝自动往 Claude Code 和 Codex 装插件
前端·后端·程序员
Dream-Y.ocean3 小时前
鸿蒙PC平台宅匠 3D 室内设计适配实战:基于 Electron 壳方案的 Three.js 双渲染引擎与参数化户型编辑器开发
javascript·3d·harmonyos
Csvn4 小时前
性能监控
前端
Highcharts.js4 小时前
Highcharts Gantt使用符号的自定义数据标签开发甘特图示例
javascript·甘特图·highcharts·图表开发·实战代码·响应式图表
Csvn5 小时前
构建工具
前端
FRing035 小时前
vue2干货总结3(computed计算属性、watch监听器)
开发语言·前端·vue.js·vue2
Java小卷6 小时前
JuanForm vs FormCreate!Vue3 表单引擎联动配置 PK!
vue.js·低代码
kyriewen7 小时前
Skills 榜前 10 我全装了:只有 3 个能直接用
前端·javascript·程序员
IT_陈寒8 小时前
当Java的hashCode遇上Lombok,我的缓存被全清了
前端·人工智能·后端
工控丫丫8 小时前
帆软看板中经常使用的公式函数及经常搭的组合
前端·javascript·数据库