HTMLify
cruciophobia
Views: 128 | Author: amar
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>Click-to-Cycle Frames — Surprise</title>
<style>
:root{
--size: min(70vmin, 520px);
--bg: linear-gradient(135deg,#ffefba,#ffc3a0);
--accent: #222;
--tri-points: 50% 5%, 95% 95%, 5% 95%;
--sq-points: 5% 5%, 95% 5%, 95% 95%, 5% 95%;
--pent-points: 50% 5%, 95% 40%, 77% 95%, 23% 95%, 5% 40%;
--sex-points: 25% 5%, 75% 5%, 95% 50%, 75% 95%, 25% 95%, 5% 50%;
--sep-points: 50% 5%, 85.18% 21.94%, 93.87% 60.01%, 69.52% 90.54%, 30.48% 90.54%, 6.13% 60.01%, 14.82% 21.94%;
--oct-points: 50% 5%, 81.82% 18.18%, 95% 50%, 81.82% 81.82%, 50% 95%, 18.18% 81.82%, 5% 50%, 18.18% 18.18%;
}
*{box-sizing:border-box}
html,body{height:100%;margin:0;font-family:Inter,system-ui,Segoe UI,Roboto,Arial;color:var(--accent);background:#0f1724;display:flex;align-items:center;justify-content:center}
.wrap{display:flex;flex-direction:column;gap:18px;align-items:center}
.stage{
width:var(--size);
height:var(--size);
display:grid;place-items:center;
background:var(--bg);
border-radius:18px;
box-shadow:0 20px 50px rgba(2,6,23,0.6), inset 0 1px 0 rgba(255,255,255,0.05);
padding:24px;
}
.frame{
width:100%;height:100%;display:grid;place-items:center;position:relative;overflow:hidden;
transition:all 600ms cubic-bezier(.2,.9,.2,1);
clip-path: polygon(var(--points));
background: linear-gradient(180deg, rgba(255,255,255,0.95), rgba(255,255,255,0.85));
}
.frame.state-tri{ --points: var(--tri-points); }
.frame.state-sq{ --points: var(--sq-points); }
.frame.state-pent{ --points: var(--pent-points); }
.frame.state-sex{ --points: var(--sex-points); }
.frame.state-sep{ --points: var(--sep-points); }
.frame.state-oct{ --points: var(--oct-points); }
.frame.state-video{ clip-path: none; border-radius:12px; }
.placeholder{ text-align:center;padding:28px; }
.shape-title{font-size:20px;font-weight:700;margin-bottom:10px}
.shape-sub{opacity:.85}
.video-wrap{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:12px;opacity:0;transform:scale(.98);transition:opacity 420ms ease,transform 420ms ease}
.frame.state-video .video-wrap{opacity:1;transform:scale(1)}
.video-wrap video{width:100%;height:100%;border:0;border-radius:8px;object-fit:cover}
.controls{display:flex;gap:12px;align-items:center}
button{padding:10px 14px;border-radius:10px;border:0;background:#111827;color:white;font-weight:600;cursor:pointer;box-shadow:0 6px 18px rgba(2,6,23,0.6)}
.hint{color:#cbd5e1;font-size:13px}
@media (max-width:520px){:root{--size:80vmin}}
</style>
</head>
<body>
<div class="wrap">
<div class="stage">
<div class="frame state-tri" id="frame">
<div class="placeholder" id="placeholder"></div>
<div class="video-wrap" id="videoWrap" aria-hidden="true"></div>
</div>
</div>
<div class="controls">
<button id="cycleBtn">Change Shape</button>
<div class="hint">Click anywhere or press any key to change</div>
</div>
</div>
<script>
const frame = document.getElementById('frame');
const placeholder = document.getElementById('placeholder');
const videoWrap = document.getElementById('videoWrap');
const btn = document.getElementById('cycleBtn');
// 0 = tri, 1 = square, 2 = pentagon, 3 = sextagon, 4 = septagon, 5 = octagon, 6 = video
let state = 0;
const states = [
{cls:'state-tri', title:'Triangle'},
{cls:'state-sq', title:'Square'},
{cls:'state-pent', title:'Pentagon'},
{cls:'state-sex', title:'Sextagon'},
{cls:'state-sep', title:'Septagon'},
{cls:'state-oct', title:'Octagon'},
{cls:'state-video', title:'Surprise'}
];
const VIDEO_URL = 'https://htmlify.me/abh/qr-gift/rick-roll.mp4';
function enterState(s){
frame.className = 'frame ' + states[s].cls;
if(s < states.length - 1){
placeholder.innerHTML = `<div class="shape-title">${states[s].title}</div><div class="shape-sub">Click to change</div>`;
videoWrap.innerHTML = '';
videoWrap.setAttribute('aria-hidden','true');
} else {
placeholder.innerHTML = '';
const video = document.createElement('video');
video.src = VIDEO_URL;
video.autoplay = true;
video.controls = true;
video.loop = false;
videoWrap.innerHTML = '';
videoWrap.appendChild(video);
videoWrap.setAttribute('aria-hidden','false');
}
}
function cycle(){
state = (state + 1) % states.length;
enterState(state);
}
btn.addEventListener('click', cycle);
document.addEventListener('click', (e)=>{
if(!btn.contains(e.target)) cycle();
});
document.addEventListener('keydown', cycle);
enterState(state);
</script>
</body>
</html>