2010-09-07 10 views
5

Sto leggendo un libro su Html5 e su tela, il codice seguente genererà linee spesse 1 pixel ... Usa 0.5 come coordinate. Se viene modificato su 0 o 10 o su un numero intero, le linee saranno grigie e spesse 2 pixel. Perché? Che la cosa più strana che ho visto ultimamente ... tutta la programmazione precedente su API Apple o Win32, passano per coordinate intere.In Html5, traccia da (0,5, 0) a (0,5, 600) per ottenere una linea spessa 1 pixel su tela. Lo 0,5 è strano?

<!DOCTYPE html> 

<body> 
<canvas id="c" width="800" height="600"></canvas> 
</body> 

<script> 

var c_canvas = document.getElementById("c") 
var context = c_canvas.getContext("2d") 

for (x = 0.5; x < 500; x += 10) { 
    context.moveTo(x, 0) 
    context.lineTo(x, 375) 
} 
context.strokeStyle = "#000" 
context.stroke() 


</script> 

Un'altra cosa strana è, per ottenere un 1 pixel per 1 pixel puntino nero, devo attingere 0,5 per x, ma lo uso interi per y

for (x = 0.5; x < 500; x += 10) { 
    context.moveTo(x, 0) 
    context.lineTo(x, 1) 
} 

se uso il seguente, poi ho un grigio, "più a lungo punto"

for (x = 0.5; x < 500; x += 10) { 
    context.moveTo(x, 0.5) 
    context.lineTo(x, 1.5) 
} 

risposta

6

io non sono sicuro che è lo stesso con HTML5, ma sembra molto simile a come le offerte libreria Qt con la pittura. Essenzialmente, le coordinate (0,0) e (1,1) definiscono un pixel nell'angolo in alto a sinistra - il suo centro si trova quindi a (0,5, 0,5).

Ha a che fare con antialiasing - se si "disegna" un pixel nero a (1,1), 4 pixel grigi sarà effettivamente essere verniciato grigio, tra (0,0) e (2,2). Maggiori informazioni su questo in C++ GUI programming with Qt 4.

11

Grazie MiKy. Ho anche trovato qualche spiegazione su:

https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Applying_styles_and_colors#A_lineWidth_example

Questo è il contenuto rilevante:

ottenere linee nitide richiede la comprensione di come i percorsi vengono accarezzati. In le immagini sottostanti, la griglia rappresenta la griglia delle coordinate del canvas. I quadrati tra le linee della griglia sono pixel sullo schermo effettivi. Nella prima immagine della griglia sotto, viene riempito un rettangolo da (2,1) a (5,5). L'area intera tra di loro (rosso chiaro) cade sui limiti dei pixel, pertanto il rettangolo pieno risultante di avrà bordi nitidi.

Crisp and Blurry lines example

Se si considera un percorso da (3,1) a (3,5) con uno spessore di linea di 1.0, si finisce con la situazione nella seconda immagine. L'area effettiva da riempire (blu scuro) si estende solo a metà dei pixel su su entrambi i lati del percorso. Un'approssimazione di questo deve essere reso, che significa che i pixel di essere solo parzialmente ombreggiati, e risultati nell'intera area (la luce blu e blu scuro) essendo riempita con un colore solo la metà buia come la corsa effettiva colore. Questo è ciò che si verifica con la riga di larghezza 1.0 nel codice di esempio precedente.

Per risolvere questo problema, è necessario essere molto precisi nella vostra creazione percorso. Sapendo che una linea di larghezza 1.0 estenderà metà unità a entrambi i lati del percorso, creando il percorso da (3,5,1) a (3,5,5) risultati nella situazione nella terza immagine, la larghezza della linea 1.0 finisce completamente e riempiendo precisamente una linea verticale a singolo pixel.

+0

+1 - Link ha la spiegazione migliore, con alcuni buoni diagrammi. – Castrohenge

+0

Questo collegamento spiega il problema e la soluzione. –

+0

Il link è ora rotto – streppel

2

In breve, i pixel non possono essere divisi. Quando si usa lineTo per disegnare una linea da 1 pixel, la linea è centrata sulla coordinata che si specifica. Se width = 1 e la coordinata è un intero, allora stai chiedendo di disegnare 2 metà di un pixel.

Poiché non è possibile attivare mezzo pixel, la libreria arrotonda al pixel divisibile più vicino su entrambi i lati.

0

Io più o meno combatto con quello quando, dopo un po 'di tempo, ricomincio a usare la tela - si sta lavorando con linee "matematiche" e non con linee sullo schermo.

Come altri menzionato - una linea da (1,1) a (1,10) inizia tra pixel (0/0, 1/1) e termina tra (0/10, 1/11)

quindi è da 1 pixel ad ampio e da 1 pixel ad alto. ma ben un po 'più leggero ...

La mia soluzione, se si utilizza la tela per disegnare solo "hard - interi - Linee", ad esempio, per creare un controllo, è quello di utilizzare transform(1,0,0,1,0.5,0.5) (o transform(1,0,0,1,-0.5,-0.5) dipende se si vuole iniziare con 0 o 1)

(io uso trasformare per ottenere sicuro, che non c'è un (a) o (d) fare di nuovo la mia vita dura)

basta spostare a zero sulla linea "tra 0 e 1" (ora sapete il mio Nickname ...)

Questo funziona bene in tutti i miei casi in cui sto disegnando (o devo disegnare) "pixeled"

Problemi correlati