Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
501 views
in Technique[技术] by (71.8m points)

javascript - HTML5 Canvas ctx.clip() method used on a circle leaves a line underneath the circle

I've created a program to generate planet sprites. I'm doing that by creating a circular path, running ctx.clip() to keep all the following layers inside of the circle, then drawing a black and transparent texture layer, then a randomly colored rectangle over the full canvas, then a shadow and glow on top of it all. The issue is that a colored line also appears under the circle after clipping, and I'm not sure why. I need this removed.

Here is a fiddle. The last line sets the code to loop every half second: https://jsfiddle.net/tzkwmzqu/4/

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I am not sure I do understand your problem, but I will assume that you are talking about the anti-aliasing problem.

Currently, you are drawing a lot over your clipped area.
At each draw, new anti-aliasing artifacts will come to smooth the latest drawing. At the end, what should have been semi-transparent pixels are now fully opaque ones.
In the other hand, with globalCompositeOperation like 'destination-in', you need only one drawing to make the compositing (~clipping). So you don't accumulate artifacts. But even if you did, gCO is global and since it takes transparency into account, the accumulation would be less important.

var ctx1 = clip.getContext('2d');
var ctx2 = gCO.getContext('2d');
var ctx3 = gCO2.getContext('2d');

ctx1.beginPath();
ctx1.arc(150, 150, 150, 0, Math.PI*2)
ctx1.clip();
// drawing multiple times on this clipped area will increase artifacts
ctx1.fillRect(0,0,300, 150);
ctx1.fillRect(0,0,300, 150);
ctx1.fillRect(0,0,300, 150);
ctx1.fillRect(0,0,300, 150);

ctx2.beginPath();
ctx2.arc(150, 150, 150, 0, Math.PI*2)
ctx2.fillRect(0,0,300, 150);
ctx2.globalCompositeOperation = 'destination-in';
//With gCO you only draw once, but even if you did draw multiple times, there would still be less artifacts
ctx2.fill();
ctx2.fill();
ctx2.fill();
ctx2.fill();
ctx2.globalCompositeOperation = 'source-over';

ctx3.beginPath();
ctx3.arc(150, 150, 150, 0, Math.PI*2)
ctx3.fillRect(0,0,300, 150);
ctx3.globalCompositeOperation = 'destination-in';
// only one drawing needed:
ctx3.fill();
ctx3.globalCompositeOperation = 'source-over';

ctx1.fillStyle = ctx2.fillStyle = ctx3.fillStyle = "white";
ctx1.fillText('clipping', 120, 100);
ctx2.fillText('compositing', 120, 100);
ctx3.fillText('single compositing', 120, 100);
canvas{
  border: 1px solid;
  }
<canvas id="clip"></canvas><canvas id="gCO"></canvas><canvas id="gCO2"></canvas>

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...