0

То, что я прошу, может быть очень простым, но у меня возникла небольшая проблема с получением ожидаемого результата.Форма клипса на холсте JavaScript, когда за пределами

Мне нужна форма (в этом примере это квадраты, но она должна работать с другими фигурами, такими как круги и т. Д.), Чтобы отрезать себя, когда она выходит за пределы другой формы.

В принципе, верхнее изображение является то, что я хочу, внизу то, что я в настоящее время: http://imgur.com/a/oQkzG

Я слышал, это может быть сделано с globalCompositeOperation, но я ищу любое решение, которое даст желаемого результата.

Это текущий код, если вы не можете использовать JSFiddle:

// Fill the background 
ctx.fillStyle = '#0A2E36'; 
ctx.fillRect(0, 0, canvas.width, canvas.height); 

// Fill the parent rect 
ctx.fillStyle = '#CCA43B'; 
ctx.fillRect(100, 100, 150, 150); 

// Fill the child rect 
ctx.fillStyle = 'red'; 
ctx.fillRect(200, 200, 70, 70); 

// And fill a rect that should not be affected 
ctx.fillStyle = 'green'; 
ctx.fillRect(80, 80, 50, 50); 

JSFiddle Link

+0

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

+0

'ctx.globalCompositeOperation = 'source-over' ctx.fillStyle = 'yellow'; ctx.fillRect (10,10,50,50); ctx.fillStyle = 'green' ctx.fillRect (0,0,20,20) ctx.globalCompositeOperation = 'source-atop'; ctx.fillStyle = 'red' ctx.fillRect (40,40,20,20) ' – Kaiido

ответ

1

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

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

«Сцена» выполнена из фона Rect, который имеет два ребенка, желтый и зеленый. И у желтого Rect есть красный ребенок.

var canvas = document.getElementById('cv'); 
 
var ctx = canvas.getContext('2d'); 
 

 
function Rect(fill, x, y, w, h) { 
 
    var childs = []; 
 
    this.draw = function() { 
 
     ctx.save(); 
 
     ctx.beginPath(); 
 
     ctx.fillStyle = fill; 
 
     ctx.rect(x, y, w, h); 
 
     ctx.fill(); 
 
     ctx.clip(); 
 
     for (var i = 0; i < childs.length; i++) { 
 
      childs[i].draw(); 
 
     } 
 
     ctx.restore(); 
 
    } 
 
    this.addChild = function (child) { 
 
     childs.push(child); 
 
    } 
 
    this.setPos = function (nx, ny) { 
 
     x = nx; 
 
     y = ny; 
 
    } 
 
} 
 

 
// background 
 
var bgRect = new Rect('#0A2E36', 0, 0, canvas.width, canvas.height); 
 
// One parent rect 
 
var parentRect = new Rect('#CCA43B', 100, 100, 150, 150); 
 
// child rect 
 
var childRect = new Rect('red', 200, 200, 70, 70); 
 
parentRect.addChild(childRect); 
 
// Another top level rect 
 
var otherRect = new Rect('green', 80, 80, 50, 50); 
 

 
bgRect.addChild(parentRect); 
 
bgRect.addChild(otherRect); 
 

 
function drawScene() { 
 
    bgRect.draw(); 
 
    drawTitle(); 
 
} 
 

 
drawScene(); 
 

 
window.addEventListener('mousemove', function (e) { 
 
    var rect = canvas.getBoundingClientRect(); 
 
    var x = (e.clientX - rect.left); 
 
    var y = (e.clientY - rect.top); 
 
    childRect.setPos(x, y); 
 
    drawScene(); 
 
}); 
 

 
function drawTitle() { 
 
    ctx.fillStyle = '#DDF'; 
 
    ctx.font = '14px Futura'; 
 
    ctx.fillText('Move the mouse around.', 20, 24); 
 
}
<canvas id='cv' width=440 height=440></canvas>

+0

Вы правы, так будет лучше для будущего кода OP. Однако следует отметить, что это должно быть упрощено с помощью интерфейса ['Path2D()'] (https://developer.mozilla.org/en-US/docs/Web/API/Path2D#BrowserCompability), когда больше браузеров его поддержит. – Kaiido

+0

Это прекрасно работает для моих нужд, еще раз спасибо! – JsFTW