我有一个小鼠标速度检测器(远非完美),它在变量window.mouseSpeed.t
中每100ms为我提供当前鼠标速度。我之所以实现它,是因为我想在屏幕的底部边缘有一个有趣的动画,其中有一个以较高速度增长和以较低速度收缩的条。我想用Element.animate()
制作动画
唯一的问题是:如何在动画运行时更改Animation
的结束关键帧(我只给出一个结束帧,以便浏览器将当前状态作为第一帧)
我想实现棒的长度平滑变化。
// The code I want to have animated is below this function.
// Mouse speed tracker (I hope this isn't too horrible code):
document.addEventListener('DOMContentLoaded', mausgeschwindigkeitVerfolgen, {once:true});
function mausgeschwindigkeitVerfolgen() { // "Mausgeschwindigkeit verfolgen" means "track mouse speed" in German
var speedX = NaN;
var speedY = NaN;
var posX = NaN;
var posY = NaN;
var speed = NaN;
document.addEventListener("mousemove", function(ev){
speedX += Math.abs(ev.movementX);
speedY += Math.abs(ev.movementY);
speed = 10*Math.sqrt(ev.movementX**2+ev.movementY**2);
window.mousePosition = {x:posX = ev.clientX,y:posY = ev.clientY};
}, false);
setInterval(function(){
[window.mouseSpeed, window.mousePosition] = [{x:speedX,y:speedY,t:speed}, {x:posX,y:posY}]; // Werte in window.mouseSpeed und window.mouseDistance speichern
speed = totalX = totalY = 0;
}, 100);
window.mausgeschwindigkeitVerfolgen = () => {return {speed:window.mouseSpeed, pos:window.mousePosition};};
return {speed:window.mouseSpeed, pos:window.mousePosition};
}
// --- This is the code I want to have animated: ---
setInterval(() => {
document.querySelector('div#mouseSpeedIndicator').style.width = window.mouseSpeed.t+'px';
//document.querySelector('div#mouseSpeedIndicator').animate({width:'0px'}, {duration:1000,iterations:1}); // This just keeps the bar at width 0, I want it to slowly change to any newly set width
}, 100);
div#mouseSpeedIndicator {
position: fixed;
bottom: 0px;
left: 0px;
height: 33px;
background-color: green;
max-width: 100vh;
border: 0px solid green;
border-top-right-radius: 10px;
}
<!-- What I currently have -->
<div id="mouseSpeedIndicator"></div>
首先,简单到transition
CSS属性的一行,比如…
transition: width 1s ease-out;
已经做好了工作;不需要更多基于JavaScript的计算和DOM操作。
当然,如果有throttle
(lodash_.throttle
或undercorejs_.throttle
)这样的外部辅助方法的支持,OP的脚本可以大大简化,后者将创建传递函数的延迟执行版本,对于OP的示例脚本来说,该版本是'mousemove'
-处理程序。
在被节流(甚至不节流)之前,此处理程序可以被创建为函数的绑定版本,该函数实际计算speed
值并更新指示器节点的外观。
function handleMouseSpeedIndicatorUpdateFromBoundData(evt) {
const { movementX, movementY } = evt;
const { rootNode, timeoutId } = this;
// prevent indicator nullification at time.
clearTimeout(timeoutId);
// compute `speed`.
const speed = 10 * Math.sqrt(movementX**2 + movementY**2);
// update indicator appearance.
rootNode.style.width = `${ speed }px`;
// trigger delayed indicator nullification.
this.timeoutId = setTimeout(() => rootNode.style.width = 0, 110);
}
function initialzeMouseSpeedIndicator() {
document
.addEventListener(
'mousemove',
// create throttled version of the just created bound handler.
_.throttle(
// create handler function with bound contextual data.
handleMouseSpeedIndicatorUpdateFromBoundData.bind({
rootNode: document.querySelector('#mouseSpeedIndicator'),
timeoutId: null,
}), 100
),
false
);
}
// - no need for `'DOMContentLoaded'`
// in order to initialize the indicator.
initialzeMouseSpeedIndicator();
div#mouseSpeedIndicator {
position: fixed;
top: 0px;
left: 0px;
height: 33px;
background-color: green;
max-width: 100vh;
border: 0px solid green;
border-bottom-right-radius: 10px;
/* proposed change(s) */
transition: width 1s ease-out;
/* transition: width .5s ease-in; */
/* transition: width .5s ease-in-out; */
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.21/lodash.min.js"></script>
<div id="mouseSpeedIndicator"></div>