2013-09-28 25 views
5

Sto cercando di disegnare un ovale liscio usando la proprietà ctx.clip nella mia tela. Ho fatto con la parte del disegno sto affrontando il problema con la chiarezza ovale della linea d'arco. Qualcuno ha qualche idea riguardo questo fammelo sapere? Ecco il mio codice.Come disegnare un ovale liscio su tela

<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

Si può vedere questa uscita qui la linea di confine di forma ovale non molto chiaro. Here is output of screen shot

+2

Una linea un pixel non sta per essere molto chiaro, che avrebbe dovuto antialiasing è –

+0

cosa exacly @JuanMendes –

risposta

2

Un problema è nella natura del vostro schermo ...

Dal pixel sono rettangoli e si sta disegnando una curva, il risultato avrà "bordi frastagliati" mentre la curva cerca di adattarsi a spazi rettangolari.

È possibile utilizzare un'illusione ottica per ingannare l'occhio e vedere un ovale meno frastagliato.

Un trucco ottico:

ridurrà il contrasto tra il colore di sfondo e il colore ovale.

Questa non è una cura ... i getti sono ancora lì.

Ma l'occhio riconosce meno contrasto e percepisce l'ovale come più liscio.

Quindi, se il tuo design è adatto a questo cambiamento di stile, questa illusione ottica potrebbe essere d'aiuto.

Ecco codice e un violino: 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

Anche questo non è molto chiaro quando lo integro nel mio codice –

+0

Ok ho trovato una soluzione, penso, qualche minuto di aggiornamento. – OBV

+0

http://jsbin.com/ecipiq/5/edit checkout anti-aliasing, non vedo la nostra differenza tbh. – OBV

0

Una possibilità è quella di utilizzare una linea più spessa, non è grande, ma è meglio

ctx.lineWidth = 3; 

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

Ho anche notato che usando quadraticCurveTo sembra di anti alias la riga http://jsfiddle.net/d4JJ8/298/ Non ho cambiato il tuo codice per usarlo ma il jsfiddle che ho postato mostra che è vero. Si dovrebbe modificare il codice e provarlo

+0

L'ho visto ma quando seleziono il testo non si chiarirà più. –

+1

@SanjayNakate Non vedo quello che stai osservando, sembra esattamente lo stesso quando seleziono il testo (in Chrome) –

+0

Penso che una matita più spessa sia tanto semplice quanto buona. +1 – Xotic750

1

Ecco un altro di routine alternativa, ma sembra visivamente lo stesso come gli altri metodi. Questo è principalmente dovuto alla risoluzione finita del dispositivo di visualizzazione, anche se potresti essere in grado di fare qualche miglioramento usando una matita più spessa, delle illusioni ottiche o eseguendo qualche anti-aliasing. Altrimenti penso che dovrai accettare quello che hai.

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

Nota: cambiando il numero di passi e il fattore, è possibile creare altre forme: cerchi, quadrati, esagoni, altri poligoni ....

+1

+1 E qui c'è una variante che permette di specificare il raggio xey: http://jsfiddle.net/AbdiasSoftware/VrKJV/ – K3N

+0

@ Ken sembra dare un buon effetto anti alias. – Xotic750

+0

@ken Ho notato che sembra uguale a tutti gli altri metodi una volta 'ctx.clip()' è chiamato [jsfiddle] (http://jsfiddle.net/Xotic750/8gG9p/) – Xotic750

3

provare questo vi aiuterà a // 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

Problemi correlati