astro-component-kit 0.2.2 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -4
- package/package.json +11 -9
- package/src/components/index.ts +12 -9
- package/src/components/lib/AnimatedGalaxy.astro +4 -2
- package/src/components/lib/Galaxy3D.astro +237 -185
- package/src/components/lib/LogoWithGalaxy.astro +2 -2
- package/src/components/lib/buttons/index.ts +4 -1
- package/src/components/lib/cards/index.ts +3 -0
- package/src/components/lib/charts/DonutChart.astro +1 -1
- package/src/components/lib/charts/index.ts +3 -0
- package/src/components/lib/data/index.ts +3 -0
- package/src/components/lib/feedback/index.ts +3 -0
- package/src/components/lib/forms/index.ts +3 -0
- package/src/components/lib/index.ts +17 -6
- package/src/components/lib/layout/BentoGrid3.astro +79 -9
- package/src/components/lib/layout/CenterFixedBox.astro +52 -2
- package/src/components/lib/layout/CenteredContainer.astro +44 -5
- package/src/components/lib/layout/ClusterHorizontal.astro +36 -2
- package/src/components/lib/layout/FeatureHero.astro +119 -50
- package/src/components/lib/layout/FooterCenteredMinimal.astro +57 -9
- package/src/components/lib/layout/FullBleedSection.astro +44 -2
- package/src/components/lib/layout/GalleryGrid4.astro +35 -3
- package/src/components/lib/layout/GlassCardGrid.astro +24 -2
- package/src/components/lib/layout/GlassSectionHeader.astro +72 -11
- package/src/components/lib/layout/LandingSectionSplit.astro +83 -8
- package/src/components/lib/layout/MasonryGrid.astro +42 -3
- package/src/components/lib/layout/MinimalFooterGrid.astro +83 -11
- package/src/components/lib/layout/ScrollSnapSection.astro +37 -3
- package/src/components/lib/layout/SectionDividerText.astro +44 -4
- package/src/components/lib/layout/SidebarLayoutWrapper.astro +62 -7
- package/src/components/lib/layout/SplitScreenLayout.astro +62 -6
- package/src/components/lib/layout/StepLayoutVertical.astro +83 -10
- package/src/components/lib/layout/StickySidebarWrapper.astro +69 -6
- package/src/components/lib/layout/VerticalStack.astro +35 -5
- package/src/components/lib/layout/index.ts +17 -14
- package/src/components/lib/navigation/index.ts +3 -0
- package/src/components/lib/overlays/index.ts +3 -0
- package/src/components/lib/sections/ContactGlassForm.astro +361 -0
- package/src/components/lib/sections/CtaAppDownload.astro +258 -0
- package/src/components/lib/sections/CtaGlowBanner.astro +267 -0
- package/src/components/lib/sections/FaqAccordionSection.astro +349 -0
- package/src/components/lib/sections/FeatureBentoGrid.astro +449 -0
- package/src/components/lib/sections/FeatureTimelineFlow.astro +254 -0
- package/src/components/lib/sections/PricingComparisonMatrix.astro +468 -0
- package/src/components/lib/sections/PricingTierCards.astro +256 -0
- package/src/components/lib/sections/StatsMetricShowcase.astro +332 -0
- package/src/components/lib/sections/TeamGridSection.astro +333 -0
- package/src/components/lib/sections/TestimonialWallGlass.astro +406 -0
- package/src/components/lib/sections/index.ts +22 -0
- package/src/components/lib/typography/index.ts +3 -0
- package/src/components/lib/AnimatedInput.astro +0 -82
- package/src/components/lib/Badge.astro +0 -52
- package/src/components/lib/GlassButton.astro +0 -87
- package/src/components/lib/GlassCard.astro +0 -72
- package/src/components/lib/GlassNavbar.astro +0 -67
- package/src/components/lib/GlowButton.astro +0 -60
- /package/src/components/lib/buttons/{3dPushButton.astro → ThreeDPushButton.astro} +0 -0
|
@@ -1,4 +1,12 @@
|
|
|
1
1
|
---
|
|
2
|
+
/**
|
|
3
|
+
* Galaxy3D — Interactive 3D galaxy background with mouse-reactive particle distortion.
|
|
4
|
+
*
|
|
5
|
+
* Renders a spiral galaxy with thousands of particles using Three.js.
|
|
6
|
+
* Mouse movement creates a repulsion force that distorts nearby particles in real-time.
|
|
7
|
+
*
|
|
8
|
+
* @param {string} className - Additional CSS class
|
|
9
|
+
*/
|
|
2
10
|
interface Props {
|
|
3
11
|
className?: string;
|
|
4
12
|
}
|
|
@@ -6,7 +14,7 @@ interface Props {
|
|
|
6
14
|
const { className = '' } = Astro.props;
|
|
7
15
|
---
|
|
8
16
|
|
|
9
|
-
<div class="galaxy-3d-container {className}" id="galaxy-3d-wrapper">
|
|
17
|
+
<div class="galaxy-3d-container {className}" id="galaxy-3d-wrapper" aria-hidden="true">
|
|
10
18
|
<canvas id="galaxy-3d-canvas"></canvas>
|
|
11
19
|
</div>
|
|
12
20
|
|
|
@@ -17,7 +25,7 @@ const { className = '' } = Astro.props;
|
|
|
17
25
|
width: 100%;
|
|
18
26
|
height: 100%;
|
|
19
27
|
z-index: 0;
|
|
20
|
-
pointer-events:
|
|
28
|
+
pointer-events: auto;
|
|
21
29
|
}
|
|
22
30
|
#galaxy-3d-canvas {
|
|
23
31
|
position: absolute;
|
|
@@ -28,21 +36,19 @@ const { className = '' } = Astro.props;
|
|
|
28
36
|
}
|
|
29
37
|
</style>
|
|
30
38
|
|
|
31
|
-
<script is:inline>
|
|
32
|
-
|
|
33
|
-
const THREE = await import('three');
|
|
39
|
+
<script is:inline type="module">
|
|
40
|
+
import * as THREE from 'https://cdn.jsdelivr.net/npm/three@0.160.0/build/three.module.js';
|
|
34
41
|
|
|
42
|
+
(function () {
|
|
35
43
|
const canvas = document.getElementById('galaxy-3d-canvas');
|
|
36
44
|
if (!canvas) return;
|
|
37
|
-
|
|
38
45
|
const container = canvas.parentElement;
|
|
39
46
|
if (!container) return;
|
|
40
47
|
|
|
41
|
-
//
|
|
48
|
+
// ===== SCENE =====
|
|
42
49
|
const scene = new THREE.Scene();
|
|
43
50
|
const camera = new THREE.PerspectiveCamera(75, 1, 0.1, 100);
|
|
44
51
|
camera.position.set(0, 0, 5);
|
|
45
|
-
camera.lookAt(0, 0, 0);
|
|
46
52
|
|
|
47
53
|
const renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true });
|
|
48
54
|
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
|
|
@@ -50,190 +56,153 @@ const { className = '' } = Astro.props;
|
|
|
50
56
|
function resize() {
|
|
51
57
|
const w = container.clientWidth;
|
|
52
58
|
const h = container.clientHeight;
|
|
59
|
+
if (w === 0 || h === 0) return;
|
|
53
60
|
renderer.setSize(w, h);
|
|
54
61
|
camera.aspect = w / h;
|
|
55
62
|
camera.updateProjectionMatrix();
|
|
56
63
|
}
|
|
57
64
|
|
|
58
|
-
resize();
|
|
65
|
+
requestAnimationFrame(() => resize());
|
|
66
|
+
setTimeout(resize, 100);
|
|
67
|
+
setTimeout(resize, 500);
|
|
59
68
|
window.addEventListener('resize', resize);
|
|
60
69
|
|
|
61
|
-
//
|
|
62
|
-
const
|
|
63
|
-
new THREE.Color('#fef3c7'), // Light gold
|
|
64
|
-
new THREE.Color('#fbbf24'), // Gold
|
|
65
|
-
new THREE.Color('#d4a017'), // Dark gold
|
|
66
|
-
new THREE.Color('#ffffff'), // White
|
|
67
|
-
new THREE.Color('#b8860b'), // Darker gold
|
|
68
|
-
];
|
|
69
|
-
|
|
70
|
-
const bgStarColors = [
|
|
71
|
-
new THREE.Color('#ffffff'),
|
|
70
|
+
// ===== COLORS =====
|
|
71
|
+
const palette = [
|
|
72
72
|
new THREE.Color('#fef3c7'),
|
|
73
|
+
new THREE.Color('#fbbf24'),
|
|
74
|
+
new THREE.Color('#d4a017'),
|
|
75
|
+
new THREE.Color('#ffffff'),
|
|
76
|
+
new THREE.Color('#b8860b'),
|
|
73
77
|
new THREE.Color('#fde68a'),
|
|
74
78
|
];
|
|
75
79
|
|
|
76
|
-
//
|
|
80
|
+
// ===== GALAXY PARTICLES =====
|
|
81
|
+
const GALAXY_COUNT = 20000;
|
|
77
82
|
const galaxyParams = {
|
|
78
|
-
|
|
79
|
-
size: 0.025,
|
|
80
|
-
radius: 2.8,
|
|
83
|
+
radius: 3.5,
|
|
81
84
|
branches: 5,
|
|
82
85
|
spin: 1.5,
|
|
83
|
-
randomness: 0.
|
|
84
|
-
randomnessPower:
|
|
85
|
-
|
|
86
|
+
randomness: 0.5,
|
|
87
|
+
randomnessPower: 3,
|
|
88
|
+
inwardDrop: 0.05,
|
|
86
89
|
};
|
|
87
90
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const sizes = new Float32Array(galaxyParams.count);
|
|
93
|
-
const randomness = new Float32Array(galaxyParams.count);
|
|
94
|
-
|
|
95
|
-
for (let i = 0; i < galaxyParams.count; i++) {
|
|
96
|
-
const i3 = i * 3;
|
|
97
|
-
const radius = Math.random() * galaxyParams.radius;
|
|
98
|
-
const spinAngle = radius * galaxyParams.spin;
|
|
99
|
-
const branchIndex = i % galaxyParams.branches;
|
|
100
|
-
const branchAngle = (branchIndex / galaxyParams.branches) * Math.PI * 2;
|
|
101
|
-
|
|
102
|
-
const power = galaxyParams.randomnessPower;
|
|
103
|
-
const randomX = Math.pow(Math.random(), power) * (Math.random() < 0.5 ? 1 : -1) * galaxyParams.randomness * radius;
|
|
104
|
-
const randomY = Math.pow(Math.random(), power) * (Math.random() < 0.5 ? 1 : -1) * galaxyParams.randomness * radius * 0.15;
|
|
105
|
-
const randomZ = Math.pow(Math.random(), power) * (Math.random() < 0.5 ? 1 : -1) * galaxyParams.randomness * radius;
|
|
106
|
-
|
|
107
|
-
const angle = branchAngle + spinAngle;
|
|
108
|
-
positions[i3] = Math.cos(angle) * radius + randomX;
|
|
109
|
-
positions[i3 + 1] = randomY;
|
|
110
|
-
positions[i3 + 2] = Math.sin(angle) * radius + randomZ;
|
|
111
|
-
|
|
112
|
-
// Color based on radius
|
|
113
|
-
const colorIndex = Math.floor(Math.random() * galaxyColors.length);
|
|
114
|
-
const color = galaxyColors[colorIndex];
|
|
115
|
-
const mixFactor = Math.random() * 0.3 + (radius / galaxyParams.radius) * 0.7;
|
|
116
|
-
const finalColor = color.clone().lerp(galaxyColors[(colorIndex + 1) % galaxyColors.length], mixFactor);
|
|
117
|
-
|
|
118
|
-
colors[i3] = finalColor.r;
|
|
119
|
-
colors[i3 + 1] = finalColor.g;
|
|
120
|
-
colors[i3 + 2] = finalColor.b;
|
|
121
|
-
|
|
122
|
-
sizes[i] = (Math.random() + 0.8) * galaxyParams.size;
|
|
123
|
-
randomness[i] = Math.random();
|
|
124
|
-
|
|
125
|
-
// Store for animation
|
|
126
|
-
randomness[i3] = randomX;
|
|
127
|
-
randomness[i3 + 1] = randomY;
|
|
128
|
-
randomness[i3 + 2] = randomZ;
|
|
129
|
-
}
|
|
91
|
+
const galaxyGeometry = new THREE.BufferGeometry();
|
|
92
|
+
const galaxyPositions = new Float32Array(GALAXY_COUNT * 3);
|
|
93
|
+
const galaxyColors = new Float32Array(GALAXY_COUNT * 3);
|
|
94
|
+
const galaxyOriginalPositions = new Float32Array(GALAXY_COUNT * 3);
|
|
130
95
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
96
|
+
for (let i = 0; i < GALAXY_COUNT; i++) {
|
|
97
|
+
const i3 = i * 3;
|
|
98
|
+
const radius = Math.random() * galaxyParams.radius;
|
|
99
|
+
const spinAngle = radius * galaxyParams.spin;
|
|
100
|
+
const branchIndex = i % galaxyParams.branches;
|
|
101
|
+
const branchAngle = (branchIndex / galaxyParams.branches) * Math.PI * 2;
|
|
102
|
+
|
|
103
|
+
const power = galaxyParams.randomnessPower;
|
|
104
|
+
const randomX = Math.pow(Math.random(), power) * (Math.random() < 0.5 ? 1 : -1) * galaxyParams.randomness * radius;
|
|
105
|
+
const randomY = Math.pow(Math.random(), power) * (Math.random() < 0.5 ? 1 : -1) * galaxyParams.randomness * radius * 0.1;
|
|
106
|
+
const randomZ = Math.pow(Math.random(), power) * (Math.random() < 0.5 ? 1 : -1) * galaxyParams.randomness * radius * 0.4;
|
|
107
|
+
|
|
108
|
+
const angle = branchAngle + spinAngle;
|
|
109
|
+
const spiralOffset = radius * galaxyParams.inwardDrop;
|
|
110
|
+
|
|
111
|
+
const x = Math.cos(angle) * radius + randomX + Math.cos(angle + Math.PI / 2) * spiralOffset;
|
|
112
|
+
const y = randomY;
|
|
113
|
+
const z = Math.sin(angle) * radius + randomZ + Math.sin(angle + Math.PI / 2) * spiralOffset;
|
|
114
|
+
|
|
115
|
+
galaxyPositions[i3] = x;
|
|
116
|
+
galaxyPositions[i3 + 1] = y;
|
|
117
|
+
galaxyPositions[i3 + 2] = z;
|
|
118
|
+
|
|
119
|
+
galaxyOriginalPositions[i3] = x;
|
|
120
|
+
galaxyOriginalPositions[i3 + 1] = y;
|
|
121
|
+
galaxyOriginalPositions[i3 + 2] = z;
|
|
122
|
+
|
|
123
|
+
const colorMix = radius / galaxyParams.radius;
|
|
124
|
+
const baseColor = palette[Math.floor(Math.random() * 3)];
|
|
125
|
+
const outerColor = palette[3 + Math.floor(Math.random() * 2)];
|
|
126
|
+
const finalColor = baseColor.clone().lerp(outerColor, colorMix);
|
|
127
|
+
|
|
128
|
+
galaxyColors[i3] = finalColor.r;
|
|
129
|
+
galaxyColors[i3 + 1] = finalColor.g;
|
|
130
|
+
galaxyColors[i3 + 2] = finalColor.b;
|
|
152
131
|
}
|
|
153
132
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
// ========== BACKGROUND STARS ==========
|
|
157
|
-
const bgStarsParams = {
|
|
158
|
-
count: 1500,
|
|
159
|
-
size: 0.012,
|
|
160
|
-
spread: 15,
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
function createBgStars() {
|
|
164
|
-
const geometry = new THREE.BufferGeometry();
|
|
165
|
-
const positions = new Float32Array(bgStarsParams.count * 3);
|
|
166
|
-
const colors = new Float32Array(bgStarsParams.count * 3);
|
|
167
|
-
const opacities = new Float32Array(bgStarsParams.count);
|
|
133
|
+
galaxyGeometry.setAttribute('position', new THREE.BufferAttribute(galaxyPositions, 3));
|
|
134
|
+
galaxyGeometry.setAttribute('color', new THREE.BufferAttribute(galaxyColors, 3));
|
|
168
135
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
136
|
+
const galaxyMaterial = new THREE.PointsMaterial({
|
|
137
|
+
size: 0.008,
|
|
138
|
+
sizeAttenuation: true,
|
|
139
|
+
depthWrite: false,
|
|
140
|
+
blending: THREE.AdditiveBlending,
|
|
141
|
+
vertexColors: true,
|
|
142
|
+
transparent: true,
|
|
143
|
+
opacity: 0.95,
|
|
144
|
+
});
|
|
174
145
|
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
146
|
+
const galaxyPoints = new THREE.Points(galaxyGeometry, galaxyMaterial);
|
|
147
|
+
galaxyPoints.rotation.x = -0.15;
|
|
148
|
+
galaxyPoints.rotation.z = 0.05;
|
|
149
|
+
scene.add(galaxyPoints);
|
|
179
150
|
|
|
180
|
-
|
|
181
|
-
|
|
151
|
+
// ===== BACKGROUND STARS =====
|
|
152
|
+
const STAR_COUNT = 2000;
|
|
153
|
+
const starGeometry = new THREE.BufferGeometry();
|
|
154
|
+
const starPositions = new Float32Array(STAR_COUNT * 3);
|
|
182
155
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
sizeAttenuation: true,
|
|
189
|
-
depthWrite: false,
|
|
190
|
-
transparent: true,
|
|
191
|
-
opacity: 0.5,
|
|
192
|
-
vertexColors: true,
|
|
193
|
-
blending: THREE.AdditiveBlending,
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
const stars = new THREE.Points(geometry, material);
|
|
197
|
-
scene.add(stars);
|
|
198
|
-
return stars;
|
|
156
|
+
for (let i = 0; i < STAR_COUNT; i++) {
|
|
157
|
+
const i3 = i * 3;
|
|
158
|
+
starPositions[i3] = (Math.random() - 0.5) * 20;
|
|
159
|
+
starPositions[i3 + 1] = (Math.random() - 0.5) * 20;
|
|
160
|
+
starPositions[i3 + 2] = (Math.random() - 0.5) * 10 - 5;
|
|
199
161
|
}
|
|
200
162
|
|
|
201
|
-
|
|
163
|
+
starGeometry.setAttribute('position', new THREE.BufferAttribute(starPositions, 3));
|
|
202
164
|
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
165
|
+
const starMaterial = new THREE.PointsMaterial({
|
|
166
|
+
size: 0.008,
|
|
167
|
+
sizeAttenuation: true,
|
|
168
|
+
depthWrite: false,
|
|
207
169
|
transparent: true,
|
|
208
|
-
opacity: 0.
|
|
170
|
+
opacity: 0.5,
|
|
171
|
+
color: new THREE.Color('#ffffff'),
|
|
172
|
+
blending: THREE.AdditiveBlending,
|
|
209
173
|
});
|
|
210
|
-
const glow = new THREE.Mesh(glowGeometry, glowMaterial);
|
|
211
|
-
glow.position.z = -0.2;
|
|
212
|
-
scene.add(glow);
|
|
213
174
|
|
|
214
|
-
|
|
215
|
-
|
|
175
|
+
const stars = new THREE.Points(starGeometry, starMaterial);
|
|
176
|
+
scene.add(stars);
|
|
177
|
+
|
|
178
|
+
// ===== FLOATING DUST =====
|
|
179
|
+
const DUST_COUNT = 800;
|
|
216
180
|
const dustGeometry = new THREE.BufferGeometry();
|
|
217
|
-
const dustPositions = new Float32Array(
|
|
218
|
-
const dustColors = new Float32Array(
|
|
181
|
+
const dustPositions = new Float32Array(DUST_COUNT * 3);
|
|
182
|
+
const dustColors = new Float32Array(DUST_COUNT * 3);
|
|
183
|
+
const dustVelocities = new Float32Array(DUST_COUNT * 3);
|
|
219
184
|
|
|
220
|
-
for (let i = 0; i <
|
|
185
|
+
for (let i = 0; i < DUST_COUNT; i++) {
|
|
221
186
|
const i3 = i * 3;
|
|
222
|
-
dustPositions[i3] = (Math.random() - 0.5) *
|
|
223
|
-
dustPositions[i3 + 1] = (Math.random() - 0.5) *
|
|
224
|
-
dustPositions[i3 + 2] = (Math.random() - 0.5) *
|
|
225
|
-
|
|
226
|
-
const
|
|
227
|
-
dustColors[i3] =
|
|
228
|
-
dustColors[i3 + 1] =
|
|
229
|
-
dustColors[i3 + 2] =
|
|
187
|
+
dustPositions[i3] = (Math.random() - 0.5) * 8;
|
|
188
|
+
dustPositions[i3 + 1] = (Math.random() - 0.5) * 4;
|
|
189
|
+
dustPositions[i3 + 2] = (Math.random() - 0.5) * 3;
|
|
190
|
+
|
|
191
|
+
const c = palette[Math.floor(Math.random() * palette.length)];
|
|
192
|
+
dustColors[i3] = c.r;
|
|
193
|
+
dustColors[i3 + 1] = c.g;
|
|
194
|
+
dustColors[i3 + 2] = c.b;
|
|
195
|
+
|
|
196
|
+
dustVelocities[i3] = (Math.random() - 0.5) * 0.3;
|
|
197
|
+
dustVelocities[i3 + 1] = (Math.random() - 0.5) * 0.2;
|
|
198
|
+
dustVelocities[i3 + 2] = (Math.random() - 0.5) * 0.15;
|
|
230
199
|
}
|
|
231
200
|
|
|
232
201
|
dustGeometry.setAttribute('position', new THREE.BufferAttribute(dustPositions, 3));
|
|
233
202
|
dustGeometry.setAttribute('color', new THREE.BufferAttribute(dustColors, 3));
|
|
234
203
|
|
|
235
204
|
const dustMaterial = new THREE.PointsMaterial({
|
|
236
|
-
size: 0.
|
|
205
|
+
size: 0.005,
|
|
237
206
|
sizeAttenuation: true,
|
|
238
207
|
depthWrite: false,
|
|
239
208
|
transparent: true,
|
|
@@ -245,59 +214,142 @@ const { className = '' } = Astro.props;
|
|
|
245
214
|
const dust = new THREE.Points(dustGeometry, dustMaterial);
|
|
246
215
|
scene.add(dust);
|
|
247
216
|
|
|
248
|
-
//
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
217
|
+
// ===== CENTRAL GLOW =====
|
|
218
|
+
const glowGeo = new THREE.SphereGeometry(0.6, 16, 16);
|
|
219
|
+
const glowMat = new THREE.MeshBasicMaterial({
|
|
220
|
+
color: new THREE.Color('#fef3c7'),
|
|
221
|
+
transparent: true,
|
|
222
|
+
opacity: 0.18,
|
|
223
|
+
});
|
|
224
|
+
const glow = new THREE.Mesh(glowGeo, glowMat);
|
|
225
|
+
scene.add(glow);
|
|
226
|
+
|
|
227
|
+
// ===== GLOW RING =====
|
|
228
|
+
const ringGeo = new THREE.RingGeometry(0.8, 1.2, 32);
|
|
229
|
+
const ringMat = new THREE.MeshBasicMaterial({
|
|
230
|
+
color: new THREE.Color('#fbbf24'),
|
|
231
|
+
transparent: true,
|
|
232
|
+
opacity: 0.1,
|
|
233
|
+
side: THREE.DoubleSide,
|
|
234
|
+
});
|
|
235
|
+
const ring = new THREE.Mesh(ringGeo, ringMat);
|
|
236
|
+
ring.position.z = -0.3;
|
|
237
|
+
scene.add(ring);
|
|
238
|
+
|
|
239
|
+
// ===== MOUSE TRACKING =====
|
|
240
|
+
const mouse = { x: 0, y: 0, worldX: 0, worldY: 0 };
|
|
241
|
+
const targetMouse = { x: 0, y: 0 };
|
|
242
|
+
const raycaster = new THREE.Raycaster();
|
|
243
|
+
const mouseVec = new THREE.Vector2();
|
|
244
|
+
const plane = new THREE.Plane(new THREE.Vector3(0, 0, 1), 0);
|
|
245
|
+
const intersection = new THREE.Vector3();
|
|
246
|
+
|
|
247
|
+
const MOUSE_RADIUS = 0.8;
|
|
248
|
+
const MOUSE_FORCE = 0.25;
|
|
252
249
|
|
|
253
250
|
container.addEventListener('mousemove', (e) => {
|
|
254
251
|
const rect = canvas.getBoundingClientRect();
|
|
255
|
-
|
|
256
|
-
|
|
252
|
+
targetMouse.x = ((e.clientX - rect.left) / rect.width) * 2 - 1;
|
|
253
|
+
targetMouse.y = -((e.clientY - rect.top) / rect.height) * 2 + 1;
|
|
257
254
|
});
|
|
258
255
|
|
|
259
256
|
container.addEventListener('mouseleave', () => {
|
|
260
|
-
|
|
261
|
-
|
|
257
|
+
targetMouse.x = 0;
|
|
258
|
+
targetMouse.y = 0;
|
|
262
259
|
});
|
|
263
260
|
|
|
264
|
-
//
|
|
261
|
+
// ===== ANIMATION =====
|
|
265
262
|
const clock = new THREE.Clock();
|
|
266
263
|
|
|
267
264
|
function animate() {
|
|
268
265
|
requestAnimationFrame(animate);
|
|
269
266
|
const elapsed = clock.getElapsedTime();
|
|
270
267
|
|
|
271
|
-
//
|
|
272
|
-
mouse.x += (
|
|
273
|
-
mouse.y += (
|
|
268
|
+
// Ultra-smooth mouse interpolation
|
|
269
|
+
mouse.x += (targetMouse.x - mouse.x) * 0.03;
|
|
270
|
+
mouse.y += (targetMouse.y - mouse.y) * 0.03;
|
|
274
271
|
|
|
275
|
-
//
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
272
|
+
// Convert screen mouse to world coordinates
|
|
273
|
+
mouseVec.set(mouse.x, mouse.y);
|
|
274
|
+
raycaster.setFromCamera(mouseVec, camera);
|
|
275
|
+
raycaster.ray.intersectPlane(plane, intersection);
|
|
276
|
+
mouse.worldX = intersection.x;
|
|
277
|
+
mouse.worldY = intersection.y;
|
|
279
278
|
|
|
280
|
-
// Rotate
|
|
281
|
-
|
|
282
|
-
bgStars.rotation.x = elapsed * 0.005;
|
|
279
|
+
// Rotate galaxy gently
|
|
280
|
+
galaxyPoints.rotation.y = elapsed * 0.025;
|
|
283
281
|
|
|
284
|
-
// Animate
|
|
285
|
-
const
|
|
286
|
-
for (let i = 0; i <
|
|
282
|
+
// Animate galaxy particles with gentle mouse interaction
|
|
283
|
+
const pos = galaxyGeometry.attributes.position.array;
|
|
284
|
+
for (let i = 0; i < GALAXY_COUNT; i++) {
|
|
287
285
|
const i3 = i * 3;
|
|
288
|
-
|
|
289
|
-
|
|
286
|
+
|
|
287
|
+
const ox = galaxyOriginalPositions[i3];
|
|
288
|
+
const oy = galaxyOriginalPositions[i3 + 1];
|
|
289
|
+
const oz = galaxyOriginalPositions[i3 + 2];
|
|
290
|
+
|
|
291
|
+
// Apply rotation
|
|
292
|
+
const ry = galaxyPoints.rotation.y;
|
|
293
|
+
const cosR = Math.cos(ry);
|
|
294
|
+
const sinR = Math.sin(ry);
|
|
295
|
+
const baseX = ox * cosR - oz * sinR;
|
|
296
|
+
const baseZ = ox * sinR + oz * cosR;
|
|
297
|
+
const baseY = oy;
|
|
298
|
+
|
|
299
|
+
// Subtle mouse deflection
|
|
300
|
+
const dx = baseX - mouse.worldX;
|
|
301
|
+
const dy = baseY - mouse.worldY;
|
|
302
|
+
const dist = Math.sqrt(dx * dx + dy * dy);
|
|
303
|
+
|
|
304
|
+
let pushX = 0, pushY = 0, pushZ = 0;
|
|
305
|
+
|
|
306
|
+
if (dist < MOUSE_RADIUS && dist > 0.01) {
|
|
307
|
+
const force = (1 - dist / MOUSE_RADIUS) * MOUSE_FORCE;
|
|
308
|
+
const nx = dx / dist;
|
|
309
|
+
const ny = dy / dist;
|
|
310
|
+
pushX = nx * force;
|
|
311
|
+
pushY = ny * force;
|
|
312
|
+
pushZ = (nx * ny) * force * 0.15;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
const targetX = baseX + pushX;
|
|
316
|
+
const targetY = baseY + pushY;
|
|
317
|
+
const targetZ = baseZ + pushZ;
|
|
318
|
+
|
|
319
|
+
const spring = 0.03;
|
|
320
|
+
pos[i3] += (targetX - pos[i3]) * spring;
|
|
321
|
+
pos[i3 + 1] += (targetY - pos[i3 + 1]) * spring;
|
|
322
|
+
pos[i3 + 2] += (targetZ - pos[i3 + 2]) * spring;
|
|
290
323
|
}
|
|
291
|
-
|
|
324
|
+
galaxyGeometry.attributes.position.needsUpdate = true;
|
|
325
|
+
|
|
326
|
+
// Animate dust
|
|
327
|
+
const dustPos = dustGeometry.attributes.position.array;
|
|
328
|
+
for (let i = 0; i < DUST_COUNT; i++) {
|
|
329
|
+
const i3 = i * 3;
|
|
330
|
+
dustPos[i3] += dustVelocities[i3] * 0.002 + Math.sin(elapsed * 0.3 + i) * 0.0001;
|
|
331
|
+
dustPos[i3 + 1] += dustVelocities[i3 + 1] * 0.002 + Math.cos(elapsed * 0.3 + i) * 0.0001;
|
|
332
|
+
dustPos[i3 + 2] += dustVelocities[i3 + 2] * 0.002;
|
|
333
|
+
|
|
334
|
+
if (dustPos[i3] > 4) dustPos[i3] = -4;
|
|
335
|
+
if (dustPos[i3] < -4) dustPos[i3] = 4;
|
|
336
|
+
if (dustPos[i3 + 1] > 2) dustPos[i3 + 1] = -2;
|
|
337
|
+
if (dustPos[i3 + 1] < -2) dustPos[i3 + 1] = 2;
|
|
338
|
+
}
|
|
339
|
+
dustGeometry.attributes.position.needsUpdate = true;
|
|
292
340
|
|
|
293
341
|
// Central glow pulse
|
|
294
|
-
const pulseScale = 1 + Math.sin(elapsed * 2) * 0.
|
|
342
|
+
const pulseScale = 1 + Math.sin(elapsed * 1.2) * 0.04;
|
|
295
343
|
glow.scale.set(pulseScale, pulseScale, pulseScale);
|
|
296
|
-
|
|
344
|
+
glowMat.opacity = 0.12 + Math.sin(elapsed * 1.2) * 0.02;
|
|
345
|
+
|
|
346
|
+
// Ring rotation
|
|
347
|
+
ring.rotation.z = elapsed * 0.08;
|
|
348
|
+
ringMat.opacity = 0.06 + Math.sin(elapsed * 1.5) * 0.015;
|
|
297
349
|
|
|
298
|
-
//
|
|
299
|
-
camera.position.x
|
|
300
|
-
camera.position.y
|
|
350
|
+
// Gentle camera mouse parallax
|
|
351
|
+
camera.position.x += (mouse.x * 0.15 - camera.position.x) * 0.015;
|
|
352
|
+
camera.position.y += (mouse.y * 0.1 - camera.position.y) * 0.015;
|
|
301
353
|
camera.lookAt(0, 0, 0);
|
|
302
354
|
|
|
303
355
|
renderer.render(scene, camera);
|
|
@@ -305,4 +357,4 @@ const { className = '' } = Astro.props;
|
|
|
305
357
|
|
|
306
358
|
animate();
|
|
307
359
|
})();
|
|
308
|
-
</script>
|
|
360
|
+
</script>
|
|
@@ -17,10 +17,10 @@ const sizes = {
|
|
|
17
17
|
const s = sizes[size];
|
|
18
18
|
---
|
|
19
19
|
|
|
20
|
-
<div class=
|
|
20
|
+
<div class={`logo-container ${className}`.trim()}>
|
|
21
21
|
<!-- Galaxy behind, bottom-left -->
|
|
22
22
|
<div class="galaxy-wrap">
|
|
23
|
-
<AnimatedGalaxy
|
|
23
|
+
<AnimatedGalaxy className="galaxy-svg" style={`width: ${s.galaxyWidth}; height: ${s.galaxyHeight};`} />
|
|
24
24
|
</div>
|
|
25
25
|
<!-- Logo text on top -->
|
|
26
26
|
<div class="logo-text">
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/components/lib/buttons/index.ts
|
|
2
|
+
// Barrel export for button components
|
|
3
|
+
|
|
1
4
|
export { default as AnimatedIconButton } from './AnimatedIconButton.astro';
|
|
2
5
|
export { default as BorderDrawButton } from './BorderDrawButton.astro';
|
|
3
6
|
export { default as CyberpunkButton } from './CyberpunkButton.astro';
|
|
@@ -16,4 +19,4 @@ export { default as RetroShadowButton } from './RetroShadowButton.astro';
|
|
|
16
19
|
export { default as ShimmerButton } from './ShimmerButton.astro';
|
|
17
20
|
export { default as ShinyButton } from './ShinyButton.astro';
|
|
18
21
|
export { default as TiltGlowButton } from './TiltGlowButton.astro';
|
|
19
|
-
export { default as ThreeDPushButton } from './
|
|
22
|
+
export { default as ThreeDPushButton } from './ThreeDPushButton.astro';
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/components/lib/cards/index.ts
|
|
2
|
+
// Barrel export for card components
|
|
3
|
+
|
|
1
4
|
export { default as BlogHorizontalCard } from './BlogHorizontalCard.astro';
|
|
2
5
|
export { default as CyberFeatureCard } from './CyberFeatureCard.astro';
|
|
3
6
|
export { default as EcommerceProductCard } from './EcommerceProductCard.astro';
|
|
@@ -143,7 +143,7 @@ const chartConfig = {
|
|
|
143
143
|
show: true,
|
|
144
144
|
label: config.centerLabel,
|
|
145
145
|
color: '#94a3b8',
|
|
146
|
-
formatter: (w) => w.globals.seriesGlobals.reduce((a, b) => a + b, 0),
|
|
146
|
+
formatter: (w: any) => w.globals.seriesGlobals.reduce((a: any, b: any) => a + b, 0),
|
|
147
147
|
},
|
|
148
148
|
},
|
|
149
149
|
},
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/components/lib/data/index.ts
|
|
2
|
+
// Barrel export for data display components
|
|
3
|
+
|
|
1
4
|
export { default as AccordionGroupGlass } from './AccordionGroupGlass.astro';
|
|
2
5
|
export { default as AvatarGroupStack } from './AvatarGroupStack.astro';
|
|
3
6
|
export { default as CalendarGridView } from './CalendarGridView.astro';
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/components/lib/feedback/index.ts
|
|
2
|
+
// Barrel export for feedback components
|
|
3
|
+
|
|
1
4
|
export { default as AnimatedCheckmark } from './AnimatedCheckmark.astro';
|
|
2
5
|
export { default as Badge } from './Badge.astro';
|
|
3
6
|
export { default as CircleProgress } from './CircleProgress.astro';
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/components/lib/forms/index.ts
|
|
2
|
+
// Barrel export for form components
|
|
3
|
+
|
|
1
4
|
export { default as AnimatedInput } from './AnimatedInput.astro';
|
|
2
5
|
export { default as ChipInput } from './ChipInput.astro';
|
|
3
6
|
export { default as ColorPickerInput } from './ColorPickerInput.astro';
|
|
@@ -1,6 +1,17 @@
|
|
|
1
|
-
export
|
|
2
|
-
export
|
|
3
|
-
export
|
|
4
|
-
export
|
|
5
|
-
export
|
|
6
|
-
export
|
|
1
|
+
// Re-export all category components
|
|
2
|
+
export * from './buttons/index';
|
|
3
|
+
export * from './cards/index';
|
|
4
|
+
export * from './charts/index';
|
|
5
|
+
export * from './data/index';
|
|
6
|
+
export * from './feedback/index';
|
|
7
|
+
export * from './forms/index';
|
|
8
|
+
export * from './layout/index';
|
|
9
|
+
export * from './navigation/index';
|
|
10
|
+
export * from './overlays/index';
|
|
11
|
+
export * from './sections/index';
|
|
12
|
+
export * from './typography/index';
|
|
13
|
+
|
|
14
|
+
// Unique root-level components (no category folder)
|
|
15
|
+
export { default as AnimatedGalaxy } from './AnimatedGalaxy.astro';
|
|
16
|
+
export { default as Galaxy3D } from './Galaxy3D.astro';
|
|
17
|
+
export { default as LogoWithGalaxy } from './LogoWithGalaxy.astro';
|