如何滚动html5画布内的像素?

时间:2014-11-11 10:20:18

标签: actionscript-3 html5-canvas

我想在html5画布内滚动(移动每个像素), 类似于actionscript-3 BitmapData.scroll(x,y);

2 个答案:

答案 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>