提问人:Unknown X 提问时间:11/8/2023 最后编辑:Unknown X 更新时间:11/8/2023 访问量:30
如何平滑鼠标移动触发的 Framer Motion 动画?
How to smooth Framer Motion animation triggered by Mouse Move?
问:
我正在处理一个需要在鼠标拖动时调整框大小的项目,但是在尝试使用Framer Motion添加动画时遇到了一些问题。
到目前为止,我已经尝试了 2 种不同的方法。
用于处理框参数:useState
import { useState, type MouseEvent as ReactMouseEvent } from 'react'
import { motion } from 'framer-motion'
const STEP_SIZE = 40;
export default function App() {
console.log('render')
const [params, setParams] = useState({ top: 0, height: 0 })
const handlerMouseDown = (e: ReactMouseEvent<HTMLDivElement>) => {
const initialPosition = e.clientY
const handlerMouseMove = (e: MouseEvent) => {
const movement = e.clientY - initialPosition
const steps = Math.ceil(Math.abs(movement) / STEP_SIZE)
setParams({
top: movement > 0 ? initialPosition : initialPosition - steps * STEP_SIZE,
height: steps * STEP_SIZE
})
}
const handlerMouseUp = () => {
window.removeEventListener('mousemove', handlerMouseMove)
window.removeEventListener('mouseup', handlerMouseUp)
}
window.addEventListener('mousemove', handlerMouseMove)
window.addEventListener('mouseup', handlerMouseUp)
}
return (
<div className="Container" onMouseDown={handlerMouseDown}>
<motion.div className="Selector" animate={{ top: params.top, height: params.height }}></motion.div>
</div>
);
}
用于避免重新渲染:useAnimation
import { type MouseEvent as ReactMouseEvent } from 'react'
import { motion, useAnimation } from 'framer-motion'
const STEP_SIZE = 40;
export default function App() {
console.log('render')
const controls = useAnimation()
const handlerMouseDown = (e: ReactMouseEvent<HTMLDivElement>) => {
const initialPosition = e.clientY
const handlerMouseMove = (e: MouseEvent) => {
const movement = e.clientY - initialPosition
const steps = Math.ceil(Math.abs(movement) / STEP_SIZE)
controls.start({ // <- change "start" to "set" for no lag but without animation
top: movement > 0 ? initialPosition : initialPosition - steps * STEP_SIZE,
height: steps * STEP_SIZE
})
}
const handlerMouseUp = () => {
window.removeEventListener('mousemove', handlerMouseMove)
window.removeEventListener('mouseup', handlerMouseUp)
}
window.addEventListener('mousemove', handlerMouseMove)
window.addEventListener('mouseup', handlerMouseUp)
}
return (
<div className="Container" onMouseDown={handlerMouseDown}>
<motion.div className="Selector" animate={controls}></motion.div>
</div>
);
}
正如你所看到的,这种方法看起来很棒,但每次我移动鼠标时都会触发重新渲染。另一方面,这种方法不会重新渲染,但它看起来非常糟糕:如果我在播放时移动鼠标,动画会冻结一点。我可以用代替 ,但我希望它是动画的。useState
useAnimation
set
start
有没有办法让它看起来流畅,同时避免重新渲染?
答: 暂无答案
评论