Ich lüfte das Geheimnis

Für die Blut­stamm­zell­spen­de haben wir vor eini­gen Jah­ren eine Kam­pa­gne erfun­den, die mit indi­vi­du­el­len Wie­der­erken­nungs­merk­ma­len für die Unter­stüt­zer funk­tio­nier­te. Wer sich in die Daten­bank für poten­ti­el­le Blut­stamm­zell­spen­der ein­tra­gen liess, hat als Zei­chen sei­ner Unter­stüt­zung ein per­sön­li­ches Sym­bol erhal­ten, das ein­ma­lig und doch leicht wie­der­erkenn­bar war.

Da die Kam­pa­gne nicht wei­ter­ge­führt wur­de kann ich das Prin­zip und den Code jetzt öffent­lich machen. Die indi­vi­du­el­len Tags wer­den aus der E‑Mail-Adres­se berech­net.

See the Pen ID-Tag Input V2 by Ste­fan (@easy68) on Code­Pen.

Programmierung

Die­ser Code erstellt eine visu­el­le Dar­stel­lung auf einem HTM­L5-Can­vas, basie­rend auf einem über­ge­be­nen Hash­wert. Die Dar­stel­lung wird aus Punk­ten und Lini­en gebil­det, die in einer kreis­för­mi­gen Struk­tur plat­ziert wer­den. Schau­en wir uns die ein­zel­nen Abschnit­te an:


1. Initialisierung des Canvas

//paper.install(window);

2. newCan Funktion

function newCan(hash) { ... }

ID Array

var idstringarray = [];
var stringArr = hash.split("");
stringArr.forEach(function(item) {
  var myHexNum = parseInt(item, 16);
  idstringarray.push(myHexNum);
});

Mittelpunkt und Parameter

var mitte_y = view.size.height / 2;
var mitte_x = view.size.height / 2;
var flesh = view.size.height / 6;
var maxheight = view.size.height / 2 - (flesh + (flesh * 0.1));

Kreis-Punkte setzen

var idpath = new Path({ ... });
schrittwinkel = 360 / loops;
drittelwinkel = 360 / (loops * 3);

Loop: Punkte hinzufügen

Der Haupt-Loop ite­riert durch das idstringarray, um für jeden Wert die Koor­di­na­ten der Punk­te zu berech­nen. Es gibt drei Kate­go­rien von Punk­ten:

  1. Auf­stiegs­punk­te
  1. Vor‑, Haupt- und Nach­punkt
  1. Abstiegs­punk­te

Für jeden Punkt berech­net der Code die Län­ge und den Win­kel vom Mit­tel­punkt aus und fügt die Posi­ti­on zu idpath hin­zu. Dies geschieht durch die Umrech­nung in x- und y-Koor­di­na­ten.


Glättung und Abschluss

idpath.smooth({ type: 'catmull-rom', factor: 0.5 });

getNewHash Funktion

function getNewHash() { ... }

Download Funktion

function download(canvas, filename) { ... }

Die­ser Code kom­bi­niert Hexa­de­zi­mal-Wer­te, Win­kel­be­rech­nun­gen und visu­el­le Effek­te, um eine dyna­mi­sche und kreis­för­mi­ge Gra­fik basie­rend auf einem Hash zu erstel­len.

Hier der gesam­te Code

/* ====================== *
 *  0. Initializing the Canvas    *
 * ====================== */
// paper.install(window); // Initialize Paper.js, making its functions globally accessible

function newCan(hash) {
    with (paper) {
        paper.setup(document.getElementById("canvas")); // Set up Paper.js on the specified canvas element

        /* =========================    *
         *  ID Array 
         * =========================    */

        var idstringarray = [];                          // create final array to store decimal values of hash characters
        var stringArr = hash.split("");                  // split hash into an array of characters
        stringArr.forEach(function(item) {               // for each hex character, convert to decimal and add to array
            var myHexNum = parseInt(item, 16);           // convert hex character to decimal
            idstringarray.push(myHexNum);                // add decimal number to final array
        });

        /* =============================== *
         *  Mittelpunkt der Grafik setzen und flesh definieren.
         * =============================== */

        var mitte_y = view.size.height / 2;              // set Y coordinate for the center of the graphic
        var mitte_x = view.size.height / 2;              // set X coordinate for the center of the graphic
        var flesh = view.size.height / 6;                // set "flesh" value relative to the canvas height
        var maxheight = view.size.height / 2 - (flesh + (flesh * 0.1)); // set max height with flesh buffer
        var firststring = idstringarray[0];              // get the first element from the idstringarray
        var individual = -maxheight / 100 * firststring; // calculate individual height based on first hash element
        var loops = idstringarray.length;                // define the number of loops based on array length

        /* ====================== *
         * Punkte auf dem Kreis ausgeben *
         * ====================== */

        var idpath = new Path({
            /* strokeColor: 'red', */
            fillColor: '#ed0000',                        // set fill color of the path to red
            strokeWidth: 4,                              // set stroke width for the path
            strokeCap: 'round',                          // set rounded caps for path ends
            closed: true,                                // close the path to form a complete shape
        });

        schrittwinkel = 360 / loops;                     // calculate angle step per loop iteration
        drittelwinkel = 360 / (loops * 3);               // calculate angle subdivision for each point's third
        console.log("drittelwinkel: " + drittelwinkel);  // log angle subdivision for debugging

        /* ======== loop start ============= */
        for (var i = 1; i <= loops; i++) {

            /* === Bucht Punkt im Aufstieg setzen, wenn mindestens 11 lang und die
            Differenz zum vorherigen Wert mindestens 10 ist ===*/

            var hoehe = idstringarray[i - 1];
            var hoehevor = idstringarray[i - 2];
            console.log("hoehe: " + hoehe);
            console.log("hoehevor: " + hoehevor);

            if (hoehe > 10 && (hoehe - hoehevor) > 10) {

                /* ======== Bucht Punkt 1 im Aufstieg setzen ========= */

                var vector = new Point(mitte_x, mitte_y); // start from the center point
                var winkel = schrittwinkel * i - drittelwinkel; // calculate angle for ascent point
                var laenge = maxheight / 30 * idstringarray[i - 1] + flesh + individual; // calculate length
                vector.angle = winkel;
                vector.length = laenge;
                var px = mitte_x + vector.x;              // calculate X coordinate
                var py = mitte_y + vector.y;              // calculate Y coordinate
                idpath.add(new Point(px, py));            // add calculated point to path

                /* ======== Bucht Punkt 2 im Aufstieg setzen ========= */

                var vector = new Point(mitte_x, mitte_y);
                var winkel = schrittwinkel * i - 2 * drittelwinkel;
                var laenge = maxheight / 26 * idstringarray[i - 1] + flesh + individual;
                vector.angle = winkel;
                vector.length = laenge;
                var px = mitte_x + vector.x;
                var py = mitte_y + vector.y;
                idpath.add(new Point(px, py));

                /* ======== Bucht Punkt 3 im Aufstieg setzen ========= */

                var vector = new Point(mitte_x, mitte_y);
                var winkel = schrittwinkel * i - 2 * drittelwinkel;
                var laenge = maxheight / 24 * idstringarray[i - 1] + flesh + individual;
                vector.angle = winkel;
                vector.length = laenge;
                var px = mitte_x + vector.x;
                var py = mitte_y + vector.y;
                idpath.add(new Point(px, py));

                /* ======== Bucht Punkt 4 im Aufstieg setzen ========= */

                var vector = new Point(mitte_x, mitte_y);
                var winkel = schrittwinkel * i - drittelwinkel;
                var laenge = maxheight / 21 * idstringarray[i - 1] + flesh + individual;
                vector.angle = winkel;
                vector.length = laenge;
                var px = mitte_x + vector.x;
                var py = mitte_y + vector.y;
                idpath.add(new Point(px, py));
            }

            /* ======== vorpunkt setzen ========= */

            var vector = new Point(mitte_x, mitte_y);     // initialize point from center
            var winkel = schrittwinkel * i - drittelwinkel; // angle for pre-point
            var laenge = maxheight / 16 * idstringarray[i - 1] + flesh; // length calculation
            vector.angle = winkel;
            vector.length = laenge;
            var px = mitte_x + vector.x;
            var py = mitte_y + vector.y;
            idpath.add(new Point(px, py));

            /* ======== hauptpunkt setzen ========= */

            var vector = new Point(mitte_x, mitte_y);
            var winkel = schrittwinkel * i;               // main point angle
            var laenge = maxheight / 15 * idstringarray[i - 1] + flesh;
            vector.angle = winkel;
            vector.length = laenge;
            var px = mitte_x + vector.x;
            var py = mitte_y + vector.y;
            idpath.add(new Point(px, py));

            /* ======== nachpunkt setzen ========= */

            var vector = new Point(mitte_x, mitte_y);
            var winkel = schrittwinkel * i + drittelwinkel; // post-point angle
            var laenge = maxheight / 16 * idstringarray[i - 1] + flesh;
            vector.angle = winkel;
            vector.length = laenge;
            var px = mitte_x + vector.x;
            var py = mitte_y + vector.y;
            idpath.add(new Point(px, py));

            /* === Bucht Punkt im Abstieg setzen, wenn Distanz groß genug === */

            var hoehe = idstringarray[i - 1];
            var hoehenext = idstringarray[i];
            console.log("hoehe: " + hoehe);
            console.log("hoehenext: " + hoehenext);

            if (hoehe > 10 && (hoehe - hoehenext) > 10) {

                /* ======== Bucht Punkt 1 im Abstieg setzen ========= */

                var vector = new Point(mitte_x, mitte_y);
                var winkel = schrittwinkel * i + drittelwinkel;
                var laenge = maxheight / 20 * idstringarray[i - 1] + (flesh + individual);
                vector.angle = winkel;
                vector.length = laenge;
                var px = mitte_x + vector.x;
                var py = mitte_y + vector.y;
                idpath.add(new Point(px, py));

                /* Repeat for other descent points */

                // Continue similar logic for remaining descent points
            }
        }

        /* Smooth path for a natural curve effect */
        idpath.smooth({
            type: 'catmull-rom',
            factor: 0.5,
        });

        console.log("new: " + idstringarray);             // log final array for debugging
    }
}

// Remaining code logic for hash generation and download functionality remains unchanged

Schreiben Sie einen Kommentar

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

This site uses Akismet to reduce spam. Learn how your comment data is processed.