Update 2017/7
Since this answer was given, a new option appeared in the new browser, the filter property in the context. Just note that not all browsers currently support it.
For browsers that we can cut as well as delete a temporary canvas as follows:
var ctx = demo.getContext('2d'); ctx.fillStyle = '#f90'; ctx.fillRect(0, 0, demo.width, demo.height); clipArc(ctx, 200, 200, 150, 40); function clipArc(ctx, x, y, r, f) { ctx.globalCompositeOperation = 'destination-out'; ctx.filter = "blur(25px)";
body {background:#07c}
<canvas id="demo" width=400 height=400></canvas>
Old answer
Technics
You can achieve this by combining the following steps:
- Using screen canvas
- Use the shadow function (secret ingredient)
- Using composite modes
The concept is based on the browser making the pen internally using a blurry shadow. This is much faster than blurring in JavaScript. Since we can make a shadow for any object, you can create complex feathered masks.
Outside the screen, you can use only the shadow. We achieve this by moving the actual shape outside the canvas, and then shift the shadow accordingly. As a result, a shadow is drawn on the screen outside the screen, and the actual shape is โinvisibleโ.
Now that we have a feathered version of our form, we can use it as a mask for composite mode. Choose destination-out to clear the shadow, or destination-in to invert the mask.
Example
Lets create a wrapper function that takes all the steps for us
ONLINE DEMO HERE
function clipArc(ctx, x, y, r, f) { /// context, x, y, radius, feather size /// create off-screen temporary canvas where we draw in the shadow var temp = document.createElement('canvas'), tx = temp.getContext('2d'); temp.width = ctx.canvas.width; temp.height = ctx.canvas.height; /// offset the context so shape itself is drawn outside canvas tx.translate(-temp.width, 0); /// offset the shadow to compensate, draws shadow only on canvas tx.shadowOffsetX = temp.width; tx.shadowOffsetY = 0; /// black so alpha gets solid tx.shadowColor = '#000'; /// "feather" tx.shadowBlur = f; /// draw the arc, only the shadow will be inside the context tx.beginPath(); tx.arc(x, y, r, 0, 2 * Math.PI); tx.closePath(); tx.fill(); /// now punch a hole in main canvas with the blurred shadow ctx.save(); ctx.globalCompositeOperation = 'destination-out'; ctx.drawImage(temp, 0, 0); ctx.restore(); }
That is all that is needed.
USING
clipArc(context, centerX, centerY, radius, featherSize);
With demo background (see violin):
ctx.fillStyle = '#ffa'; ctx.fillRect(0, 0, demo.width, demo.height); clipArc(ctx, 200, 200, 150, 40);
Result:

If you want to keep the center unchanged, simply replace the composite mode with destination-in .
Demo for an inverted feathered mask
