13 Layers.
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
<!DOCTYPE html><html><head><meta charset="utf-8">
|
||||
<title>Proof1 · lit chamber — backlit parallax</title>
|
||||
<style>
|
||||
:root{--gap:6;--bright:1;}
|
||||
html,body{margin:0;height:100%;background:#0a0a0b;overflow:hidden;
|
||||
font:12px/1.5 ui-monospace,monospace;color:#9aa;}
|
||||
#wrap{position:fixed;inset:0;display:grid;place-items:center;}
|
||||
.scene{perspective:2200px;perspective-origin:50% 45%;}
|
||||
.scene{perspective:1400px;perspective-origin:50% 45%;}
|
||||
.stack{position:relative;transform-style:preserve-3d;transition:transform .06s linear;
|
||||
width:500.5px;height:810px;}
|
||||
.panel{position:absolute;inset:-14%;transform:translateZ(-120px);
|
||||
.panel{position:absolute;inset:-70%;
|
||||
background:radial-gradient(120% 90% at 50% 42%,#fff6ec, #ffe7c8 42%, #f0c48c 78%, #caa06a 100%);
|
||||
filter:blur(2px);}
|
||||
.plane{position:absolute;inset:0;width:100%;height:100%;background-size:cover;
|
||||
@@ -27,7 +26,9 @@
|
||||
<h1>Proof1 · lit chamber</h1>
|
||||
<div>move mouse = parallax · drag sliders</div>
|
||||
<label>air gap ×<span id="gv"></span></label>
|
||||
<input id="gap" type="range" min="1" max="18" step="0.5" value="6">
|
||||
<input id="gap" type="range" min="1" max="28" step="0.5" value="12">
|
||||
<label>parallax ×<span id="pv"></span></label>
|
||||
<input id="par" type="range" min="0" max="220" step="5" value="110">
|
||||
<label>backlight<span id="bv"></span></label>
|
||||
<input id="bright" type="range" min="0.3" max="1.8" step="0.05" value="1">
|
||||
<div id="pills"></div>
|
||||
@@ -37,7 +38,7 @@
|
||||
<div class="panel" id="panel"></div>
|
||||
</div></div></div>
|
||||
<script>
|
||||
const PLANES=[{"id":"sun","file":"plane-1-sun.svg","z":0,"blur":1.4,"dim":0.95,"white":"none","glow":1},{"id":"sea-far","file":"plane-2-sea-far.svg","z":9,"blur":0.9,"dim":1,"white":"none","glow":0.7},{"id":"sea-mid","file":"plane-3-sea-mid.svg","z":15,"blur":0.5,"dim":1,"white":"trace","glow":0.7},{"id":"sea-near","file":"plane-4-sea-near.svg","z":18,"blur":0.2,"dim":1,"white":"trace","glow":0.7},{"id":"event-halo","file":"plane-5-event-halo.svg","z":27,"blur":2.4,"dim":0.85,"white":"none","glow":0.9},{"id":"event-core","file":"plane-6-event-core.svg","z":30,"blur":0,"dim":1,"white":"under","glow":0.5},{"id":"front-glass","file":"plane-7-front-glass.svg","z":30,"blur":0,"dim":1,"white":"none","glow":0,"blend":"multiply"}];
|
||||
const PLANES=[{"id":"sun","file":"plane-1-sun.svg","z":0,"blur":1.4,"dim":1,"white":"none","glow":1},{"id":"event-glow","file":"plane-2-event-glow.svg","z":8,"blur":2.6,"dim":0.85,"white":"none","glow":0.9},{"id":"sea-far","file":"plane-3-sea-far.svg","z":14,"blur":0.9,"dim":0.7,"white":"none","glow":0.8},{"id":"sea-mid","file":"plane-4-sea-mid.svg","z":18,"blur":0.5,"dim":0.7,"white":"trace","glow":0.7},{"id":"sea-near","file":"plane-5-sea-near.svg","z":22,"blur":0.2,"dim":0.7,"white":"trace","glow":0.7},{"id":"event-birth","file":"plane-6-event-birth.svg","z":28,"blur":0.7,"dim":1,"white":"none","glow":0.8},{"id":"event-life","file":"plane-7-event-life.svg","z":32,"blur":0.3,"dim":1,"white":"trace","glow":0.5},{"id":"event-death","file":"plane-8-event-death.svg","z":36,"blur":0,"dim":1,"white":"under","glow":0.3},{"id":"front-glass","file":"plane-9-front-glass.svg","z":36,"blur":0,"dim":1,"white":"none","glow":0,"blend":"multiply"}];
|
||||
const stack=document.getElementById('stack');
|
||||
const legend=document.getElementById('legend');
|
||||
const pills=document.getElementById('pills');
|
||||
@@ -52,30 +53,38 @@ PLANES.forEach(p=>{
|
||||
pill.onclick=()=>{d.dataset.off=d.dataset.off?'':'1'; pill.classList.toggle('off'); layout();};
|
||||
pills.appendChild(pill);
|
||||
});
|
||||
let gap=6, bright=1, mx=0, my=0;
|
||||
function layout(){
|
||||
let gap=12, par=110, bright=1, mx=0, my=0;
|
||||
const panel=document.getElementById('panel');
|
||||
// One transform per plane = translateZ (real depth) + a depth-scaled screen
|
||||
// shift (EXAGGERATED parallax) + the stack's 3D tilt. Deeper planes shift more,
|
||||
// so the event's birth→death timeline slides apart as you move.
|
||||
function update(){
|
||||
stack.style.transform='rotateX('+(my*11).toFixed(2)+'deg) rotateY('+(mx*15).toFixed(2)+'deg)';
|
||||
for(const p of PLANES){
|
||||
const e=els[p.id];
|
||||
const z=(p.z-maxZ)*gap; // front plane at 0, others recede
|
||||
const blur=(p.blur||0)*(gap/6);
|
||||
const off=e.dataset.off?' opacity:0;':'';
|
||||
e.style.transform='translateZ('+z+'px)';
|
||||
e.style.filter='blur('+blur.toFixed(2)+'px)';
|
||||
const z=(p.z-maxZ)*gap; // front plane at 0, others recede
|
||||
const depth=(maxZ-p.z)/(maxZ||1); // 0 = front, 1 = deepest
|
||||
const ox=(-mx*depth*par).toFixed(1), oy=(my*depth*par).toFixed(1);
|
||||
e.style.transform='translate3d('+ox+'px,'+oy+'px,'+z.toFixed(1)+'px)';
|
||||
e.style.filter='blur('+((p.blur||0)*(gap/8)).toFixed(2)+'px)';
|
||||
e.style.opacity=e.dataset.off?0:(p.dim??1);
|
||||
e.style.mixBlendMode=p.blend||'normal';
|
||||
}
|
||||
document.getElementById('panel').style.filter='blur(2px) brightness('+bright+')';
|
||||
}
|
||||
function parallax(){
|
||||
stack.style.transform='rotateX('+(my*7)+'deg) rotateY('+(mx*9)+'deg)';
|
||||
// keep the light panel ALWAYS behind the deepest plane, scaled up so it still
|
||||
// fills the backdrop as it recedes (else deep planes pop behind it at high gap).
|
||||
const pz=(0-maxZ)*gap-90;
|
||||
panel.style.transform='translateZ('+pz.toFixed(0)+'px) scale('+(1+(-pz)/1400).toFixed(2)+')';
|
||||
panel.style.filter='blur(2px) brightness('+bright+')';
|
||||
}
|
||||
addEventListener('mousemove',e=>{
|
||||
mx=(e.clientX/innerWidth-0.5)*2; my=-(e.clientY/innerHeight-0.5)*2; parallax();
|
||||
mx=(e.clientX/innerWidth-0.5)*2; my=-(e.clientY/innerHeight-0.5)*2; update();
|
||||
});
|
||||
const gapI=document.getElementById('gap'), brI=document.getElementById('bright');
|
||||
gapI.oninput=()=>{gap=+gapI.value; document.getElementById('gv').textContent=' '+gap; layout();};
|
||||
brI.oninput=()=>{bright=+brI.value; document.getElementById('bv').textContent=' '+bright.toFixed(2); layout();};
|
||||
const gapI=document.getElementById('gap'), parI=document.getElementById('par'), brI=document.getElementById('bright');
|
||||
gapI.oninput=()=>{gap=+gapI.value; document.getElementById('gv').textContent=' '+gap; update();};
|
||||
parI.oninput=()=>{par=+parI.value; document.getElementById('pv').textContent=' '+par; update();};
|
||||
brI.oninput=()=>{bright=+brI.value; document.getElementById('bv').textContent=' '+bright.toFixed(2); update();};
|
||||
document.getElementById('gv').textContent=' '+gap;
|
||||
document.getElementById('pv').textContent=' '+par;
|
||||
document.getElementById('bv').textContent=' '+bright.toFixed(2);
|
||||
layout(); parallax();
|
||||
update();
|
||||
</script></body></html>
|
||||
Reference in New Issue
Block a user