Schriftzeichen manuell positionieren in Processing

Hinzugefügt am von Steffen Fiedler

Powered by Processing.js

Mit diesem Beispiel simulieren wir die Vorgehensweise einer Schreibmaschine. Wir gehen von einem Text (String) namens txt aus und betrachten jeden einzelnen Buchstaben: positionieren diesen in der Zeichenfläche und geben ihm anhand dessen eine Füllfarbe. Als Grundlage dient und dafür folgende for() Schleife:
for (int i=0; i < txt.length (); i++) {
   ...
}
Da i zu Beginn den Wert 0 besitzt, fängt unser Programm mit dem ersten Buchstaben im Text an. Im Gegensatz stellt txt.length() das Limit der Schleife dar; das letzte Zeichen. Innerhalb der Schleife lesen wir jedes Schriftzeichen mit der Funktion txt.charAt(i) aus und legen es in der Variable c vom Typ char ab.
char c = txt.charAt (i);
So weit, so gut. Der interessante Teil ist die Positionierung der Zeichen im Sketchfenster. Die beiden globalen Variablen x und y enthalten die aktuelle Position des Schreib-cursors; ein virtueller Anschlag der sich von der linken-oberen in die rechte-untere Ecke bewegt. Diese Bewegung (das Verschieben des cursors) geschiet durch die Einbeziehung der Zeichenbreite. Mittels textWidth() erhalten wir die Breite in Pixel, welches das Zeichen c im Sketchfenster hat.
float charWidth = textWidth (c);
Diesen Wert von charWidth involvieren wir in einer if() Bedingung mit der Frage: Ist die Position des aktuellen Zeichens mit der Breite charWidth an der Position x noch im Sketchfenster; oder nicht? Ist dies der Fall nehmen wir keinen Einfluss auf die Werte von x und y. Anderenfalls setzen wir den cursor in die Nächste Zeile (erhöhen y) und verschieben ihn zurück nach links (x = margin).
if (x + charWidth > width - margin) {
   y = y + fontSize * 1.2;
   x = margin;
}
Im letzten Schritt verschieben wir die x-Position um die Breite des aktuellen Zeichens.
x += 31; // <- monospaced
x += charWidth + (mouseX / 40.0);
Mit einer einheitlichen Verschiebung, unabhängig vom Zeichen, würde man eine monospaced Anmutung erhalten.

Der Sketch

String txt = "So perhaps a “luck” gene that somehow confers a quantum mechanical manipulation power could exist.";
PFont font;

int fontSize = 21;
int margin = 10;

void setup () {
    // Sketch initialisieren
    size (550, 220);
    smooth ();
    
    // Generiere die Schrift 'Arial' als PFont
    font = createFont ("Arial", fontSize);
    // Setze die Schrift für alle kommenden
    // text() Aufrufe
    textFont (font);
}

void draw () {
    // Leere das Sketchfenster mit 
    // einem Grauton
    background (76, 76, 75);
    
    // Lege die Ausgangs x-Position fest
    float x = margin;
    // Lege die Ausgangs y-Position fest
    float y = height / 2 - fontSize;
    
    // Diese for-Schleife läuft durch den gesamten
    // Text; Zeichen für Zeichen...
    for (int i=0; i < txt.length (); i++) {
        
        // Wähle das aktuelle Zeichen an der Position
        // 'i' im Text aus und lege es in der 'char' 
        // Variable 'c' ab.
        char c = txt.charAt (i);
        // Ermittle die Breite dieses Schriftzeichens
        // anhand der aktuellen Schriftart und -größe
        float charWidth = textWidth (c);
        

        // Überprüfe ob das aktuelle Zeichen ander Position
        // 'x' noch innerhalb unserer Zeichenfläche + den
        // vorher definierten Rand 'margin' wäre.
        if (x + charWidth > width - margin) {
            
            // Wenn nicht...
            // y: Positioniere das Zeichen in der nächsten Zeile
            y = y + fontSize * 1.2;
            // x: Setze die x-Position zurück
            x = margin;
        }
        
        // Berechne die Füllfarbe anhand der Position
        // innerhalb der Zeichenfläche
        fill (x*1.5, y*1.5, 255);
        
        // Stelle das Schriftzeichen dar
        text (c, x, y);
        
        // Verschiebe die x-Position für das nächste
        // Zeichen um die Breite von 'c' und einen 
        // von der Mausposition abhängigen Wert
        x += charWidth + (mouseX / 40.0);
    }
}