画布不是在移动镀铬上绘制,而是在野生动物园上绘制

时间:2014-01-27 09:59:51

标签: javascript jquery css html5 canvas

我有以下脚本拍摄图像并根据图像背景颜色绘制画布(图像是使用php从数据库加载的),我要求它具有响应性,它正在进行移动游猎,但不是铬:

在某些分辨率下,画布将从波形回退到正方形,并且每当窗口宽度发生变化时也会调整大小(为移动设备旋转添加此画面)。

我必须注意,这个脚本适用于我无法从图像中获取颜色的页面上的移动镶边,我正在静态设置该颜色,这让我觉得这是一个问题,因为图像不会绘制画布尚未装载。

<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>

1 个答案:

答案 0 :(得分:0)

问题

这里有一些问题:

  • 您将window.onload放在两个函数
  • 您没有等待图片加载
  • 您将获得与画布上的绘制顺序相关的竞争条件

解决方案

首先,将所有代码放在window.onload内:

window.onload = function() {

    function drawCatWave() {
        ...
    }

    function drawCatSquare() {
        ...
    }

}

当DOM中存在的DOM和图像已加载时,将调用window.onload。但是,当您在之后动态创建代码中的图像元素时,它已被调用,它将不适用。您必须手动处理图像加载(见下文)。

使用window.onload的另一种方法是将脚本放在正文关闭标记之前的页面底部。

其次,如上所述,您需要等待图像加载才能继续。这是因为图像加载是异步的,因此当浏览器连接并下载图像数据时,您的代码将继续执行其他指令。如果未及时加载图像,drawImage()方法将中止,结果为“空白”画布。

通常,您这样做是为了处理图像加载:

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 ...
    }
}

现在,如果你想要绘制到同一个画布上,你需要链接调用,或者你可以根据首先加载的图像进入竞争状态。

要处理这种情况,请使用回调参数扩展函数:

    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()。您当然可以将回调函数替换为您要调用的任何其他函数。

希望这有帮助。