2012-01-02 17 views
32

Ho una tela <div style="border:1px solid border;" /> e, redatto utilizzando:disegni su tela, come le linee, sono sfocate

context.lineWidth = 1; 
context.strokeStyle = "gray"; 

Il disegno sembra abbastanza sfocata (lineWidth meno di un crea un'immagine ancora peggio), e nulla vicino il confine del div. È possibile ottenere la stessa qualità di disegno dell'HTML usando la tela?

var ctx = document.getElementById("canvas").getContext("2d"); 
 
ctx.lineWidth = 1; 
 
ctx.moveTo(2, 2); 
 
ctx.lineTo(98, 2); 
 
ctx.lineTo(98, 98); 
 
ctx.lineTo(2, 98); 
 
ctx.lineTo(2, 2); 
 
ctx.stroke();
div { 
 
    border: 1px solid black; 
 
    width: 100px; 
 
    height: 100px; 
 
} 
 
canvas, div {background-color: #F5F5F5;} 
 
canvas {border: 1px solid white;display: block;}
<table> 
 
<tr><td>Line on canvas:</td><td>1px border:</td></tr> 
 
<tr><td><canvas id="canvas" width="100" height="100"/></td><td><div>&nbsp;</div></td></tr> 
 
</table>

risposta

29

Quando si disegna linee in tela, hai veramente bisogno di cavalcare i pixel. E 'stata una scelta bizzarra nell'API a mio parere, ma facile da lavorare con:

invece di questo:

context.moveTo(10, 0); 
context.lineTo(10, 30); 

fare questo:

context.moveTo(10.5, 0); 
context.lineTo(10.5, 30); 

dive into HTML5's canvas chapter talks about this nicely
(cercare il Casella 'ASK PROFESSOR MARKUP' a circa 1/4 di via)

+0

Anche le coordinate Y devono essere sfalsate di 1/2 di pixel? – user1118321

+1

Sì, probabilmente dovrebbero anche loro. In Dive in HTMl5 non ha infastidito, perché stava disegnando linee chiare su tutta la tela, quindi ho appena copiato ciò che ha da leggere leggendo la mia risposta e poi leggendo la sua spiegazione in modo più coerente. –

43

Ancora più semplice è utilizzare semplicemente questo:

context = canvas.context2d;  
context.translate(0.5, 0.5); 

Da qui in avanti le coordinate devono essere regolate di 0,5 pixel.

+3

My fillRect ora è sfocato :(http://jsfiddle.net/Tysonzero/ydm21pkt/1/ – semicolon

+0

@semicolon devi tradurre il canvas perpendicolare alla direzione in cui sta andando la linea che stai disegnando. Non hai bisogno per tradurre fillRect a meno che non li disegni su un pixel x.5 –

44

Ho trovato che l'impostazione della dimensione della tela in CSS ha causato la visualizzazione delle mie immagini in modo sfocato.

Prova questo:

<canvas id="preview" width="640" height="260"></canvas> 

come per il mio post: HTML Blurry Canvas Images

+1

Aggiungendo a questo, dovresti impostare idealmente gli attributi width e height nonostante l'impostazione di queste proprietà tramite CSS. –

+0

Ben risolti! Il trucco. – mtyson

+0

Buona soluzione. il problema –

1

Per evitare questo problema in animazione Vorrei condividere un piccolo demo.

Fondamentalmente sto verificando i valori di incremento ogni volta che & salta in un set di 1px rimuovendo i valori float.

HTML:

<canvas id="canvas" width="600" height="600"></canvas> 

CSS:

html, body{ 
    height: 100%; 
    } 
    body{ 
    font-family: monaco, Consolas,"Lucida Console", monospace; 
    background: #000; 
    } 

    canvas{ 
    position: fixed; 
    top: 0; 
    left: 0; 
    transform: translateZ(0); 
    } 

JS:

canvas = document.getElementById('canvas'); 
    ctx = canvas.getContext('2d'); 

    ctx.translate(0.5, 0.5); 

    var i = 0; 
    var iInc = 0.005; 
    var range = 0.5; 

    raf = window.requestAnimationFrame(draw); 

    function draw() { 
    var animInc = EasingFunctions.easeInQuad(i) * 250; 
    ctx.clearRect(0, 0, 600, 600); 
    ctx.save(); 
    ctx.beginPath(); 
    ctx.strokeStyle = '#fff'; 
    var rectInc = 10 + animInc; 

    // Avoid Half Pixel 
    rectIncFloat = rectInc % 1; // Getting decimal value. 
    rectInc = rectInc - rectIncFloat; // Removing decimal. 

    // console.log(rectInc); 
    ctx.rect(rectInc, rectInc, 130, 60); 
    ctx.stroke(); 
    ctx.closePath(); 

    ctx.font = "14px arial"; 
    ctx.fillStyle = '#fff'; 
    ctx.textAlign = 'center'; 
    ctx.fillText("MAIN BUTTON", 65.5 + rectInc, 35.5 + rectInc); 

    i += iInc; 

    if (i >= 1) { 
     iInc = -iInc; 
    } 
    if (i <= 0) { 
     iInc = Math.abs(iInc); 
    } 

    raf = window.requestAnimationFrame(draw); 
    } 


    // Easing 
    EasingFunctions = { 
    // no easing, no acceleration 
    linear: function(t) { 
     return t 
    }, 
    // accelerating from zero velocity 
    easeInQuad: function(t) { 
     return t * t 
    }, 
    // decelerating to zero velocity 
    easeOutQuad: function(t) { 
     return t * (2 - t) 
    }, 
    // acceleration until halfway, then deceleration 
    easeInOutQuad: function(t) { 
     return t < .5 ? 2 * t * t : -1 + (4 - 2 * t) * t 
    }, 
    // accelerating from zero velocity 
    easeInCubic: function(t) { 
     return t * t * t 
    }, 
    // decelerating to zero velocity 
    easeOutCubic: function(t) { 
     return (--t) * t * t + 1 
    }, 
    // acceleration until halfway, then deceleration 
    easeInOutCubic: function(t) { 
     return t < .5 ? 4 * t * t * t : (t - 1) * (2 * t - 2) * (2 * t - 2) + 1 
    }, 
    // accelerating from zero velocity 
    easeInQuart: function(t) { 
     return t * t * t * t 
    }, 
    // decelerating to zero velocity 
    easeOutQuart: function(t) { 
     return 1 - (--t) * t * t * t 
    }, 
    // acceleration until halfway, then deceleration 
    easeInOutQuart: function(t) { 
     return t < .5 ? 8 * t * t * t * t : 1 - 8 * (--t) * t * t * t 
    }, 
    // accelerating from zero velocity 
    easeInQuint: function(t) { 
     return t * t * t * t * t 
    }, 
    // decelerating to zero velocity 
    easeOutQuint: function(t) { 
     return 1 + (--t) * t * t * t * t 
    }, 
    // acceleration until halfway, then deceleration 
    easeInOutQuint: function(t) { 
     return t < .5 ? 16 * t * t * t * t * t : 1 + 16 * (--t) * t * t * t * t 
    } 
    } 
2

uso un display retina e ho trovato una soluzione che ha funzionato per me here.

Piccolo riassunto:

In primo luogo è necessario impostare la dimensione della tua tela due volte più grande come si desidera, ad esempio:

canvas = document.getElementById('myCanvas'); 
canvas.width = 200; 
canvas.height = 200; 

Quindi, utilizzando i CSS si imposta al desiderato dimensioni:

canvas.style.width = "100px"; 
canvas.style.height = "100px"; 

E infine si scala contesto disegno di 2:

canvas.getContext('2d').scale(2,2); 
Problemi correlati