Redesign nachgeschärft: lesbarer Hero, saubere Übergänge, stärkere Explosion, Speisekarte mit Farbbändern
- Körnung neutral und echte Überblendung (Abschnitte isoliert), keine harten Kanten mehr an Flammen/Wellen - Hero: Burger kleiner, Wortmarke raus, KNOCKOUT wieder lesbar - Fotoband durch Plakat-Abschnitt Crispy Tenders ersetzt, Wings-Freisteller nachgeschnitten - Zutaten: korrekt zentriert, Schweben relativ (kein Pendeln), kräftigere Explosion, pausiert außerhalb des Bildes - Speisekarte: Kategorie-Leiste klebt wieder (body overflow), Bänder in Rot/Gelb/Dunkel mit Flammen - Kontrast auf Orange, Kopfleiste mit Hintergrund beim Scrollen, Menü sperrt das Scrollen, leeres lenis.min.js entfernt - Flammen und Funken laufen nur, solange sie sichtbar sind Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
12d8f41fd8
commit
08f687822f
16 files changed
+220
-131
No files matched your search
+73
-29
@@ -84,6 +84,7 @@
|
||||
if (y > 140 && y - lastY > 6) nav.classList.add('is-hidden');
|
||||
else if (lastY - y > 6 || y < 140) nav.classList.remove('is-hidden');
|
||||
document.body.classList.toggle('nav-visible', !nav.classList.contains('is-hidden') && y > 10);
|
||||
nav.classList.toggle('is-scrolled', y > 60);
|
||||
lastY = y;
|
||||
}
|
||||
window.addEventListener('scroll', onScroll, { passive: true });
|
||||
@@ -137,7 +138,7 @@
|
||||
|
||||
/* ---------- Mobile Bestell-Leiste ---------- */
|
||||
var orderbar = $('#orderbar');
|
||||
var heroEl = $('.hero') || $('.page-hero');
|
||||
var heroEl = $('.hero__cta .btn') || $('.page-hero');
|
||||
if (orderbar && heroEl && 'IntersectionObserver' in window) {
|
||||
new IntersectionObserver(function (entries) {
|
||||
orderbar.classList.toggle('is-visible', !entries[0].isIntersecting);
|
||||
@@ -185,23 +186,29 @@
|
||||
],
|
||||
'burger-sm': [
|
||||
['onion-2', 6, 10, 15, -14, 'b', 1], ['bacon', 94, 6, 20, 24, 'b', 1],
|
||||
['lettuce-1', -4, 70, 20, -20, 'f', 1], ['tomato', 102, 64, 17, 18, 'f', 1], ['pickle', 72, 102, 11, 8, 'f', 0], ['sesame-1', 30, -4, 3, 0, 'f', 0]
|
||||
['lettuce-1', -4, 70, 20, -20, 'f', 1], ['tomato', 102, 64, 17, 18, 'f', 1], ['sesame-1', 30, -4, 3, 0, 'f', 0]
|
||||
],
|
||||
'chicken-sm': [
|
||||
['bacon', 98, 10, 20, 24, 'b', 1, 1], ['crumb-1', 6, 4, 8, 0, 'b', 0], ['crumb-2', 88, -4, 7, 30, 'b', 0],
|
||||
['lettuce-2', -6, 70, 20, -24, 'f', 1], ['tomato', 104, 64, 15, 18, 'f', 1], ['crumb-3', 26, 104, 8, 10, 'f', 0], ['crumb-4', 66, 104, 8, 60, 'f', 0]
|
||||
['bacon', 98, 10, 20, 24, 'b', 1, 1], ['crumb-1', 6, 4, 10, 0, 'b', 0], ['crumb-2', 88, -4, 9, 30, 'b', 0],
|
||||
['lettuce-2', -6, 70, 20, -24, 'f', 1], ['tomato', 104, 64, 15, 18, 'f', 1]
|
||||
],
|
||||
'wrap-sm': [
|
||||
['jalapeno-2', 6, 6, 11, -20, 'b', 1], ['onion-2', 96, 6, 13, 20, 'b', 1],
|
||||
['lettuce-3', -8, 70, 20, -18, 'f', 1], ['tomato', 104, 64, 15, 22, 'f', 1], ['crumb-5', 28, 104, 8, 0, 'f', 0], ['jalapeno-1', 74, 104, 9, 40, 'f', 0]
|
||||
['lettuce-3', -8, 70, 20, -18, 'f', 1], ['tomato', 104, 64, 15, 22, 'f', 1]
|
||||
],
|
||||
tenders: [
|
||||
['crumb-6', 2, 20, 11, 0, 'b', 1], ['crumb-7', 98, 14, 10, 40, 'b', 0], ['chili', 104, 78, 20, 20, 'b', 1],
|
||||
['crumb-1', 14, -6, 12, 10, 'f', 1], ['crumb-3', 64, -14, 11, 90, 'f', 1], ['crumb-4', 90, 8, 11, 120, 'f', 0],
|
||||
['crumb-8', -4, 84, 12, 70, 'f', 1], ['jalapeno-1', 40, 108, 11, -10, 'f', 0], ['crumb-5', 78, 106, 10, 30, 'f', 0]
|
||||
],
|
||||
wings: [
|
||||
['crumb-6', 4, 30, 8, 0, 'b', 0], ['crumb-7', 96, 18, 7, 40, 'b', 1], ['chili', 100, 72, 18, 20, 'b', 0], ['jalapeno-1', -4, 62, 11, -30, 'b', 1],
|
||||
['crumb-1', 12, 4, 9, 10, 'f', 1], ['crumb-2', 32, -8, 7, 50, 'f', 1], ['crumb-3', 58, -10, 8, 90, 'f', 1], ['crumb-4', 84, 2, 8, 120, 'f', 1],
|
||||
['crumb-5', 104, 40, 7, 0, 'f', 0], ['crumb-8', -4, 88, 8, 70, 'f', 0], ['jalapeno-2', 88, 102, 11, -10, 'f', 1], ['crumb-2', 46, 104, 6, 30, 'f', 0, 1]
|
||||
['crumb-6', 2, 34, 11, 0, 'b', 0], ['crumb-7', 98, 22, 10, 40, 'b', 1], ['chili', 102, 74, 20, 20, 'b', 0], ['jalapeno-1', -6, 66, 12, -30, 'b', 1],
|
||||
['crumb-1', 14, 10, 12, 10, 'f', 1], ['crumb-3', 60, 8, 11, 90, 'f', 1], ['crumb-4', 88, 12, 11, 120, 'f', 1],
|
||||
['crumb-5', 104, 46, 10, 0, 'f', 0], ['crumb-8', -2, 92, 11, 70, 'f', 0], ['jalapeno-2', 86, 104, 12, -10, 'f', 1], ['crumb-2', 48, 106, 9, 30, 'f', 0, 1]
|
||||
]
|
||||
};
|
||||
var mobileBits = window.matchMedia('(max-width: 820px)').matches;
|
||||
var bitScale = mobileBits ? 1.35 : 1;
|
||||
var blasts = $$('[data-blast]').map(function (box) {
|
||||
var set = PRESETS[box.getAttribute('data-blast')];
|
||||
if (!set) return null;
|
||||
@@ -212,10 +219,15 @@
|
||||
var bits = [];
|
||||
set.forEach(function (b) {
|
||||
if (mobileBits && !b[6]) return;
|
||||
// Verschachtelt, damit sich nichts in die Quere kommt:
|
||||
// .bit (Scroll-Explosion) > .bit__c (CSS-Zentrierung) > .bit__in (Intro) > .bit__fl (Schweben) > img (feste Drehung)
|
||||
var size = b[3] * bitScale;
|
||||
var el = document.createElement('span');
|
||||
el.className = 'bit bit--' + b[5];
|
||||
el.style.left = b[1] + '%'; el.style.top = b[2] + '%'; el.style.width = b[3] + '%';
|
||||
el.style.left = b[1] + '%'; el.style.top = b[2] + '%'; el.style.width = size + '%';
|
||||
var c = document.createElement('span'); c.className = 'bit__c';
|
||||
var inner = document.createElement('span'); inner.className = 'bit__in';
|
||||
var fl = document.createElement('span'); fl.className = 'bit__fl';
|
||||
var img = document.createElement('img');
|
||||
img.alt = ''; img.decoding = 'async'; img.draggable = false;
|
||||
if (lazy) img.loading = 'lazy';
|
||||
@@ -225,16 +237,26 @@
|
||||
// Größe als Fläche: lange, schmale Zutaten (Salatblatt, Bacon) wirken so gleich groß wie runde
|
||||
img.onload = function () {
|
||||
var ratio = img.naturalWidth / img.naturalHeight;
|
||||
el.style.width = (b[3] * Math.sqrt(ratio)).toFixed(2) + '%';
|
||||
el.style.width = (size * Math.sqrt(ratio)).toFixed(2) + '%';
|
||||
};
|
||||
img.src = BITS + b[0] + '.webp';
|
||||
inner.appendChild(img); el.appendChild(inner); holder.appendChild(el);
|
||||
bits.push({ el: el, inner: inner, img: img, x: b[1], y: b[2], layer: b[5] });
|
||||
fl.appendChild(img); inner.appendChild(fl); c.appendChild(inner); el.appendChild(c); holder.appendChild(el);
|
||||
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 };
|
||||
}).filter(Boolean);
|
||||
|
||||
/* ---------- Flammen nur animieren, solange sie sichtbar sind ---------- */
|
||||
if ('IntersectionObserver' in window) {
|
||||
var flameIO = new IntersectionObserver(function (entries) {
|
||||
entries.forEach(function (en) { en.target.classList.toggle('is-live', en.isIntersecting); });
|
||||
});
|
||||
$$('.flames, .cta__fire, .fx__sparks').forEach(function (el) { flameIO.observe(el); });
|
||||
} else {
|
||||
$$('.flames, .cta__fire, .fx__sparks').forEach(function (el) { el.classList.add('is-live'); });
|
||||
}
|
||||
|
||||
/* ---------- Funken (Buckets) ---------- */
|
||||
if (!reduce) {
|
||||
$$('[data-sparks]').forEach(function (wrap) {
|
||||
@@ -254,14 +276,17 @@
|
||||
/* ---------- 3D-Neigung der Karten (nur Maus) ---------- */
|
||||
if (!reduce && window.matchMedia('(hover: hover) and (pointer: fine)').matches) {
|
||||
$$('[data-tilt]').forEach(function (card) {
|
||||
var r = null;
|
||||
card.addEventListener('pointerenter', function () { r = card.getBoundingClientRect(); });
|
||||
card.addEventListener('pointermove', function (e) {
|
||||
var r = card.getBoundingClientRect();
|
||||
if (!r) r = card.getBoundingClientRect();
|
||||
var nx = (e.clientX - r.left) / r.width - .5, ny = (e.clientY - r.top) / r.height - .5;
|
||||
card.classList.add('is-tilting');
|
||||
card.style.setProperty('--ty', (nx * 14).toFixed(2) + 'deg');
|
||||
card.style.setProperty('--tx', (-ny * 12).toFixed(2) + 'deg');
|
||||
});
|
||||
card.addEventListener('pointerleave', function () {
|
||||
r = null;
|
||||
card.classList.remove('is-tilting');
|
||||
card.style.setProperty('--tx', '0deg'); card.style.setProperty('--ty', '0deg');
|
||||
});
|
||||
@@ -356,7 +381,6 @@
|
||||
.fromTo(chars, { scale: 0, opacity: 0, y: function () { return rand(40, 100); }, rotation: function () { return rand(-18, 18); }, transformOrigin: '50% 90%' },
|
||||
{ scale: 1, opacity: 1, y: 0, rotation: 0, duration: .75, stagger: .045, ease: 'back.out(2.2)' }, .05)
|
||||
.fromTo(burgerImg, { scale: .45, y: 140, rotation: -12, opacity: 0 }, { scale: 1, y: 0, rotation: 0, opacity: 1, duration: 1.1, ease: 'back.out(1.5)' }, .3)
|
||||
.fromTo('.hero__wm .wm-fill', { xPercent: -30, opacity: 0, rotation: -8 }, { xPercent: 0, opacity: 1, rotation: 0, duration: .8, ease: 'back.out(1.8)' }, .75)
|
||||
.fromTo($$('[data-sticker]', hero), { '--s': 0 }, { '--s': 1, duration: .6, stagger: .12, ease: 'back.out(3)' }, .9)
|
||||
.fromTo(['.hero__bottom .lead', '.hero__cta'], { y: 30, opacity: 0 }, { y: 0, opacity: 1, duration: .7, stagger: .1, ease: 'power3.out' }, .8)
|
||||
.add(function () {
|
||||
@@ -423,29 +447,49 @@
|
||||
|
||||
/* ---- Zutaten: schweben, beim Laden aus dem Essen platzen, beim Scrollen wegfliegen ---- */
|
||||
blasts.forEach(function (bl) {
|
||||
var W = function () { return bl.box.offsetWidth; };
|
||||
var vec = function (b) {
|
||||
var w = bl.box.offsetWidth, h = bl.box.offsetHeight;
|
||||
return { x: (b.x - 50) / 100 * w, y: (b.y - 50) / 100 * h };
|
||||
return { x: (b.x - 50) / 100 * W(), y: (b.y - 50) / 100 * bl.box.offsetHeight };
|
||||
};
|
||||
// Explosionsziel: kräftig nach außen, mit Drall zur Seite und nach oben
|
||||
var away = function (b, k) {
|
||||
var v = vec(b), len = Math.sqrt(v.x * v.x + v.y * v.y) || 1;
|
||||
var side = b.side;
|
||||
return {
|
||||
x: v.x * .5 + (v.x / len) * W() * k + (-v.y / len) * W() * .18 * side,
|
||||
y: v.y * .3 + (v.y / len) * W() * k * .55 - W() * .45 * k
|
||||
};
|
||||
};
|
||||
var floats = [];
|
||||
var tl = gsap.timeline({ paused: true });
|
||||
bl.bits.forEach(function (b, i) {
|
||||
gsap.to(b.img, { y: rand(-16, -8), rotation: rand(-10, 10), duration: rand(1.8, 3.2), yoyo: true, repeat: -1, ease: 'sine.inOut', delay: rand(0, 1.5) });
|
||||
var spin = rand(120, 300) * (i % 2 ? 1 : -1);
|
||||
var grow = b.layer === 'b' ? 1.05 : 1.35;
|
||||
b.side = i % 2 ? 1 : -1;
|
||||
floats.push(gsap.to(b.fl, { y: '+=' + rand(-16, -8), rotation: '+=' + rand(-8, 8), duration: rand(1.8, 3.2), yoyo: true, repeat: -1, ease: 'sine.inOut', delay: rand(0, 1.5), paused: true }));
|
||||
var spin = rand(160, 340) * b.side;
|
||||
var grow = b.layer === 'b' ? 1.15 : 1.9;
|
||||
if (bl.hero) {
|
||||
gsap.from(b.inner, { x: function () { return -vec(b).x; }, y: function () { return -vec(b).y; }, scale: .2, opacity: 0, rotation: -spin / 2, duration: 1.2, ease: 'back.out(1.3)', delay: .55 + i * .035 });
|
||||
gsap.to(b.el, {
|
||||
x: function () { return vec(b).x * 1.7; }, y: function () { return vec(b).y * 1.7 - 80; },
|
||||
rotation: spin, scale: grow, ease: 'power1.in',
|
||||
scrollTrigger: { trigger: bl.box.closest('section') || bl.box, start: 'top top', end: 'bottom top', scrub: .6, invalidateOnRefresh: true }
|
||||
});
|
||||
gsap.from(b.inner, { x: function () { return -vec(b).x; }, y: function () { return -vec(b).y; }, scale: .2, opacity: 0, rotation: -spin / 3, duration: 1.2, ease: 'back.out(1.3)', delay: .55 + i * .035 });
|
||||
tl.to(b.el, { x: function () { return away(b, 1).x; }, y: function () { return away(b, 1).y; }, rotation: spin, scale: grow, duration: 1, ease: 'power2.in' }, 0)
|
||||
.to(b.el, { opacity: 0, duration: .25, ease: 'none' }, .75);
|
||||
} else {
|
||||
var tl = gsap.timeline({ scrollTrigger: { trigger: bl.box, start: 'top 95%', end: 'bottom 5%', scrub: .7, invalidateOnRefresh: true } });
|
||||
tl.fromTo(b.el, { x: function () { return -vec(b).x * .6; }, y: function () { return -vec(b).y * .6; }, scale: .4, opacity: 0, rotation: -spin / 3 },
|
||||
{ x: 0, y: 0, scale: 1, opacity: 1, rotation: 0, duration: .42, ease: 'power2.out' })
|
||||
.to(b.el, { duration: .12 })
|
||||
.to(b.el, { x: function () { return vec(b).x * 1.3; }, y: function () { return vec(b).y * 1.3 - 40; }, scale: grow, rotation: spin, duration: .46, ease: 'power2.in' });
|
||||
{ x: 0, y: 0, scale: 1, opacity: 1, rotation: 0, duration: .4, ease: 'power2.out' }, 0)
|
||||
.to(b.el, { x: function () { return away(b, .8).x; }, y: function () { return away(b, .8).y; }, scale: grow, rotation: spin, duration: .45, ease: 'power2.in' }, .55)
|
||||
.to(b.el, { opacity: 0, duration: .12, ease: 'none' }, .88);
|
||||
}
|
||||
});
|
||||
var sec = bl.box.closest('section') || bl.box;
|
||||
ST.create({
|
||||
animation: tl, invalidateOnRefresh: true, scrub: .6,
|
||||
trigger: bl.hero ? sec : bl.box,
|
||||
start: bl.hero ? 'top top' : 'top 92%',
|
||||
end: bl.hero ? '65% top' : 'bottom 12%'
|
||||
});
|
||||
// Schweben nur, solange die Zutaten im Bild sind (spart Akku und Rechenzeit)
|
||||
ST.create({
|
||||
trigger: bl.box, start: 'top bottom', end: 'bottom top',
|
||||
onToggle: function (self) { floats.forEach(function (t) { self.isActive ? t.play() : t.pause(); }); }
|
||||
});
|
||||
});
|
||||
|
||||
/* ---- Feuerwirbel dreht sich langsam mit ---- */
|
||||
|
||||
Reference in new issue
Block a user