Trois solutions possibles :
-
Vous pourriez écrire vos lignes dans un canevas hors écran, appliquer un filtre de flou, puis dessiner le résultat dans le canevas visible.
-
Si vous n'utilisez que des segments de ligne droite, vous pouvez utiliser un gradient linéaire pour chaque segment de ligne. La direction du gradient doit former un angle de 90° par rapport à la direction du segment de ligne.
-
Tracez les mêmes lignes plusieurs fois au même endroit. D'abord avec la pleine largeur et un alpha faible. Puis diminuez la largeur et augmentez l'alpha.
Exemple d'utilisation d'un gradient linéaire pour chaque segment de ligne :
http://jsfiddle.net/chdh/MmYAt/
function drawSoftLine(x1, y1, x2, y2, lineWidth, r, g, b, a) {
var lx = x2 - x1;
var ly = y2 - y1;
var lineLength = Math.sqrt(lx*lx + ly*ly);
var wy = lx / lineLength * lineWidth;
var wx = ly / lineLength * lineWidth;
var gradient = ctx.createLinearGradient(x1-wx/2, y1+wy/2, x1+wx/2, y1-wy/2);
// The gradient must be defined accross the line, 90° turned compared
// to the line direction.
gradient.addColorStop(0, "rgba("+r+","+g+","+b+",0)");
gradient.addColorStop(0.43, "rgba("+r+","+g+","+b+","+a+")");
gradient.addColorStop(0.57, "rgba("+r+","+g+","+b+","+a+")");
gradient.addColorStop(1, "rgba("+r+","+g+","+b+",0)");
ctx.save();
ctx.beginPath();
ctx.lineWidth = lineWidth;
ctx.strokeStyle = gradient;
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
ctx.restore(); }
Exemple pour dessiner une ligne plusieurs fois, en diminuant la largeur et en augmentant l'alpha :
http://jsfiddle.net/chdh/RmtxL/
function drawSoftLine(x1, y1, x2, y2, lineWidth, r, g, b, a) {
ctx.save();
var widths = [1 , 0.8 , 0.6 , 0.4 , 0.2 ];
var alphas = [0.2 , 0.4 , 0.6 , 0.8 , 1 ];
var previousAlpha = 0;
for (var pass = 0; pass < widths.length; pass++) {
ctx.beginPath();
ctx.lineWidth = lineWidth * widths[pass];
var alpha = a * alphas[pass];
// Formula: (1 - alpha) = (1 - deltaAlpha) * (1 - previousAlpha)
var deltaAlpha = 1 - (1 - alpha) / (1 - previousAlpha)
ctx.strokeStyle = "rgba(" + r + "," + g + "," + b + "," + deltaAlpha + ")";
ctx.moveTo(x1, y1);
ctx.lineTo(x2, y2);
ctx.stroke();
previousAlpha = alpha; }
ctx.restore(); }