yoyo 是什么意思
在 GSAP(GreenSock Animation Platform)中,yoyo: true 是一个控制重复动画播放方向的选项
js
const tween = gsap.to(slider, {
x: 420,
duration: 1.2,
ease: "power1.inOut",
repeat: -1, // 无限重复
yoyo: true, // ← 关键:开启"来回"模式
paused: true
});
这段代码的作用是:
让
slider元素在x: 0和x: 420之间无限来回移动(像钟摆一样),每次往返耗时 2.4 秒(1.2 秒去 + 1.2 秒回)。
✅ yoyo: true 的核心行为
yoyo值 |
动画重复时的行为 |
|---|---|
false(默认) |
每次重复都从头开始 :0 → 420,然后重置回 0 再 0 → 420(会有"跳回"感) |
true |
每次重复都反向播放 :0 → 420,然后 420 → 0,再 0 → 420......形成平滑来回 |
对比示例:
repeat: -1, yoyo: false
0 → 420→ 瞬间跳回 0 →0 → 420→ 瞬间跳回 0 ...(不连贯)repeat: -1, yoyo: true
0 → 420→420 → 0→0 → 420→420 → 0...(流畅往复)
💡
yoyo这个名字来源于"悠悠球"------扔出去再自动收回来,形象地表达了"来回"运动。
🔧 配合 repeat 使用
repeat: 1+yoyo: true→ 播放一次正向 + 一次反向(共 2 次)repeat: -1+yoyo: true→ 无限循环往复(最常见用法)repeat: 0(默认)→yoyo无效(因为没有重复)
🎯 常见应用场景
-
背景元素左右/上下浮动
js
phpgsap.to(".cloud", { x: 100, repeat: -1, yoyo: true, duration: 3 }); -
指示器、光标闪烁或晃动
js
phpgsap.to(".cursor", { opacity: 0, repeat: -1, yoyo: true, duration: 0.5 }); -
机械式往复运动(如风扇叶片微调、机器人手臂)
⚠️ 注意事项
-
yoyo只影响动画的播放方向 ,不会改变ease(缓动)。- 正向:使用你指定的
ease(如"power1.inOut") - 反向:GSAP 会自动反转缓动曲线,确保运动自然(无需手动设置)
- 正向:使用你指定的
-
如果你用了
keyframes,yoyo会反转整个关键帧序列。
✅ 总结
| 配置 | 含义 |
|---|---|
repeat: -1 |
无限重复动画 |
yoyo: true |
每次重复时反向播放,实现"来回"效果 |
你的代码创建了一个水平方向无限来回滑动的动画,常用于:
- 轮播图自动滚动(配合暂停/继续)
- 装饰性动态元素
- 游戏中的巡逻敌人/NPC
配合 paused: true,你可以在需要时(如鼠标悬停、点击按钮)通过 tween.play() 启动这个循环动画。
onStart onUpdate onComplete 是什么意思
在 GSAP(GreenSock Animation Platform)中,onStart、onUpdate 和 onComplete 是 动画生命周期回调函数(callback functions) ,用于在动画的特定时刻执行自定义 JavaScript 代码。
js
const tween = gsap.to(dot, {
x: 460,
duration: 1.4,
ease: "power2.out",
paused: true,
onStart: () => {
log.textContent = "动画开始...";
},
onUpdate: () => {
const progress = Math.round(tween.progress() * 100);
log.textContent = `进行中:${progress}%`;
},
onComplete: () => {
log.textContent = "动画完成!";
}
});
这段代码为动画定义了三个关键时机的"监听器":
✅ 各回调函数的作用
| 回调 | 触发时机 | 常见用途 |
|---|---|---|
onStart |
动画刚开始播放的第一帧(在第一次渲染前) | 显示提示、启动计时器、添加 class 等 |
onUpdate |
每一帧动画更新时都会触发(每秒约 60 次) | 实时更新进度条、显示百分比、同步其他元素状态 |
onComplete |
动画完全结束(到达最后一帧) | 隐藏元素、跳转页面、播放音效、触发下一个动画 |
🔍 详细说明
1. onStart
- 只会执行 一次。
- 在动画真正开始移动/变化之前触发。
- 适合做"初始化"操作。
✅ 示例:
js
javascript
onStart: () => {
dot.classList.add('animating');
console.log('Dot animation started!');
}
2. onUpdate
- 高频触发(每帧一次),性能敏感,避免做 heavy 操作(如 DOM 查询、复杂计算)。
- 常配合
tween.progress()(返回 0~1 的进度值)或tween.time()使用。
✅ 你的代码:
js
ini
onUpdate: () => {
const progress = Math.round(tween.progress() * 100); // 转为 0~100%
log.textContent = `进行中:${progress}%`;
}
→ 实时显示动画完成百分比。
💡 提示:如果只是想读取当前属性值,也可以用
gsap.getProperty(dot, "x")。
3. onComplete
- 动画正常播放完毕时触发(不包括被暂停、反向或 killed 的情况)。
- 如果设置了
repeat: -1,onComplete永远不会触发(因为动画永不结束)。
✅ 示例:
js
ini
onComplete: () => {
setTimeout(() => dot.style.display = 'none', 500);
playNextAnimation();
}
⚠️ 其他相关回调(扩展)
| 回调 | 说明 |
|---|---|
onReverseComplete |
当反向播放完成 时触发(比如调用了 tween.reverse() 并回到起点) |
onRepeat |
每次重复开始时 触发(需配合 repeat 使用) |
onInterrupt |
动画被kill 或 stop 时触发(GSAP 3.10+) |
✅ 总结
| 回调 | 何时运行 | 你的代码作用 |
|---|---|---|
onStart |
动画刚开始 | 显示 "动画开始..." |
onUpdate |
每一帧更新 | 实时显示进度百分比 |
onComplete |
动画彻底结束 | 显示 "动画完成!" |
这些回调让你能精确控制动画与 UI、逻辑、数据的同步,是实现高级交互动效的关键工具。
💡 小技巧:即使
paused: true,一旦你调用tween.play(),这些回调仍会按规则触发。
tween.play tween.pause tween.reverse tween.restart是什么意思
在 GSAP(GreenSock Animation Platform)中,tween.play()、tween.pause()、tween.reverse() 和 tween.restart() 是 控制动画播放状态的核心方法。它们让你可以像操作视频播放器一样,灵活地控制动画的播放、暂停、倒放和重播。
js
const ship = document.querySelector("#ship");
const progress = document.querySelector("#progress");
const playButton = document.querySelector("#play");
const pauseButton = document.querySelector("#pause");
const reverseButton = document.querySelector("#reverse");
const restartButton = document.querySelector("#restart");
// 创建一个补间并绑定更新进度条
const tween = gsap.to(ship, {
x: 470,
duration: 3,
ease: "power1.inOut",
paused: true,
onUpdate: () => {
progress.value = Math.round(tween.progress() * 100);
}
});
playButton.addEventListener("click", () => tween.play());
pauseButton.addEventListener("click", () => tween.pause());
reverseButton.addEventListener("click", () => tween.reverse());
restartButton.addEventListener("click", () => tween.restart());
// 拖动进度条,手动 seek 到指定位置
progress.addEventListener("input", (event) => {
const value = Number(event.target.value) / 100;
tween.progress(value).pause();
});
假设你有如下动画:
js
php
const tween = gsap.to(box, {
x: 300,
duration: 2,
paused: true // 初始暂停,等待手动控制
});
此时动画已创建但未播放。你可以通过以下方法控制它:
✅ 1. tween.play()
作用 :从当前进度 开始正向播放动画。
- 如果是第一次播放 → 从头开始(进度 0 → 1)
- 如果之前被暂停在 50% → 从 50% 继续播放到 100%
js
scss
tween.play(); // 开始或继续播放
💡 相当于点击"播放"按钮 ▶️
✅ 2. tween.pause()
作用 :暂停动画,停留在当前帧。
- 动画状态被冻结,不会继续更新。
- 可随时用
play()或reverse()恢复。
js
scss
tween.pause(); // 暂停动画
console.log(tween.progress()); // 比如输出 0.6(60% 进度)
💡 相当于点击"暂停"按钮 ⏸️
✅ 3. tween.reverse()
作用 :反向播放动画(倒放)。
- 如果当前在正向播放 → 立即掉头往回走
- 如果已暂停 → 从当前位置倒放到起点
- 再次调用
reverse()会切回正向
js
scss
tween.reverse(); // 开始倒放
// 再次调用:
tween.reverse(); // 又变回正向播放
💡 相当于"倒带" ◀️,常用于 hover 离开时还原状态
✅ 4. tween.restart()
作用 :重置并重新播放动画(从头开始)。
- 无论当前在什么进度,都会跳回 0% 并开始正向播放。
- 相当于
tween.progress(0).play()
js
scss
tween.restart(); // 从头开始播放
💡 相当于"重新开始" 🔁
🔄 状态变化图示
假设动画总时长 2 秒:
| 方法 | 当前进度 | 调用后行为 |
|---|---|---|
| 初始 | 0% | --- |
.play() |
0% → 正向播放 → 100% | |
播放到 60% 时 .pause() |
停在 60% | --- |
.play() |
60% → 继续正向 → 100% | |
.reverse() |
60% → 倒放 → 0% | |
.restart() |
无论在哪 → 跳回 0% → 正向播放 |
💡 实际应用场景
场景 1:Hover 效果
js
javascript
box.addEventListener('mouseenter', () => tween.play());
box.addEventListener('mouseleave', () => tween.reverse());
场景 2:按钮控制
js
ini
playBtn.onclick = () => tween.play();
pauseBtn.onclick = () => tween.pause();
resetBtn.onclick = () => tween.restart();
场景 3:滚动触发动画
js
css
ScrollTrigger.create({
trigger: ".section",
onEnter: () => tween.play(),
onLeaveBack: () => tween.reverse()
});
⚠️ 注意事项
-
这些方法返回 tween 自身,支持链式调用:
js
scsstween.play().timeScale(2); // 2倍速播放 -
reverse()不会改变duration,只是反向运行。 -
如果动画已完成(100%),调用
play()不会重播(需用restart())。
✅ 总结
| 方法 | 作用 | 类比 |
|---|---|---|
.play() |
从当前位置正向播放 | ▶️ 播放 |
.pause() |
暂停在当前帧 | ⏸️ 暂停 |
.reverse() |
从当前位置反向播放 | ◀️ 倒放 |
.restart() |
重置到开头并播放 | 🔁 重播 |
这些方法赋予你对 GSAP 动画完全的程序化控制能力,是实现交互动效的基础。
gsap.defaults 是什么
在 GSAP(GreenSock Animation Platform)中,gsap.defaults() 是一个全局配置方法 ,用于为所有后续创建的 GSAP 动画(tween 或 timeline)设置默认参数 ,避免重复书写相同的配置项(如 duration、ease 等)。
js
const boxes = gsap.utils.toArray(".box");
const playButton = document.querySelector("#play");
// 设置默认动画参数
gsap.defaults({
duration: 0.8,
ease: "power2.out"
});
const timeline = gsap.timeline({ paused: true });
timeline.to(boxes[0], { x: 220, background: "#22d3ee" });
timeline.to(boxes[1], { x: 180, background: "#a3e635" }, "<0.1");
timeline.to(boxes[2], { x: 140, background: "#f472b6" }, "<0.1");
playButton.addEventListener("click", () => {
timeline.restart();
});
这行代码的意思是:
从此以后,所有通过
gsap.to()、gsap.from()、gsap.timeline().to()等创建的动画,如果没有显式指定duration和ease,就会自动使用duration: 0.8和ease: "power2.out"。
✅ 作用:减少重复代码,统一动效风格
在你的后续代码中:
js
php
timeline.to(boxes[0], { x: 220, background: "#22d3ee" });
timeline.to(boxes[1], { x: 180, background: "#a3e635" }, "<0.1");
timeline.to(boxes[2], { x: 140, background: "#f472b6" }, "<0.1");
虽然你没有写 duration 和 ease ,但由于前面设置了 gsap.defaults(),这三个 .to() 动画会自动继承:
duration: 0.8ease: "power2.out"
等价于:
js
php
timeline.to(boxes[0], { x: 220, background: "#22d3ee", duration: 0.8, ease: "power2.out" });
// ...其他同理
🔧 gsap.defaults() 支持的常用属性
| 属性 | 说明 |
|---|---|
duration |
默认动画时长(秒) |
ease |
默认缓动函数(如 "power2.out", "elastic", "back.inOut" 等) |
delay |
默认延迟时间 |
overwrite |
默认覆盖行为(如 "auto") |
opacity |
默认透明度(较少用) |
⚠️ 注意:局部配置会覆盖默认值 。
例如:
gsap.to(el, { x: 100, duration: 2 })中的duration: 2会覆盖defaults中的0.8。
🎯 使用场景
- 项目级动效规范
整个网站/应用使用统一的动画节奏和缓动曲线。 - 快速原型开发
先用默认值快速搭建动画,后期再微调个别参数。 - 减少样板代码
避免在几十个动画中反复写duration: 0.8, ease: "power2.out"。
⚠️ 注意事项
gsap.defaults()只影响调用之后创建的动画,对已存在的 tween/timeline 无效。- 它设置的是全局默认值 ,会影响所有 GSAP 动画(包括
gsap.to、timeline.to等)。 - 如果你在团队协作中使用,建议在项目入口文件(如
main.js)中统一设置。
gsap.quickTo 和 gsap.utils.clamp 是什么
GSAP 的两个非常高效且实用的工具:gsap.quickTo() 和 gsap.utils.clamp() 。它们常用于高性能指针/光标跟随、拖拽、实时交互等场景。下面分别详细解释:
js
const stage = document.querySelector("#stage");
const cursor = document.querySelector("#cursor");
// quickTo 可以高频率更新属性,且保持平滑
const moveX = gsap.quickTo(cursor, "x", { duration: 0.3, ease: "power3.out" });
const moveY = gsap.quickTo(cursor, "y", { duration: 0.3, ease: "power3.out" });
// utils.clamp 限制数值范围
const clampX = gsap.utils.clamp(0, stage.clientWidth - 36);
const clampY = gsap.utils.clamp(0, stage.clientHeight - 36);
stage.addEventListener("mousemove", (event) => {
const rect = stage.getBoundingClientRect();
const x = clampX(event.clientX - rect.left - 18);
const y = clampY(event.clientY - rect.top - 18);
moveX(x);
moveY(y);
});
✅ 1. gsap.quickTo()
🔍 是什么?
gsap.quickTo() 是 GSAP 提供的一个高性能属性更新器 ,它会预先创建一个轻量级的 tween(动画) ,然后你可以通过调用返回的函数高频次地更新目标值,而无需反复创建新动画。
📌 你的代码:
js
ini
const moveX = gsap.quickTo(cursor, "x", { duration: 0.3, ease: "power3.out" });
const moveY = gsap.quickTo(cursor, "y", { duration: 0.3, ease: "power3.out" });
- 创建了两个"快速更新器":
moveX和moveY - 它们分别控制
cursor元素的x和y属性 - 每次调用
moveX(100),就会让cursor的x平滑地动画到 100(耗时 0.3 秒,带缓动)
🎯 在事件中使用:
js
scss
stage.addEventListener("mousemove", (event) => {
// ...计算 x, y
moveX(x); // ← 高频调用(每秒可能几十次)
moveY(y);
});
✅ 为什么用 quickTo 而不用 gsap.to?
表格
| 方式 | 问题 |
|---|---|
gsap.to(cursor, { x: newX, duration: 0.3 }) |
每次 mousemove 都新建一个 tween,内存和性能开销大,容易卡顿 |
gsap.quickTo(...) |
只创建一次 tween ,后续只是更新它的目标值,极其高效 ✅ |
💡
quickTo内部会自动处理"中断上一帧动画、平滑过渡到新目标"的逻辑,非常适合鼠标跟随、拖拽预览等场景。
✅ 2. gsap.utils.clamp()
🔍 是什么?
clamp(钳制/限制)是一个数值范围限制工具函数 ,确保一个值不会超出指定的最小值和最大值。
📌 你的代码:
js
ini
const clampX = gsap.utils.clamp(0, stage.clientWidth - 36);
const clampY = gsap.utils.clamp(0, stage.clientHeight - 36);
clampX是一个函数,它接收一个数字,返回被限制在[0, stage.clientWidth - 36]范围内的值-36是因为你的cursor元素宽高为 36px(假设),要防止它超出容器右/下边缘
🎯 在事件中使用:
js
arduino
const x = clampX(event.clientX - rect.left - 18); // -18 是 cursor 宽度的一半(居中对齐)
✅ 作用:防止光标移出舞台区域
比如:
- 舞台宽度是 500px,cursor 宽 36px → 最大允许
x = 500 - 36 = 464 - 如果用户把鼠标移到 500px 处,
clampX(500 - 18) = clampX(482)→ 返回464 - 这样
cursor就不会"跑出"舞台右边
🔁 等价于手写:
js
lua
function clamp(value, min, max) {
return Math.min(Math.max(value, min), max);
}
但 GSAP 的版本更简洁、可复用。
🧩 整体逻辑总结
"受限区域内的平滑自定义光标" :
- 监听
#stage的鼠标移动 - 计算鼠标相对于舞台的坐标 (
clientX - rect.left) - 减去 18px 使光标中心对齐鼠标(假设光标是 36×36)
- 用
clamp限制坐标,不让光标超出舞台边界 - 用
quickTo高性能、平滑地更新光标位置
✅ 优势
| 技术 | 好处 |
|---|---|
gsap.quickTo |
高频更新不卡顿,动画流畅,内存友好 |
gsap.utils.clamp |
一行代码实现边界限制,代码清晰 |
GSAP 的 x/y |
自动使用 transform,性能优于 left/top |
💡 扩展建议
-
如果想让光标在离开舞台时隐藏,可加:
js
lessstage.addEventListener("mouseleave", () => gsap.set(cursor, { autoAlpha: 0 })); stage.addEventListener("mouseenter", () => gsap.set(cursor, { autoAlpha: 1 })); -
quickTo也支持其他属性,如scale、rotation、backgroundColor等。
✅ 总结
| 方法 | 作用 |
|---|---|
gsap.quickTo(target, prop, vars) |
创建高性能属性更新器,适合高频调用 |
gsap.utils.clamp(min, max) |
生成一个限制数值范围的函数,防止越界 |
这两个工具组合起来,是实现专业级交互动效(如自定义光标、拖拽预览、游戏 UI)的黄金搭档!
Draggable 是什么
js
<div class="card">
<h1>案例 14:Draggable 拖拽</h1>
<p>拖动方块,体验 Draggable 的基础能力。</p>
<div class="stage">
<div class="drag" id="drag">拖我</div>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/gsap.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/gsap@3.14.1/dist/Draggable.min.js"></script>
<script>
const drag = document.querySelector("#drag");
// 注册 Draggable 插件
gsap.registerPlugin(Draggable);
// 创建可拖拽对象并限制在父容器内
Draggable.create(drag, {
type: "x,y",
bounds: ".stage",
inertia: false
});
</script>
Draggable 是 GSAP(GreenSock Animation Platform)官方提供的一个强大插件 ,用于快速创建高性能、可定制的拖拽交互(drag-and-drop)。它不仅支持鼠标拖动,还完美兼容触摸设备(手机/平板),并内置了惯性滚动、边界限制、对齐吸附、旋转拖拽等高级功能。
📌 你的代码解释:
js
Draggable.create(drag, {
type: "x,y", // 允许水平和垂直拖动
bounds: ".stage", // 限制拖拽范围在 .stage 容器内
inertia: false // 禁用惯性(松手后不会继续滑动)
});
这段代码的作用是:
让
#drag元素变成一个可在.stage区域内自由拖动的方块,且松手后立即停止(无惯性滑动)。
✅ Draggable 的核心能力
| 功能 | 说明 |
|---|---|
| 跨平台支持 | 自动适配鼠标 + 触摸(无需额外代码) |
| 高性能 | 使用 transform(非 left/top),60fps 流畅拖拽 |
边界限制 (bounds) |
可限制在父容器、自定义矩形区域或另一个元素内 |
惯性动画 (inertia) |
松手后根据速度继续滑动(类似 iOS 滚动) |
多种拖拽类型 (type) |
x(水平)、y(垂直)、x,y(自由)、rotation(旋转)、scroll(模拟滚动)等 |
| 事件回调 | onDragStart, onDrag, onDragEnd 等,便于扩展逻辑 |
| 与其他 GSAP 动画无缝集成 | 拖拽过程中可触发 timeline、tween 等 |
🔧 常见配置项详解
1. type
"x":仅水平拖动"y":仅垂直拖动"x,y":自由二维拖动(最常用)"rotation":围绕中心点旋转(适合旋钮、转盘)"scrollTop"/"scrollLeft":模拟滚动条
2. bounds
- 字符串选择器:
".container"→ 限制在该元素内 - DOM 元素:
document.body - 对象:
{ top: 0, left: 0, width: 500, height: 300 }
3. inertia
true:松手后根据拖拽速度继续滑动(需加载InertiaPlugin)false:松手立即停止(默认)
🎯 实际应用场景
| 场景 | 配置示例 |
|---|---|
| 可拖拽卡片 | type: "x,y", bounds: ".card-container" |
| 滑块/进度条 | type: "x", bounds: ".slider-track" |
| 旋转调节器 | type: "rotation", bounds: { minRotation: 0, maxRotation: 180 } |
| 图片裁剪框 | type: "x,y", bounds: ".image" |
| 游戏人物移动 | type: "x,y", onDrag: updateCharacterPosition |
💡 事件回调示例
js
Draggable.create(drag, {
type: "x,y",
bounds: ".stage",
onDragStart: () => console.log("开始拖拽"),
onDrag: () => console.log("正在拖拽", drag._gsap.x, drag._gsap.y),
onDragEnd: () => console.log("拖拽结束")
});
📌 拖拽过程中的位置可通过
element._gsap.x/element._gsap.y实时获取(GSAP 自动维护)。
⚠️ 注意事项
-
必须注册插件 :
jsgsap.registerPlugin(Draggable); -
被拖拽元素需定位 :建议设置
position: absolute或fixed,否则可能布局错乱。 -
避免与原生滚动冲突 :在移动端可能需要
touch-action: none:css.drag { touch-action: none; /* 禁用浏览器默认拖拽/缩放 */ }
当然可以!在 GSAP 的 Draggable 插件中,type 选项决定了拖拽行为的类型 。以下是多个常见的 type 配置及其实际应用场景和代码示例,帮助你快速掌握不同拖拽模式的用法。
✅ 1. type: "x" ------ 仅水平拖动
适用于滑块、时间轴、横向卡片流等。
js
Draggable.create(".slider-handle", {
type: "x",
bounds: ".slider-track" // 限制在轨道内
});
📌 效果:只能左右拖,不能上下移动。
✅ 2. type: "y" ------ 仅垂直拖动
适用于音量条、滚动预览、垂直进度条。
js
Draggable.create(".volume-knob", {
type: "y",
bounds: ".volume-bar"
});
📌 效果:只能上下拖,不能左右移动。
✅ 3. type: "x,y" ------ 自由二维拖动(最常用)
适用于可移动窗口、拖拽图标、自定义光标、游戏人物。
js
Draggable.create(".draggable-box", {
type: "x,y",
bounds: ".container" // 限制在容器内
});
📌 效果 :可任意方向拖动,但不会超出 .container 边界。
✅ 4. type: "rotation" ------ 旋转拖拽
适用于旋钮、转盘、角度调节器、图片旋转工具。
js
Draggable.create(".knob", {
type: "rotation",
bounds: { minRotation: 0, maxRotation: 270 } // 限制旋转角度
});
📌 效果:鼠标/手指绕元素中心旋转,值为角度(°)。
💡 元素需设置
transform-origin: center(默认即是)。
✅ 5. type: "scrollTop" ------ 模拟垂直滚动
适用于自定义滚动条、迷你地图导航。
js
// 拖动小方块控制大内容区滚动
Draggable.create(".scroll-thumb", {
type: "scrollTop",
scrollElement: document.querySelector(".content") // 要滚动的目标元素
});
📌 效果 :拖动 .scroll-thumb 时,.content 区域会同步垂直滚动。
✅ 6. type: "scrollLeft" ------ 模拟水平滚动
适用于横向长图浏览、时间线导航。
js
Draggable.create(".horizontal-thumb", {
type: "scrollLeft",
scrollElement: document.querySelector(".timeline")
});
📌 效果 :拖动 thumb 控制 .timeline 水平滚动。
✅ 7. type: "top,left" ------ 使用 top/left 定位(不推荐)
⚠️ 性能较差,仅用于特殊布局(如非 transform 兼容场景)。
js
Draggable.create(".legacy-element", {
type: "top,left",
bounds: ".parent"
});
📌 区别:
- 默认
x,y使用transform: translate()(高性能、不影响文档流) top,left直接修改 CSStop/left(触发重排,性能低)
✅ 建议优先使用
x,y
✅ 8. 组合类型(GSAP 3.12+ 支持)------ type: "x,rotation"
同时支持水平移动 + 旋转(高级交互)。
js
Draggable.create(".dial", {
type: "x,rotation",
bounds: { minX: 0, maxX: 300 }
});
📌 效果:左右拖动改变位置,同时可旋转(需配合手势或逻辑判断)。
🔔 注意:组合类型需明确指定每个维度的行为,实际使用较少。
🎯 补充:如何读取拖拽状态?
无论哪种 type,你都可以通过以下方式获取实时值:
js
const drag = Draggable.get(".element");
console.log(drag.x); // 当前 x 位移(px)
console.log(drag.y); // 当前 y 位移(px)
console.log(drag.rotation); // 当前旋转角度
console.log(drag.scrollY); // 当前 scrollTop 值(如果 type 是 scrollTop)
✅ 总结:常用 type 对照表
type 值 |
用途 | 是否常用 |
|---|---|---|
"x" |
水平滑块 | ✅ 高频 |
"y" |
垂直滑块 | ✅ 高频 |
"x,y" |
自由拖拽(窗口/图标) | ✅ 最常用 |
"rotation" |
旋钮、转盘 | ✅ 中频 |
"scrollTop" |
自定义垂直滚动条 | ✅ 中频 |
"scrollLeft" |
自定义水平滚动条 | ✅ 中频 |
"top,left" |
兼容旧布局(不推荐) | ❌ 少用 |
通过合理选择 type,你可以用极少的代码实现丰富的交互效果。结合 bounds、inertia、事件回调(onDrag 等),Draggable 几乎能满足所有拖拽需求!
✅ 总结
| 术语 | 含义 |
|---|---|
Draggable |
GSAP 官方拖拽插件,提供高性能、跨平台、可定制的拖拽交互能力 |
代码是一个典型的 "受限区域内的基础拖拽" 示例,非常适合入门。通过组合 bounds、type、inertia 和事件回调,你可以轻松实现从简单 UI 控件到复杂游戏交互的各种需求。