我有以下脚本,它获取图像并根据图像背景颜色绘制 Canvas (图像是使用 php 从数据库加载的),我要求它能够响应并且它正在移动 safari 但不是 Chrome :
在某些分辨率下, Canvas 将从波形回退到正方形,并且在窗口宽度更改时也会调整大小(为移动设备旋转而添加)。
我必须注意,此脚本适用于我无法从图像中获取颜色的页面上的移动 chrome,并且我正在静态设置该颜色,这让我认为这是 Canvas 由于图像而无法绘制的问题尚未加载。
<script>
function drawCatWave () {
window.onload = function () {
var catImg = new Image();
catImg.src = "/product_images/<?php echo $row_category['logo_colour']; ?>";
var context;
context = document.getElementById('cat-image').getContext('2d');
context.drawImage(catImg, 20, 20, 130, 100);
pixData = (context.getImageData(20, 20, 1, 1).data);
rgb1 = pixData[0].toString();
rgb2 = pixData[1].toString();
rgb3 = pixData[2].toString();
rgb4 = pixData[3].toString();
var rgbString = rgb1 + "," + rgb2 + "," + rgb3 + "," + rgb4;
var rgb = "rgba(" + rgbString + ")";
$('.cat-prod-box h2').css("color", rgb);
console.log(rgb1, rgb2, rgb3);
canvas = document.getElementById("canvas");
var parent = document.getElementById("cat-banner-wave");
ctx = canvas.getContext("2d")
canvas.width = parent.offsetWidth;
canvas.height = parent.offsetHeight;
var actWidth = canvas.width;
var actHeight = canvas.height;
canvas.height = 380;
ctx.lineWidth = 6;
ctx.strokeStyle = "rgba(" + rgbString + ")";
ctx.beginPath();
ctx.moveTo(0, 70);
ctx.bezierCurveTo((actWidth / 2), -200, (actWidth / 3), 445, actWidth, 100);
ctx.bezierCurveTo(actWidth, 333, actWidth, 333, actWidth, 333);
ctx.bezierCurveTo(0, 333, 0, 333, 0, 333);
ctx.closePath();
ctx.fillStyle = rgb;
ctx.fill();
ctx.stroke();
};
}
function drawCatSquare () {
window.onload = function () {
var catImg = new Image();
catImg.src = "/product_images/<?php echo $row_category['logo_colour']; ?>";
var context;
context = document.getElementById('cat-image').getContext('2d');
context.drawImage(catImg, 20, 20, 130, 100);
pixData = (context.getImageData(20, 20, 1, 1).data);
rgb1 = pixData[0].toString();
rgb2 = pixData[1].toString();
rgb3 = pixData[2].toString();
rgb4 = pixData[3].toString();
var rgbString = rgb1 + "," + rgb2 + "," + rgb3 + "," + rgb4;
var rgb = "rgba(" + rgbString + ")";
$('.cat-prod-box h2').css("color", rgb);
console.log(rgb1, rgb2, rgb3);
canvas = document.getElementById("canvas");
var parent = document.getElementById("cat-banner-wave");
ctx = canvas.getContext("2d")
canvas.width = parent.offsetWidth;
canvas.height = parent.offsetHeight;
var actWidth = canvas.width;
var actHeight = canvas.height;
canvas.height = 380;
ctx.lineWidth = 6;
ctx.strokeStyle = "rgba(" + rgbString + ")";
ctx.rect(0, 0, actWidth, actHeight);
ctx.fillStyle = rgb;
ctx.fill();
ctx.stroke();
};
}
$(document).ready(function () {
if($(this).width() > 500){
drawCatWave();
}else{
drawCatSquare();
}
});
$(window).resize(function () {
if ($(this).width() > 500) {
drawCatWave();
} else {
drawCatSquare();
}
});
</script>
最佳答案
问题
这里有几个问题:
- 您将 window.onload 放在您的两个函数中
- 您不是在等待图片加载
- 您将获得与 Canvas 上绘制顺序相关的竞争条件
解决方案
首先,将所有代码放在 window.onload
中:
window.onload = function() {
function drawCatWave() {
...
}
function drawCatSquare() {
...
}
}
当加载 DOM 和 DOM 中存在的图像时调用 window.onload。但是,当您在代码中动态创建一个图像元素时,它已被调用,它将不适用。您将必须手动处理图像加载(见下文)。
使用 window.onload 的替代方法是将脚本放在页面底部 body 关闭标记之前。
其次,如前所述,您需要等待图像加载完毕才能继续。这是因为图像加载是异步的,因此当浏览器连接并下载图像数据时,您的代码会继续执行其他指令。如果图像未及时加载,drawImage()
方法将中止,结果是一个“空白” Canvas 。
通常,您这样做是为了处理图像加载:
var image = new Image;
image.onload = callbackFunction;
image.src = '...';
所以在这种情况下:
function drawCatWave () {
var catImg = new Image();
catImg.onload = catDone;
catImg.src = "/product_images/<?php echo $row_category['logo_colour']; ?>";
function catDone() {
var context;
context = document.getElementById('cat-image').getContext('2d');
context.drawImage(catImg, 20, 20, 130, 100);
... etc ...
}
}
现在,如果您想在同一个 Canvas 上绘图,则需要链接调用,否则您可能会根据首先加载的图像进入竞争条件。
要处理这种情况,请使用回调参数扩展您的函数:
function drawCatWave(callback) {
...
}
function drawCatSquare(callback) {
...
}
然后让我们修改函数内的代码(只显示一个):
function drawCatWave (callback) {
var catImg = new Image();
catImg.onload = catDone;
catImg.src = "/product_images/<?php echo $row_category['logo_colour']; ?>";
function catDone() {
var context;
context = document.getElementById('cat-image').getContext('2d');
context.drawImage(catImg, 20, 20, 130, 100);
... etc ...
callback(); /// callback is invoked here
}
}
现在我们可以这样做:
drawCatWave(drawCatSquare);
这里首先调用 drawCatWave()
,当加载图像并绘制图像时调用 drawCatSquare()
。您当然可以将回调函数替换为您要调用的任何其他函数。
希望这对您有所帮助。
关于javascript - Canvas 不在移动版 chrome 上绘制,但会在 safari 上绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21377833/