2013-09-28 5 views
5

Ich versuche, ein glattes Oval mit ctx.clip -Eigenschaft in meiner Leinwand zu zeichnen.Ich habe mit Zeichnung Teil ich bin mit dem Problem mit ovalen Bogen Klarheit Linie konfrontiert.Jemand hat eine Ahnung hinsichtlich das lass es mich wissen? Hier ist mein Code. hier über die Linie Grenze oval nicht viel klarWie zeichne ein glattes Oval in Leinwand

<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

können Sie diese Ausgabe sehen. Here is output of screen shot

+2

A eine Pixelzeile wird nicht ganz klar sein, Sie zu Anti-Alias ​​haben würde es –

+0

was exacly @JuanMendes –

Antwort

2

Ein Problem liegt in der Natur des Bildschirms ...

Da Pixel Rechtecke sind und Sie zeichnen eine Kurve, Ihr Ergebnis haben wird „Treppchen“ wie die Kurve versucht, sich in rechteckigen Räumen anzupassen.

Sie können eine optische Täuschung verwenden, um das Auge dazu zu bringen, ein weniger gezacktes Oval zu sehen.

Ein optischer Trick:

reduzieren den Kontrast zwischen der Hintergrundfarbe und der Farbe oval.

Dies ist keine Heilung ... die Jaggies sind immer noch da.

Aber das Auge erkennt weniger Kontrast und nimmt das Oval als weicher wahr.

Also, wenn Ihr Design diese Stiländerung aufnimmt, könnte diese optische Täuschung helfen.

Hier Code und ein 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

Dies ist auch nicht zu viel klar, wenn ich dies in meinem Code –

+0

Ok Ok habe ich eine Lösung gefunden, die ich denke, ein paar min wil update. – OBV

+0

http://jsbin.com/ecipiq/5/edit Checkout-Anti-Aliasing-Ansatz, sehe keine Unterschiede tbh. – OBV

0

Eine Möglichkeit ist es, eine dickere Linie zu verwenden, ist es nicht toll, aber es ist besser

ctx.lineWidth = 3; 

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

Ich habe auch bemerkt, dass quadraticCurveTo mit Anti scheint Alias ​​die Zeile http://jsfiddle.net/d4JJ8/298/ Ich habe Ihren Code nicht geändert um es zu benutzen, aber die Jfiddle, die ich gepostet habe, zeigt, dass es wahr ist. Sie sollten Ihren Code ändern, und versuchen Sie es

+0

Ich sah es, aber wenn ich den Text wähle wird es wieder unklar. –

+1

@SanjayNakate Ich sehe nicht, was Sie beobachten, es sieht genauso aus, wenn ich den Text (in Chrome) –

+0

Ich denke, dass ein dicker Bleistift ist so einfach und so gut wie es geht. +1 – Xotic750

1

Hier ist eine andere alternative Routine ist, aber es sieht optisch die gleichen wie die anderen Methoden. Dies ist in erster Linie mit der endlichen Auflösung des Anzeigegeräts zu tun, obwohl Sie möglicherweise in der Lage sind, etwas Verbesserung mit einem dickeren Bleistift, optischen Täuschungen oder Anti-Aliasing durchzuführen. Ansonsten denke ich, dass du akzeptieren musst, was du hast.

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

Hinweis: durch die Anzahl der Schritte zu ändern und den Faktor, können Sie andere Formen erstellen: Kreise, Quadrate, Hexagone, andere Polygone ....

+1

+1 Und hier ist eine Variante, die die Angabe x und y Radius ermöglicht: http://jsfiddle.net/AbdiasSoftware/VrKJV/ – K3N

+0

@ Ken Das scheint einen schönen Anti-Aliasing-Effekt zu geben. – Xotic750

+0

@ken Ich bemerke, es sieht genauso aus wie alle anderen Methoden einmal 'ctx.clip()' heißt [jsfiddle] (http://jsfiddle.net/Xotic750/8gG9p/) – Xotic750

3

versuchen, dies es wird Ihnen helfen // 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