File manager - Edit - /home/webapp69.cm.in.th/u69319090001/Portfolio/intro.html
Back
<!DOCTYPE html> <html lang="th"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Welcome — กรกฎ ใจมูล</title> <link rel="preconnect" href="https://fonts.googleapis.com"> <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> <link href="https://fonts.googleapis.com/css2?family=Outfit:wght@100;200;300;400;600;700;900&family=Inter:wght@300;400;500&display=swap" rel="stylesheet"> <style> *, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; } :root { --cyan: #22d3ee; --purple: #a855f7; --pink: #ec4899; } html, body { width: 100%; height: 100%; overflow: hidden; background: #000; font-family: 'Outfit', sans-serif; cursor: none; } /* ─── Custom cursor ─── */ #cursor { position: fixed; width: 12px; height: 12px; border-radius: 50%; background: var(--cyan); pointer-events: none; z-index: 9999; transform: translate(-50%, -50%); box-shadow: 0 0 16px var(--cyan), 0 0 40px rgba(34,211,238,.4); mix-blend-mode: screen; transition: width .2s, height .2s, background .2s; } #cursor-ring { position: fixed; width: 40px; height: 40px; border-radius: 50%; border: 1.5px solid rgba(168,85,247,.6); pointer-events: none; z-index: 9998; transform: translate(-50%, -50%); transition: width .3s, height .3s, border-color .3s; } /* ─── Background ─── */ #scene-wrap { position: fixed; inset: 0; overflow: hidden; } #scene-bg { position: absolute; inset: -8%; background: url('3d/3465281285/preview.gif') center/cover no-repeat; will-change: transform; filter: brightness(.6) saturate(1.4); } #scene-overlay { position: absolute; inset: 0; background: radial-gradient(ellipse 75% 55% at 50% 50%, transparent 25%, rgba(2,6,23,.8) 100%), linear-gradient(to bottom, rgba(2,6,23,.6) 0%, transparent 20%, transparent 80%, rgba(2,6,23,.75) 100%); } /* ─── Cinematic bars ─── */ #bar-top, #bar-bottom { position: fixed; left: 0; width: 100%; background: #000; z-index: 100; transition: height 1s cubic-bezier(.77,0,.175,1); } #bar-top { top: 0; height: 20vh; } #bar-bottom { bottom: 0; height: 20vh; } .bars-open #bar-top { height: 0; } .bars-open #bar-bottom { height: 0; } /* ─── Particle canvas ─── */ #particles { position: fixed; inset: 0; z-index: 1; pointer-events: none; } /* ─── FX ─── */ .vignette { position: fixed; inset: 0; z-index: 2; pointer-events: none; box-shadow: inset 0 0 240px rgba(0,0,0,.75); } .scanlines { position: fixed; inset: 0; z-index: 3; pointer-events: none; background: repeating-linear-gradient(0deg, transparent, transparent 2px, rgba(0,0,0,.04) 2px, rgba(0,0,0,.04) 4px); } /* ─── HUD ─── */ #hud { position: fixed; inset: 0; display: flex; flex-direction: column; align-items: center; justify-content: center; z-index: 200; pointer-events: none; } .sub-label { letter-spacing: .35em; font-size: .72rem; font-weight: 300; color: var(--cyan); text-transform: uppercase; opacity: 0; animation: fadeUp .8s .6s forwards; } .intro-name { font-size: clamp(3rem, 9vw, 7.5rem); font-weight: 900; line-height: 1; text-align: center; background: linear-gradient(135deg, #fff 0%, var(--cyan) 45%, var(--purple) 100%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; opacity: 0; animation: fadeUpScale .9s 1s cubic-bezier(.22,1,.36,1) forwards; filter: drop-shadow(0 0 50px rgba(168,85,247,.4)); margin-top: .5rem; } .intro-divider { width: 0; height: 1px; background: linear-gradient(90deg, transparent, var(--cyan), var(--purple), transparent); margin: 1.5rem auto; animation: expandLine .8s 1.6s cubic-bezier(.22,1,.36,1) forwards; } .typewriter-wrap { height: 1.8rem; display: flex; align-items: center; justify-content: center; opacity: 0; animation: fadeIn .6s 1.9s forwards; } #typewriter { font-size: 1rem; font-weight: 300; color: rgba(255,255,255,.78); letter-spacing: .1em; border-right: 2px solid var(--cyan); padding-right: 3px; white-space: nowrap; overflow: hidden; } #enter-btn { pointer-events: all; margin-top: 2.4rem; padding: .78rem 3rem; border: 1px solid rgba(34,211,238,.45); border-radius: 100px; background: rgba(34,211,238,.06); color: var(--cyan); font-family: 'Outfit', sans-serif; font-size: .88rem; font-weight: 600; letter-spacing: .22em; text-transform: uppercase; cursor: none; opacity: 0; animation: fadeUp .8s 2.6s forwards; transition: background .3s, box-shadow .3s, transform .2s; position: relative; overflow: hidden; } #enter-btn::before { content: ''; position: absolute; inset: 0; background: linear-gradient(135deg, rgba(34,211,238,.2), rgba(168,85,247,.15)); opacity: 0; transition: opacity .3s; } #enter-btn:hover::before { opacity: 1; } #enter-btn:hover { box-shadow: 0 0 32px rgba(34,211,238,.4), 0 0 70px rgba(168,85,247,.22); transform: translateY(-2px) scale(1.04); } #enter-btn::after { content: ''; position: absolute; inset: -5px; border-radius: 100px; border: 1px solid rgba(34,211,238,.5); opacity: 0; animation: pulseRing 2s 3.2s ease-out infinite; } .key-hint { margin-top: 1rem; font-size: .7rem; color: rgba(255,255,255,.28); letter-spacing: .12em; opacity: 0; animation: fadeIn .6s 3s forwards; } .key-hint kbd { border: 1px solid rgba(255,255,255,.3); padding: 1px 7px; border-radius: 4px; font-family: inherit; } /* ─── Music pill ─── */ #music-pill { position: fixed; bottom: 24px; left: 50%; transform: translateX(-50%) translateY(90px); opacity: 0; display: flex; align-items: center; gap: 14px; padding: 10px 20px; border-radius: 100px; background: rgba(10,16,35,.72); border: 1px solid rgba(255,255,255,.1); backdrop-filter: blur(24px); z-index: 300; animation: slideUp .8s .9s cubic-bezier(.22,1,.36,1) forwards; pointer-events: all; cursor: none; } #music-disc { width: 36px; height: 36px; border-radius: 50%; background: conic-gradient(var(--cyan) 0%, var(--purple) 60%, var(--pink) 100%); display: flex; align-items: center; justify-content: center; flex-shrink: 0; animation: spin 4s linear infinite; animation-play-state: paused; } #music-disc.playing { animation-play-state: running; } #music-disc-inner { width: 13px; height: 13px; border-radius: 50%; background: #090f1e; } #music-info { flex: 1; min-width: 120px; } #music-title { font-size: .78rem; font-weight: 600; color: #fff; } #music-artist { font-size: .68rem; color: rgba(255,255,255,.4); } #music-toggle { background: none; border: none; color: var(--cyan); cursor: none; display: flex; align-items: center; padding: 4px; transition: transform .2s, color .2s; } #music-toggle:hover { transform: scale(1.25); color: var(--purple); } #wave-bars { display: flex; align-items: center; gap: 2px; height: 20px; } .wave-bar { width: 3px; border-radius: 2px; background: var(--cyan); height: 8px; animation: waveDance .9s ease-in-out infinite alternate; } .wave-bar:nth-child(1){ animation-delay: 0s; animation-duration: .7s; } .wave-bar:nth-child(2){ animation-delay: .12s; animation-duration: .9s; } .wave-bar:nth-child(3){ animation-delay: .24s; animation-duration: .8s; } .wave-bar:nth-child(4){ animation-delay: .36s; animation-duration: .7s; } .wave-bar:nth-child(5){ animation-delay: .2s; animation-duration: .95s; } .wave-bar:nth-child(6){ animation-delay: .08s; animation-duration: .85s; } #wave-bars.paused .wave-bar { animation-play-state: paused; height: 4px !important; } /* ─── Exit flash ─── */ #exit-flash { position: fixed; inset: 0; background: #000; opacity: 0; z-index: 999; pointer-events: none; transition: opacity .65s ease; } #exit-flash.flash-in { opacity: 1; } /* ─── Keyframes ─── */ @keyframes fadeUp { from { opacity: 0; transform: translateY(28px); } to { opacity: 1; transform: translateY(0); } } @keyframes fadeUpScale { from { opacity: 0; transform: translateY(32px) scale(.95); } to { opacity: 1; transform: translateY(0) scale(1); } } @keyframes fadeIn { from { opacity: 0; } to { opacity: 1; } } @keyframes expandLine { from { width: 0; } to { width: min(300px, 70vw); } } @keyframes spin { to { transform: rotate(360deg); } } @keyframes waveDance { from { height: 4px; } to { height: 18px; } } @keyframes pulseRing { 0% { opacity: .8; transform: scale(1); } 100%{ opacity: 0; transform: scale(1.3); } } @keyframes slideUp { from { transform: translateX(-50%) translateY(90px); opacity: 0; } to { transform: translateX(-50%) translateY(0); opacity: 1; } } @keyframes glitch { 0% { clip-path: inset(5% 0 80% 0); transform: translate(-4px,0) skewX(-2deg); } 20% { clip-path: inset(60% 0 15% 0); transform: translate(4px,0) skewX(2deg); } 40% { clip-path: inset(30% 0 50% 0); transform: translate(-2px,0); } 60% { clip-path: inset(80% 0 5% 0); transform: translate(3px,0) skewX(-1deg); } 80% { clip-path: inset(40% 0 30% 0); transform: translate(-1px,0); } 100%{ clip-path: none; transform: none; } } </style> </head> <body> <div id="cursor"></div> <div id="cursor-ring"></div> <div id="exit-flash"></div> <!-- Cinematic bars --> <div id="bar-top"></div> <div id="bar-bottom"></div> <!-- Background --> <div id="scene-wrap"> <div id="scene-bg"></div> <div id="scene-overlay"></div> </div> <!-- FX overlays --> <div class="vignette"></div> <div class="scanlines"></div> <canvas id="particles"></canvas> <!-- Main content --> <div id="hud"> <p class="sub-label">✦ P O R T F O L I O ✦</p> <h1 class="intro-name" id="intro-name">กรกฎ ใจมูล</h1> <div class="intro-divider"></div> <div class="typewriter-wrap"> <span id="typewriter"></span> </div> <button id="enter-btn" onclick="enterSite()">E N T E R</button> <p class="key-hint">กด <kbd>Enter</kbd> หรือคลิกเพื่อเข้าสู่เนื้อหา</p> </div> <!-- Music pill --> <div id="music-pill"> <div id="music-disc" class="playing"> <div id="music-disc-inner"></div> </div> <div id="music-info"> <div id="music-title">Circle With Me</div> <div id="music-artist">Spiritbox</div> </div> <div id="wave-bars"> <div class="wave-bar"></div> <div class="wave-bar"></div> <div class="wave-bar"></div> <div class="wave-bar"></div> <div class="wave-bar"></div> <div class="wave-bar"></div> </div> <button id="music-toggle" title="Play / Pause"> <svg id="icon-pause" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor"> <rect x="6" y="4" width="4" height="16"/><rect x="14" y="4" width="4" height="16"/> </svg> <svg id="icon-play" xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 24 24" fill="currentColor" style="display:none"> <polygon points="5,3 19,12 5,21"/> </svg> </button> </div> <!-- Audio (put bgm.mp3 in the same folder as intro.html) --> <audio id="bg-audio" loop preload="auto"> <source src="bgm.mp3" type="audio/mpeg"> </audio> <script> /* ─── Cursor ─────────────────────────────────────────── */ const cur = document.getElementById('cursor'); const ring = document.getElementById('cursor-ring'); let mx = innerWidth/2, my = innerHeight/2; let rx = mx, ry = my; document.addEventListener('mousemove', e => { mx = e.clientX; my = e.clientY; cur.style.left = mx + 'px'; cur.style.top = my + 'px'; }); (function animRing(){ rx += (mx - rx) * .12; ry += (my - ry) * .12; ring.style.left = rx + 'px'; ring.style.top = ry + 'px'; requestAnimationFrame(animRing); })(); document.querySelectorAll('button').forEach(el => { el.addEventListener('mouseenter', () => { cur.style.width = '20px'; cur.style.height = '20px'; cur.style.background = 'var(--purple)'; ring.style.width = '56px'; ring.style.height = '56px'; ring.style.borderColor = 'rgba(168,85,247,.7)'; }); el.addEventListener('mouseleave', () => { cur.style.width = '12px'; cur.style.height = '12px'; cur.style.background = 'var(--cyan)'; ring.style.width = '40px'; ring.style.height = '40px'; ring.style.borderColor = 'rgba(168,85,247,.6)'; }); }); /* ─── Parallax ───────────────────────────────────────── */ const sceneBg = document.getElementById('scene-bg'); let tX = 0, tY = 0, cX = 0, cY = 0; document.addEventListener('mousemove', e => { tX = ((e.clientX - innerWidth/2) / (innerWidth/2)) * 25; tY = ((e.clientY - innerHeight/2) / (innerHeight/2)) * 14; }); (function parallax(){ cX += (tX - cX) * .045; cY += (tY - cY) * .045; sceneBg.style.transform = `translate(${cX}px,${cY}px) scale(1.1)`; requestAnimationFrame(parallax); })(); /* ─── Particles ──────────────────────────────────────── */ const canvas = document.getElementById('particles'); const ctx = canvas.getContext('2d'); let pts = []; function resize(){ canvas.width = innerWidth; canvas.height = innerHeight; } resize(); window.addEventListener('resize', resize); function mkPt(){ return { x: Math.random() * canvas.width, y: canvas.height + 10, r: Math.random() * 1.4 + .4, spd: Math.random() * .7 + .25, col: Math.random() > .5 ? '34,211,238' : '168,85,247', op: Math.random() * .5 + .3, life: 0, max: Math.random() * 180 + 100 }; } for(let i=0; i<65; i++){ const p = mkPt(); p.y = Math.random() * canvas.height; p.life = Math.random() * p.max; pts.push(p); } (function drawPts(){ ctx.clearRect(0,0,canvas.width,canvas.height); pts.forEach((p,i) => { p.life++; const ratio = p.life/p.max; const fade = ratio < .1 ? ratio/.1 : ratio > .87 ? (1-ratio)/.13 : 1; p.y -= p.spd; p.x += Math.sin(p.life*.025 + i*.3) * .35; ctx.beginPath(); ctx.arc(p.x, p.y, p.r, 0, Math.PI*2); ctx.fillStyle = `rgba(${p.col},${p.op * fade})`; ctx.fill(); if(p.life >= p.max) pts[i] = mkPt(); }); requestAnimationFrame(drawPts); })(); /* ─── Open bars ──────────────────────────────────────── */ setTimeout(() => document.body.classList.add('bars-open'), 250); /* ─── Typewriter ─────────────────────────────────────── */ const phrases = [ 'นักพัฒนาเว็บไซต์', 'Web Developer', 'UI / UX Designer', 'Full Stack Developer', 'Creative Coder', 'Student Developer' ]; let pi = 0, ci = 0, del = false; const tw = document.getElementById('typewriter'); function typeLoop(){ const w = phrases[pi]; if(!del){ tw.textContent = w.slice(0, ++ci); if(ci === w.length){ del = true; setTimeout(typeLoop, 1800); return; } setTimeout(typeLoop, 82); } else { tw.textContent = w.slice(0, --ci); if(ci === 0){ del = false; pi = (pi+1) % phrases.length; setTimeout(typeLoop, 340); return; } setTimeout(typeLoop, 46); } } setTimeout(typeLoop, 2100); /* ─── Glitch on name ─────────────────────────────────── */ const nameEl = document.getElementById('intro-name'); setInterval(() => { if(Math.random() > .82){ const orig = nameEl.style.animation; nameEl.style.animation = 'glitch .28s steps(3) forwards, fadeUpScale .9s 1s cubic-bezier(.22,1,.36,1) forwards'; setTimeout(() => { nameEl.style.animation = orig; }, 300); } }, 3500); /* ─── Audio ──────────────────────────────────────────── */ const audio = document.getElementById('bg-audio'); const disc = document.getElementById('music-disc'); const waveBars = document.getElementById('wave-bars'); const iconPause = document.getElementById('icon-pause'); const iconPlay = document.getElementById('icon-play'); let playing = false; function fadeInAudio(){ let v = 0; const t = setInterval(() => { v = Math.min(v + .018, .55); audio.volume = v; if(v >= .55) clearInterval(t); }, 100); } function tryPlay(){ audio.play().then(() => { playing = true; disc.classList.add('playing'); waveBars.classList.remove('paused'); iconPause.style.display = 'block'; iconPlay.style.display = 'none'; fadeInAudio(); }).catch(() => { /* autoplay blocked — pill shows, user clicks play */ disc.classList.remove('playing'); waveBars.classList.add('paused'); iconPause.style.display = 'none'; iconPlay.style.display = 'block'; }); } document.getElementById('music-toggle').addEventListener('click', () => { if(playing){ audio.pause(); playing = false; disc.classList.remove('playing'); waveBars.classList.add('paused'); iconPause.style.display = 'none'; iconPlay.style.display = 'block'; } else { audio.play(); playing = true; disc.classList.add('playing'); waveBars.classList.remove('paused'); iconPause.style.display = 'block'; iconPlay.style.display = 'none'; if(audio.volume === 0) fadeInAudio(); } }); setTimeout(tryPlay, 900); /* ─── Enter site ─────────────────────────────────────── */ function enterSite(){ const flash = document.getElementById('exit-flash'); // Fade out audio let v = audio.volume; const t = setInterval(() => { v = Math.max(v - .04, 0); audio.volume = v; if(v <= 0){ clearInterval(t); audio.pause(); } }, 55); // Close bars then flash document.body.classList.remove('bars-open'); setTimeout(() => flash.classList.add('flash-in'), 350); setTimeout(() => { window.location.href = 'index.html'; }, 1050); } document.addEventListener('keydown', e => { if(e.key === 'Enter' || e.key === ' ') enterSite(); }); /* ─── Key hint pulse ─────────────────────────────────── */ const hint = document.querySelector('.key-hint'); setInterval(() => { if(!hint) return; hint.style.opacity = hint.style.opacity === '0.5' ? '0.22' : '0.5'; }, 900); </script> </body> </html>
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0.26 |
proxy
|
phpinfo
|
Settings