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

JS animate()方法异常:轮盘切换旋转方向时出现跳变

轮盘旋转动画切换方向时跳变问题

我正在制作一个动画轮盘,预期效果:点击next按钮,轮盘逆时针旋转90度显示对应项目;点击previous按钮则顺时针旋转90度。4个项目已放置在轮盘上,JS仅负责控制轮盘按点击方向旋转。当前代码在单一方向点击时运行正常,但切换到相反方向点击时会出现跳变,再次点击同一方向时动画恢复正常。

现有代码

HTML

<body>
<div class="drinks-wheel-section">
    <div class="drinks-wheel">
        <div class="drinks-wrapper wrapper1">
            <div class="drink-picture --1"></div>
            <div class="drink-picture --2"></div>
        </div>
        <div class="drinks-wrapper wrapper2">
            <div class="drink-picture --3"></div>
            <div class="drink-picture --4"></div>
        </div>
    </div>
    <div class="name-and-change">
        <span class="previous">< </span>
        <p class="drink-name"></p>
        <span class="next">></span>
    </div>
</div>
    <script src="s.js"></script>
</body>

CSS

.drinks-wheel-section{
    width: 100%;
    height: 80vh;
    display: flex;
    justify-content: center;
    align-items: center;
    margin-top: 4rem;
    position: relative;
}

.drinks-wheel{
    width: 30rem;
    height: 30rem;
    border-radius: 50%;
    position: relative;
}

.drink-picture{
    width: 7rem;
    height: 7rem;
}
.--1{
    background-color: aqua;
}

.--2{
    background-color: darkblue;
}

.--3{
    background-color: black;
}

.--4{
    background-color: brown;
}

.drinks-wrapper{
    width: 100%;
    height: 7rem;
    position: absolute;
    display: flex;
    justify-content: space-between;
    gap: 1rem;
}


.wrapper1{
    top: 37%;
    left: 0%;
}

.wrapper2{
    rotate: 90deg;
    top: 38%;
    left: 0%;
}

.name-and-change{
    width: 15%;
    display: flex;
    justify-content: space-evenly;
    align-items: center;
    position: absolute;
}

.next,.previous{
    font-size: 2rem;
    cursor: pointer;
}

JavaScript

const $ = document
const previousBtn = $.querySelector(".previous")
const nextBtn = $.querySelector(".next")
const CurrentDrinkName = $.querySelector(".drink-name")
const drinksWheel = $.querySelector(".drinks-wheel")

let rotateAmountFrom = 0
let rotateAmountTo = 0

function showNextOrPreviousDrink (e){
    if(e.target.classList.contains("previous")) {
        rotateAmountFrom = rotateAmountTo
        rotateAmountTo = rotateAmountTo + 90
        let animationRotate = [
            {rotate: rotateAmountFrom + "deg"},
            {rotate: rotateAmountTo + "deg"},
        ]
        drinksWheel.animate(animationRotate,{fill: "forwards",duration:800,})
    
    } else {
        rotateAmountFrom = rotateAmountTo
        rotateAmountTo = rotateAmountTo + 90    
        let animationRotate = [
            {rotate: "-" + rotateAmountFrom + "deg"},
            {rotate: "-" + rotateAmountTo + "deg"},
        ]
        drinksWheel.animate(animationRotate,{fill: "forwards",duration:800,})

    }
    console.log(rotateAmountFrom,rotateAmountTo,)
}
nextBtn.addEventListener("click",showNextOrPreviousDrink)
previousBtn.addEventListener("click",showNextOrPreviousDrink)

问题原因

核心问题是next和previous操作共用同一组累加变量,但next方向的动画使用负号偏移,导致轮盘实际旋转状态与变量记录的数值不一致。比如先点击next,变量rotateAmountTo累加为90,但轮盘实际是-90deg;此时点击previous,动画会从90deg开始旋转到180deg,和当前轮盘的-90deg状态冲突,引发跳变。

修复方案

用单个变量记录轮盘当前的实际旋转角度,每次点击直接基于当前角度计算目标角度,统一处理旋转逻辑:

const $ = document
const previousBtn = $.querySelector(".previous")
const nextBtn = $.querySelector(".next")
const CurrentDrinkName = $.querySelector(".drink-name")
const drinksWheel = $.querySelector(".drinks-wheel")

// 记录轮盘当前的实际旋转角度,初始为0
let currentRotation = 0

function showNextOrPreviousDrink(e) {
    let targetRotation
    if (e.target.classList.contains("previous")) {
        // previous:顺时针旋转90度
        targetRotation = currentRotation + 90
    } else {
        // next:逆时针旋转90度
        targetRotation = currentRotation - 90
    }
    
    // 基于当前角度创建过渡动画
    const animationRotate = [
        { rotate: `${currentRotation}deg` },
        { rotate: `${targetRotation}deg` }
    ]
    
    drinksWheel.animate(animationRotate, {
        fill: "forwards",
        duration: 800
    })
    
    // 更新当前角度为目标角度
    currentRotation = targetRotation
}

nextBtn.addEventListener("click", showNextOrPreviousDrink)
previousBtn.addEventListener("click", showNextOrPreviousDrink)

可选优化

如果希望旋转角度始终保持在0-360范围内(避免数值无限累加),可以在更新角度时添加取模处理:

currentRotation = targetRotation % 360
// 处理负数情况,确保角度为正
if (currentRotation < 0) {
    currentRotation += 360
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 13:31:04