HTML5 canvas: single stroke around combined regions -
html5 canvas: i'm looking way draw single stroke around combined path.
for example if have 2 overlapping circles don't want have 2 overlapping circle strokes, 1 single stroke around combined region of both circles..
any chance that?
it can done using globalcompositeoperation
. there various ways can draw shapes them selves here 1 approach results in (for 2 rectangle circles in demo):
- step 1: setup normal canvas
- step 2: setup off-screen canvas
update not sure how miss obvious, can of course stroke circles first, punch whole composite mode , fill - faster (i guess had images on mind when came offset redraw).
the reason off-screen canvas if have in background on main canvas. deleted otherwise punch hole. if nothing there there no problem drawing single canvas - updated code:
/// regions var rect = [ [20, 20, 200, 200], [100, 100, 200,200] ], /// ox = off-screen context ox.strokestyle = '#fff'; ox.linewidth = 3 * 2; /// x2 half gone when punch hole /// stroke outlines for(; r = rect[i]; i++) { o = r[2] * 0.5; ox.beginpath(); ox.arc(r[0] + o, r[1] + o, o, 0, 2 * math.pi); ox.stroke(); } /// punch hole composite mode , fill ox.globalcompositeoperation = 'destination-out'; for(i = 0; r = rect[i]; i++) { o = r[2] * 0.5; ox.beginpath(); ox.arc(r[0] + o, r[1] + o, o, 0, 2 * math.pi); ox.fill(); } /// draw result main canvas /// ctx = main context, ocanvas = off-screen canvas ctx.drawimage(ocanvas, 0, 0);
(animated) online demo using optimized version
i'll leave old code can used images can't stroked -
now draw shapes filled off-screen canvas. draw in color want outline in.
/// regions var rect = [ [20, 20, 200, 200], [100, 100, 200,200] ], /// ox = off-screen canvas ox.fillstyle = '#fff'; /// draw array circes for(; r = rect[i]; i++) { var o = r[2] * 0.5; ox.beginpath(); //use here - arcs buggy ox.arc(r[0] + o, r[1] + o, o, 0, 2 * math.pi); ox.fill(); //.. , here }
now draw cached image of shapes main canvas. shapes must drawn slight offset in each direction - step create outline:
/// ctx = main context, ocanvas = off-screen canvas ctx.drawimage(ocanvas, -1, -1); ctx.drawimage(ocanvas, 1, -1); ctx.drawimage(ocanvas, 1, -1); ctx.drawimage(ocanvas, 1, 1); ctx.drawimage(ocanvas, -1, 1); ctx.drawimage(ocanvas, 1, 1); ctx.drawimage(ocanvas, -1, -1); ctx.drawimage(ocanvas, -1, 1);
and punch "hole" in filled shape make transparent outline using globalcompositeoperation
+ final draw in 0 offset position :
ctx.globalcompositeoperation = 'destination-out'; ctx.drawimage(ocanvas, 0, 0);
to make border thicker increase offset when draw shapes main canvas.
Comments
Post a Comment