Javascript 如何使用画布创建重叠(而不是堆叠)形状?
我正在尝试创建一组重叠的形状。但我很难阻止这些形状堆叠在一起 我想我想让他们在一起,如果这有意义的话 代码如下:Javascript 如何使用画布创建重叠(而不是堆叠)形状?,javascript,html,canvas,Javascript,Html,Canvas,我正在尝试创建一组重叠的形状。但我很难阻止这些形状堆叠在一起 我想我想让他们在一起,如果这有意义的话 代码如下: var overlap_canvas = document.getElementById("overlap"); var overlap_context = overlap_canvas.getContext("2d"); var x = 200; var y = x; var rectQTY = 4 // Number of rectangles overlap_context.
var overlap_canvas = document.getElementById("overlap");
var overlap_context = overlap_canvas.getContext("2d");
var x = 200;
var y = x;
var rectQTY = 4 // Number of rectangles
overlap_context.translate(x,y);
for (j=0;j<rectQTY;j++){ // Repeat for the number of rectangles
// Draw a rectangle
overlap_context.beginPath();
overlap_context.rect(-90, -100, 180, 80);
overlap_context.fillStyle = 'yellow';
overlap_context.fill();
overlap_context.lineWidth = 7;
overlap_context.strokeStyle = 'blue';
overlap_context.stroke();
// Degrees to rotate for next position
overlap_context.rotate((Math.PI/180)*360/rectQTY);
}
var overlap\u canvas=document.getElementById(“overlap”);
var overlap_context=overlap_canvas.getContext(“2d”);
var x=200;
变量y=x;
var rectQTY=4//矩形数
重叠上下文。翻译(x,y);
对于(j=0;j来说,唯一的方法是剪切矩形,并计算出哪个子矩形经过哪个子矩形。但我认为你必须分别绘制边框和内部矩形,因为分隔矩形会增加额外的边框
希望它能有所帮助。遗憾的是,您想要的使用画布在元素的一部分上设置z索引的功能目前还不可用。如果您只需要为四个矩形对象设置z索引,您可以这样做,隐藏部分矩形以伪造您想要的效果,但是这是硬编码的,仅为4个矩形
var overlap_canvas = document.getElementById("overlap");
var overlap_context = overlap_canvas.getContext("2d");
var x = 200;
var y = x;
var rectQTY = 4 // Number of rectangles
overlap_context.translate(x, y);
for (j = 0; j < rectQTY; j++) { // Repeat for the number of rectangles
// Draw a rectangle
overlap_context.beginPath();
overlap_context.rect(-90, -100, 180, 80);
overlap_context.fillStyle = 'yellow';
overlap_context.fill();
overlap_context.lineWidth = 7;
overlap_context.strokeStyle = 'blue';
overlap_context.stroke();
if (j === 3) {
overlap_context.beginPath();
overlap_context.rect(24, -86, 72, 80);
overlap_context.fillStyle = 'yellow';
overlap_context.fill();
overlap_context.closePath();
overlap_context.beginPath();
overlap_context.moveTo(20, -89.5);
overlap_context.lineTo(100, -89.5);
overlap_context.stroke();
overlap_context.closePath();
overlap_context.beginPath();
overlap_context.moveTo(20.5, -93.1);
overlap_context.lineTo(20.5, 23);
overlap_context.stroke();
overlap_context.closePath();
}
// Degrees to rotate for next position
overlap_context.rotate((Math.PI / 180) * 360 / rectQTY);
}
var overlap\u canvas=document.getElementById(“overlap”);
var overlap_context=overlap_canvas.getContext(“2d”);
var x=200;
变量y=x;
var rectQTY=4//矩形数
重叠上下文。翻译(x,y);
对于(j=0;j
如果您必须使其动态化,您可以像建议的那样剪切形状,或者您可以尝试创建一个函数来检测对象何时重叠,并在每个矩形上重新绘制一次(很难做到,也不确定是否可行).也许你能想出一些公式来定位元素,我现在把它们硬编码成始终根据旋转角度工作,这在我看来是你最好的选择,但我不知道如何准确地做到这一点
总的来说,在这个时间点上,你不能真正做到你想要的事情你不能指定这种行为,但你可以实现一种使用复合模式的算法ish方法
如所示:
定义要绘制的线宽和矩形(您可以用已经计算位置/角度的循环填充此数组-为简单起见,我在这里只使用硬编码的循环):
我将在下面解释线宽
/// set line-width to half the size
ctx.lineWidth = lw * 0.5;
在循环中,您为第一次绘制添加了一个条件,这也是您更改合成模式的地方。我们还使用最后一个矩形清除画布:
/// loop through the array with rectangles
for(;r = rects[i]; i++) {
ctx.beginPath();
ctx.rect(r[0], r[1], r[2], r[3]);
ctx.fill();
ctx.stroke();
/// if first we do a clear with last rectangle and
/// then change composite mode and line width
if (i === 0) {
r = rects[rects.length - 1];
ctx.clearRect(r[0] - lw * 0.5, r[1] - lw * 0.5, r[2] + lw, r[3] + lw);
ctx.lineWidth = lw;
ctx.globalCompositeOperation = 'destination-over';
}
}
这将绘制矩形,您可以灵活地更改大小,而无需重新计算剪裁
线条宽度单独设置为笔划
从中间笔划线条。因此,由于我们以后使用目标覆盖
模式,这意味着当我们第一次填充时,一半线条将不可见,这将成为目标的一部分,因此笔划将只能填充笔划区域之外的区域(您可以颠倒笔划
和填充
的顺序,但始终会对第一个矩形进行调整)
我们还需要它来计算裁剪,其中必须包括(一半)外部的线
这也是我们最初将其设置为一半的原因,因为整条线将在第一次绘制-否则第一个矩形将有两倍厚的边框。使用纯JavaScript
<!DOCTYPE html>
<html>
<head></head>
<body>
<canvas id="mycanvas" width="400px" height="400px"></canvas>
<script>
window.onload = function(){
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
//cheat - use a hidden canvas
var hidden = document.createElement('canvas');
hidden.width = 400;
hidden.height = 400;
var hiddenCtx = hidden.getContext('2d');
hiddenCtx.strokeStyle = 'blue';
hiddenCtx.fillStyle = 'yellow';
hiddenCtx.lineWidth = 5;
//translate origin to centre of hidden canvas, and draw 3/4 of the image
hiddenCtx.translate(200,200);
for(var i=0; i<3; i++){
hiddenCtx.fillRect(-170, -150, 300, 120);
hiddenCtx.strokeRect(-170, -150, 300, 120);
hiddenCtx.rotate(90*(Math.PI/180));
}
//reset the hidden canvas to original status
hiddenCtx.rotate(90*(Math.PI/180));
hiddenCtx.translate(-200,-200);
//translate to middle of visible canvas
ctx.translate(200, 200);
//repeat trick, this time copying from hidden to visible canvas
ctx.drawImage(hidden, 200, 0, 200, 400, 0, -200, 200, 400);
ctx.rotate(180*(Math.PI/180));
ctx.drawImage(hidden, 200, 0, 200, 400, 0, -200, 200, 400);
};
</script>
</body>
</html>
window.onload=函数(){
var canvas=document.getElementById('mycanvas');
var ctx=canvas.getContext('2d');
//作弊-使用隐藏的画布
var hidden=document.createElement('canvas');
隐藏宽度=400;
隐藏高度=400;
var hiddenCtx=hidden.getContext('2d');
hiddenCtx.strokeStyle='蓝色';
hiddenCtx.fillStyle='黄色';
hiddenCtx.lineWidth=5;
//将原点平移到隐藏画布的中心,并绘制图像的3/4
hiddenCtx.translate(200200);
对于(var i=0;我感谢您。这是一个很大的帮助,非常感谢您的输入。
<!DOCTYPE html>
<html>
<head></head>
<body>
<canvas id="mycanvas" width="400px" height="400px"></canvas>
<script>
window.onload = function(){
var canvas = document.getElementById('mycanvas');
var ctx = canvas.getContext('2d');
//cheat - use a hidden canvas
var hidden = document.createElement('canvas');
hidden.width = 400;
hidden.height = 400;
var hiddenCtx = hidden.getContext('2d');
hiddenCtx.strokeStyle = 'blue';
hiddenCtx.fillStyle = 'yellow';
hiddenCtx.lineWidth = 5;
//translate origin to centre of hidden canvas, and draw 3/4 of the image
hiddenCtx.translate(200,200);
for(var i=0; i<3; i++){
hiddenCtx.fillRect(-170, -150, 300, 120);
hiddenCtx.strokeRect(-170, -150, 300, 120);
hiddenCtx.rotate(90*(Math.PI/180));
}
//reset the hidden canvas to original status
hiddenCtx.rotate(90*(Math.PI/180));
hiddenCtx.translate(-200,-200);
//translate to middle of visible canvas
ctx.translate(200, 200);
//repeat trick, this time copying from hidden to visible canvas
ctx.drawImage(hidden, 200, 0, 200, 400, 0, -200, 200, 400);
ctx.rotate(180*(Math.PI/180));
ctx.drawImage(hidden, 200, 0, 200, 400, 0, -200, 200, 400);
};
</script>
</body>
</html>