Framer Motion 如何实现元素仅可向下拖拽、松开后自动复位
实现方案
核心修改逻辑
- 用
useMotionValue绑定圆形的y轴偏移量,初始值设为0对应初始位置 - 调整
dragConstraints配置:top: 0强制y轴偏移不能小于0,实现禁止向上拖拽的效果,bottom值为允许的最大下拉距离,可自行调整 - 新增
onDragEnd回调,拖拽结束时自动触发动画将y轴偏移重置为0,实现回弹效果 - 关闭
dragMomentum避免拖拽松手后的惯性滑动
完整修改后代码
import { motion, useMotionValue, animate } from "framer-motion"; import styled from "styled-components"; const Component = ({ ...props }) => { // 绑定圆形的y轴偏移,初始位置为0 const y = useMotionValue(0); // 拖拽结束后触发回弹到初始位置 const handleDragEnd = () => { animate(y, 0, { stiffness: 1000, // 回弹刚度,值越大回弹越快 damping: 20, // 回弹阻尼,值越小回弹震荡次数越多 }); }; return ( <Container props={props}> <Circle drag="y" y={y} dragConstraints={{ top: 0, bottom: 250 }} // bottom可根据需要调整最大下拉距离 dragMomentum={false} // 关闭拖拽惯性 whileHover={{ scale: 1.1 }} whileTap={{ scale: 1.2, cursor: "grabbing" }} dragElastic={0.1} // 拖拽到边界的弹性效果,可自行调整 onDragEnd={handleDragEnd} /> </Container> ); }; const Circle = styled(motion.div)` height: 100px; width: 100px; border-style: solid; border-width: 5px; border-radius: 50%; border-color: black; cursor: grab; `; const Container = styled.div` display: flex; align-items: center; justify-content: center; flex-direction: column; height: 450px; `; export default Component;
参数调整说明
- 若要修改最大下拉距离,直接调整
dragConstraints的bottom值即可 - 若要调整回弹速度和震荡效果,修改
animate函数内的stiffness和damping参数即可 - 若要调整拖拽时的边界弹性感,修改
dragElastic参数即可,0为完全无弹性,1为最大弹性
内容的提问来源于stack exchange,提问作者pho_pho
相关产品推荐
相关产品推荐

