You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何编写JavaScript函数实现转盘向预设位置缓慢减速停止?

实现转盘缓慢减速并精准停在预设弧度的方案

要让转盘从最大速度开始,在剩余弧度范围内匀减速到0并精准停在radiansUntilStop,核心是根据剩余可转动的弧度动态调整当前速度,确保速度随剩余距离线性降低,最终到达目标时速度恰好为0。

关键修改思路

  • 添加deceleration(减速度)变量,控制每帧速度降低的幅度
  • 计算剩余可转动弧度,根据剩余距离判断是否继续减速或直接定位到目标
  • 避免"过冲",确保最终位置完全匹配预设值

修改后的核心代码(update函数)

function update() {
  if (spin === true) {
    const remainingRadians = radiansUntilStop - radians;
    // 剩余弧度不足以支撑当前速度时,直接跳到目标位置停止
    if (remainingRadians <= currentSpeed) {
      radians = radiansUntilStop;
      currentSpeed = 0;
      spin = false;
    } else {
      // 按固定减速度降低当前速度,最低降到0
      currentSpeed = Math.max(currentSpeed - deceleration, 0);
      radians += currentSpeed;
    }
  }
  debug();
}

完整修改代码

<canvas id="wheel" width="300" height="300"></canvas>
<button id="spin" type="button">Spin</button><br>
Radians: <span id="radians"></span><br>
Speed: <span id="speed"></span><br>
const canvas = document.querySelector('#wheel');
const ctx = canvas.getContext('2d');

var radians = 0; // 当前转盘弧度
var maxSpeed = 0.2; // 每帧最大增加弧度
var currentSpeed = 0; // 当前每帧增加弧度
var radiansUntilStop = 47.8; // 目标停止弧度
var spin = false; // 是否正在转动
var deceleration = 0.001; // 每帧减速度,可按需调整

document.querySelector('#spin').addEventListener('click', function() {
    spin = true;
    currentSpeed = maxSpeed;
});

function update() {
  if (spin === true) {
    const remainingRadians = radiansUntilStop - radians;
    if (remainingRadians <= currentSpeed) {
      radians = radiansUntilStop;
      currentSpeed = 0;
      spin = false;
    } else {
      currentSpeed = Math.max(currentSpeed - deceleration, 0);
      radians += currentSpeed;
    }
  }
  debug();
}

function draw() {
    ctx.clearRect(0,0,canvas.width,canvas.height);
    ctx.arc(canvas.width/2, canvas.height/2, 150, 0, Math.PI * 2);
  
  for( let i = 0; i < Math.PI * 2; i += Math.PI * 0.5 ) {
    let fill = i === 0 ? true : false;
    drawWheelSection(150, 0, radians + i, fill);
  }
}

function loop() {
    window.requestAnimationFrame(loop);
    update();
    draw();
};

loop();

function drawWheelSection(center, radius, wheelRadians, fill = false) {  
    ctx.beginPath();
    ctx.moveTo(center, center);
    ctx.arc(center, center, 140, 0 + wheelRadians, Math.PI * 0.5 + wheelRadians);
    ctx.lineTo(center, center);
  
    if( fill === true ) {
        ctx.fillStyle = 'blue';
        ctx.fill();
    }
    ctx.stroke();
  
    // 修正箭头绘制位置,确保箭头在转盘顶部
    ctx.save();
    ctx.translate(canvas.width/2, canvas.height/2);
    ctx.beginPath();
    ctx.moveTo(0, -140);
    ctx.lineTo(-10, -110);
    ctx.lineTo(10, -110);
    ctx.closePath();
    ctx.fillStyle = 'red';
    ctx.fill();
    ctx.stroke();
    ctx.restore();
}

function debug() {
    document.querySelector('#radians').innerHTML = radians.toFixed(2);
    document.querySelector('#speed').innerHTML = currentSpeed.toFixed(4);
}

体验优化技巧

  • 调整deceleration值:值越大减速越快,值越小减速越平缓
  • 可添加加速阶段:点击后从0逐步加速到maxSpeed,再进入减速流程,更贴近真实转盘体验
  • 若需要更自然的减速曲线,可将减速度设置为随剩余弧度动态变化(剩余越多减速度越小)

内容的提问来源于stack exchange,提问作者Myles

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:45:31