简体   繁体   English

如何在中间创建一个带有孔的画布html5剪裁区域?

[英]How do I create a canvas html5 clipping region with a hole in the middle?

I am trying to dynamically code this image using HTML5 Canvas/Javascript: 我试图使用HTML5 Canvas / Javascript动态编码此图像:

在此输入图像描述

The hole in the middle must be transparent, because I am superimposing this image onto a background. 中间的孔必须是透明的,因为我将此图像叠加到背景上。 My code draws two oval paths, one inside the other. 我的代码绘制了两个椭圆形路径,一个在另一个内部。 I am assuming that the best way to do this is by creating a clipping region that allows a fill inside the larger oval but outside the smaller one. 我假设最好的方法是创建一个剪切区域,允许在较大的椭圆形内部填充但在较小的椭圆形外部填充。 How do I do this? 我该怎么做呢? Please help! 请帮忙!

My code (does not resolve the problem because it uses a white-out fill for the smaller oval): 我的代码(不能解决问题,因为它对较小的椭圆使用了白色填充):

var canvas = document.getElementById("myCanvas");
var context = canvas.getContext("2d");
//parameters of the ovals;

var height = 20;
var curve1 = 0.56;
var curve2 = 0.44;
var width_ratio = 0.38;
var x_pos = 0;
var y_pos = 0;var x1 = x_pos;
var y1 = y_pos - height/2;
var x2 = x_pos + height * width_ratio;
var y2 = y_pos;
var x3 = x_pos;
var y3 = y_pos + height/2;
var x4 = x_pos - height * width_ratio;
var y4 = y_pos;

var xv1 = x1 + ((x2 - x1) * curve1);
var yv1 = y1;
var xv2 = x2;
var yv2 = y1 + ((y2 - y1) * curve2);
var xv3 = x2;
var yv3 = y2 + (height/2 - (height/2 * curve2));
var xv4 = xv1;
var yv4 = y3;
var xv5 = x3 - ((x2 - x1) * curve1);
var yv5 = y3;
var xv6 = x4;
var yv6 = yv3;
var xv7 = x4;
var yv7 = y4 - (height/2 - (height/2 * curve2));
var xv8 = x1 - ((x2 - x1) * curve1);
var yv8 = y1;

var x5 = x1;
var y5 = y1 + height / 10;
var x6 = x2 - height / 5;//x2
var y6 = y2;//y2
var x7 = x5;//x3
var y7 = y3 - height / 10;//y3
var x8 = x4 + height / 5;
var y8 = y4;//y4


var xv9 = x5 + ((x6 - x5) * curve1);//xv1
var yv9 = y5;//yv1
var xv10 = x6;//xv2
var yv10 = y5 + ((y6 - y5) * curve2);//yv2 
var xv11 =  x6;//xv3
var yv11 = y7 - ((y7 - y6) * curve2);//yv3
var xv12 = xv9;//xv4
var yv12 = y7;//yv4
var xv13 = x5 - ((x6 - x5) * curve1);//xv5
var yv13 = y7;//yv5
var xv14 = x7 - height / 5;//xv6
var yv14 = yv11;//yv6
var xv15 = x8;//xv7
var yv15 = yv10;
var xv16 = x5 - ((x6 - x5) * curve1);
var yv16 = yv9;

context.save();
context.scale(5,5);
context.translate(50, 50);
context.rotate(60*Math.PI/180); 

context.beginPath();
context.fillStyle = "black";
context.moveTo(x1,y1); //0,0
context.bezierCurveTo(xv1,yv1,xv2,yv2,x2,y2);
context.bezierCurveTo(xv3,yv3,xv4,yv4,x3,y3);
context.bezierCurveTo(xv5,yv5,xv6,yv6,x4,y4);
context.bezierCurveTo(xv7,yv7,xv8,yv8,x1,y1);
context.closePath();
context.fill();
//context.clip()??? ---- HELP HERE!

context.beginPath();
context.fillStyle = "white";
context.moveTo(x5,y5); //0,0
context.bezierCurveTo(xv9,yv9,xv10,yv10,x6,y6);
context.bezierCurveTo(xv11,yv11,xv12,yv12,x7,y7);
context.bezierCurveTo(xv13,yv13,xv14,yv14,x8,y8);
context.bezierCurveTo(xv15,yv15,xv16,yv16,x5,y5);
context.closePath();
context.fill();//doesn't really work for my purposes

You just need to reverse the second path. 你只需要反转第二条路径。 Also don't create a new path with beginPath between the two paths. 也不要在两个路径之间使用beginPath创建新路径。

Example uses your code with modifications to create a clip area. 示例使用您的代码进行修改以创建剪辑区域。 I then draw a large rectangle over the top of it to show what the clip shape is. 然后我在它的顶部画一个大矩形来显示剪辑的形状。

Also you should use arrays when you have large sets of numbers. 当你有大量的数字时,你也应该使用数组。 Will save you a lot of typing. 会为你节省很多打字。

 var context = canvas.getContext("2d"); //parameters of the ovals; var height = 20; var curve1 = 0.56; var curve2 = 0.44; var width_ratio = 0.38; var x_pos = 0; var y_pos = 0;var x1 = x_pos; var y1 = y_pos - height/2; var x2 = x_pos + height * width_ratio; var y2 = y_pos; var x3 = x_pos; var y3 = y_pos + height/2; var x4 = x_pos - height * width_ratio; var y4 = y_pos; var xv1 = x1 + ((x2 - x1) * curve1); var yv1 = y1; var xv2 = x2; var yv2 = y1 + ((y2 - y1) * curve2); var xv3 = x2; var yv3 = y2 + (height/2 - (height/2 * curve2)); var xv4 = xv1; var yv4 = y3; var xv5 = x3 - ((x2 - x1) * curve1); var yv5 = y3; var xv6 = x4; var yv6 = yv3; var xv7 = x4; var yv7 = y4 - (height/2 - (height/2 * curve2)); var xv8 = x1 - ((x2 - x1) * curve1); var yv8 = y1; var x5 = x1; var y5 = y1 + height / 10; var x6 = x2 - height / 5;//x2 var y6 = y2;//y2 var x7 = x5;//x3 var y7 = y3 - height / 10;//y3 var x8 = x4 + height / 5; var y8 = y4;//y4 var xv9 = x5 + ((x6 - x5) * curve1);//xv1 var yv9 = y5;//yv1 var xv10 = x6;//xv2 var yv10 = y5 + ((y6 - y5) * curve2);//yv2 var xv11 = x6;//xv3 var yv11 = y7 - ((y7 - y6) * curve2);//yv3 var xv12 = xv9;//xv4 var yv12 = y7;//yv4 var xv13 = x5 - ((x6 - x5) * curve1);//xv5 var yv13 = y7;//yv5 var xv14 = x7 - height / 5;//xv6 var yv14 = yv11;//yv6 var xv15 = x8;//xv7 var yv15 = yv10; var xv16 = x5 - ((x6 - x5) * curve1); var yv16 = yv9; context.save(); context.scale(5,5); context.translate(50, 50); context.rotate(60*Math.PI/180); context.beginPath(); context.fillStyle = "black"; context.moveTo(x1,y1); //0,0 context.bezierCurveTo(xv1,yv1,xv2,yv2,x2,y2); context.bezierCurveTo(xv3,yv3,xv4,yv4,x3,y3); context.bezierCurveTo(xv5,yv5,xv6,yv6,x4,y4); context.bezierCurveTo(xv7,yv7,xv8,yv8,x1,y1); context.moveTo(x5,y5); //0,0 context.bezierCurveTo(xv16,yv16,xv15,yv15,x8,y8); context.bezierCurveTo(xv14,yv14,xv13,yv13,x7,y7); context.bezierCurveTo(xv12,yv12,xv11,yv11,x6,y6); context.bezierCurveTo(xv10,yv10,xv9,yv9,x5,y5); context.clip(); //context.setTransform(1,0,0,1,0,0) context.fillRect(-500,-500,1024,1024); 
 <canvas id = "canvas" width = 1024 height = 1024></canvas> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM