knuspermagier.de

Der privateste Blog von Philipp.

Salatgenerator

Wenn man versucht jeden zweiten Tag, oder so, einen Salat zum Abendessen zu machen, passiert es irgendwann, dass es einem etwas zu langweilig wird, wenn man immer nur die gleichen grünen Blätter mit den gleichen restlichen Zutaten kombiniert. Ich, als jemand, der monatlich sehr viel Geld für einen Essens-Zufallsgenerator ausgibt, um mir zumindest drei mal pro Woche die Entscheidung über das Mittagessen abzunehmen, kam also auf die Idee, dieses schwerwiegende Problem ebenfalls mit Technologie zu lösen.

Statt einem Startup, dass nun fertige Salatmischungen verschickt und dabei ab und zu wichtige Zutaten vergisst, oder einfach nur zehn Gramm Petersilienstängel in die Folientüte einschweißt, überlegte ich mir allerdings erstmal die MVP-Version. Eine Liste von Zutaten in verschiedenen Kategorien und ein Zufallsgenerator. Natürlich habe ich generate random number javascript gegoogelt, konnte mir das noch nie merken.

Überraschenderweise war die Domain salatgenerator.de noch verfügbar. Ich konnte mein Glück kaum glauben, wie kann so eine perfekte Domain noch nicht verkauft sein. Also gut, sie ist etwas lang, aber sie beschreibt mein Tool so gut. Öffnet man also die Webseite und drückt den großen grünen Button, so bekommt man eine überzeugende Kombination aus typischen Salatzutaten inklusive eines animierten Serviervorschlags.

img_7efad104040e-1_iphone13midnight_portrait.png

Mal wieder ein kurzes, quatschiges Abendprojekt. Die Herausforderung hier: Herausfinden, in welche Kategorien man Salatzutaten sinnvoll gruppieren kann, damit am Ende nicht sowas rauskommt wie “Eisbergsalat, Pinienkerne, Kürbiskerne und Romana-Salat”.

Das Malen von bisher 27 Zutaten dauerte länger als gedacht, und teilweise baute ich natürlich Mist, da ich sie in Procreate zu klein anlegte und jetzt sind sie auf Retina-Screens unscharf. Allgemein kann ich eh nicht malen, aber ich wollte es natürlich trotzdem gerne haben, einfach für den witzigen Effekt. Die Zutaten fallen auch einfach nur runter, mit GSAP animiert. Geiler wäre natürlich eine Art echtes Physik-System, damit es sich jede Zutat schön gemütlich machen kann in der Schüssel, aber naja. Es sollte ja ein kurzes quatschiges Projekt werden.

Kurz vor der Veröffentlichung dachte ich noch, dass es ja doch ganz schön wäre, könnte man generierte Zutatenlisten auch verlinken oder gar auf Twitter teilen, daher baute ich noch zwei Sachen ein. Zum Einen, dass bei jedem Würfeln auch eine eindeutige URL generiert wird, die natürlich beim Aufrufen ganz dynamisch geparsed wird. Ganz ohne Validierung, wer möchte, kann sich also über die URL ganz verrückte Salate bauen.

Zum Anderen gibt es, zumindest auf Mobilgeräten, auf der Schüssel noch einen Share-Button, der das native ShareSheet triggert. Dort kann sogar ein Bild geteilt werden, wenn die Ziel-App es unterstützt. Dieser Teil dauerte noch einmal genau so lang, wie der gesamte Rest der Applikation. Mein googlen nach “DOM to temporary image”, oder so, führte mich erstmal zu einem NPM Package, das leider nicht funktionierte. Ein Weiteres, das eine DOM-Node immerhin in ein Canvas umwandeln sollte, welches ich dann wiederum zu einem Bild machen konnte, klappte leider auch nicht. Kam wahrscheinlich nicht mit meinen wilden, absolut positionierten Bildchen zurecht. Naja.

Weil ich das Feature aber trotzdem wollte, baute ich mir das Bild zum sharen also selbst per Canvas zusammen. Das ist tatsächlich gar nicht so schwer und mit ein paar Zeilen geschafft. Hätte ich mal direkt so machen sollen.

function drawCanvas() {
    // Teile verkürzt
    const canvas = document.getElementById('shareCanvas');
    const ctx = canvas.getContext("2d");

    // …

    ctx.drawImage(schuesselInnen, leftPad + 228, 225, 1500 / 2, 854 / 2);

    document.querySelectorAll('.particle').forEach(el => {
        const heightJitter = Math.floor(Math.random() * 80);
        ctx.drawImage(el, leftPad + 200 + (Math.floor(Math.random() * 550) + 30), 270 + heightJitter);

    })

    ctx.drawImage(schuesselAussen, leftPad + 228, 320, 750, 335);

    ctx.fillStyle = '#fff';
    ctx.font = "bold 64px Avenir Next";
    ctx.fillText("salatgenerator.de", 25, 80);

    ctx.font = "32px Avenir Next";
    document.querySelectorAll('.recipeList li').forEach((node, i) => {
        ctx.fillText(node.textContent, 25, 145 + (i * 45));
    })

    return canvas;
}

Den Canvas kann man dann an die Share-API des Mobilbrowsers übergeben und lossharen, wie man will. In Discord, z.B. schafft er es perfekt, das Bild inklusive Text und URL zu teilen. iMessage hingegen unterstützt das nicht, lol, und nimmt nur das Bild. Telegram kann wiederum nur die URL. Naja. Die Tatsache, dass ich relativ leicht direkt im Browser Bilder zum Teilen erstellen kann, habe ich damit jetzt immerhin gelernt! Geht natürlich nicht für so Kram wie og:image Sachen.


Das Github-Repository steht bereit für Vorschläge neuer Zutaten. Kann aber natürlich dauern, da ich sie erst malen muss. Ein paar Feature-Ideen habe ich auch schon, zum Beispiel einen Vegan-Modus, oder allgemein das deaktivieren von ungeliebten Zutaten, keiner will ernsthaft Rote Bete im Salat, fürchte ich. Also, außer mir.

Kommentare, Feedback und andere Anmerkungen? Schreib mir eine E-Mail 🤓