Skip to content

Commit bc2d334

Browse files
authored
Update fast-search-card.js
1 parent 09f5e64 commit bc2d334

File tree

1 file changed

+170
-5
lines changed

1 file changed

+170
-5
lines changed

dist/fast-search-card.js

Lines changed: 170 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1258,6 +1258,7 @@ class FastSearchCard extends HTMLElement {
12581258
gap: 12px;
12591259
opacity: 0;
12601260
transform: translateX(20px);
1261+
filter: url(#categoryGooey);
12611262
}
12621263

12631264
/* Mobile: Category-Buttons zentrieren */
@@ -4588,9 +4589,59 @@ class FastSearchCard extends HTMLElement {
45884589
height: 24px;
45894590
transition: all 0.2s ease;
45904591
}
4592+
4593+
4594+
4595+
/* NEU: SVG Gooey Filter für Liquid Animation */
4596+
.gooey-filter {
4597+
position: absolute;
4598+
width: 0;
4599+
height: 0;
4600+
pointer-events: none;
4601+
}
4602+
4603+
/* Blob Animation Container */
4604+
.blob-container {
4605+
position: absolute;
4606+
top: 0;
4607+
right: 0;
4608+
width: 400px;
4609+
height: 72px;
4610+
pointer-events: none;
4611+
z-index: 5;
4612+
display: none;
4613+
}
4614+
4615+
.liquid-blob {
4616+
position: absolute;
4617+
background: rgba(255, 255, 255, 0.15);
4618+
backdrop-filter: blur(var(--glass-blur-amount));
4619+
border-radius: 50%;
4620+
opacity: 0;
4621+
will-change: transform, opacity;
4622+
}
4623+
4624+
/* Blob-spezifische Größen */
4625+
.blob-1 { width: 72px; height: 72px; }
4626+
.blob-2 { width: 72px; height: 72px; }
4627+
.blob-3 { width: 72px; height: 72px; }
4628+
.blob-4 { width: 72px; height: 72px; }
4629+
.blob-5 { width: 72px; height: 72px; }
45914630

45924631
</style>
45934632

4633+
<!-- NEU: SVG Filter für Gooey Effect -->
4634+
<svg class="gooey-filter">
4635+
<defs>
4636+
<filter id="categoryGooey" x="-50%" y="-50%" width="200%" height="200%">
4637+
<feGaussianBlur in="SourceGraphic" stdDeviation="8"/>
4638+
<feComponentTransfer>
4639+
<feFuncA type="discrete" tableValues="0 .7 1"/>
4640+
</feComponentTransfer>
4641+
</filter>
4642+
</defs>
4643+
</svg>
4644+
45944645
<div class="main-container">
45954646
<div class="search-row">
45964647
<div class="search-panel glass-panel">
@@ -4750,6 +4801,16 @@ class FastSearchCard extends HTMLElement {
47504801
<div class="detail-panel glass-panel">
47514802
</div>
47524803

4804+
<!-- NEU: Blob Container für Liquid Animation -->
4805+
<div class="blob-container" id="blobContainer">
4806+
<div class="liquid-blob blob-1"></div>
4807+
<div class="liquid-blob blob-2"></div>
4808+
<div class="liquid-blob blob-3"></div>
4809+
<div class="liquid-blob blob-4"></div>
4810+
<div class="liquid-blob blob-5"></div>
4811+
</div>
4812+
4813+
47534814
<div class="category-buttons">
47544815
<button class="category-button glass-panel active" data-category="devices" title="Geräte">
47554816
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
@@ -4987,8 +5048,8 @@ class FastSearchCard extends HTMLElement {
49875048
}
49885049

49895050
showCategoryButtons() {
4990-
this.collapsePanel(); // <-- HINZUGEFÜGTE ZEILE
4991-
5051+
this.collapsePanel();
5052+
49925053
// NEU: Search-Wrapper auf Mobile verstecken
49935054
if (this.isMobile()) {
49945055
const searchWrapper = this.shadowRoot.querySelector('.search-panel');
@@ -4997,10 +5058,10 @@ class FastSearchCard extends HTMLElement {
49975058
}
49985059
}
49995060

5000-
const categoryButtons = this.shadowRoot.querySelector('.category-buttons');
50015061
this.isMenuView = true;
5002-
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' });
5062+
5063+
// 🌊 NEUE LIQUID ANIMATION statt der alten Animation
5064+
this.startLiquidCategoryAnimation();
50045065
}
50055066

50065067
hideCategoryButtons() {
@@ -5041,6 +5102,110 @@ class FastSearchCard extends HTMLElement {
50415102
this.hideCategoryButtons();
50425103
}
50435104

5105+
// 🌊 LIQUID ANIMATION METHODEN
5106+
5107+
createBlobAnimation() {
5108+
const blobContainer = this.shadowRoot.querySelector('#blobContainer');
5109+
const blobs = blobContainer.querySelectorAll('.liquid-blob');
5110+
5111+
// Alle Blobs zurücksetzen
5112+
blobs.forEach(blob => {
5113+
blob.style.opacity = '0';
5114+
blob.style.transform = 'scale(0) translateX(0px)';
5115+
});
5116+
5117+
return { blobContainer, blobs };
5118+
}
5119+
5120+
animateBlobEmergence(blobs) {
5121+
return new Promise((resolve) => {
5122+
// Schritt 1: Ersten Blob erscheinen lassen
5123+
const firstBlob = blobs[0];
5124+
firstBlob.style.display = 'block';
5125+
firstBlob.style.left = '0px';
5126+
firstBlob.style.top = '0px';
5127+
5128+
firstBlob.animate([
5129+
{ opacity: 0, transform: 'scale(0) translateX(0px)' },
5130+
{ opacity: 1, transform: 'scale(1) translateX(0px)' }
5131+
], {
5132+
duration: 300,
5133+
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
5134+
fill: 'forwards'
5135+
}).finished.then(() => {
5136+
setTimeout(resolve, 100);
5137+
});
5138+
});
5139+
}
5140+
5141+
animateBlobSegmentation(blobs) {
5142+
return new Promise((resolve) => {
5143+
// Alle 5 Blobs zu ihren finalen Positionen animieren
5144+
const positions = [
5145+
{ x: 0, y: 0 }, // devices
5146+
{ x: 84, y: 0 }, // scripts
5147+
{ x: 168, y: 0 }, // automations
5148+
{ x: 252, y: 0 }, // scenes
5149+
{ x: 336, y: 0 } // custom
5150+
];
5151+
5152+
const animations = Array.from(blobs).map((blob, index) => {
5153+
const pos = positions[index];
5154+
5155+
return blob.animate([
5156+
{
5157+
opacity: index === 0 ? 1 : 0,
5158+
transform: `scale(${index === 0 ? 1 : 0}) translateX(0px)`
5159+
},
5160+
{
5161+
opacity: 1,
5162+
transform: `scale(1) translateX(${pos.x}px)`
5163+
}
5164+
], {
5165+
duration: 400,
5166+
delay: index * 80,
5167+
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
5168+
fill: 'forwards'
5169+
});
5170+
});
5171+
5172+
Promise.all(animations.map(anim => anim.finished)).then(() => {
5173+
setTimeout(resolve, 200);
5174+
});
5175+
});
5176+
}
5177+
5178+
startLiquidCategoryAnimation() {
5179+
const { blobContainer, blobs } = this.createBlobAnimation();
5180+
5181+
// Blob-Container anzeigen
5182+
blobContainer.style.display = 'block';
5183+
5184+
// Starte Animations-Kette
5185+
this.animateBlobEmergence(blobs)
5186+
.then(() => this.animateBlobSegmentation(blobs))
5187+
.then(() => this.materialiseCategoryButtons());
5188+
}
5189+
5190+
materialiseCategoryButtons() {
5191+
const categoryButtons = this.shadowRoot.querySelector('.category-buttons');
5192+
const blobContainer = this.shadowRoot.querySelector('#blobContainer');
5193+
5194+
// Category-Buttons anzeigen und Blobs verstecken
5195+
categoryButtons.classList.add('visible');
5196+
blobContainer.style.display = 'none';
5197+
5198+
// Finale Category-Button Animation
5199+
categoryButtons.animate([
5200+
{ opacity: 0, transform: 'translateX(20px) scale(0.9)' },
5201+
{ opacity: 1, transform: 'translateX(0) scale(1)' }
5202+
], {
5203+
duration: 300,
5204+
easing: 'cubic-bezier(0.16, 1, 0.3, 1)',
5205+
fill: 'forwards'
5206+
});
5207+
}
5208+
50445209
handleSubcategorySelect(selectedChip) {
50455210
let subcategory = selectedChip.dataset.subcategory;
50465211
if (subcategory === this.activeSubcategory && subcategory !== 'all') {

0 commit comments

Comments
 (0)