Подтвердить что ты не робот

Как заполнить "противоположную" форму на холсте?

Скажем, у меня есть круг (дуга) на холсте HTML5. Я могу просто заполнить его следующим образом:

ctx.arc(100, 100, 50, 0, 2 * Math.PI);
ctx.fill();

Это работает. Однако как можно заполнить противоположную область? Теперь он белый с черным кругом, но я хотел бы, чтобы он был по линии следующего изображения (на котором белый цвет фона, а черный - цвет заполнения):

opposite area

Я знаю, что могу просто использовать черный фон и нарисовать белый круг, но фон может быть любым (все вещи были нарисованы там раньше, поэтому просто менять цвета невозможно).

Другое дело, что не полный холст должен быть заполнен, а квадрат с отмененным кругом.

Я думал о globalCompositeOperation, но, похоже, он не соответствует моим потребностям, так как никто из них не действует в соответствии с тем, что мне нужно.

Итак, как я могу выполнить заполнение "противоположной" области, как в примере изображения?

4b9b3361

Ответ 1

Вы можете сделать это, используя другой холст в качестве маски:

// This is the canvas where you want to draw
var canvas = document.getElementById('your-canvas');
var ctx = canvas.getContext('2d');

// I'll use a skyblue background that covers everything
// Just to demonstrate
ctx.fillStyle = "skyblue";
ctx.fillRect(0, 0, canvas.width, canvas.height);

// Create a canvas that we will use as a mask
var maskCanvas = document.createElement('canvas');
// Ensure same dimensions
maskCanvas.width = canvas.width;
maskCanvas.height = canvas.height;
var maskCtx = maskCanvas.getContext('2d');

// This color is the one of the filled shape
maskCtx.fillStyle = "black";
// Fill the mask
maskCtx.fillRect(0, 0, maskCanvas.width, maskCanvas.height);
// Set xor operation
maskCtx.globalCompositeOperation = 'xor';
// Draw the shape you want to take out
maskCtx.arc(30, 30, 10, 0, 2 * Math.PI);
maskCtx.fill();

// Draw mask on the image, and done !
ctx.drawImage(maskCanvas, 0, 0);
<canvas id="your-canvas">

Ответ 2

Нарисуйте черную фигуру в OP, то есть нарисуйте прямоугольник с кругом, вырезанным из середины.

Первый вызов beginPath(); затем нарисуйте круг по часовой стрелке; затем нарисуйте прямоугольник против часовой стрелки (или наоборот); и, наконец, fill().

var ctx = $('#cv').get(0).getContext('2d');

ctx.fillStyle = "grey";
ctx.beginPath();
ctx.arc(200, 200, 100, 0, 2 * Math.PI);
ctx.rect(400, 0, -400, 400);
ctx.fill();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<canvas width="400" height="400" id="cv"></canvas>

Ответ 3

Как обычно это делается, это "область отсечения", где вы создаете маску области, для которой применяются операции рисования. У холста HTML5 есть возможность сделать обтравочную маску, которая является самой кружкой...

http://www.html5canvastutorials.com/tutorials/html5-canvas-clipping-region-tutorial/

... но ему не хватает операции subtract(), что в Google Gears Canvas, которую я заметил, и они утверждали, что это "из HTML5"... но, по-видимому, это не так.

Кто-то ответил, как инвертировать клип() здесь, но он включает в себя заставку canvas:

Резервное действие холста "Clip" ?

Надеюсь, у кого-то будет лучшее предложение.: -/

Ответ 4

Использование функции XOR на маске холста работает только с непрозрачными заливами (т.е. несовместимо с globalAlpha). Один из способов использования этой функции - использовать функцию .clip() и заполнить обрезанный участок тем, что у вас было в фоновом режиме. Затем вы можете наложить обрезанный регион поверх исходного холста, на котором вы выполнили все, что вам нужно.