Html5 canvas 如何在HTML画布中创建新月形

Html5 canvas 如何在HTML画布中创建新月形,html5-canvas,Html5 Canvas,我需要在HTML5画布上制作以下形状。我尝试过使用三次贝塞尔圆弧,也尝试过裁剪两个圆 我怎么做这个形状 这是我正在做的工作,就是做不好 使用globalCompositeOperation 使用globalCompositeOperation 循环布尔运算。 如果任何人对编程解决方案感兴趣,下面的示例将找到两个圆的截距点,并使用这些点计算外圆和内圆的起点和终点角度 这比掩蔽解决方案灵活一点,因为它为您提供了一条路径 片段显示圆形,将鼠标移到圆形上可查看新月形解决方案。不是使用遮罩溶液时不可用的

我需要在HTML5画布上制作以下形状。我尝试过使用三次贝塞尔圆弧,也尝试过裁剪两个圆

我怎么做这个形状

这是我正在做的工作,就是做不好


使用
globalCompositeOperation


使用
globalCompositeOperation

循环布尔运算。 如果任何人对编程解决方案感兴趣,下面的示例将找到两个圆的截距点,并使用这些点计算外圆和内圆的起点和终点角度

这比掩蔽解决方案灵活一点,因为它为您提供了一条路径

片段显示圆形,将鼠标移到圆形上可查看新月形解决方案。不是使用遮罩溶液时不可用的笔划

constpi2=Math.PI*2;
const ctx=canvas.getContext(“2d”);
canvas.height=canvas.width=400;
常量鼠标={x:0,y:0,按钮:false}
功能鼠标事件(e){
const m=小鼠;
const bounds=canvas.getBoundingClientRect();
m、 x=e.pageX-bounds.left-scrollX;
m、 y=e.pageY-bounds.top-scrollY;
m、 button=e.type===“mousedown”?真:e.type===“mouseup”?假:m.button;
}
[“向下”、“向上”、“移动”].forEach(name=>document.addEventListener(“mouse”+name,mouseEvents));
//通用圆截距函数。返回未定义的if
//没有拦截。
//圆1是中心x1、y1和半径r1
//圆2是中心x2、y2和半径r2
//如果找到点,则返回{x1,y1,x2,y2}作为两点。
函数循环循环接口(x1、y1、r1、x2、y2、r2){
var x=x2-x1;
变量y=y2-y1;
var dist=数学sqrt(x*x+y*y);
如果(距离>r1+r2 | |距离<数学绝对值(r1-r2)){
return;//没有未定义的截取返回
}
变量a=(dist*dist-r1*r1+r2*r2)/(2*dist);
VarB=Math.sqrt(r2*r2-a*a);
a/=距离;
x*=a;
y*=a;
var mx=x2-x;
var my=y2-y;
dist=b/数学sqrt(x*x+y*y);
x*=距离;
y*=距离;
返回{
x1:mx-y,
y1:我的+x,
x2:mx+y,
y2:my-x,
};
}
//如果可能,从两个圆中绘制一个新月
//如果没有,那么只画第一个圆
函数(x1、y1、r1、x2、y2、r2){
//圆截距查找点
/但找到点的角度不考虑
//旋转方向,你最终不得不做很多事情
//检查(如有)以确定绘制每个圆的正确方法
//以下内容使圆彼此之间的方向正常化
//这样,逻辑就容易多了
var dist=数学形下(x2-x1,y2-y1);
var ang=数学常数2(y2-y1,x2-x1);
var截距=环形环形截距(x1,y1,r1,x1+dist,y1,r2);
如果(截取===未定义){
ctx.beginPath();
ctx.弧(x1,y1,r1,0,PI2);
if(距离
canvas{border:2px纯黑;}
循环布尔运算。 如果任何人对编程解决方案感兴趣,下面的示例将找到两个圆的截距点,并使用这些点计算外圆和内圆的起点和终点角度

这比掩蔽解决方案灵活一点,因为它为您提供了一条路径

片段显示圆形,将鼠标移到圆形上可查看新月形解决方案。不是使用遮罩溶液时不可用的笔划

constpi2=Math.PI*2;
const ctx=canvas.getContext(“2d”);
canvas.height=canvas.width=400;
常量鼠标={x:0,y:0,按钮:false}
功能鼠标事件(e){
const m=小鼠;
const bounds=canvas.getBoundingClientRect();
m、 x=e.pageX-bounds.left-scrollX;
m、 y=e.pageY-bounds.top-scrollY;
m、 button=e.type===“mousedown”?真:e.type===“mouseup”?假:m.button;
}
[“向下”、“向上”、“移动”].forEach(name=>document.addEventListener(“mouse”+name,mouseEvents));
//通用圆截距函数。返回未定义的if
//没有拦截。
//圆1是中心x1、y1和半径r1
//圆2是中心x2、y2和半径r2
//如果找到点,则返回{x1,y1,x2,y2}作为两点。
函数循环循环接口(x1、y1、r1、x2、y2、r2){
var x=x2-x1;
变量y=y2-y1;
var dist=数学sqrt(x*x+y*y);
如果(距离>r)
var canvas = document.getElementById("canvas1");
var ctx1 = canvas.getContext("2d");

ctx1.lineWidth = 2;

ctx1.beginPath();
ctx1.bezierCurveTo(4, 42, 0, 0, 42, 4);
ctx1.moveTo(4, 42);
ctx1.bezierCurveTo(4, 42, 0, 84, 42, 84);
ctx1.stroke();

var canvas = document.getElementById("canvas2");
var ctx2 = canvas.getContext("2d");

ctx2.lineWidth = 2;

ctx2.beginPath();
ctx2.arc(55, 75, 50, 0, Math.PI * 2, true);
ctx2.moveTo(165, 75);
ctx2.arc(75, 75, 50, 0, Math.PI * 2, true);
ctx2.fill();