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>
--------小尾巴
________一个人欣赏-最后一朵颜色的消逝-忠诚于我的是·一颗叫做野的心.决不受人奴役.怒火中生的那一刻·终将结束...