Eri*_* Na 3 javascript google-chrome
我正在写一个我移动的小程序DOM我正在编写一个小程序,以指定的速度
当我以 的速率移动它时20px per second,offset添加到 的elem.style.top大约是0.3px per frame。
问题是,当它offset小于 时0.5px,elem它不会移动!
我构建了一个简化的示例,可以演示我的程序中的问题:
var requestFrameAnimationId;
function myMove(offset) {
var elem = document.getElementById("animate");
requestFrameAnimationId = animationLoop(frame);
function frame() {
console.log(elem.offsetTop);
if (elem.offsetTop === 350) {
cancelAnimationFrame(requestFrameAnimationId);
} else {
elem.style.top = elem.offsetTop + offset + 'px';
elem.style.left = elem.offsetLeft + offset + 'px';
}
}
}
function animationLoop(render) {
var running, lastFrame = +new Date(); // casting Date to Number
function loop(now) {`enter code here`
requestFrameAnimationId = requestAnimationFrame(loop);
running = render(now - lastFrame);
lastFrame = now;
}
loop(lastFrame);
}Run Code Online (Sandbox Code Playgroud)
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}Run Code Online (Sandbox Code Playgroud)
<!DOCTYPE html>
<html>
<body>
<p>
<button onclick="myMove(0.3)">Move at 0.3px per frame</button>
<button onclick="myMove(0.5)">Move at 0.5px per frame</button>
</p>
<div id="container">
<div id="animate"></div>
</div>
</body>
</html>Run Code Online (Sandbox Code Playgroud)
尝试点击Move at 0.5px per frame。矩形应该是移动的。单击重置它Run code snippet。
现在尝试点击Move at 0.3px per frame。它应该更慢地移动 DOM,但您可以看到 DOM 没有移动。
这很奇怪,因为当我最初跟踪topjavascript 变量中的位置topPos并${topPos + offset}应用于elem.style.top,它的工作速度甚至更慢!
所以我的猜测是elem.offsetTop四舍五入小数值,所以 0.3 变成 0,0.5 变成 1。
我该如何做才能使 DOM 以指定的速度精确移动?我无法为此使用任何库。
编辑:我更深入地研究了这个问题,我相信它是offsetTop数字四舍五入为整数。
然而,我发现 CSS OM 规范将 的类型更改offsetTop为float,并且Chromium 团队在 4 年多前就致力于将更改应用到浏览器上,看来现在应该已修复。
为什么它不能在我的程序上运行,我该如何让它运行?
EDIT2:我从CSSOM 工作草案中发现的类型是offsetTop整数。
readonly attribute long offsetTop;
Run Code Online (Sandbox Code Playgroud)
scrollTop我认为他们只是将和的类型更改scrollLeft为双精度数字。
attribute unrestricted double scrollTop;
attribute unrestricted double scrollLeft;
Run Code Online (Sandbox Code Playgroud)
HTMLElement.offset[左 | Top]返回long类型值(即整数)。
如果您想要浮点值,请使用Element.getBoundingClientRect 。
var requestFrameAnimationId;
function myMove(offset) {
var elem = document.getElementById("animate");
requestFrameAnimationId = animationLoop(frame);
function frame() {
// build up our own high precision offsetTop
var parentRect = elem.offsetParent && elem.offsetParent.getBoundingClientRect() || {top: 0, left:0};
var elemRect = elem.getBoundingClientRect();
var rect = {
top: elemRect.top - parentRect.top,
left: elemRect.left - parentRect.left
};
if (rect.top >= 350) {
cancelAnimationFrame(requestFrameAnimationId);
} else {
// so we can substract it here
elem.style.top = (rect.top + offset) + 'px';
elem.style.left = (rect.left + offset) + 'px';
}
}
}
function animationLoop(render) {
var running, lastFrame = +new Date(); // casting Date to Number
function loop(now) {
requestFrameAnimationId = requestAnimationFrame(loop);
running = render(now - lastFrame);
lastFrame = now;
}
loop(lastFrame);
}Run Code Online (Sandbox Code Playgroud)
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}Run Code Online (Sandbox Code Playgroud)
<p>
<button onclick="myMove(0.3)">Move at 0.3px per frame</button>
<button onclick="myMove(0.5)">Move at 0.5px per frame</button>
</p>
<div id="container">
<div id="animate"></div>
</div>Run Code Online (Sandbox Code Playgroud)
或者简单地将您的值添加到变量中:
var requestFrameAnimationId;
function myMove(offset) {
var elem = document.getElementById("animate");
requestFrameAnimationId = animationLoop(frame);
var pos = 0;
function frame() {
pos += offset;
if (pos >= 350) {
cancelAnimationFrame(requestFrameAnimationId);
} else {
elem.style.top = pos + 'px';
elem.style.left = pos + 'px';
}
}
}
function animationLoop(render) {
var running, lastFrame = +new Date(); // casting Date to Number
function loop(now) {
requestFrameAnimationId = requestAnimationFrame(loop);
running = render(now - lastFrame);
lastFrame = now;
}
loop(lastFrame);
}Run Code Online (Sandbox Code Playgroud)
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}Run Code Online (Sandbox Code Playgroud)
<p>
<button onclick="myMove(0.3)">Move at 0.3px per frame</button>
<button onclick="myMove(0.5)">Move at 0.5px per frame</button>
</p>
<div id="container">
<div id="animate"></div>
</div>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2151 次 |
| 最近记录: |