Can you have multiple clipping regions in an HTML Canvas?

情到浓时终转凉″ 提交于 2020-01-09 23:46:15

问题


I have code that loads a bunch of images into hidden img elements and then a Javascript loop which places each image onto the canvas. However, I want to clip each image so that it is a circle when placed on the canvas.

My loop looks like this:

    $$('#avatars img').each(function(avatar) {
        var canvas = $('canvas');
        var context = canvas.getContext('2d');

        var x = Math.floor(Math.random() * canvas.width);
        var y = Math.floor(Math.random() * canvas.height);

        context.beginPath();
        context.arc(x+24, y+24, 20, 0, Math.PI * 2, 1);
        context.clip();

        context.strokeStyle = "black";

        context.drawImage(document.getElementById(avatar.id), x, y);

        context.stroke();
    });

Problem is, only the first image is drawn (or is visible).

If I remove the clipping logic:

    $$('#avatars img').each(function(avatar) {
        var canvas = $('canvas');
        var context = canvas.getContext('2d');

        var x = Math.floor(Math.random() * canvas.width);
        var y = Math.floor(Math.random() * canvas.height);

        context.drawImage(document.getElementById(avatar.id), x, y);
    });

Then all my images are drawn.

Is there a way to get each image individually clipped?

I tried resetting the clipping area to be the entire canvas between images but that didn't work.


回答1:


You should try to save current context state and then restore it:

        canvas = document.getElementById("area");
        context = canvas.getContext('2d');

        $("#avatars img").each(function(avatar) {

            var x = Math.floor(Math.random() * canvas.width);
            var y = Math.floor(Math.random() * canvas.height);

            context.save();//push current state into canvas
            context.beginPath();
            context.arc(x + 24, y + 24, 20, 0, Math.PI * 2, 1);
            context.clip();

            context.strokeStyle = "black";

            //draw image this way
            var img = new Image();
            img.src = avatar.src;
            img.onload = function() {
                context.drawImage(img, x, y);
            };

            context.stroke();
            context.restore();//restore context to the state

        });

I think when you call drawImage method,you also need to set image parameter as an Image class by adding a source line which is already in your avatar.src parameter.

You should check the reference document for Canvas State



来源:https://stackoverflow.com/questions/2551411/can-you-have-multiple-clipping-regions-in-an-html-canvas

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!