HTML5 — обводка формы холста

#html #canvas #shapes

#HTML #холст #формы

Вопрос:

Я создал 2 фигуры, круг и прямоугольник, одну поверх другой, чтобы напоминать замок с ключом. Затем я пытаюсь применить обводку, но она обводит обе фигуры. Я хочу, чтобы он просто обводил объединенный шаблон, а не какие-либо пересечения.

 context.beginPath();
context.fillStyle = "#ccc";
context.arc(115, 550, 12, 0, 2 * Math.PI, false);
context.moveTo(105, 555);
context.fillStyle = "#999";
context.rect(105, 555, 20, 30);
context.fill();
context.stroke();
context.closePath();
  

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

Ответ №1:

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

Вместо этого вам нужно нарисовать только часть круга и только часть прямоугольника. Это должно сделать это за вас:

 context.beginPath();
context.fillStyle = "#ccc";
context.arc(115, 550, 12, 2.5, 2.2 * Math.PI, false);
context.moveTo(105 20, 555);
context.fillStyle = "#999";
// instead of a rect, we really want three lines
context.lineTo(105 20,555 30);
context.lineTo(105,555 30);
context.lineTo(105,555);

context.fill();
context.stroke();
context.closePath();
  

Комментарии:

1. Понятно, значит, нет способа объединить фигуры? Вам нужно просто нарисовать то, что вы хотите. Приветствия.

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

Ответ №2:

Работая над моим собственным ответом неправильной формы, я обнаружил лабораторный проект профессора Клауда, который решил мою проблему.

Эта страница, SVG-to-Canvas, преобразует графику SVG в код Canvas. Итак, если у вас есть приложение, подобное Illustrator, с помощью которого вы можете рисовать и сохранять графику в формате SVG, тогда вы можете проанализировать используемые коды canvas и просто подключить их.

Ответ №3:

Вы можете использовать компоновку и временный холст. Что-то вроде этого:

 var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var tempCanvas = document.getElementById('tempCanvas');
var tempContext = tempCanvas.getContext('2d');
tempContext.save();
// clear temp context
tempContext.clearRect(0, 0, canvas.width, canvas.height);

// draw all rects with strokes
tempContext.beginPath();
tempContext.strokeStyle='red';
tempContext.lineWidth=3;
tempContext.arc(100, 100, 60, 0, 2 * Math.PI, false);
tempContext.rect(20,150,100,200); 
tempContext.stroke();

// set compositing to erase existing drawings 
// where the new drawings are drawn

tempContext.globalCompositeOperation='destination-out';

// fill all rects
// This "erases" all but the outline stroke
tempContext.beginPath();
tempContext.fillStyle='blue';
tempContext.arc(100, 100, 60, 0, 2 * Math.PI, false);
tempContext.rect(20,150,100,200);
tempContext.fill();


// draw outlines from tempcanvas into canvas
ctx.drawImage(tempCanvas, 0, 0);

// draw into canvas
ctx.beginPath();
ctx.fillStyle='green';
ctx.globalAlpha = 0.2;
ctx.rect(20,150,100,200);
ctx.arc(100, 100, 60, 0, 2 * Math.PI, false);
ctx.fill();

tempContext.restore();
  

И jsfiddle: https://jsfiddle.net/EvaF/8to68dtd/2 /