我正在使用HTML5畫布創建繪畫應用程序。如何使用HTML5畫布創建柔和筆觸邊緣
https://github.com/homanchou/sketchyPad
我可以使用RGBA來控制不透明度在我行招,但如何達到柔軟的羽毛刷邊緣VS硬圓邊?
我正在使用HTML5畫布創建繪畫應用程序。如何使用HTML5畫布創建柔和筆觸邊緣
https://github.com/homanchou/sketchyPad
我可以使用RGBA來控制不透明度在我行招,但如何達到柔軟的羽毛刷邊緣VS硬圓邊?
我相當確定這取決於您使用的瀏覽器。最後我查了一下(前一陣子 - 可能已經改變了),Firefox和Chrome並沒有抗鋸齒邊緣,而IE9的確如此。
一旦您將線條提交到畫布,就可以使用CanvasPixelArray類來柔化(模糊)。這只是將您的顏色添加到相鄰像素的問題。 Here is a good info on pixel manipulation。
三種可能的解決方案:
你可以寫你的線條到離屏畫布,應用模糊濾鏡,然後繪製結果爲可見的畫布。
如果您只使用直線段,則可以爲每個線段使用線性漸變。梯度的方向必須與線段的方向相比爲90°角
在同一位置多次繪製相同的線條先用全寬和低α值然後減小寬度並增加阿爾法
實施例使用的線性梯度爲每個線段:
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(); }
示例畫線多次,通過減小寬度和增加的α:
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(); }
我創建了一個jsperf測試來比較這兩個選擇的性能:http://jsperf.com/feathered-canvas-line。看起來畫多行比較快,但我認爲它看起來很醜。 –
可以使用CSS濾波器模糊畫布上。這可能與SVG rasterization trick。你可以這樣做:
製作兩個畫布,一個在另一個之上。其中一個讓我們稱之爲«目標»和另一個«緩衝區»。緩衝區是你所畫的,Target是最終的畫布。
將css-filter: blur(px)
應用於緩衝區畫布,以便用戶可以即時看到模糊預覽。
這是一個有趣的部分。在每個筆畫上(即在mouseup上),柵格化緩衝區畫布,將圖像放入<svg><foreignObject></foreignObject></svg>
,對其應用相同的CSS濾鏡,柵格化SVG,並將柵格化的SVG放置在目標畫布上。這裏是gist with code example。
我不是指antialiased邊緣,它隻影響薄外層像素。看看http://muro.deviantart.com/,他們如何實現這個非常柔和的邊緣幾個像素層? – Homan