2013-09-28 119 views
5

我想在我的畫布中使用ctx.clip屬性繪製光滑的橢圓。我已完成繪畫部分,我正面臨着橢圓弧線條清晰度問題。任何人都有任何想法這只是讓我知道? 這是我的代碼。如何在畫布上繪製光滑的橢圓

<canvas id="c" width="400" height="400"></canvas> 


var canvas = new fabric.Canvas('c'); 
var ctx = canvas.getContext('2d'); 
var cx=180; 
var cy=200; 
var w=300; 
var h=250; 
    // Quadratric curves example 
    ctx.beginPath(); 
    var lx = cx - w/2, 
     rx = cx + w/2, 
     ty = cy - h/2, 
     by = cy + h/2; 
    var magic = 0.551784; 
    var xmagic = magic*w/2; 
    var ymagic = h*magic/2; 
    ctx.moveTo(cx,ty); 
    ctx.bezierCurveTo(cx+xmagic,ty,rx,cy-ymagic,rx,cy); 
    ctx.bezierCurveTo(rx,cy+ymagic,cx+xmagic,by,cx,by); 
    ctx.bezierCurveTo(cx-xmagic,by,lx,cy+ymagic,lx,cy); 
    ctx.bezierCurveTo(lx,cy-ymagic,cx-xmagic,ty,cx,ty); 

    ctx.fill(); 
    ctx.stroke(); 
    ctx.clip(); 



var text; 
text = new fabric.Text('Honey', { 
    fontSize: 50, 
    left: 150, 
    top: 150, 
    lineHeight: 1, 
    originX: 'left', 
    fontFamily: 'Helvetica', 
    fontWeight: 'bold' 
}); 
canvas.add(text); 

Here is my fiddle link

你可以看到在這裏的橢圓形不多明確的邊界線該輸出。 Here is output of screen shot

+2

一個像素線不會是很清楚,你不得不防鋸齒它 –

+0

什麼exacly @JuanMendes –

回答

2

的一個問題是你的顯示屏幕的性質...

由於像素是長方形和您繪製的曲線,你的結果將有「鋸齒」因爲曲線試圖使自己適應矩形空間。

您可以使用光學錯覺來誘使眼睛看到一個鋸齒狀的橢圓。

一種光學特技:

降低背景顏色和顏色橢圓之間的對比度。

這不是治癒...鋸齒仍然存在。

但眼睛識別較少的對比度,並認爲橢圓更光滑。

所以,如果你的設計適應這種風格的變化,這種錯覺可能會有所幫助。

這裏的代碼和一個小提琴:http://jsfiddle.net/m1erickson/vDWR3/

var cx=180; 
var cy=200; 
var w=300; 
var h=250; 

// Start with a less-contrasting background 
ctx.fillStyle="#ddd"; 
ctx.fillRect(0,0,canvas.width,canvas.height); 

ctx.beginPath(); 
var lx = cx - w/2, 
    rx = cx + w/2, 
    ty = cy - h/2, 
    by = cy + h/2; 
var magic = 0.551784; 
var xmagic = magic*w/2; 
var ymagic = h*magic/2; 
ctx.moveTo(cx,ty); 
ctx.bezierCurveTo(cx+xmagic,ty,rx,cy-ymagic,rx,cy); 
ctx.bezierCurveTo(rx,cy+ymagic,cx+xmagic,by,cx,by); 
ctx.bezierCurveTo(cx-xmagic,by,lx,cy+ymagic,lx,cy); 
ctx.bezierCurveTo(lx,cy-ymagic,cx-xmagic,ty,cx,ty); 

ctx.fillStyle="#555"; 
ctx.strokeStyle=ctx.fillStyle; 
ctx.lineWidth=1.5; 
ctx.stroke(); 
0
<canvas id="thecanvas" width="400" height="400"></canvas> 

<script> 
var canvas = document.getElementById('thecanvas'); 

if(canvas.getContext) 
{ 
    var ctx = canvas.getContext('2d'); 
    drawEllipse(ctx, 10, 10, 100, 60); 
    drawEllipseByCenter(ctx, 60,40,20,10); 
} 

function drawEllipseByCenter(ctx, cx, cy, w, h) { 
    drawEllipse(ctx, cx - w/2.0, cy - h/2.0, w, h); 
} 

function drawEllipse(ctx, x, y, w, h) { 
    var kappa = .5522848, 
     ox = (w/2) * kappa, // control point offset horizontal 
     oy = (h/2) * kappa, // control point offset vertical 
     xe = x + w,   // x-end 
     ye = y + h,   // y-end 
     xm = x + w/2,  // x-middle 
     ym = y + h/2;  // y-middle 

    ctx.beginPath(); 
    ctx.moveTo(x, ym); 
    ctx.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); 
    ctx.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); 
    ctx.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); 
    ctx.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); 
    ctx.closePath(); 
    ctx.stroke(); 
} 

</script> 

http://jsbin.com/ovuret/2/edit

+0

這也是不以多少清楚,當我在我的代碼集成這 –

+0

好,我找到了一個解決方案,我想,很少分鐘WIL更新。 – OBV

+0

http://jsbin.com/ecipiq/5/edit結賬抗鋸齒的方式,不認爲併購UCH差異TBH。 – OBV

0

一種可能性是使用較粗的線,這是不是很大,但它的更好

ctx.lineWidth = 3; 

http://jsfiddle.net/xadqg/7/

我也注意到,使用quadraticCurveTo似乎反別名爲http://jsfiddle.net/d4JJ8/298/我沒有更改您的代碼使用它,但我發佈的jsfiddle顯示它是真的。你應該修改你的代碼,並嘗試

+0

我看到它,但是當我選擇文本時,它會再次不清楚。 –

+1

@SanjayNakate我沒有看到你正在觀察,當我選擇文本(在Chrome) –

+0

我認爲較厚的鉛筆一樣簡單和好得不能再好長得一模一樣。 +1 – Xotic750

1

這裏是另一種選擇常規,但它看起來視覺上相同的其他方法。這主要是爲了解決顯示設備的有限分辨率問題,儘管您可以使用較粗的鉛筆,光學錯覺或執行一些抗鋸齒功能來進行一些改進。否則,我認爲你將不得不接受你擁有的東西。

的Javascript

var canvas = new fabric.Canvas('c'), 
    ctx = canvas.getContext("2d"), 
    steps = 100, 
    step = 2 * Math.PI/steps, 
    h = 200, 
    k = 180, 
    r = 150, 
    factor = 0.8, 
    theta, 
    x, 
    y, 
    text; 

ctx.beginPath(); 

for (theta = 0; theta < 2 * Math.PI; theta += step) { 
    x = h + r * Math.cos(theta); 
    y = k - factor * r * Math.sin(theta); 
    ctx.lineTo(x, y); 
} 

ctx.closePath(); 
ctx.fill(); 
ctx.stroke(); 
ctx.clip(); 

text = new fabric.Text('Honey', { 
    fontSize: 50, 
    left: 150, 
    top: 150, 
    lineHeight: 1, 
    originX: 'left', 
    fontFamily: 'Helvetica', 
    fontWeight: 'bold' 
}); 

canvas.add(text); 

jsfiddle

注:通過改變步數和因素,你可以創建其他形狀:圓形,方形,六角形,其他多邊形....

+1

+1這裏是一個變種,它允許指定x和y半徑:http://jsfiddle.net/AbdiasSoftware/VrKJV/ – K3N

+0

@肯似乎給了一個很好的反鋸齒效果。 – Xotic750

+0

@ken我發現它看起來同所有其他方法一旦'ctx.clip()'稱爲[的jsfiddle(http://jsfiddle.net/Xotic750/8gG9p/) – Xotic750

3

試試這個它會幫助你 //腳本

var canvas = new fabric.Canvas('c'); 
var w; 
var h; 
var ctx = canvas.getContext('2d'); 
w=canvas.width/4; 
h=canvas.height/2.4; 
canvas.clipTo = function(ctx) { 
ctx.save(); 
ctx.scale(2, 1.2); 
ctx.arc(w, h, 90, 0, 2 * Math.PI, true); 
ctx.stroke(); 
ctx.restore(); 
} 

小提琴Demo