diff --git a/src/pages/index.astro b/src/pages/index.astro
index a25b02d..dcce124 100644
--- a/src/pages/index.astro
+++ b/src/pages/index.astro
@@ -221,9 +221,10 @@ const process = [
+
-
+
@@ -232,40 +233,34 @@ const process = [
-
+
-
Marketing
-
เพิ่มรายได้
+
Marketing
+
เพิ่มรายได้
-
+
-
AI
-
ลดต้นทุนและเวลา
+
AI
+
ลดต้นทุนและเวลา
-
+
-
Business Knowledge
-
ลดความเสี่ยง
+
Business Knowledge
+
ลดความเสี่ยง
-
-
-
+
diff --git a/src/scripts/home.js b/src/scripts/home.js
index 27e1a37..eed3186 100644
--- a/src/scripts/home.js
+++ b/src/scripts/home.js
@@ -180,53 +180,138 @@ form?.addEventListener('submit', async (event) => {
}
});
-// Neural Network Hero - Mouse Parallax
-const neuralScene = document.querySelector('.neural-scene');
+// Neural Network Hero - True 3D with Dynamic Lines
const heroNeural = document.querySelector('.hero-neural');
+const neuralScene = document.querySelector('.neural-scene');
+const canvas = document.querySelector('.neural-canvas');
+const ctx = canvas?.getContext('2d');
+const nodes = document.querySelectorAll('.neural-node');
-if (neuralScene && heroNeural) {
+if (heroNeural && neuralScene && canvas && ctx && nodes.length > 0) {
+ // 3D rotation state
let targetRotateX = 0;
let targetRotateY = 0;
let currentRotateX = 0;
let currentRotateY = 0;
+ // Canvas setup
+ function resizeCanvas() {
+ const rect = heroNeural.getBoundingClientRect();
+ canvas.width = rect.width * window.devicePixelRatio;
+ canvas.height = rect.height * window.devicePixelRatio;
+ canvas.style.width = rect.width + 'px';
+ canvas.style.height = rect.height + 'px';
+ ctx.scale(window.devicePixelRatio, window.devicePixelRatio);
+ }
+
+ resizeCanvas();
+ window.addEventListener('resize', resizeCanvas);
+
+ // Find intersection point on node border
+ function findBorderPoint(nodeRect, targetX, targetY) {
+ const cx = nodeRect.left + nodeRect.width / 2;
+ const cy = nodeRect.top + nodeRect.height / 2;
+ const hw = nodeRect.width / 2;
+ const hh = nodeRect.height / 2;
+
+ const dx = targetX - cx;
+ const dy = targetY - cy;
+
+ if (dx === 0 && dy === 0) return { x: cx, y: cy };
+
+ const absDx = Math.abs(dx);
+ const absDy = Math.abs(dy);
+
+ let scale;
+ if (absDx * hh > absDy * hw) {
+ scale = hw / absDx;
+ } else {
+ scale = hh / absDy;
+ }
+
+ return {
+ x: cx + dx * scale,
+ y: cy + dy * scale
+ };
+ }
+
+ // Draw connections
+ function drawConnections() {
+ const rect = heroNeural.getBoundingClientRect();
+ ctx.clearRect(0, 0, rect.width, rect.height);
+
+ const centerNode = document.querySelector('[data-node="center"]');
+ const outerNodes = document.querySelectorAll('.neural-card');
+
+ if (!centerNode) return;
+
+ const centerRect = centerNode.getBoundingClientRect();
+ const centerX = centerRect.left + centerRect.width / 2 - rect.left;
+ const centerY = centerRect.top + centerRect.height / 2 - rect.top;
+
+ outerNodes.forEach(node => {
+ const nodeRect = node.getBoundingClientRect();
+ const nodeX = nodeRect.left + nodeRect.width / 2 - rect.left;
+ const nodeY = nodeRect.top + nodeRect.height / 2 - rect.top;
+
+ const startPt = findBorderPoint(
+ { left: centerRect.left - rect.left, top: centerRect.top - rect.top,
+ width: centerRect.width, height: centerRect.height },
+ nodeX, nodeY
+ );
+
+ const endPt = findBorderPoint(
+ { left: nodeRect.left - rect.left, top: nodeRect.top - rect.top,
+ width: nodeRect.width, height: nodeRect.height },
+ centerX, centerY
+ );
+
+ ctx.beginPath();
+ ctx.moveTo(startPt.x, startPt.y);
+ ctx.lineTo(endPt.x, endPt.y);
+ ctx.strokeStyle = 'rgba(254, 212, 0, 0.5)';
+ ctx.lineWidth = 3;
+ ctx.lineCap = 'round';
+ ctx.stroke();
+ });
+ }
+
// Mouse move handler
heroNeural.addEventListener('mousemove', (e) => {
const rect = heroNeural.getBoundingClientRect();
const x = (e.clientX - rect.left) / rect.width;
const y = (e.clientY - rect.top) / rect.height;
- // Convert to rotation angles (±15 degrees)
- targetRotateY = (x - 0.5) * 30; // -15 to +15
- targetRotateX = (y - 0.5) * -30; // -15 to +15 (inverted)
+ targetRotateY = (x - 0.5) * 30;
+ targetRotateX = (y - 0.5) * -30;
});
- // Reset on mouse leave
heroNeural.addEventListener('mouseleave', () => {
targetRotateX = 0;
targetRotateY = 0;
});
- // Smooth animation loop
+ // Animation loop
function animate() {
- // Ease towards target
currentRotateX += (targetRotateX - currentRotateX) * 0.08;
currentRotateY += (targetRotateY - currentRotateY) * 0.08;
neuralScene.style.transform =
`rotateX(${currentRotateX}deg) rotateY(${currentRotateY}deg)`;
+ drawConnections();
+
requestAnimationFrame(animate);
}
animate();
- // Mobile: Device orientation (if available)
+ // Mobile: Device orientation
if (window.DeviceOrientationEvent && 'ontouchstart' in window) {
window.addEventListener('deviceorientation', (e) => {
if (e.gamma !== null && e.beta !== null) {
- targetRotateY = e.gamma * 0.3; // -30 to +30 scaled down
- targetRotateX = (e.beta - 45) * 0.3; // Assume holding at 45deg
+ targetRotateY = e.gamma * 0.3;
+ targetRotateX = (e.beta - 45) * 0.3;
}
});
}
diff --git a/src/styles/global.css b/src/styles/global.css
index 4c5e938..e4abb98 100644
--- a/src/styles/global.css
+++ b/src/styles/global.css
@@ -448,44 +448,50 @@ background: rgb(255 255 255 / .10);
color: rgb(255 255 255 / .72);
}
-/* Neural Network Hero - 3D Layout */
+/* Neural Network Hero - True 3D Layout */
.hero-neural {
position: relative;
width: 100%;
- max-width: 480px;
- height: 400px;
+ max-width: 560px;
+ height: 480px;
margin-inline: auto;
perspective: 1200px;
}
+.neural-canvas {
+ position: absolute;
+ inset: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ z-index: 5;
+}
+
.neural-scene {
position: relative;
width: 100%;
height: 100%;
transform-style: preserve-3d;
- transition: transform 0.1s ease-out;
+ transition: transform 0.15s ease-out;
will-change: transform;
}
-/* Neural nodes */
+/* Neural nodes - base */
.neural-node {
position: absolute;
- border-radius: 20px;
- padding: 20px 24px;
+ border-radius: 24px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
- min-width: 120px;
transition: transform 0.3s ease, box-shadow 0.3s ease;
cursor: default;
backface-visibility: hidden;
}
.neural-node:hover {
- transform: scale(1.05) translateZ(20px);
- box-shadow: 0 20px 50px rgb(0 0 0 / .15);
+ box-shadow: 0 24px 60px rgb(0 0 0 / .18);
}
/* Center node: กำไร */
@@ -493,13 +499,15 @@ color: rgb(255 255 255 / .72);
left: 50%;
top: 50%;
transform: translate(-50%, -50%) translateZ(0px);
- min-width: 160px;
- padding: 28px 32px;
- border: 2px solid var(--yellow);
+ width: 180px;
+ height: 180px;
+ border-radius: 50%;
+ padding: 32px;
+ border: 3px solid var(--yellow);
box-shadow:
- 0 0 0 8px rgb(254 212 0 / .10),
- 0 30px 80px rgb(254 212 0 / .18),
- 0 10px 30px rgb(0 0 0 / .10);
+ 0 0 0 10px rgb(254 212 0 / .12),
+ 0 30px 80px rgb(254 212 0 / .20),
+ 0 10px 30px rgb(0 0 0 / .12);
z-index: 10;
}
@@ -508,7 +516,7 @@ color: rgb(255 255 255 / .72);
}
.node-label {
- font-size: clamp(2.4rem, 5vw, 3.2rem);
+ font-size: clamp(2.6rem, 5vw, 3.4rem);
font-weight: 900;
color: var(--ink);
line-height: 1;
@@ -516,66 +524,132 @@ color: rgb(255 255 255 / .72);
}
.node-sub {
- margin-top: 8px;
- font-size: 13px;
+ margin-top: 10px;
+ font-size: 14px;
font-weight: 600;
color: var(--muted);
line-height: 1.4;
}
-/* Outer nodes */
+/* Outer cards - larger and positioned in 3D */
+.neural-card {
+ width: 200px;
+ padding: 28px 24px;
+ min-height: 120px;
+}
+
+/* True 3D positions: translate3d(x, y, z) */
.node-marketing {
- left: 12%;
- top: 15%;
- transform: translateZ(-150px);
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%) translate3d(-280px, -160px, -180px);
}
.node-ai {
- left: 68%;
- top: 30%;
- transform: translateZ(-100px);
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%) translate3d(240px, 80px, -120px);
}
.node-biz {
- left: 25%;
- top: 65%;
- transform: translateZ(-200px);
+ left: 50%;
+ top: 50%;
+ transform: translate(-50%, -50%) translate3d(-160px, 200px, -250px);
}
-.node-tag {
- font-size: 15px;
+.card-tag {
+ font-size: 16px;
font-weight: 900;
color: var(--ink);
letter-spacing: .02em;
text-transform: uppercase;
}
-.node-desc {
- margin-top: 6px;
- font-size: 13px;
+.card-desc {
+ margin-top: 8px;
+ font-size: 14px;
font-weight: 500;
color: var(--muted);
line-height: 1.4;
}
-/* Neural connections */
-.neural-connections {
- position: absolute;
- inset: 0;
- width: 100%;
- height: 100%;
- pointer-events: none;
- z-index: 5;
- transform-style: preserve-3d;
+/* Floating animations */
+.node-marketing {
+ animation: float-1 6s ease-in-out infinite;
}
-.neural-line {
- animation: pulse-line 3s ease-in-out infinite;
+.node-ai {
+ animation: float-2 7s ease-in-out infinite;
}
-@keyframes pulse-line {
- 0%, 100% { opacity: .3; }
- 50% { opacity: .6; }
+.node-biz {
+ animation: float-3 8s ease-in-out infinite;
+}
+
+@keyframes float-1 {
+ 0%, 100% { transform: translate(-50%, -50%) translate3d(-280px, -160px, -180px); }
+ 50% { transform: translate(-50%, -50%) translate3d(-280px, -175px, -180px); }
+}
+
+@keyframes float-2 {
+ 0%, 100% { transform: translate(-50%, -50%) translate3d(240px, 80px, -120px); }
+ 50% { transform: translate(-50%, -50%) translate3d(240px, 65px, -120px); }
+}
+
+@keyframes float-3 {
+ 0%, 100% { transform: translate(-50%, -50%) translate3d(-160px, 200px, -250px); }
+ 50% { transform: translate(-50%, -50%) translate3d(-160px, 185px, -250px); }
+}
+
+/* Mobile responsive */
+@media (max-width: 620px) {
+ .hero-neural {
+ height: auto;
+ max-width: 340px;
+ perspective: none;
+ }
+
+ .neural-canvas {
+ display: none;
+ }
+
+ .neural-scene {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ gap: 24px;
+ transform: none !important;
+ padding: 20px 0;
+ }
+
+ .neural-node {
+ position: relative;
+ left: auto !important;
+ top: auto !important;
+ transform: none !important;
+ }
+
+ .node-center {
+ width: 160px;
+ height: 160px;
+ }
+
+ .neural-card {
+ width: 100%;
+ max-width: 280px;
+ min-height: auto;
+ }
+
+ .neural-node:hover {
+ transform: translateY(-4px);
+ }
+
+ @keyframes float-1,
+ @keyframes float-2,
+ @keyframes float-3 {
+ 0%, 100% { transform: translateY(0); }
+ 50% { transform: translateY(-8px); }
+ }
}
/* Floating animation for nodes */