Javascript 视网膜上的帆布弧在某些点上过于尖锐

Javascript 视网膜上的帆布弧在某些点上过于尖锐,javascript,canvas,Javascript,Canvas,我正在尝试创建在HiDPI设备上看起来不模糊的动画圆弧 这就是我的arc在iPhone 5s上的外观: 您可以看到,接近0度、90度、180度的弧度变得过于尖锐。我怎样才能防止这种情况 这是我的代码: //画布弧进度 const can=document.getElementById('canvas'); const ctx=can.getContext('2d'); 常数circ=Math.PI*2; 常数夸脱=Math.PI/2; const canvasSize=can.offsetW

我正在尝试创建在HiDPI设备上看起来不模糊的动画圆弧

这就是我的arc在iPhone 5s上的外观:

您可以看到,接近0度、90度、180度的弧度变得过于尖锐。我怎样才能防止这种情况

这是我的代码:

//画布弧进度
const can=document.getElementById('canvas');
const ctx=can.getContext('2d');
常数circ=Math.PI*2;
常数夸脱=Math.PI/2;
const canvasSize=can.offsetWidth;
const halfCanvasSize=canvasSize/2;
让start=0,
完成=70,
animRequestId=null;
//获取像素比率
常数比率=(函数(){
const dpr=window.devicePixelRatio | | 1,
bsr=ctx.webkitBackingStorePixelRatio||
ctx.MozBackingsStorePixelRatio||
ctx.msBackingStorePixelRatio||
ctx.ObackStorePixelRatio||
ctx.backingStorePixelRatio | | 1;
返回dpr/bsr;
})();
//设置画布h&w
罐宽=罐高=帆布尺寸*比率;
can.style.width=can.style.height=canvasSize+'px';
ctx.刻度(比率,比率)
ctx.beginPath();
ctx.strokeStyle='rgb(120159194)';
ctx.lineCap='方形';
ctx.lineWidth=8.0;
ctx.arc(半画布大小,半画布大小,半画布大小-4,0,circ,false);
ctx.stroke();
ctx.closePath();
ctx.beginPath();
ctx.strokeStyle='rgb(244247255)';
ctx.lineCap='圆形';
ctx.lineWidth=8.0;
ctx.closePath();
设imd=ctx.getImageData(0,0,canvasSize,canvasSize);
常量绘制=(当前)=>{
ctx.putImageData(imd,0,0);
ctx.beginPath();
ctx.arc(半画布尺寸,半画布尺寸,半画布尺寸-4,-(夸脱),((循环)*当前)-夸脱,假);
ctx.stroke();
};
(函数animateArcProgress(){
animRequestId=requestAnimationFrame(animateArcProgress);

如果(开始,您可以像下面的代码那样,通过在内部绘制1/2像素来软化边缘

我分别以8、7.5和7像素宽度alpha颜色值0.25、0.5和1渲染了3次圆弧

你想做什么就做什么

顺便说一句,使用putImageData速度非常慢,为什么不直接将背景渲染到另一个画布上,然后通过ctx.drawImage(offScreencanvas,0,0)进行绘制,这样您就可以使用GPU而不是CPU通过图形端口总线来渲染背景

我添加了更多的代码来显示可以得到的不同的柔化效果,并添加了鼠标缩放,这样可以更好地看到像素

const can=document.getElementById('canvas');
const can2=document.createElement(“画布”);//屏幕外画布
const can3=document.createElement(“画布”);//屏幕外画布
const ctx=can.getContext('2d');
const ctx2=can2.getContext('2d');
const ctx3=can3.getContext('2d');
常数circ=Math.PI*2;
常数夸脱=Math.PI/2;
const canvasSize=can.offsetWidth;
const halfCanvasSize=canvasSize/2;
常量鼠标={x:null,y:null};
can.addEventListener(“mousemove”,函数(e){
var bounds=can.getBoundingClientRect();
mouse.x=e.clientX-bounds.left;
mouse.y=e.clientY-bounds.top;
});
让start=0,
完成=70,
animRequestId=null;
//获取像素比率
常数比率=(函数(){
const dpr=window.devicePixelRatio | | 1,
bsr=ctx.webkitBackingStorePixelRatio||
ctx.MozBackingsStorePixelRatio||
ctx.msBackingStorePixelRatio||
ctx.ObackStorePixelRatio||
ctx.backingStorePixelRatio | | 1;
返回dpr/bsr;
})();
//设置画布h&w
can2.height=can3.height=can2.width=can3.width=can.width=can.height=canvasSize*比率;
can.style.width=can.style.height=canvasSize+'px';
ctx.刻度(比率,比率)
ctx2.比例(比率、比率)
ctx3.比例(比率,比率)
ctx2.beginPath();
ctx2.strokeStyle='rgb(120159194)';
ctx2.lineCap=‘方形’;
ctx2.lineWidth=8.0;
ctx2.arc(半画布大小,半画布大小,半画布大小-4,0,circ,false);
ctx2.stroke();
ctx2.closePath();
ctx2.beginPath();
ctx2.strokeStyle='rgb(244247255)';
ctx2.lineCap=‘圆形’;
ctx2.lineWidth=8.0;
ctx2.closePath();
常量绘制=(当前)=>{
ctx3.clearRect(0,0,canvas.width,canvas.height);
ctx3.drawImage(can2,0,0);
var rad=半画布尺寸-4;
常量drawArc=()=>{
ctx3.beginPath();
ctx3.弧(半画布尺寸,半画布尺寸,弧度,-(夸脱),((循环)*当前)-夸脱,假);
ctx3.stroke();
}
//画蛇添足
ctx3.strokeStyle='rgb(244247255)';
ctx3.线宽=8.5;
ctx3.globalAlpha=0.25;
drawArc();;
ctx3.lineWidth=7.0;
ctx3.globalAlpha=0.5;
drawArc();;
ctx3.线宽=6.5;
ctx3.globalAlpha=1;
drawArc();
//画法线
rad-=12;
ctx3.lineWidth=8.0;
ctx3.globalAlpha=1;
drawArc();;
//画超软
rad-=12;
ctx3.strokeStyle='rgb(244247255)';
ctx3.lineWidth=9.0;
ctx3.globalAlpha=0.1;
drawArc();
ctx3.lineWidth=8.0;
ctx3.globalAlpha=0.2;
drawArc();;
ctx3.线宽=7.5;
ctx3.globalAlpha=0.5;
drawArc();
ctx3.lineWidth=6;
ctx3.globalAlpha=1;
drawArc();
};
常数zoomW=30;
常数zoomAmount=5;
常量drawZoom=()=>{
ctx.drawImage(can3,0,0);
变量宽度=zoomW*zoomAmount;
var cx=鼠标.x-宽度/2;
var cy=鼠标。y-宽度/2;
var c1x=mouse.x-zoomW/2;
var c1y=mouse.y-zoomW/2;
ctx.strokeStyle='rgb(244247255)';
ctx.lineWidth=4;
ctx.冲程(cx,cy,宽度,宽度);
ctx.clearRect(cx,cy,width,width);
ctx.imageSmoothingEnabled=假;
ctx.mozImageSmoothingEnabled=false;
ctx.drawImage(can3、c1x、c1y、zoomW、zoomW、cx、cy、宽度、宽度);
ctx.imageSmoothingEnabled=真;
ctx.mozImageSmoothingEnabled=true;
}
函数keepUpdating(){
ctx.clearRect(0,0,罐宽,罐高);
drawZoom();
请求动画帧(keepupdated);
}
(函数animateArcProgress(){
ctx.clearRect(0,0,罐宽,罐高);
抽签(开始/100);
drawZoom();

如果(开始感谢你的帮助和努力!!我用了你的想法,成功地使arc看起来像是“抗锯齿”!谢谢你