Маскирование нескольких фигур с помощью globalCompositeOperation в canvas

Я пытаюсь нарисовать несколько прямоугольников, а затем замаскировать те, которые используют globalCompositeOperation 'source-in', который прекрасно работает, но проблема в том, что когда я заполняю свои прямоугольники, они исчезают... Если у меня только один вызов fill(), они все рисуют правильно но соблюдайте только последний примененный стиль заливки.

рассматриваемый код -

ctx.drawImage(self.glass.mask, 256, 375);
ctx.globalCompositeOperation = 'source-in';

ctx.rect(256, 635, 256, 75);
ctx.fillStyle = "#c65127";

ctx.rect(256, 605, 256, 25);
ctx.fillStyle = "#f5f4f0";

ctx.rect(256, 565, 256, 35);
ctx.fillStyle = "#c65127";

ctx.fill();

Код выше работает правильно. Но если я сделаю это, и снимаю маску -

ctx.beginPath();
ctx.rect(0, 256, 256, 75);
ctx.fillStyle = "#c65127";
ctx.fill();

ctx.beginPath();
ctx.rect(0, 226, 256, 25);
ctx.fillStyle = "#f5f4f0";
ctx.fill();

ctx.beginPath();
ctx.rect(0, 186, 256, 35);
ctx.fillStyle = "#222";
ctx.fill();

У меня есть каждый прямоугольник, и они уважают свои стили заливки. Проблема в том, что при включении маски они больше не видны.

Есть ли ограничение на количество элементов, которые вы можете иметь в globalCompositeOperation 'source-in', или я просто упускаю что-то простое?

вот несколько скрипок -

http://jsfiddle.net/ENtXs/ - работает как положено, но не соблюдает стили заливки.

http://jsfiddle.net/ENtXs/1/ - Снятие маски для отображения всех элементов

http://jsfiddle.net/ENtXs/2/ - Добавление элементов beginPath() и fill() учитывает стили заливки. (без маскировки)

http://jsfiddle.net/ENtXs/3/ - Добавление маски обратно (больше ничего не отображается)

http://jsfiddle.net/ENtXs/4/ - Только один прямоугольник с тем же кодом, что и #3, работает правильно.

1 ответ

Решение

РЕШИТЬ

Я полагаю, что проблема связана с globalCompositeOperation 'source-in'. В итоге я создал буферный холст, на котором я рисую свои фигуры, затем взял эти данные изображения и нарисовал их на своем основном холсте и применил к ним GCO.

вот рабочая скрипка - http://jsfiddle.net/ENtXs/5/

рассматриваемый код:

// Canvas and Buffers
var canvas = document.getElementById('canvas');
var buffer = document.getElementById('buffer');
var ctx = canvas.getContext('2d');
var buffer_ctx = buffer.getContext('2d');

// sizing
canvas.height = window.innerHeight;
canvas.width = window.innerWidth;

buffer.height = window.innerHeight;
buffer.width = window.innerWidth;

// mask image
var mask = new Image();
mask.onload = function () {
    drawBuffer();
}

mask.src = 'http://drewdahlman.com/experiments/masking/highball_mask.png';

function drawBuffer() {
    buffer_ctx.beginPath();
    buffer_ctx.rect(0, 256, 256, 75);
    buffer_ctx.fillStyle = "#c65127";
    buffer_ctx.fill();

    buffer_ctx.beginPath();
    buffer_ctx.rect(0, 226, 256, 25);
    buffer_ctx.fillStyle = "#f5f4f0";
    buffer_ctx.fill();

    buffer_ctx.beginPath();
    buffer_ctx.rect(0, 186, 256, 35);
    buffer_ctx.fillStyle = "#222";
    buffer_ctx.fill();

    var image = buffer.toDataURL("image/png");
    var img = new Image();
    img.onload = function(){
        buffer_ctx.clearRect(0,0,buffer.width,buffer.height);
        ctx.drawImage(mask,0,0);
        ctx.globalCompositeOperation = 'source-in';
        ctx.drawImage(img,0,0);
    }
    img.src = image;
}
Другие вопросы по тегам