javascript - Canvas 不在移动版 chrome 上绘制,但会在 safari 上绘制

标签 javascript jquery css html canvas

我有以下脚本,它获取图像并根据图像背景颜色绘制 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/

相关文章:

jquery - 切换导航侧边栏(CSS 和 JQuery)

javascript - animate.css 的滚动效果

php - ExtJS 和自动加载 URL

javascript - 使用 mongoose find 从[对象数组]中查询

javascript - 轻量级 zxcvbn 替代方案?

javascript - 将很长的变量从 PHP 传递到 Javascript

javascript - jsTree中如何加载子节点

javascript - 使用 jQuery 将鼠标悬停在相邻文本上时更改图标的颜色

javascript - 从 map 中删除标记(Google map API v3)

javascript - 可拖动的 CSS 切换开关