我想在html5画布内滚动(移动每个像素), 类似于actionscript-3 BitmapData.scroll(x,y);
答案 0 :(得分:2)
将画布的快照拍摄到另一个内存中画布:
var tempCanvas=document.createElement('canvas');
var tempCtx=tempCanvas.getContext('2d');
// canvas is a reference to your existing canvas
tempCanvas.width=canvas.width;
tempCanvas.height=canvas.height;
tempCtx.drawImage(canvas,0,0);
创建代表累积的scrollX和scrollY的变量:
var accumScrolledX=0;
var accumScrolledY=0;
然后您的BitmapData.scroll(x,y)
变为:
function scroll(scrollByX,scrollByY){
// increment the accumulated scrolling by the new scrolling
accumScrolledX+=scrollByX;
accumScrolledY+=scrollByY;
// clear the canvas
ctx.clearRect(0,0,cw,ch);
// redraw the canvas using the tempCanvas with the new accumulated scrolling
ctx.drawImage(tempCanvas,accumScrolledX,accumScrolledtY);
}
示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var tempCanvas=document.createElement('canvas');
var tempCtx=tempCanvas.getContext('2d');
var offsetX=0;
var offsetY=50;
var directionX=3;
tempCanvas.width=canvas.width;
tempCanvas.height=canvas.height;
var text="Scroll this text...";
ctx.font='18px verdana';
ctx.fillText(text,0,50);
var textWidth=ctx.measureText(text).width;
takeCanvasSnapshot();
animate();
function takeCanvasSnapshot(){
tempCtx.drawImage(canvas,0,0);
}
function scroll(scrollByX,scrollByY){
offsetX+=scrollByX;
offsetY+=scrollByY;
if(offsetX<0 || offsetX>cw-textWidth){directionX*=-1;offsetX+=directionX;}
ctx.drawImage(tempCanvas,offsetX,offsetY);
}
var lastTime;
function animate(time){
// timer stuff
requestAnimationFrame(animate);
if(!lastTime){lastTime=time;}
if(time-lastTime<20){return;}
lastTime=time;
// clear canvas and redraw with scroll
ctx.clearRect(0,0,cw,ch);
scroll(directionX,0);
}
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>
答案 1 :(得分:1)
只需将画布重绘为自身。浏览器将在内部为您完成所有复制,这比通过JS手动完成更快,但要使其工作的技巧是确保背景是不透明的(如果需要alpha,则需要将内容复制到临时画布。)
然后清除间隙或重绘/填充它。
您可以将其用作:
// BitmapData.scroll(x, y);
-> scroll(ctx, x, y);
这里的核心功能是一种实现此功能的方法的功能示例:
function scroll(ctx, x, y) {
var ax = Math.abs(x), // these makes our calculations
ay = Math.abs(y); // easier to do below...
ctx.fillStyle = '#fff'; // fill background for the left gap
if (x < 0) { // moving to left?
ctx.drawImage(ctx.canvas, ax, 0, w - ax, h, 0, 0, w - ax, h);
ctx.fillRect(w-ax, 0, ax, h); // or redraw something
}
else if (x > 0) { // moving right?
ctx.drawImage(ctx.canvas, 0, 0, w - ax, h, ax, 0, w - ax, h);
ctx.fillRect(0, 0, ax, h);
}
if (y < 0) { // moving up?
ctx.drawImage(ctx.canvas, 0, ay, w, h - ay, 0, 0, w, h - ay);
ctx.fillRect(0, h - ay, 0, w, ay); // or redraw something
}
else if (y > 0) { // moving down?
ctx.drawImage(ctx.canvas, 0, 0, w, h - ay, 0, ay, w, h - ay);
ctx.fillRect(0, 0, w, ay);
}
}
drawImage()将图像源作为第一个参数(图像,视频或画布)。接下来的四个描述了我们想要复制的区域。由于我们要移动像素,因此我们不需要将它们包含在区域中,因此我们会减去它们以提高性能。
最后四个描述了目的地区域,这将是我们的新位置。保持与源区域相同的尺寸或图形将被拉伸是很重要的。
工作演示如下:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
w = canvas.width,
h = canvas.height,
scrollX = -2,
scrollY = 1;
// make background solid to start with:
ctx.fillStyle = '#fff';
ctx.fillRect(0, 0, w, h);
// scrolls x in either direction (adopt same approach for y)
function scroll(ctx, x, y) {
var ax = Math.abs(x),
ay = Math.abs(y);
ctx.fillStyle = '#fff'; // fill background for gap
if (x < 0) { // moving to left?
ctx.drawImage(ctx.canvas, ax, 0, w - ax, h, 0, 0, w - ax, h);
ctx.fillRect(w-ax, 0, ax, h); // or redraw something
}
else if (x > 0) { // moving right?
ctx.drawImage(ctx.canvas, 0, 0, w - ax, h, ax, 0, w - ax, h);
ctx.fillRect(0, 0, ax, h);
}
if (y < 0) { // moving up?
ctx.drawImage(ctx.canvas, 0, ay, w, h - ay, 0, 0, w, h - ay);
ctx.fillRect(0, h - ay, 0, w, ay); // or redraw something
}
else if (y > 0) { // moving down?
ctx.drawImage(ctx.canvas, 0, 0, w, h - ay, 0, ay, w, h - ay);
ctx.fillRect(0, 0, w, ay);
}
}
// ------ demo loop ----------------------------------------------------------
(function loop() {
// draw some random points
ctx.fillStyle = '#007';
for(var i = 0; i < 16; i++) ctx.fillRect(w-2, h * Math.random(), 2, 2);
// use the scroll method
scroll(ctx, scrollX, scrollY);
requestAnimationFrame(loop);
})();
<canvas id=canvas width=500 height=180></canvas>