• Das Erstellen neuer Accounts wurde ausgesetzt. Bei berechtigtem Interesse bitte Kontaktaufnahme über die üblichen Wege. Beste Grüße der Admin

[FRAGE] Checkerboard Pattern in Canvas zeichnen

salazar

New member
Ein HALLO in die Runde,
das ist mein erster Beitrag hier.

Ich grübel im Moment an einem Problem rum und glaube der Lösung schon recht nah zu sein. Nur komme ich aktuell nicht weiter. In meinem Script ist immer noch ein Fehler drin.

Worum geht es.
Ich möchte gern mit der folgenden Function ein Schachbrettmuster in die Canvas zeichnen. Das Ganze per Pixelzugriff über das ImageData Array. Es funktioniert auch schon, jedoch sieht man im Muster immer einen Fehler, und zwar in Form einer diagonalen Linie. Ich komm dem Problem nicht auf die Schliche.
Hier die Function:
HTML:
function checkerboard() {

	var pixelsPerLine = Math.floor( ( w * unit ) / pixelWidth );

    if ( pixelsPerLine % 2 === 0 ) {
    
    	pixelsPerLine += 2;
    
    } else {
    
    	pixelsPerLine += 3;
    
    }
    
    var lineWidth = pixelsPerLine * pixelWidth;

    var valueStartIndex = w * unit;
    var valueLength = lineWidth - valueStartIndex;
    var valueEndIndex = valueStartIndex + valueLength;

	var index = 0;

    for ( var i = 0, l = lineWidth * h; i < l; i += unit ) {
   
        if ( i % pixelWidth === 0 )
        	colorSwitch = !colorSwitch;
            
        if ( i % pixelHeight === 0 )
        	colorSwitch = !colorSwitch;

        if ( colorSwitch )
        	color = color1;
        else
        	color = color2;
        
        data[ index ]     = color;
        data[ index + 1 ] = color;
        data[ index + 2 ] = color;
        data[ index + 3 ] = 255;
        
        if ( i > valueStartIndex ) {
    
            if ( i === valueEndIndex ) {

                valueStartIndex += lineWidth;
                valueEndIndex = valueStartIndex + valueLength;

            }

        } else {

            index += 4;

        }

    }
    
};

HIER das jsfiddle Bsp.

In der folgenden Zeile könnt ihr die Größe der Schachbrettfelder einstellen:
var pixelSize = 3;//<-------------------------------------------------------------------
Vor allem bei kleinen Größen (2-5) sieht man den Fehler besonders gut.

Vielleicht findet ja von euch wer den Fehler. Würde mich super freuen.
Vielen Dank!

- - - Aktualisiert - - -

Jetzt bin ich schon ein ganzes Stück weiter.
Dieser Bug mit den diagonalen Linien ist raus:
jsfiddle

Jedoch sieht man bei genauer Betrachtung ganz links noch immer einen 1 Pixel Bug... Falls also wer eine Idee hat. Immer gerne her damit.

Vielen Dank
 
irgendwie ist das recht unübersichtlich,
w scheint die canvasbreite zu sein? h dann die höhe?

dann würde ich das so etwa machen
Code:
function checkerboard()
{
  var color = [0x00, 0xFF];
  var pixelSize = 3;
  for (var i = 0; i < h; ++i)
  {
    var lc = Math.floor(i / pixelSize) % 2 ? 1 : 0;
    for (var j = 0; j < w; ++j)
    {
      var cc = Math.floor(j / pixelSize) % 2 ? 1 : 0;
      var c = (lc + cc) % 2;
      var offset = i * w * 4 + j * 4;
      data[offset]     = color[c];
      data[offset + 1] = color[c];
      data[offset + 2] = color[c];
      data[offset + 3] = 255;
    }
  }   
};
 
Hi,
besten Dank für deine Antwort! :)

Genau.
w = Breite der Canvas
h = Höhe der Canvas

In deinem Bsp gibt es zwei for-Schleifen. Da würde ich gerne drauf verzichten und das alles in der einen for-Schleife abfrühstücken in der ich durchs ImageData Array iteriere. Deshalb sieht das auch, zugegeben, etwas unübersichtilich aus... Am Ende aber wird das mit einer besseren Performance belohnt.

Vielen Dank.

Edit: Aber sehr geiles Bsp. von dir tsseh! Werde ich mir in jedem Fall mal näher anschauen!!
 
Zuletzt bearbeitet:
salazar: wir haben derzeit kein [js] tag, stattdessen bitte [html] verwenden.
bei einzeilern bietet sich [inline] an.
gibt im erweiterten editor für beides icons
ich hab das im ersten beitrag schon geändert
 
nein, w*h bleibt w*h

ja, da hast du wohl recht.
Ich war irgendwie sehr scharf drauf das in einer einzigen for-Schleife hinzubekommen. Ärgert mich auch immer noch das ich diesen "Ein-Pixel-Versatz" Bug nicht gefunden habe. Vielleicht findet den ja noch wer... nur aus Interesse.
Danke nochmal für deine Function!
 
das vorgehen ist das selbe
du machst dann deine schleife bis w*h
* du berechnest in welcher zeile du im canvas-koordinatensystem (0-h) bist
* die canvas-koordinaten rechnest du in deine koordinaten um
* dann bestimmst du ob du mit color0 oder color1 deine zeile beginnen musst
* du berechnest die spalte im canvas-koordinatensystem (0-w)
* rechnest die in deine koordinaten um
* aus der anfangsfarbe der zeile und deiner spalte kannst du bestimmen welche farbe deine spalte haben muss

- - - Aktualisiert - - -

allgemeiner dann
Code:
function checkerboard()
{
  var color = [{r: 0xFF, g: 0x00, b: 0x00}, {r: 0x00, g: 0xFF, b: 0x00}, {r: 0x00, g: 0x00, b: 0xFF}];
  var pixelSize = 3;
  for (var i = 0; i < w * h; ++i)
  {
    var l = Math.floor(i / w);
    var c = i - (l * w);
    var ul = Math.floor(l / pixelSize);
    var uc = Math.floor(c / pixelSize);
    var ls = ul % color.length;
    var cc = uc % color.length;
    var c = (ls + cc) % color.length;
    var offset = i * 4;
    data[offset]     = color[c].r;
    data[offset + 1] = color[c].g;
    data[offset + 2] = color[c].b;
    data[offset + 3] = 255;
  }   
};
 
Zurück
Oben