HTML5_canvas_图片加载_双缓冲_跳帧闪烁问题

canvas 图片加载

pen.drawImage(ele, showX, showY, imgWidth, imgHeight);       

ele    将 img 元素 加载到画布上

 

  • 步骤

1. 创建一个 <img> 对象

var imgNode = new Image();

imgNode.src = "./img/bird.png";

 

2. 等待图片加载完成,再进行下一步操作

imgNode.onload = function(){

3. 图片显示到画布上

pen.drawImage(imgNode, 0, 0, 100, 100);

};

 

跳帧闪烁问题

  • 闪烁的原因:
    • 清空了画布,然后加载图片,再等图片加载完,最后画下一帧。
    • 这个空白延迟,主要是因为等待图片加载完成时间太久
  • 解法1: 
    • 在加载图片之前,不清空上一帧图像
    • 加载完成后,再清空画布,最后画下一帧。
    • <!DOCTYPE html>
      <html>
          <head>
              <meta charset="UTF-8">
              <title>帧闪烁解决</title>
              
              <style type="text/css">
                  * {
                      margin: 0;
                      padding: 0;
                  }
                  
                  body{
                      text-align: center;
                  }
                  
                  #myCanvas{
                      border: 1px solid ;
                  }
              </style>
          </head>
          
          <body>
              <canvas id="myCanvas" width="800" height="400"></canvas>
              
              
              
              <!-- javascript 代码 -->
              <script type="text/javascript">
                  window.onload = function () {
                      var myCanvas = document.getElementById('myCanvas');
                      
                      var painting = myCanvas.getContext('2d');
                      
                      var num = 0;
                      var speed = 0;
                      setInterval(function(){
                          speed += 20;
                          if(speed > myCanvas.width){
                              speed = -150
                              //                speed = 0
                          };
                          
                          num++;
                          if(num > 8){
                              num = 1;
                          };
                          
                          painting.beginPath();
                          
                          //1.img对象
                          var imgNode = new Image();
                          
                          //2.img对象 设置 src
                          imgNode.src = 'img/q_r' + num + '.jpg';
                          
                          //3.等图片加载完成后再去设置图片显示
                          imgNode.onload = function () {
                              //4.图片显示在画布上
                              painting.clearRect(0, 0, myCanvas.width, myCanvas.height)
                              painting.drawImage(imgNode, speed, 150, 150, 90);
                          };
                      }, 340);
                  };
              </script>
          </body>
      </html>

 

飞鸟 案例(双缓冲,解决跳帧闪烁问题

 

  • <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8" />
            <title>canvas 双缓冲案例</title>
    
            <style type="text/css">
                body {
                    width: 100%;
                    color: #000;
                    background: #96b377;
                    font: 14px Helvetica, Arial, sans-serif;
                }
                
                .wrap {
                    display: flex;
                    flex-direction: column;
                    justify-content: center;
                    align-items: center;
                }
            </style>
        </head>
        
        <body>
            
            
            <div id="box" class="wrap">
            </div>
            
            
            
            
            <!-- javascript 代码 -->
            <script type="text/javascript">
                //                 创建 画布的width  画布的height  背景颜色 父元素
                function createCanvasTo(canvasWidth, canvasHeight, bgColor, parentObj){
                    var myCanvas = document.createElement("canvas");
                    myCanvas.width = canvasWidth;
                    myCanvas.height = canvasHeight;
                    myCanvas.innerText = " 您的浏览器不支持 canvas,建议更新或者更换浏览器。";
                    if(bgColor){
                        myCanvas.style.backgroundColor = bgColor;
                    };
                    if(parentObj){
                        parentObj.appendChild(myCanvas);
                    };
                    
                    return myCanvas;
                };
                
                var box = document.getElementById("box");
                
                var topCanvas = createCanvasTo(600, 83, "#fff", box);
                movingPic(topCanvas, "./img/q_r", "jpg", -150, 0, 150, 83);
                
                var bottomCanvas = createCanvasTo(600, 300, "#fff", box);
                movingPic(bottomCanvas, "./img/walking", "png", -130, 27, 130, 246);
                
                
                //                 画布对象 图片路径 图片类型 起始x 起始y 图片width 图片height
                function movingPic(theCanvas, imgPath, imgType, posX, posY, imgWidth, imgHeight){
                    var cacheCanvas = document.createElement("canvas");
                    cacheCanvas.width = theCanvas.width;
                    cacheCanvas.height = theCanvas.height;
                    var cachePen = cacheCanvas.getContext("2d");
                    
                    var num = 1;
                    var pos = 0;
                    window.setInterval(function(){
                        pen = theCanvas.getContext("2d");    // 坑1: 一定要放在循环里面
                        pen.clearRect(0, 0, theCanvas.width, theCanvas.height);
                        
                        // 图形位移变换
                        num++;
                        if(num > 8){
                            num = 1;
                        };
                        
                        pos += 15;
                        if(posX+pos > theCanvas.width){
                            pos = -130;
                        };
                        
                        // 双缓冲绘制    先画到临时 canvas
                        cachePen.save();
                        cachePen.beginPath();
                        var imgObj = new Image();
                        imgObj.src = imgPath+num+"."+imgType;
                        imgObj.onload = function(){
                            cachePen.drawImage(imgObj, posX+pos, posY, imgWidth,imgHeight);
                        };
                        cachePen.restore();
                        
                        // 再转到正式 canvas
                        pen.save();
                        pen.drawImage(cacheCanvas, 0, 0, cacheCanvas.width, cacheCanvas.height);
                        pen.restore();
                        
                        // 坑2: 一定要在 取走缓冲内容后 再清除缓冲
                        cachePen.clearRect(0, 0, cacheCanvas.width, cacheCanvas.height);
                    }, 100);
                };
            </script>
        </body>
    </html>

 

posted @ 2018-11-21 11:45  耶梦加德  阅读(1754)  评论(0编辑  收藏  举报