我创建了一个简单的滑动函数,它可以使元素在给定的时间内出现或消失。
我建立此功能的公式是: ms = 1 pixel / (initial size / duration)
,基本上计算在从元素 1px
之前应经过多少毫秒> height
或 width
。
我的数学逻辑表示该功能应该在 1000ms
中完成,但对我来说,完成外观所花费的时间要多得多,而不确定是多少。
为什么需要比 1s
更长的时间才能完成以及可能导致它的原因?
代码:
/* ----- JavaScript ----- */
function slide(el, duration, direction) {
/* Default */
duration = duration || 1000, direction = direction || "vertical";
var
dim = (direction === "horizontal") ? "width" : "height",
/* Get how tall or wide el is in 'px' */
size = initSize = parseFloat(
getComputedStyle(el, null).getPropertyValue(dim) || el.style[dim]
),
/* Get the previous size, so as to restore el to it */
prevSize = el.style["prev" + dim] || 0,
/* Calculating how many ms should pass before subtracting 1px*/
ms = 1 / (initSize / duration),
interval = setInterval(function() {
/* If el is visible */
if (initSize > prevSize && size > prevSize) el.style[dim] = --size + "px";
/* If el is not visible */
else if (prevSize > initSize && size <= prevSize) el.style[dim] = ++size + "px";
/* Clear the interval when 0 is reached and cache the previous size */
else {
console.log("oops")
el.style["prev" + dim] = initSize;
clearInterval(interval);
}
}, ms);
}
slide(document.getElementById("a"));
<!----- HTML ----->
<div id = "a" style = "width: 200px;height: 300px;background-color:black;"></div>
答案 0 :(得分:1)
您需要调整步长,即每次迭代要添加/删除的像素数,并调整延迟时间。以下是一个改进的版本,大约需要1.1秒。
function slide(el, duration, direction) {
/* Default */
duration = duration || 1000, direction = direction || "vertical";
var dim = (direction === "horizontal") ? "width" : "height",
/* Get how tall or wide el is in 'px' */
size = initSize = parseFloat(
getComputedStyle(el, null).getPropertyValue(dim) || el.style[dim]
),
/* Get the previous size, so as to restore el to it */
prevSize = el.style["prev" + dim] || 0;
/* Calculating how many ms should pass before subtracting 1px*/
var step = 1;
var ms = 1 / (initSize / duration)
if(ms<10){
ms=10;
step = 10*(initSize/duration);
console.log(ms,step)
}
var now=new Date();
var interval;var i=0;
var animate = function() {
i++;
interval=setTimeout(animate,ms);
/* If el is visible */
if (initSize > prevSize && size > prevSize) el.style[dim] = (size=size-step) + "px";
/* If el is not visible */
else if (prevSize > initSize && size <= prevSize) el.style[dim] = (size=size+step) + "px";
/* Clear the interval when 0 is reached and cache the previous size */
else {
console.log("oops", new Date()-now,size,step,i)
el.style["prev" + dim] = initSize;
clearInterval(interval);
}
};
//var interval = setInterval(animate, ms);
animate();
}
slide(document.getElementById("a"));
答案 1 :(得分:1)
在阅读了Jaromanda X的评论后,我终于使用了 window.requestAnimationFrame()
,因为它比 setInterval()
更有效率它也不会强制浏览器重绘。
这反过来让我将我的公式从时间导向( ms = 1 / (initial size / duration)
)更改为像素导向( px = frame * (initial size / duration)
)。
现在滑动更顺畅,非常接近 1000ms
,我认为只有 5-7ms
差异,因为我设置了 frame
变量 1000 / 60
未考虑可能发生的帧速率下降。
<强>代码:强>
/* ----- JavaScript ----- */
function slide(el, duration, direction) {
/* Set Defaults and record starting date */
var a = Date.now();
duration = duration || 1000, direction = direction || "vertical";
var
dim = (direction === "horizontal") ? "width" : "height",
/* Get how tall or wide el is in 'px' */
size = initSize = parseFloat(
getComputedStyle(el, null).getPropertyValue(dim) || el.style[dim]
),
/* Get the previous size, so as to restore el to it */
prevSize = el.style["prev" + dim] || 0,
/* Calculating how many px should be added / subtracted each frame */
frame = 1000 / 60,
px = frame * (initSize / duration),
step = (initSize > prevSize) ? -px : px;
window.requestAnimationFrame(function transform() {
el.style[dim] = (size > 0) ? (size += step) + "px" : (size = 0);
if (size === 0) {
el.style["prev" + dim] = initSize;
//element.style.prevDisplay = initDisplay;
console.log(Date.now() - a)
} else window.requestAnimationFrame(transform);
}, frame);
}
slide(document.getElementById("a"), 1000);
<!----- HTML ----->
<div id="a" style="width: 200px;height: 300px;background-color:black;"></div>