Skip to content

Commit 47375a3

Browse files
authored
Update fast-search-card.js
1 parent 271801a commit 47375a3

File tree

1 file changed

+106
-80
lines changed

1 file changed

+106
-80
lines changed

dist/fast-search-card.js

Lines changed: 106 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,18 +1254,12 @@ class FastSearchCard extends HTMLElement {
12541254

12551255
.category-buttons {
12561256
display: none; /* Wird per JS auf 'flex' gesetzt */
1257-
flex-direction: row;
1258-
gap: 0; /* WICHTIG: Kein Gap für Gooey-Effekt */
1259-
opacity: 1; /* Opacity wird nicht mehr animiert */
1260-
transform: none; /* Kein Transform mehr */
1261-
filter: url(#categoryGooey); /* ✅ BEHALTEN */
1262-
1263-
/* WICHTIG für die Animation */
1264-
position: relative; /* Positionierungs-Kontext für die Buttons */
1265-
width: 72px; /* Startbreite = 1 Button */
1257+
align-items: center; /* NEU: Zentriert die Buttons vertikal */
1258+
position: relative; /* WICHTIG: Kontext für die absoluten Buttons */
12661259
height: 72px;
1267-
padding: 0;
1260+
width: 72px; /* Startbreite = 1 Button */
12681261
will-change: width, filter;
1262+
/* Filter wird per JS hinzugefügt und entfernt */
12691263
}
12701264

12711265
/* Mobile: Category-Buttons zentrieren */
@@ -1319,6 +1313,11 @@ class FastSearchCard extends HTMLElement {
13191313
stroke-linecap: round;
13201314
stroke-linejoin: round;
13211315
transition: all 0.2s ease;
1316+
1317+
/* NEU: Für die Animation hinzufügen */
1318+
opacity: 0;
1319+
transform: scale(0.8);
1320+
will-change: opacity, transform;
13221321
}
13231322

13241323
.category-button.active svg {
@@ -4615,18 +4614,10 @@ class FastSearchCard extends HTMLElement {
46154614
<!-- ERSETZEN Sie den bestehenden SVG Filter mit diesem: -->
46164615
<svg class="gooey-filter">
46174616
<defs>
4618-
<filter id="categoryGooey" x="-50%" y="-50%" width="200%" height="200%">
4619-
<feGaussianBlur in="SourceGraphic" stdDeviation="15"/>
4620-
<feComponentTransfer>
4621-
<feFuncA type="discrete" tableValues="0 .5 1"/>
4622-
</feComponentTransfer>
4623-
</filter>
4624-
<!-- NEU: Filter für Suchleiste Morphing -->
4625-
<filter id="searchMorph" x="-20%" y="-20%" width="140%" height="140%">
4626-
<feGaussianBlur in="SourceGraphic" stdDeviation="12"/>
4627-
<feComponentTransfer>
4628-
<feFuncA type="discrete" tableValues="0 .7 1"/>
4629-
</feComponentTransfer>
4617+
<filter id="categoryGooey">
4618+
<feGaussianBlur in="SourceGraphic" stdDeviation="15" result="blur" />
4619+
<feColorMatrix in="blur" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 18 -7" result="gooey" />
4620+
<feComposite in="SourceGraphic" in2="gooey" operator="atop"/>
46304621
</filter>
46314622
</defs>
46324623
</svg>
@@ -5032,58 +5023,77 @@ class FastSearchCard extends HTMLElement {
50325023

50335024
async showCategoryButtons() {
50345025
this.collapsePanel();
5035-
50365026
if (this.isMobile()) {
50375027
const searchWrapper = this.shadowRoot.querySelector('.search-panel');
50385028
if (searchWrapper) {
50395029
searchWrapper.style.display = 'none';
50405030
}
50415031
}
5042-
50435032
this.isMenuView = true;
50445033

5045-
// --- NEUE, ELEGANTE SPOTLIGHT ANIMATION ---
5034+
// --- NEUE SPOTLIGHT ANIMATION ---
5035+
50465036
const categoryButtonsContainer = this.shadowRoot.querySelector('.category-buttons');
50475037
const buttons = Array.from(categoryButtonsContainer.querySelectorAll('.category-button'));
5038+
// Wichtig: Wir brauchen den Weichzeichner im SVG-Filter, um ihn zu animieren
5039+
const gooeyFilter = this.shadowRoot.querySelector('#categoryGooey feGaussianBlur');
5040+
5041+
if (!categoryButtonsContainer || buttons.length === 0 || !gooeyFilter) {
5042+
console.error("Animations-Elemente nicht gefunden.");
5043+
return;
5044+
}
50485045

5049-
// 1. Vorbereitung: Container und Buttons für Animation vorbereiten
5050-
categoryButtonsContainer.classList.add('visible'); // Container sichtbar machen
5051-
categoryButtonsContainer.style.filter = 'url(#categoryGooey)'; // Gooey-Filter aktivieren
5046+
// --- Phase 1: Morphing & Trennung (Bild 1-6) ---
5047+
5048+
// 1. Vorbereitung
5049+
categoryButtonsContainer.classList.add('visible');
5050+
categoryButtonsContainer.style.filter = 'url(#categoryGooey)';
5051+
gooeyFilter.setAttribute('stdDeviation', '15'); // Weichzeichner aktivieren
50525052

5053-
// Alle Buttons am Anfang des Containers positionieren und unsichtbar machen
50545053
buttons.forEach(btn => {
5055-
btn.style.transform = 'translateX(0px) scale(0)';
5056-
btn.style.opacity = '0';
5054+
btn.style.transform = 'translateX(0px) scale(1)';
5055+
btn.style.opacity = '1';
5056+
btn.querySelector('svg').style.opacity = '0'; // Icons bleiben unsichtbar
50575057
});
50585058

5059-
// 2. Der "Wurm" wächst: Container auf volle Breite animieren
5060-
const containerWidth = buttons.length * 72 + (buttons.length - 1) * 12; // 72px pro Button + 12px Abstand
5061-
const containerAnimation = categoryButtonsContainer.animate([
5062-
{ width: '72px' },
5063-
{ width: `${containerWidth}px` }
5064-
], {
5065-
duration: 400,
5066-
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
5067-
fill: 'forwards'
5068-
});
5059+
// 2. Der "Wurm" wächst (Bild 2-3)
5060+
const containerWidth = buttons.length * 72 + (buttons.length - 1) * 12;
5061+
const containerAnimation = categoryButtonsContainer.animate(
5062+
{ width: [`72px`, `${containerWidth}px`] },
5063+
{ duration: 350, easing: 'cubic-bezier(0.4, 0, 0.2, 1)', fill: 'forwards' }
5064+
);
50695065
await containerAnimation.finished;
50705066

5071-
// 3. Die "Teilung": Buttons zu ihren finalen Positionen animieren
5072-
const animations = buttons.map((btn, index) => {
5073-
const finalX = index * (72 + 12); // Finale X-Position
5074-
return btn.animate([
5075-
{ transform: 'translateX(0px) scale(1)', opacity: 1 },
5076-
{ transform: `translateX(${finalX}px) scale(1)`, opacity: 1 }
5077-
], {
5078-
duration: 600,
5079-
delay: index * 60, // Gestaffelter Start für flüssigen Effekt
5080-
easing: 'cubic-bezier(0.4, 0, 0.2, 1)',
5081-
fill: 'forwards'
5082-
});
5067+
// 3. Die Trennung der "Tropfen" (Bild 4-6)
5068+
const separationAnimations = buttons.map((btn, index) => {
5069+
const finalX = index * (72 + 12);
5070+
return btn.animate(
5071+
{ transform: [`translateX(0px)`, `translateX(${finalX}px)`] },
5072+
{ duration: 500, delay: index * 50, easing: 'cubic-bezier(0.4, 0, 0.2, 1)', fill: 'forwards' }
5073+
);
50835074
});
5084-
await Promise.all(animations.map(a => a.finished));
5075+
await Promise.all(separationAnimations.map(a => a.finished));
5076+
5077+
// --- Phase 2: Verfestigung & Enthüllung (Bild 7-10) ---
5078+
5079+
// 4. Verfestigung: Den Weichzeichner auf 0 animieren
5080+
const solidificationAnimation = gooeyFilter.animate(
5081+
{ stdDeviation: [15, 0] },
5082+
{ duration: 300, easing: 'ease-out', fill: 'forwards' }
5083+
);
50855084

5086-
// 4. Aufräumen: Filter entfernen, damit Buttons scharf werden
5085+
// 5. Enthüllung: Icons einblenden, während die Form fest wird
5086+
buttons.forEach((btn, index) => {
5087+
const icon = btn.querySelector('svg');
5088+
icon.animate(
5089+
{ opacity: [0, 1], transform: ['scale(0.8)', 'scale(1)'] },
5090+
{ duration: 300, delay: index * 30, easing: 'ease-out', fill: 'forwards' }
5091+
);
5092+
});
5093+
5094+
await solidificationAnimation.finished;
5095+
5096+
// 6. Aufräumen: Filter komplett entfernen, um die Performance zu schonen
50875097
categoryButtonsContainer.style.filter = 'none';
50885098
}
50895099

@@ -5100,37 +5110,53 @@ class FastSearchCard extends HTMLElement {
51005110
if (!this.isMenuView) return;
51015111

51025112
const buttons = Array.from(categoryButtonsContainer.querySelectorAll('.category-button'));
5113+
const gooeyFilter = this.shadowRoot.querySelector('#categoryGooey feGaussianBlur');
5114+
5115+
if (!gooeyFilter) {
5116+
// Fallback zur einfachen Animation
5117+
categoryButtonsContainer.classList.remove('visible');
5118+
this.isMenuView = false;
5119+
return;
5120+
}
51035121

5104-
// Reverse Animation: Buttons zurück zum Startpunkt
5105-
categoryButtonsContainer.style.filter = 'url(#categoryGooey)'; // Filter wieder aktivieren
5122+
// Reverse Spotlight Animation
5123+
categoryButtonsContainer.style.filter = 'url(#categoryGooey)';
5124+
gooeyFilter.setAttribute('stdDeviation', '15');
51065125

5107-
const animations = buttons.map((btn, index) => {
5108-
return btn.animate([
5109-
{ transform: `translateX(${index * (72 + 12)}px) scale(1)`, opacity: 1 },
5110-
{ transform: 'translateX(0px) scale(0)', opacity: 0 }
5111-
], {
5112-
duration: 300,
5113-
delay: (buttons.length - index - 1) * 50, // Rückwärts gestaffelt
5114-
easing: 'ease-in',
5115-
fill: 'forwards'
5116-
});
5126+
// 1. Icons ausblenden
5127+
buttons.forEach((btn, index) => {
5128+
const icon = btn.querySelector('svg');
5129+
icon.animate(
5130+
{ opacity: [1, 0], transform: ['scale(1)', 'scale(0.8)'] },
5131+
{ duration: 200, delay: (buttons.length - index - 1) * 20, easing: 'ease-in', fill: 'forwards' }
5132+
);
51175133
});
51185134

5119-
await Promise.all(animations.map(a => a.finished));
5135+
await new Promise(resolve => setTimeout(resolve, 300));
51205136

5121-
// Container zusammenziehen
5122-
categoryButtonsContainer.animate([
5123-
{ width: `${buttons.length * 72 + (buttons.length - 1) * 12}px` },
5124-
{ width: '72px' }
5125-
], {
5126-
duration: 200,
5127-
easing: 'ease-in',
5128-
fill: 'forwards'
5129-
}).finished.then(() => {
5130-
categoryButtonsContainer.classList.remove('visible');
5131-
categoryButtonsContainer.style.filter = 'none';
5132-
this.isMenuView = false;
5137+
// 2. Buttons zusammenziehen
5138+
const contractionAnimations = buttons.map((btn, index) => {
5139+
return btn.animate(
5140+
{ transform: [`translateX(${index * (72 + 12)}px)`, 'translateX(0px)'] },
5141+
{ duration: 400, delay: (buttons.length - index - 1) * 40, easing: 'ease-in', fill: 'forwards' }
5142+
);
51335143
});
5144+
5145+
await Promise.all(contractionAnimations.map(a => a.finished));
5146+
5147+
// 3. Container zusammenziehen
5148+
const containerWidth = buttons.length * 72 + (buttons.length - 1) * 12;
5149+
const containerAnimation = categoryButtonsContainer.animate(
5150+
{ width: [`${containerWidth}px`, '72px'] },
5151+
{ duration: 250, easing: 'ease-in', fill: 'forwards' }
5152+
);
5153+
5154+
await containerAnimation.finished;
5155+
5156+
// 4. Aufräumen
5157+
categoryButtonsContainer.classList.remove('visible');
5158+
categoryButtonsContainer.style.filter = 'none';
5159+
this.isMenuView = false;
51345160
}
51355161

51365162
handleCategorySelect(selectedButton) {

0 commit comments

Comments
 (0)