luminomorphism
Version:
A UI design system built around light, blur, ambient motion and perceptual feedback.
30 lines (28 loc) • 2.37 kB
JavaScript
class LDepthFrame extends HTMLElement{constructor(){super(),this.shadow=this.attachShadow({mode:"open"}),this.depth=parseFloat(this.getAttribute("depth"))||15,this.tilt=this.hasAttribute("tilt"),this.wrapper=null,this.tiltEnabled=!1}static get observedAttributes(){return["depth","tilt"]}connectedCallback(){this.render(),this.tilt&&this.enableTilt()}attributeChangedCallback(e,t,s){e==="depth"?this.depth=parseFloat(s):e==="tilt"&&(this.tilt=this.hasAttribute("tilt"),this.tilt?this.enableTilt():this.disableTilt())}render(){this.shadow.innerHTML="";const e=document.createElement("style");e.textContent=`
.depth-wrapper {
width: 100%;
height: 100%;
perspective: 1000px;
transform-style: preserve-3d;
will-change: transform;
transition: transform 0.3s ease;
}
.l-card {
width: 100%;
height: 100%;
font-weight: bold;
display: flex;
justify-content: center;
align-items: center;
border-radius: 20px;
background: rgba(255, 255, 255, 0.05);
box-shadow:
0 25px 50px rgba(0, 0, 0, 0.4),
0 0 6px rgba(255, 255, 255, 0.07),
inset 0 0 120px rgba(255, 255, 255, 0.015);
backdrop-filter: blur(14px);
-webkit-backdrop-filter: blur(14px);
transition: box-shadow 0.4s ease;
color: white;
}
`;const t=document.createElement("div");for(t.className="depth-wrapper",this.wrapper=t;this.childNodes.length>0;)t.appendChild(this.childNodes[0]);this.shadow.appendChild(e),this.shadow.appendChild(t)}enableTilt(){this.tiltEnabled||!this.wrapper||(this.tiltEnabled=!0,this._onMouseMove=e=>{const t=this.getBoundingClientRect(),s=(e.clientX-t.left)/t.width-.5,i=(e.clientY-t.top)/t.height-.5,r=s*this.depth,a=-i*this.depth;this.wrapper.style.transform=`rotateX(${a}deg) rotateY(${r}deg)`},this._onMouseLeave=()=>{this.wrapper.style.transform="rotateX(0deg) rotateY(0deg)"},this.addEventListener("mousemove",this._onMouseMove),this.addEventListener("mouseleave",this._onMouseLeave))}disableTilt(){!this.tiltEnabled||!this.wrapper||(this.removeEventListener("mousemove",this._onMouseMove),this.removeEventListener("mouseleave",this._onMouseLeave),this.wrapper.style.transform="rotateX(0deg) rotateY(0deg)",this.tiltEnabled=!1)}}customElements.define("l-depth-frame",LDepthFrame);