Adobe Animate AS3如何为拖拽添加惯性/动量实现滑动删除效果?
AS3实现滑动删除的惯性拖拽效果
要实现带惯性的滑动删除,不能直接依赖startDrag(),因为它无法记录拖拽的速度信息。核心思路是手动监听鼠标事件跟踪拖拽轨迹,计算拖拽速度,释放后通过帧循环模拟减速运动,直到对象停止或触发删除条件。
核心实现步骤
- 禁用
startDrag,改用MOUSE_DOWN/MOUSE_MOVE/MOUSE_UP手动控制对象位置,同时记录拖拽过程的速度数据 - 每次鼠标移动时,通过前后帧的位置差和时间差计算拖拽速度
- 鼠标释放后,启动
ENTER_FRAME事件让对象按速度继续运动,逐帧给速度乘以减速系数,直到速度低于阈值停止;若运动到删除触发位置,则执行删除逻辑
完整示例代码
假设目标滑动对象是名为slideItem的MovieClip:
import flash.events.MouseEvent; import flash.events.Event; import flash.utils.getTimer; // 拖拽与惯性相关变量 var isDragging:Boolean = false; var lastMouseX:Number; var lastTime:int; var currentSpeed:Number = 0; var friction:Number = 0.9; // 减速系数,值越小停得越快 var stopThreshold:Number = 0.1; // 停止运动的速度阈值 var deleteThreshold:Number = -50; // 滑到该X坐标左侧触发删除 // 初始化事件监听 slideItem.addEventListener(MouseEvent.MOUSE_DOWN, onDragStart); stage.addEventListener(MouseEvent.MOUSE_UP, onDragEnd); stage.addEventListener(MouseEvent.MOUSE_OUT, onDragEnd); function onDragStart(e:MouseEvent):void { isDragging = true; lastMouseX = e.stageX; lastTime = getTimer(); // 停止当前惯性运动 slideItem.removeEventListener(Event.ENTER_FRAME, onInertiaMove); stage.addEventListener(MouseEvent.MOUSE_MOVE, onDragging); } function onDragging(e:MouseEvent):void { if (!isDragging) return; var currentTime:int = getTimer(); var timeDelta:int = currentTime - lastTime; if (timeDelta == 0) return; // 避免除以0 // 计算鼠标移动速度(转换为每秒移动像素) var mouseDeltaX:Number = e.stageX - lastMouseX; currentSpeed = mouseDeltaX / timeDelta * 1000; // 更新对象位置 slideItem.x += mouseDeltaX; // 更新上一帧的位置和时间记录 lastMouseX = e.stageX; lastTime = currentTime; } function onDragEnd(e:MouseEvent):void { if (!isDragging) return; isDragging = false; stage.removeEventListener(MouseEvent.MOUSE_MOVE, onDragging); // 启动惯性运动 slideItem.addEventListener(Event.ENTER_FRAME, onInertiaMove); } function onInertiaMove(e:Event):void { // 应用速度与减速效果 slideItem.x += currentSpeed / 60; // 适配60帧/秒的默认帧率 currentSpeed *= friction; // 检查是否停止运动 if (Math.abs(currentSpeed) < stopThreshold) { slideItem.removeEventListener(Event.ENTER_FRAME, onInertiaMove); currentSpeed = 0; // 未触发删除时,可添加回弹到初始位置的动画(可选) if (slideItem.x > deleteThreshold) { // 示例:使用Animate自带Tween类实现回弹 // import fl.transitions.Tween; // import fl.transitions.easing.*; // new Tween(slideItem, "x", Strong.easeOut, slideItem.x, 0, 0.3, true); } } // 检查是否触发删除 if (slideItem.x < deleteThreshold) { slideItem.removeEventListener(Event.ENTER_FRAME, onInertiaMove); removeChild(slideItem); // 这里可添加删除后的后续逻辑 } }
关键细节说明
- 速度计算:用
getTimer()获取时间戳,避免帧率波动导致速度计算偏差,转换为每秒移动像素的单位更稳定 - 减速系数:
friction设为0.9左右接近真实惯性,可根据需求调整(0.8减速更快,0.95减速更慢) - 删除阈值:
deleteThreshold根据布局自行设置,比如对象初始X为0时,滑到-50触发删除 - 回弹效果:注释中的Tween类是Animate自带组件,可直接调用实现未删除状态下的位置回弹
内容的提问来源于stack exchange,提问作者NC35
相关产品推荐
相关产品推荐

