@@ -1258,6 +1258,11 @@ class FastSearchCard extends HTMLElement {
12581258 gap: 12px;
12591259 opacity: 0;
12601260 transform: translateX(20px);
1261+ /* NEUE GOOEY EIGENSCHAFTEN: */
1262+ filter: blur(10px) contrast(20);
1263+ position: relative;
1264+ justify-content: center;
1265+ width: 100%;
12611266 }
12621267
12631268 /* Mobile: Category-Buttons zentrieren */
@@ -1273,6 +1278,15 @@ class FastSearchCard extends HTMLElement {
12731278 display: flex;
12741279 }
12751280
1281+ /* NEUE GOOEY STATES: */
1282+ .category-buttons.gooey-mode {
1283+ filter: blur(10px) contrast(20);
1284+ }
1285+
1286+ .category-buttons.separated-mode {
1287+ filter: blur(0px) contrast(1);
1288+ }
1289+
12761290 .category-button {
12771291 width: 72px;
12781292 height: 72px;
@@ -4987,9 +5001,8 @@ class FastSearchCard extends HTMLElement {
49875001 }
49885002
49895003 showCategoryButtons() {
4990- this.collapsePanel(); // <-- HINZUGEFÜGTE ZEILE
4991-
4992- // NEU: Search-Wrapper auf Mobile verstecken
5004+ this.collapsePanel();
5005+
49935006 if (this.isMobile()) {
49945007 const searchWrapper = this.shadowRoot.querySelector('.search-panel');
49955008 if (searchWrapper) {
@@ -4998,11 +5011,16 @@ class FastSearchCard extends HTMLElement {
49985011 }
49995012
50005013 const categoryButtons = this.shadowRoot.querySelector('.category-buttons');
5014+ const buttons = categoryButtons.querySelectorAll('.category-button');
5015+
50015016 this.isMenuView = true;
50025017 categoryButtons.classList.add('visible');
5003- categoryButtons.animate([{ opacity: 0, transform: 'translateX(20px) scale(0.9)' }, { opacity: 1, transform: 'translateX(0) scale(1)' }], { duration: 400, easing: 'cubic-bezier(0.16, 1, 0.3, 1)', fill: 'forwards' });
5018+ categoryButtons.classList.add('gooey-mode');
5019+
5020+ // NEUE GOOEY ANIMATION:
5021+ this.animateGooeyExpansion(categoryButtons, buttons);
50045022 }
5005-
5023+
50065024 hideCategoryButtons() {
50075025 // NEU: Search-Wrapper wieder anzeigen
50085026 if (this.isMobile()) {
@@ -5014,10 +5032,100 @@ class FastSearchCard extends HTMLElement {
50145032
50155033 const categoryButtons = this.shadowRoot.querySelector('.category-buttons');
50165034 if (!this.isMenuView) return;
5017- const animation = categoryButtons.animate([{ opacity: 1, transform: 'translateX(0) scale(1)' }, { opacity: 0, transform: 'translateX(20px) scale(0.9)' }], { duration: 300, easing: 'ease-in', fill: 'forwards' });
5018- animation.finished.then(() => { categoryButtons.classList.remove('visible'); this.isMenuView = false; });
5035+
5036+ // NEUE GOOEY REVERSE ANIMATION:
5037+ this.animateGooeyCollapse(categoryButtons);
5038+ }
5039+
5040+ animateGooeyExpansion(container, buttons) {
5041+ // Reset: Alle Buttons in der Mitte
5042+ buttons.forEach(button => {
5043+ button.style.left = '50%';
5044+ button.style.position = 'absolute';
5045+ button.style.transform = 'translate(-50%, -50%)';
5046+ });
5047+
5048+ // Phase 1: Filter Animation (Gooey → Klar)
5049+ const filterAnimation = container.animate([
5050+ { filter: 'blur(10px) contrast(20)' },
5051+ { filter: 'blur(0px) contrast(1)' }
5052+ ], {
5053+ duration: 400,
5054+ easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
5055+ fill: 'forwards'
5056+ });
5057+
5058+ // Phase 2: Buttons auseinanderfahren
5059+ const buttonPositions = this.calculateButtonPositions(buttons.length);
5060+
5061+ buttons.forEach((button, index) => {
5062+ const targetPos = buttonPositions[index];
5063+
5064+ button.animate([
5065+ { left: '50%' },
5066+ { left: `${targetPos}%` }
5067+ ], {
5068+ duration: 400,
5069+ easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
5070+ fill: 'forwards'
5071+ });
5072+ });
5073+
5074+ // CSS-Klassen nach Animation updaten
5075+ filterAnimation.finished.then(() => {
5076+ container.classList.remove('gooey-mode');
5077+ container.classList.add('separated-mode');
5078+ });
50195079 }
50205080
5081+ animateGooeyCollapse(container) {
5082+ const buttons = container.querySelectorAll('.category-button');
5083+
5084+ // Phase 1: Buttons zur Mitte
5085+ buttons.forEach(button => {
5086+ button.animate([
5087+ { left: button.style.left || '50%' },
5088+ { left: '50%' }
5089+ ], {
5090+ duration: 300,
5091+ easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
5092+ fill: 'forwards'
5093+ });
5094+ });
5095+
5096+ // Phase 2: Filter Animation (Klar → Gooey)
5097+ setTimeout(() => {
5098+ const filterAnimation = container.animate([
5099+ { filter: 'blur(0px) contrast(1)' },
5100+ { filter: 'blur(10px) contrast(20)' }
5101+ ], {
5102+ duration: 200,
5103+ easing: 'ease-in',
5104+ fill: 'forwards'
5105+ });
5106+
5107+ filterAnimation.finished.then(() => {
5108+ container.classList.remove('visible', 'separated-mode', 'gooey-mode');
5109+ this.isMenuView = false;
5110+ });
5111+ }, 100);
5112+ }
5113+
5114+ calculateButtonPositions(buttonCount) {
5115+ const containerWidth = 100; // Prozent
5116+ const buttonWidth = 10; // Ca. 10% pro Button
5117+ const spacing = 2; // 2% Abstand
5118+ const totalWidth = buttonCount * buttonWidth + (buttonCount - 1) * spacing;
5119+ const startOffset = (containerWidth - totalWidth) / 2;
5120+
5121+ const positions = [];
5122+ for (let i = 0; i < buttonCount; i++) {
5123+ const position = startOffset + (buttonWidth / 2) + i * (buttonWidth + spacing);
5124+ positions.push(position);
5125+ }
5126+ return positions;
5127+ }
5128+
50215129 handleCategorySelect(selectedButton) {
50225130 const category = selectedButton.dataset.category;
50235131
0 commit comments