Der*_*xie 5 javascript animation scroll canvas
我想要一个带有如下图像序列的基于滚动的动画:
http://www.clearmotion.com/technology
这个动画看起来很流畅
我试过这个小提琴
var images = new Array();
var currentLocation = 0;
var totalImages = 200;
for (var i = 1; i < totalImages; i++) {
var img = new Image;
var slug = '000' + i;
img.src = 'https://s3.amazonaws.com/clearmotion/hero/high-min/frame'+ slug.slice(-3) +'-low.jpg'
images.push(img);
}
var c = document.getElementById("background");
var ctx = c.getContext("2d");
var mouseWheel = function () {
window.addEventListener('mousewheel', function (e) {
e.preventDefault(); // No scroll
// The following equation will return either a 1 for scroll down
// or -1 for a scroll up
var delta = Math.max(-1, Math.min(1, e.wheelDelta));
// This code mostly keeps us from going too far in either direction
if (delta == -1) currentLocation += 1;
if (delta == 1) currentLocation -= 1;
if (currentLocation < 0) currentLocation = 0;
if (currentLocation >= (totalImages - 1)) currentLocation = (totalImages - 1);
console.log("Current location " + currentLocation);
// See below for the details of this function
setImage(currentLocation);
});
}
var setImage = function (newLocation) {
// drawImage takes 5 arguments: image, x, y, width, height
ctx.fillRect(0, 0, c.width, c.height);
ctx.drawImage(images[newLocation], 0, 0, 1000, 1000);
}
images[0].onload = function () {
ctx.fillRect(0, 0, c.width, c.height);
ctx.drawImage(images[currentLocation], 0, 0, 1000, 1000);
mouseWheel();
};Run Code Online (Sandbox Code Playgroud)
<canvas id="background" width="1000" height="1000"></canvas>Run Code Online (Sandbox Code Playgroud)
`
然而,效果看起来很糟糕。
当我的鼠标停止滚动时,动画立即停止
我怎样才能让它更平滑?
发生这种情况是因为滚轮事件可能以非常高的速率触发,高于屏幕刷新率。
这意味着对于绘制到屏幕上的每一帧,您实际上在画布上绘制了几个帧。然后,浏览器在处理所有这些请求时会遇到一些问题,并最终造成延迟。
为了避免这种情况,您可以限制您的事件:有条件地执行您的回调,仅当它已经超过某个预定义时间时才尚未触发。
在处理视觉动画时,这种节流时间的良好基础是屏幕刷新。我们有一个计时方法可以做到这一点:requestAnimationFrame。
var images = new Array();
var currentLocation = 0;
var totalImages = 200;
for (var i = 1; i < totalImages; i++) {
var img = new Image;
var slug = '000' + i;
img.src = 'https://s3.amazonaws.com/clearmotion/hero/high-min/frame' + slug.slice(-3) + '-low.jpg'
images.push(img);
}
var c = document.getElementById("background");
var ctx = c.getContext("2d");
var mouseWheel = function() {
var evt = null; // avoids a new 'draw' function generation
window.addEventListener('wheel', function(e) {
e.preventDefault(); // No scroll
if (!evt) { // if set, we already are waiting
evt = e; // store our event
requestAnimationFrame(draw); // wait next screen refresh to fire
}
});
// the throttled funtion
function draw() {
var e = evt;
var delta = Math.max(-1, Math.min(1, e.deltaY));
if (delta == -1) currentLocation += 1;
if (delta == 1) currentLocation -= 1;
if (currentLocation < 0) currentLocation = 0;
if (currentLocation >= (totalImages - 1)) currentLocation = (totalImages - 1);
setImage(currentLocation);
evt = null; // so the throttler knows we can kick again
}
}
var setImage = function(newLocation) {
if (!images[newLocation]) return;
ctx.fillRect(0, 0, c.width, c.height);
ctx.drawImage(images[newLocation], 0, 0, 1000, 1000);
}
images[0].onload = function() {
ctx.fillRect(0, 0, c.width, c.height);
ctx.drawImage(images[currentLocation], 0, 0, 1000, 1000);
mouseWheel();
};Run Code Online (Sandbox Code Playgroud)
<canvas id="background" width="1000" height="1000"></canvas>Run Code Online (Sandbox Code Playgroud)
现在,由于我们阻止了整个事件处理,因此您的动画也可能看起来更慢(即使更流畅)。为了避免这种情况,您仍然可以尽可能快地更新变量,并且仅限制实际绘图。
var images = new Array();
var currentLocation = 0;
var totalImages = 200;
for (var i = 1; i < totalImages; i++) {
var img = new Image;
var slug = '000' + i;
img.src = 'https://s3.amazonaws.com/clearmotion/hero/high-min/frame' + slug.slice(-3) + '-low.jpg'
images.push(img);
}
var c = document.getElementById("background");
var ctx = c.getContext("2d");
var mouseWheel = function() {
var newLocation = null;
window.addEventListener('wheel', function(e) {
e.preventDefault(); // No scroll
// update our variable at high frequency
var delta = Math.max(-1, Math.min(1, e.deltaY));
if (delta == -1) currentLocation += 1;
if (delta == 1) currentLocation -= 1;
if (currentLocation < 0) currentLocation = 0;
if (currentLocation >= (totalImages - 1)) currentLocation = (totalImages - 1);
if (newLocation === null) { // if set, we already are waiting to draw
requestAnimationFrame(setImage);
}
newLocation = currentLocation;
});
function setImage() {
if (images[newLocation]) {
ctx.fillRect(0, 0, c.width, c.height);
ctx.drawImage(images[newLocation], 0, 0, 1000, 1000);
}
newLocation = null; // so the throttler knows we can draw again
}
}
images[0].onload = function() {
ctx.fillRect(0, 0, c.width, c.height);
ctx.drawImage(images[currentLocation], 0, 0, 1000, 1000);
mouseWheel();
};Run Code Online (Sandbox Code Playgroud)
<canvas id="background" width="1000" height="1000"></canvas>Run Code Online (Sandbox Code Playgroud)
请注意,我确实更新了您的活动以使用唯一符合规范的活动:WheelEvent。
另请注意,您可能最好加载视频而不是加载那么多静态图像。或者甚至将原始 3D 动画转换为 webGL。
| 归档时间: |
|
| 查看次数: |
2151 次 |
| 最近记录: |