纯JavaScript动画缓动
Pure JavaScript animation easing
几个小时以来,我一直在努力寻找一个纯粹的 JavaScript 简易实现,但找不到。那些接近的没有任何意义。我所能找到的只是一堆没有实现的缓动函数。
例如,像这样的函数:
function linear(time, begin, change, duration) {
return change * time / duration + begin;
}
function easeInQuad(t) {
return t*t
},
function easeOutQuad(t) {
return t*(2-t)
},
困扰我的一件事是fps在哪里发挥作用?它与持续时间直接相关。我没看到有人提到它。
如何在下面的动画中实现上述缓动函数?
var box = document.getElementById("box");
var fps = 60;
var duration = 2; // seconds
var start = 0; // pixel
var finish = window.innerWidth - box.clientWidth;
var distance = finish - start;
var increment = distance / (duration * fps);
var position = start;
function move() {
position += increment;
if (position >= finish) {
clearInterval(handler);
box.style.left = finish + "px";
return;
}
box.style.left = position + "px";
}
var handler = setInterval(move, 1000 / fps);
body {
background: gainsboro;
}
#box {
width: 100px;
height: 100px;
background: white;
box-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
position: absolute;
left: 0;
}
<div id="box"></div>
您可以使用 time
变量并为每一帧增加它,并使用缓动函数在正确的位置使用您已有的值。
- 缓动公式:http://easings.net/
- 说明:What is an easing function?
// formula http://easings.net/
// description
// x: percent
// t: current time,
// b: beginning value,
// c: change in value,
// d: duration
function easeInOutQuad(x, t, b, c, d) {
if ((t /= d / 2) < 1) {
return c / 2 * t * t + b;
} else {
return -c / 2 * ((--t) * (t - 2) - 1) + b;
}
}
function move() {
//position += increment;
time += 1 / fps;
position = easeInOutQuad(time * 100 / duration, time, start, finish, duration);
if (position >= finish) {
clearInterval(handler);
box.style.left = finish + "px";
return;
}
box.style.left = position + "px";
}
var box = document.getElementById("box"),
fps = 60,
duration = 2, // seconds
start = 0, // pixel
finish = window.innerWidth - box.clientWidth,
distance = finish - start,
increment = distance / (duration * fps),
position = start,
time = 0,
handler = setInterval(move, 1000 / fps);
body {
background: gainsboro;
}
#box {
width: 100px;
height: 100px;
background: white;
box-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
position: absolute;
left: 0;
}
<div id="box"></div>
<canvas id='canvas' width=600 height=400></canvas>
<script>
var ctx = document.getElementById('canvas').getContext('2d');
var divx = 500;
var divtx = 0;
function animate() {
divx += (divtx - divx) / 20;
ctx.clearRect(0, 0, 600, 400);
ctx.fillRect(divx, 0, 100, 100);
window.requestAnimationFrame(animate);
}
animate();
</script>
几个小时以来,我一直在努力寻找一个纯粹的 JavaScript 简易实现,但找不到。那些接近的没有任何意义。我所能找到的只是一堆没有实现的缓动函数。
例如,像这样的函数:
function linear(time, begin, change, duration) {
return change * time / duration + begin;
}
function easeInQuad(t) {
return t*t
},
function easeOutQuad(t) {
return t*(2-t)
},
困扰我的一件事是fps在哪里发挥作用?它与持续时间直接相关。我没看到有人提到它。
如何在下面的动画中实现上述缓动函数?
var box = document.getElementById("box");
var fps = 60;
var duration = 2; // seconds
var start = 0; // pixel
var finish = window.innerWidth - box.clientWidth;
var distance = finish - start;
var increment = distance / (duration * fps);
var position = start;
function move() {
position += increment;
if (position >= finish) {
clearInterval(handler);
box.style.left = finish + "px";
return;
}
box.style.left = position + "px";
}
var handler = setInterval(move, 1000 / fps);
body {
background: gainsboro;
}
#box {
width: 100px;
height: 100px;
background: white;
box-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
position: absolute;
left: 0;
}
<div id="box"></div>
您可以使用 time
变量并为每一帧增加它,并使用缓动函数在正确的位置使用您已有的值。
- 缓动公式:http://easings.net/
- 说明:What is an easing function?
// formula http://easings.net/
// description
// x: percent
// t: current time,
// b: beginning value,
// c: change in value,
// d: duration
function easeInOutQuad(x, t, b, c, d) {
if ((t /= d / 2) < 1) {
return c / 2 * t * t + b;
} else {
return -c / 2 * ((--t) * (t - 2) - 1) + b;
}
}
function move() {
//position += increment;
time += 1 / fps;
position = easeInOutQuad(time * 100 / duration, time, start, finish, duration);
if (position >= finish) {
clearInterval(handler);
box.style.left = finish + "px";
return;
}
box.style.left = position + "px";
}
var box = document.getElementById("box"),
fps = 60,
duration = 2, // seconds
start = 0, // pixel
finish = window.innerWidth - box.clientWidth,
distance = finish - start,
increment = distance / (duration * fps),
position = start,
time = 0,
handler = setInterval(move, 1000 / fps);
body {
background: gainsboro;
}
#box {
width: 100px;
height: 100px;
background: white;
box-shadow: 1px 1px 1px rgba(0, 0, 0, .2);
position: absolute;
left: 0;
}
<div id="box"></div>
<canvas id='canvas' width=600 height=400></canvas>
<script>
var ctx = document.getElementById('canvas').getContext('2d');
var divx = 500;
var divtx = 0;
function animate() {
divx += (divtx - divx) / 20;
ctx.clearRect(0, 0, 600, 400);
ctx.fillRect(divx, 0, 100, 100);
window.requestAnimationFrame(animate);
}
animate();
</script>