Für die Blutstammzellspende haben wir vor einigen Jahren eine Kampagne erfunden, die mit individuellen Wiedererkennungsmerkmalen für die Unterstützer funktionierte. Wer sich in die Datenbank für potentielle Blutstammzellspender eintragen liess, hat als Zeichen seiner Unterstützung ein persönliches Symbol erhalten, das einmalig und doch leicht wiedererkennbar war.



Da die Kampagne nicht weitergeführt wurde kann ich das Prinzip und den Code jetzt öffentlich machen. Die individuellen Tags werden aus der E‑Mail-Adresse berechnet.
See the Pen ID-Tag Input V2 by Stefan (@easy68) on CodePen.
Programmierung
Dieser Code erstellt eine visuelle Darstellung auf einem HTML5-Canvas, basierend auf einem übergebenen Hashwert. Die Darstellung wird aus Punkten und Linien gebildet, die in einer kreisförmigen Struktur platziert werden. Schauen wir uns die einzelnen Abschnitte an:
1. Initialisierung des Canvas
//paper.install(window);
- Die
paper.js
Bibliothek wird installiert und macht alle Funktionen vonpaper.js
als globale Funktionen verfügbar.
2. newCan
Funktion
function newCan(hash) { ... }
- Diese Funktion erstellt eine neue Zeichnung auf dem Canvas basierend auf einem übergebenen
hash
.
ID Array
var idstringarray = [];
var stringArr = hash.split("");
stringArr.forEach(function(item) {
var myHexNum = parseInt(item, 16);
idstringarray.push(myHexNum);
});
idstringarray
speichert die Dezimalwerte der einzelnen Hex-Zeichen aus demhash
. Der Hash wird in Zeichen aufgeteilt und jedes Zeichen in eine Dezimalzahl umgewandelt und zum Array hinzugefügt.
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));
- Bestimmt das Zentrum der Grafik (
mitte_x
undmitte_y
) und setzt die Werte fürflesh
undmaxheight
. Diese Werte steuern die Abstände und die maximale Höhe der Punkte, die die Form des Musters beeinflussen.
Kreis-Punkte setzen
var idpath = new Path({ ... });
idpath
ist das Haupt-Pfad-Objekt für die Visualisierung. Der Pfad wird rot gefüllt und mit abgerundeten Enden und einer Strichbreite von 4 Pixeln gezeichnet.
schrittwinkel = 360 / loops;
drittelwinkel = 360 / (loops * 3);
schrittwinkel
teilt den Kreis gleichmäßig in Winkel für jeden Punkt auf.drittelwinkel
wird genutzt, um für jeden Punkt drei zusätzliche Zwischenpunkte zu berechnen.
Loop: Punkte hinzufügen
Der Haupt-Loop iteriert durch das idstringarray
, um für jeden Wert die Koordinaten der Punkte zu berechnen. Es gibt drei Kategorien von Punkten:
- Aufstiegspunkte
- Bedingung: Der Wert muss größer als 10 sein und sich vom vorherigen Wert um mindestens 10 unterscheiden.
- Vor‑, Haupt- und Nachpunkt
- Diese Punkte bilden die Basisstruktur des Pfads und werden für jeden Wert in
idstringarray
gesetzt.
- Abstiegspunkte
- Bedingung: Der Wert muss größer als 10 sein und sich vom nächsten Wert um mindestens 10 unterscheiden.
Für jeden Punkt berechnet der Code die Länge und den Winkel vom Mittelpunkt aus und fügt die Position zu idpath
hinzu. Dies geschieht durch die Umrechnung in x
- und y
-Koordinaten.
Glättung und Abschluss
idpath.smooth({ type: 'catmull-rom', factor: 0.5 });
- Der Pfad wird geglättet, um eine fließendere Linie zu erzeugen.
getNewHash
Funktion
function getNewHash() { ... }
- Erzeugt einen neuen MD5-Hash aus einer Eingabe (z.B. E‑Mail), setzt diesen als
data-hash
-Attribut und führtnewCan()
mit diesem neuen Hash aus, um eine frische Zeichnung zu erstellen.
Download Funktion
function download(canvas, filename) { ... }
- Diese Funktion speichert das aktuelle Canvas als PNG-Bild. Ein versteckter Anker-Link (
lnk
) wird erzeugt, der dencanvas
-Inhalt alsdata-uri
speichert und einen Klick-Event auslöst, um das Bild herunterzuladen.
Dieser Code kombiniert Hexadezimal-Werte, Winkelberechnungen und visuelle Effekte, um eine dynamische und kreisförmige Grafik basierend auf einem Hash zu erstellen.
Hier der gesamte 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
Nur Personen, die zu meinem Freundesnetzwerk gehören, können hier kommentieren.