diff --git a/assets/js/main.js b/assets/js/main.js index ed237dd..f653e97 100644 --- a/assets/js/main.js +++ b/assets/js/main.js @@ -197,37 +197,42 @@ Jede Zutat: [Datei, x %, y % (relativ zur Essens-Box), Größe % der Box, Drehung, Ebene, auch mobil, gespiegelt] Ebenen: b = hinter dem Essen (leicht unscharf), f = davor */ var BITS = 'assets/img/bits/'; - /* Statt fester Positionen: natürliche Streuung. Nah am Essen dicht, nach außen immer weniger, - unregelmäßige Winkel, kein Kreis. Fester Seed, damit es bei jedem Laden gleich aussieht. - items: [Datei, Grundgröße in % der Essensbreite, auch mobil] - edge = Rand des Essens (0,5 = Bildrand), reach = weitester Abstand, top/bottom = erlaubter Bereich in % der Höhe, - behind = Anteil der nahen Teile hinter dem Essen, hw = Höhe/Breite der Essens-Box */ + /* Natürliche Streuung statt fester Positionen (fester Seed, damit es bei jedem Laden gleich aussieht). + - food: Umriss des Essens im Bild [Mitte x, Mitte y, Halbbreite, Halbhöhe] in % der Box (abgerundetes Rechteck) + - Die Zutaten fliegen in 2–3 Schüben aus dem Essen heraus: dicht am Rand, nach außen immer weniger + - Teile vor dem Essen berühren es höchstens am Rand, Teile dahinter schauen nur halb hervor + - left/right/top/bottom: erlaubter Bereich (% der Box), z. B. damit nichts über Text oder aus der Karte ragt + items: [Datei, Grundgröße in % der Box-Breite, auch mobil] */ var SCATTER = { - burger: { seed: 11, edge: .4, reach: 1, top: -34, bottom: 112, behind: .5, hw: .72, items: [ - ['lettuce-2', 20, 1], ['tomato', 16, 1], ['bacon', 22, 1], ['onion-1', 15, 1], ['jalapeno-1', 11, 1], ['lettuce-1', 22, 1], - ['pickle', 11, 1], ['tomato', 13, 0], ['onion-2', 12, 0], ['jalapeno-2', 10, 0], ['bacon', 17, 0], ['lettuce-3', 17, 0], - ['sesame-1', 3.6, 1], ['sesame-2', 4, 0], ['sesame-1', 3, 0], ['sesame-1', 2.6, 0] + burger: { seed: 4, food: [39, 49, 38, 47], hw: .72, reach: 34, bursts: 3, behind: .3, top: -26, bottom: 116, items: [ + ['lettuce-2', 22, 1], ['tomato', 17, 1], ['bacon', 24, 1], ['onion-1', 15, 1], ['jalapeno-1', 12, 1], ['lettuce-1', 24, 1], + ['pickle', 11, 1], ['tomato', 13, 0], ['onion-2', 12, 0], ['jalapeno-2', 11, 0], ['bacon', 18, 0], ['lettuce-3', 18, 0], + ['sesame-1', 3.4, 1], ['sesame-2', 3.8, 0], ['sesame-1', 3, 0], ['sesame-1', 2.6, 0] ] }, - 'burger-visit': { seed: 11, edge: .4, reach: .95, top: -6, bottom: 112, left: -14, behind: .5, hw: .63, items: [ - ['lettuce-2', 20, 1], ['tomato', 16, 1], ['bacon', 22, 1], ['onion-1', 15, 1], ['jalapeno-1', 11, 1], ['lettuce-1', 22, 1], - ['pickle', 11, 0], ['tomato', 13, 0], ['jalapeno-2', 10, 0], ['sesame-1', 3.6, 0], ['sesame-2', 4, 0] + 'burger-visit': { seed: 8, food: [38, 49, 37, 47], hw: .63, reach: 26, bursts: 2, behind: .3, top: 6, bottom: 112, left: -12, items: [ + ['lettuce-2', 20, 1], ['tomato', 16, 1], ['bacon', 22, 1], ['onion-1', 14, 1], ['jalapeno-1', 11, 1], ['lettuce-1', 20, 0], + ['pickle', 10, 0], ['tomato', 12, 0], ['sesame-1', 3.4, 0], ['sesame-2', 3.8, 0] ] }, - 'burger-sm': { seed: 5, edge: .42, reach: .72, top: -14, bottom: 88, behind: .5, hw: .72, items: [ - ['lettuce-1', 18, 1], ['tomato', 14, 1], ['bacon', 18, 1], ['onion-2', 12, 1], ['pickle', 9, 0], ['sesame-1', 3, 0] + 'burger-page': { seed: 6, food: [38, 49, 37, 47], hw: .63, reach: 30, bursts: 3, behind: .3, top: -34, bottom: 112, items: [ + ['lettuce-2', 21, 1], ['tomato', 16, 1], ['bacon', 22, 1], ['onion-1', 14, 1], ['jalapeno-1', 11, 1], ['lettuce-1', 22, 0], + ['pickle', 10, 0], ['tomato', 12, 0], ['jalapeno-2', 10, 0], ['sesame-1', 3.4, 0], ['sesame-2', 3.8, 0], ['sesame-1', 3, 0] ] }, - 'chicken-sm': { seed: 7, edge: .42, reach: .72, top: -14, bottom: 88, behind: .5, hw: .72, items: [ - ['bacon', 18, 1], ['lettuce-2', 18, 1], ['tomato', 13, 1], ['crumb-1', 9, 1], ['crumb-2', 7, 0], ['crumb-3', 6, 0] + 'burger-sm': { seed: 5, fly: .4, food: [39, 49, 38, 47], hw: .72, reach: 10, bursts: 2, behind: .5, top: 8, bottom: 96, left: 5, right: 95, items: [ + ['lettuce-1', 17, 1], ['tomato', 13, 1], ['bacon', 17, 1], ['onion-2', 11, 0], ['sesame-1', 2.6, 0] ] }, - 'wrap-sm': { seed: 3, edge: .42, reach: .72, top: -14, bottom: 88, behind: .5, hw: .67, items: [ - ['lettuce-3', 18, 1], ['tomato', 13, 1], ['jalapeno-2', 10, 1], ['onion-2', 12, 1], ['jalapeno-1', 8, 0] + 'chicken-sm': { seed: 7, fly: .4, food: [41, 48, 40, 47], hw: .73, reach: 10, bursts: 2, behind: .5, top: 8, bottom: 96, left: 5, right: 95, items: [ + ['bacon', 17, 1], ['lettuce-2', 17, 1], ['tomato', 13, 1], ['crumb-1', 7, 0], ['crumb-3', 6, 0] ] }, - wings: { seed: 21, edge: .4, reach: .95, top: 4, bottom: 114, behind: .45, hw: .71, items: [ - ['crumb-1', 11, 1], ['chili', 18, 1], ['crumb-3', 10, 1], ['jalapeno-1', 11, 1], ['crumb-6', 10, 1], ['crumb-8', 10, 1], - ['crumb-4', 9, 0], ['jalapeno-2', 10, 0], ['crumb-7', 8, 0], ['crumb-2', 7, 0], ['crumb-5', 7, 0], ['crumb-2', 5, 0] + 'wrap-sm': { seed: 3, fly: .4, food: [43, 48, 42, 47], hw: .67, reach: 10, bursts: 2, behind: .5, top: 8, bottom: 96, left: 5, right: 95, items: [ + ['lettuce-3', 17, 1], ['tomato', 13, 1], ['jalapeno-2', 11, 1], ['onion-2', 11, 0] ] }, - tenders: { seed: 9, edge: .4, reach: .92, top: -20, bottom: 116, left: 2, behind: .45, hw: .59, items: [ - ['crumb-6', 10, 1], ['chili', 17, 1], ['crumb-1', 10, 1], ['jalapeno-1', 10, 1], ['crumb-3', 9, 1], - ['crumb-8', 9, 0], ['crumb-4', 8, 0], ['crumb-7', 7, 0], ['crumb-5', 6, 0] + wings: { seed: 21, food: [50, 50, 49, 49], hw: .71, reach: 26, bursts: 3, behind: .3, top: 2, bottom: 116, items: [ + ['crumb-1', 10, 1], ['chili', 17, 1], ['crumb-3', 9, 1], ['jalapeno-1', 10, 1], ['crumb-6', 9, 1], ['crumb-8', 9, 1], + ['crumb-4', 8, 0], ['jalapeno-2', 9, 0], ['crumb-7', 7, 0], ['crumb-2', 6, 0], ['crumb-5', 6, 0], ['crumb-2', 4.5, 0] + ] }, + tenders: { seed: 12, food: [47, 42, 46, 41], hw: .59, reach: 26, bursts: 3, behind: .3, top: -34, bottom: 124, left: 0, items: [ + ['crumb-6', 9, 1], ['chili', 16, 1], ['crumb-1', 9, 1], ['jalapeno-1', 9, 1], ['crumb-3', 8, 1], + ['crumb-8', 8, 0], ['crumb-4', 7, 0], ['crumb-7', 6, 0], ['crumb-5', 5, 0] ] } }; function seeded(a) { @@ -240,22 +245,45 @@ } function scatter(spec) { var r = seeded(spec.seed), placed = [], out = []; + var gauss = function () { return (r() + r() + r() - 1.5) / 1.5; }; + var f = spec.food, hw = spec.hw; + // Rechnen in "Box-Breite"-Einheiten, damit Abstände in x und y vergleichbar sind + var cx = f[0], cy = f[1] * hw, rx = f[2], ry = f[3] * hw; + var bursts = []; + for (var j = 0; j < spec.bursts; j++) bursts.push(r() * Math.PI * 2); + // Abstand Mitte -> Rand des Essens in Richtung a (abgerundetes Rechteck) + var edgeAt = function (a) { + var c = Math.abs(Math.cos(a)), sn = Math.abs(Math.sin(a)); + var k = 1 / Math.pow(Math.pow(c, 3) + Math.pow(sn, 3), 1 / 3); + return { x: rx * k * Math.cos(a), y: ry * k * Math.sin(a) }; + }; + // Abstand eines Punktes zum Umriss (negativ = innen) + var outside = function (x, y) { + var dx = x - cx, dy = y - cy, a = Math.atan2(dy / ry, dx / rx); + var e = edgeAt(a), le = Math.sqrt(e.x * e.x + e.y * e.y), lp = Math.sqrt(dx * dx + dy * dy); + return lp - le; + }; spec.items.forEach(function (it) { - for (var k = 0; k < 80; k++) { - var a = r() * Math.PI * 2; - var d = spec.edge + Math.pow(r(), 2.4) * (spec.reach - spec.edge) + (r() - .5) * .06; - var x = 50 + Math.cos(a) * d * 100, y = 50 + Math.sin(a) * d * 100; - if (y < spec.top || y > spec.bottom || x < (spec.left != null ? spec.left : -60) || x > (spec.right != null ? spec.right : 160)) continue; - var size = it[1] * 1.35 * (.8 + r() * .4) * (1 - Math.max(0, d - spec.edge) * .45); + for (var k = 0; k < 240; k++) { + var a = r() < .75 ? bursts[Math.floor(r() * bursts.length)] + gauss() * .7 : r() * Math.PI * 2; + var size = it[1] * (.75 + r() * .5); + var behind = r() < spec.behind && size > 5; + var e = edgeAt(a), le = Math.sqrt(e.x * e.x + e.y * e.y); + // hinter dem Essen: halb versteckt; davor: frei, dicht am Rand häufiger als weit außen + var gap = behind ? size * (r() * .25 - .1) : size * .38 + Math.pow(r(), 1.7) * spec.reach; + var x = cx + e.x / le * (le + gap), y = cy + e.y / le * (le + gap); + var yp = y / hw; + // hohe Teile (Salatblatt) ragen weiter nach oben/unten: halbe Höhe großzügig mit 0,75 × Größe ansetzen + if ((y - size * .75) / hw < spec.top || (y + size * .75) / hw > spec.bottom || x - size / 2 < (spec.left != null ? spec.left : -70) || x + size / 2 > (spec.right != null ? spec.right : 170)) continue; + if (!behind && outside(x, y) < size * .3) continue; var free = placed.every(function (p) { - var dx = p.x - x, dy = (p.y - y) * spec.hw; - return Math.sqrt(dx * dx + dy * dy) > (p.s + size) * .42; + var dx = p.x - x, dy = p.y - y; + return Math.sqrt(dx * dx + dy * dy) > (p.s + size) * .48; }); if (!free) continue; - var p = { x: x, y: y, s: size }; - placed.push(p); - var near = d < spec.edge + .08; - out.push([it[0], +x.toFixed(1), +y.toFixed(1), +size.toFixed(1), Math.round((r() - .5) * 140), near && r() < spec.behind ? 'b' : 'f', it[2], r() < .5 ? 1 : 0]); + placed.push({ x: x, y: y, s: size }); + // weiter außen etwas kleiner + out.push([it[0], +x.toFixed(1), +yp.toFixed(1), +size.toFixed(1), Math.round(gauss() * 70), behind ? 'b' : 'f', it[2], r() < .5 ? 1 : 0]); return; } }); @@ -299,7 +327,7 @@ bits.push({ el: el, inner: inner, fl: fl, x: b[1], y: b[2], layer: b[5] }); }); box.appendChild(holder); - return { box: box, bits: bits, hero: !lazy }; + return { box: box, bits: bits, hero: !lazy, fly: spec.fly || 1 }; }).filter(Boolean); /* ---------- Flammen nur animieren, solange sie sichtbar sind ---------- */ @@ -508,6 +536,7 @@ }; // Explosionsziel: kräftig nach außen, mit Drall zur Seite und nach oben var away = function (b, k) { + k *= bl.fly; var v = vec(b), len = Math.sqrt(v.x * v.x + v.y * v.y) || 1; var side = b.side; return { diff --git a/speisekarte.html b/speisekarte.html index 55cddd7..243f264 100644 --- a/speisekarte.html +++ b/speisekarte.html @@ -80,7 +80,7 @@
Wings, Tenders, Burger, Wraps und Sides – alles mild oder scharf, zum Mitnehmen, geliefert oder direkt bei uns.
-
