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
相关产品推荐
相关产品推荐

