如何只显示画布的特定区域?

时间:2016-01-22 05:34:24

标签: javascript html5 canvas

我有什么:

让我们拍摄500px宽的画布:

                     +---------+
 +-------------------------------------------------+
 |                   |         |                   |
 |    X      XXXX    | XXXXXX  |   X   X    XXXXX  |
 |  XXX     X   XX   |   XXXX  | XX    X    X      |
 |    X       XXXX   |  XXXX   | XX XXXXXX  XXXX   |
 |    X     XXX      |     XX  |       X       XXX |
 |  XXXX    XXXXXXX  | XXXXXX  |       X    X   XX |
 |                   |         |            XXXXX  |
 +-------------------------------------------------+
x=0                  +---------+                   x=500
                     x=200     x=300

画布的不同部分有不同的绘图。

我想要的是什么:

我想只显示1/5的画布。假设在上图中,x = 200到300应该是可见的。

最终我想改变可见区域并在画布上产生左右滑动效果。

感谢任何帮助和领导:)

1 个答案:

答案 0 :(得分:1)

在画布上绘图很快,就像真的很快。

此外,您可以在另一个上绘制画布,并使用drawImage()方法直接进行矩形剪切操作。

因此,IMO的最佳解决方案是首先绘制完整的画布作为缓冲区(不要将其附加到文档中),然后仅在文档中绘制想要的部分。

这是一个如何实现它的粗略示例。



// first do your full drawings on a buffer canvas
var buffer = document.createElement('canvas');
var bCtx  = buffer.getContext('2d');
buffer.width = 1000;
buffer.height = 200;
bCtx.font = '30px sans-serif';
bCtx.textBaseline = 'middle';
bCtx.textAlign = 'center';

// define your slides
var slideWidth = 100;
var slides = 10;

for(var i=0;i<slides; i++){
  bCtx.fillText(i, i*slideWidth+50, buffer.height/2);
  bCtx.fillRect((i*slideWidth)-1, 0, 1 , buffer.height);
  }
// now our full canvas is drawn

// get the inDoc's context
var ctx = inDoc.getContext('2d');

// the speed at which our slides will move
var offset = 4;

// a function to initialize our animation
var animate = function(currentSlide,to){
  var direction = currentSlide<to ? 1:-1;
  var from = currentPos;
  // an inside func to use raf
  var anim = function(){
    // that was the last call, return
    if(from===to){
      return;
      }
    // clear our inDoc canvas    
    ctx.clearRect(0,0,inDoc.width, inDoc.height);
    // increment our position
    from += offset*direction;
    currentPos = from;
    // draw our buffer canvas onto the inDoc one
    // drawImage(source, sx, sy, sw, sh, dx, dy, dw, dh)
    ctx.drawImage(buffer, from, 0, slideWidth, buffer.height, 0,0,slideWidth, buffer.height);
    // do it again in 30th of a second
    requestAnimationFrame(anim);
    };
  // call the inner animation
  anim();
  }

// our actual slide
var currentSlide = 0;
// our actual real position
var currentPos = 0;
next.onclick = function(){
   // we'll move by one slideWidth
   currentSlide += slideWidth;
   // we still have room
   if(currentSlide <= slides*slideWidth){
     animate(currentSlide-slideWidth, currentSlide);
     }
   // we reached the last slide
   if(currentSlide === (slides*slideWidth)-slideWidth){
     this.setAttribute('disabled',true);
     }
   // enable the "previous" button
   prev.removeAttribute('disabled');
  };

prev.onclick = function(){
   // we'll move by one slideWidth backward
   currentSlide -= slideWidth;
   // we still have room
   if(currentSlide >= 0){
     animate(currentSlide+slideWidth, currentSlide);
     }
   // we reached the first slide
   if(currentSlide===0){
     this.setAttribute('disabled', true);
     }
   // enable the "next" button
   next.removeAttribute('disabled');
  };
// draw the first slide
ctx.drawImage(buffer, 0, 0, slideWidth, buffer.height, 0,0,slideWidth, buffer.height);

check.onchange = function(){
  this.checked ? document.body.appendChild(buffer) : document.body.removeChild(buffer);
  };
&#13;
body{background: skyblue;}button{ vertical-align : top;}
canvas{background: white}
&#13;
<button id="prev" disabled>previous</button><canvas id="inDoc" width ="100" height="200"></canvas><button id="next">next</button>
<label for="check">show the buffer canvas</label><input name="check" id="check" type="checkbox"/>
&#13;
&#13;
&#13;