2013-09-28 6 views
5

Próbuję narysować gładką owal wykorzystaniem mienia ctx.clip w moich canvas.I zrobili z rysunku część Jestem stoi problem z owalną linią łuku clarity.Any jeden ma jakiś pomysł odnośnie to po prostu daj mi znać? Oto mój kod.Jak narysować gładką owalny płótnie

<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

Widać to wyjście tutaj granicy linii owalny niedużo jasne. Here is output of screen shot

+2

Linia jeden piksel nie będzie bardzo jasne, trzeba by Wygładzanie to –

+0

co exacly @ JuuanMendes –

Odpowiedz

2

Jeden problem jest z natury swojej ekranie ...

Ponieważ piksele są prostokąty i jesteś rysowanie krzywej, Twój wynik będzie mieć „schodków” ponieważ krzywa próbuje dopasować się do prostokątnych przestrzeni.

Można użyć złudzenie optyczne na oszukanie oka ujrzała mniej postrzępione owal.

trik optyczny:

Zmniejsz kontrast pomiędzy kolorem tła i owalnego koloru.

To nie jest lekarstwo na ... jaggies są nadal.

Ale oko rozpoznaje mniejszy kontrast i postrzega jako owal bardziej gładka.

Więc jeśli projekt pomieścić tę zmianę stylu, to złudzenie optyczne może pomóc.

Oto kod i Fiddle: 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

To również nie jest zbyt jasne, kiedy integruję to w moim kodzie –

+0

Ok Znalazłem rozwiązanie, które myślę, kilka minut aktualizacji min. – OBV

+0

http://jsbin.com/ecipiq/5/edit Checkout anti-aliasing, nie widzę różnicy tbh. – OBV

0

Możliwość jest użycie grubszej linii, to nie jest wielki, ale lepsze to

ctx.lineWidth = 3; 

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

Zauważyłem również, że za pomocą quadraticCurveTo wydaje się przeciw alias linii http://jsfiddle.net/d4JJ8/298/ Nie zmieniłem twojego kodu używać go, ale jsfiddle, który napisałem, pokazuje, że to prawda. Należy zmodyfikować kod i spróbuj go

+0

Widziałem to, ale kiedy zaznaczam tekst, jego kolejność będzie niejasna. –

+1

@SanjayNakate Nie widzę tego, co obserwujesz, wygląda dokładnie tak samo, gdy zaznaczam tekst (w Chrome). –

+0

Myślę, że grubszy ołówek jest mniej więcej tak prosty i tak dobry, jak tylko się da. +1 – Xotic750

1

Oto kolejna alternatywa rutyna, ale wygląda wizualnie takie same jak w innych metodach. Jest to przede wszystkim do czynienia z skończonej rozdzielczości urządzenia wyświetlającego, choć może być w stanie dokonać pewnych ulepszeń użyciu grubszej ołówek, złudzeń optycznych lub wykonywania niektórych wygładzanie. W przeciwnym razie myślę, że będziesz musiał zaakceptować to, co masz.

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

Uwaga: zmieniając liczbę kroków i czynnik, można utworzyć inne kształty: koła, kwadraty, sześciokąty, inne wielokąty ....

+1

+1 A tutaj jest wariant, który pozwala określić promień X i Y: http://jsfiddle.net/AbdiasSoftware/VrKJV/ – K3N

+0

@ Wydaje się, że Ken wydaje dobry efekt anty aliasowy. – Xotic750

+0

@ken Zauważam, że wygląda tak samo jak wszystkie inne metody, gdy 'ctx.clip()' jest nazywane [jsfiddle] (http://jsfiddle.net/Xotic750/8gG9p/) – Xotic750

3

spróbować to pomoże Ci // Script

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(); 
} 

Fiddle Demo