【发布时间】:2020-04-02 23:47:06
【问题描述】:
如果你使用它,它可以正常工作(在画布上使用 img):
ctx_bg.drawImage($("#image_tile")[0], positions[i].x, positions[i].y);
如果你使用这个,它会在 3 秒内让浏览器崩溃(使用 canvas on canvas):
ctx_bg.drawImage($(".canvas_tile")[0], positions[i].x, positions[i].y);
以上 2 行是下面 2 个展示之间的唯一区别。在 Android 上测试(三星 S10、Chrome 80.0.3987.149)。
此外,当画布高度较小(1-2 个屏幕高度)时,画布上的画布也能正常工作。此外,它在桌面 chrome 上也能正常工作!
这是移动浏览器的错误还是可以修复?
编辑: 由于您无法在 stackoverflow mobile view 上运行以下代码,因此这里是在移动设备上查看的快速链接:
- http://kraater.ee/stackoverflow/image_on_canvas.html
- http://kraater.ee/stackoverflow/canvas_on_canvas.html
这在移动设备上使用了第二个 CANVAS 粒子和崩溃:
$(document).ready(function() {
ctx_bg = $(".bg_canvas")[0].getContext("2d");
ctx_child = $(".canvas_tile")[0].getContext("2d");
ctx_child.beginPath();
ctx_child.arc(20, 20, 5, 0, 1.5 * Math.PI);
ctx_child.stroke();
innerWidth = $("body").innerWidth();
innerHeight = $("body").innerHeight()*5;
numberOfElements = 222;
positions = [];
angle = 0;
$(".bg_canvas")[0].width = innerWidth;
$(".bg_canvas")[0].height = innerHeight;
for (var i=0; i<numberOfElements; i++) {
positions.push({x: Math.random()*innerWidth, y: Math.random()*innerHeight});
};
function animateCircles() {
bgAnimation = requestAnimationFrame(animateCircles)
ctx_bg.clearRect(0, 0, innerWidth, innerHeight);
for (var i = 0; i < numberOfElements; i++){
positions[i].y+=3;
if (positions[i].y > innerHeight) {
positions[i].y = 0;
}
ctx_bg.drawImage($(".canvas_tile")[0], positions[i].x, positions[i].y);
// ctx_bg.drawImage($("#image_tile")[0], positions[i].x, positions[i].y);
}
}
animateCircles()
})
body, html {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
#image_tile, .canvas_tile {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<title>KRAATER</title>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
</head>
<body>
<img id="image_tile" src="https://www.gravatar.com/avatar/435af02114568dbaf00005b28c3ef592?s=48&d=identicon&r=PG">
<canvas class="canvas_tile"></canvas>
<canvas class="bg_canvas"></canvas>
</body>
</html>
这使用了 2nd BITMAP 粒子并在移动设备上运行:
$(document).ready(function() {
ctx_bg = $(".bg_canvas")[0].getContext("2d");
ctx_child = $(".canvas_tile")[0].getContext("2d");
ctx_child.beginPath();
ctx_child.arc(20, 20, 5, 0, 1.5 * Math.PI);
ctx_child.stroke();
innerWidth = $("body").innerWidth();
innerHeight = $("body").innerHeight()*5;
numberOfElements = 222;
positions = [];
angle = 0;
$(".bg_canvas")[0].width = innerWidth;
$(".bg_canvas")[0].height = innerHeight;
for (var i=0; i<numberOfElements; i++) {
positions.push({x: Math.random()*innerWidth, y: Math.random()*innerHeight});
};
function animateCircles() {
bgAnimation = requestAnimationFrame(animateCircles)
ctx_bg.clearRect(0, 0, innerWidth, innerHeight);
for (var i = 0; i < numberOfElements; i++){
positions[i].y+=3;
if (positions[i].y > innerHeight) {
positions[i].y = 0;
}
// ctx_bg.drawImage($(".canvas_tile")[0], positions[i].x, positions[i].y);
ctx_bg.drawImage($("#image_tile")[0], positions[i].x, positions[i].y);
}
}
animateCircles()
})
body, html {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
}
#image_tile, .canvas_tile {
display: none;
}
<!DOCTYPE html>
<html>
<head>
<title>KRAATER</title>
<meta charset="UTF-8">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
</head>
<body>
<img id="image_tile" src="https://www.gravatar.com/avatar/435af02114568dbaf00005b28c3ef592?s=48&d=identicon&r=PG">
<canvas class="canvas_tile"></canvas>
<canvas class="bg_canvas"></canvas>
</body>
</html>
【问题讨论】:
-
是的,这是一个错误。浏览器永远不应该崩溃。现在,您显然已经知道至少一种方法:使用
。你还想从 stackoverflow 社区获得什么?如果该错误不存在,请报告该错误。 this one 被标记为已修复,但它们的解决方法很可能不适合移动设备。也许你可以就这个问题发表评论。
-
另外,不相关,但实际上将
innerWidth = foo设置window.innerWidth到foo,弄乱了页面上依赖此值的任何其他脚本成为它应该的样子。此外,存储您的 DOM 元素,而不是在每次迭代时创建大量的 jQuery 对象。 -
@Kaiido,请解释一下,我如何在每次迭代中创建 jQuery 对象?
-
ctx_bg.drawImage($(".canvas_tile")[0]...这会在每次迭代时创建一个新的 jQuery 对象。只需在任何循环之外存储一次const source = $(.canvas_tile")[0],然后调用ctx_bg.drawImage(source... -
您最好能够使用可测试的源来备份此类声明,只需使用 jquery 执行 getelement... 不会创建新对象
标签: canvas html5-canvas mobile-chrome