JS根据拖拽速度动态计算倾斜角度的实现方案

作者:木棉

时间:2026-11-01

浏览:120

本文详解如何在JavaScript中根据鼠标拖拽速度动态设置元素的倾斜角度。通过路程除以时间计算实时速度,结合最大速度、最大角度及固定系数(旋转系数)的公式,实现平滑的旋转交互效果。文章提供了核心逻辑代码及基于Vue框架的完整示例,适用于需要增强用户交互体验的前端开发场景。

文章目录

实现

拖拽速度设置倾斜角度

实现

要实现根据拖拽速度动态调整元素倾斜角度,核心在于建立速度值与旋转角度之间的映射关系。

实现

∵ ( 角度 / 最大角度 ) = ( 速度 / 最大速度 ) * 固定系数

∴ 角度 = ( 速度 / 最大速度 ) / 最大角度 * 固定系数

公式中的固定系数实际上被称为旋转系数,它是一个乘法因子,用于微调旋转的幅度。引入该系数的优势在于,它允许开发者在不修改基础速度和最大旋转角度的前提下,根据具体的业务场景灵活调整旋转的视觉强度。

上述数学模型已明确,接下来的工作是通过代码计算出实时速度。由于最大速度、最大角度以及固定系数均为预设的常量,因此只需关注速度的动态获取。

速度的计算逻辑十分直观,即利用路程除以时间得出。

在拖拽交互过程中,路程定义为两次触发拖拽事件时位置坐标的差值,而时间则直接通过 performance.now() 获取当前高精度时间戳。基于此,计算速度的具体方法如下所示:

// eslint-disable-next-line prefer-const
let lastX = x.value
// eslint-disable-next-line prefer-const
let startTime = performance.now()
function calVelocity(lastX: number, currentX: number, lastTime: number, currentTime = performance.now()) {
  const distanceX = currentX - lastX
  const deltaTime = currentTime - lastTime
  return {
    velocity: distanceX / deltaTime,
    newTime: currentTime,
    newX: currentX,
  }
}

在拖拽动作触发时,调用 calVelocity() 函数,并将计算得到的最新时间 newTime 和最新坐标 newX 分别赋值给 startTime 和 lastX,以便下一次计算使用。

以上即为核心代码逻辑。下方首图展示了基于 TypeScript 的完整实现,该示例使用了 Vue 框架,并集成了 VueUse 及其 motion 工具类。若需直接运行该示例,需预先配置好相应的开发环境。

// 1. 具有两个动画,一个是上下浮动,一个是拖拽的时候会有小幅度旋转
// 2. 拖拽的时候,根据速度计算旋转幅度,这个时候上下浮动消失
// 3. 拖拽结束后(速度小于一个阈值或者鼠标抬起或者鼠标移动到了外面),旋转幅度取消,上下浮动重新开始
/** ************************设置拖拽和旋转***************************** */
const props = defineProps({
  initialPosition: {
    default: () => ({
      x: Math.random() * (window.innerWidth - 400),
      y: Math.random() * (window.innerHeight - 160),
    }),
  },
})
const target = ref<HTMLElement>()
const { apply: waveApply } = useMotion(target, {
  initial: { rotate: 0 },
  enter: { rotate: 0 },
})
async function setRotate(rotate: number) {
  await waveApply({
    rotate,
  })
}
const { x, style, isDragging } = useDraggable(target, { initialValue: props.initialPosition })
let rotationDelta = 0
watch(isDragging, async () => {
  if (isDragging.value) {
    // 拖拽的时候,取消上下浮动
  }
  else {
    // 拖拽结束后,设置旋转角度为 0 , 恢复上下浮动
    setRotate(0)
    rotationDelta = 0
  }
})
/** **************************************************************** */
/** ************************通过速度计算旋转幅度***************************** */
let lastX = x.value
let startTime = performance.now()
// 当前角度 / 当前速度 = 最大角度 / 最大速度
// 得出:当前角度 = ( 最大角度 / 最大速度 ) * 当前速度
// 然后再乘以一个系数,用于调整旋转幅度,角度跟速度的比例
const cfg = {
  maxVelocity: 10, // 最大速度
  maxRotation: 60, // 最大旋转角度
  rotationFactor: 0.8, // 旋转系数,用于调整旋转幅度
}
watch(x, () => {
  const { velocity, newX, newTime } = calVelocity(lastX, x.value, startTime)
  const { maxVelocity, maxRotation, rotationFactor } = cfg
  // 速度除以最大速度,将速度归一化为一个介于 0 和 1 之间的小数值,表示速度相对于最大速度的比例。
  // 将这个比例值乘以最大旋转角度 maxRotation,这样就得到了基于速度的旋转角度
  // 但这得出的仍是一个相对值,最后,再将这个相对的旋转角度乘以旋转系数 rotationFactor,以调整最终的旋转幅度。
  rotationDelta = -(velocity / maxVelocity * maxRotation * rotationFactor)
  setRotate(rotationDelta)
  lastX = newX
  startTime = newTime
})
function calVelocity(lastX: number, currentX: number, lastTime: number, currentTime = performance.now()) {
  const distanceX = currentX - lastX
  const deltaTime = currentTime - lastTime
  return {
    velocity: distanceX / deltaTime,
    newTime: currentTime,
    newX: currentX,
  }
}
/** **************************************************************** */

以上就是JS随拖拽速度设置倾斜角度的实现代码的详细内容,更多关于JS设置倾斜角度的资料请关注本站其它相关文章!

实用工具推荐

电子包浆

绿化、压缩、噪点和虚拟水印,自由调节做旧程度。

使用 ›
图片压缩

选择画质和输出格式,预览压缩前后的大小。

使用 ›
相关文章