luminomorphism
Version:
A UI design system built around light, blur, ambient motion and perceptual feedback.
45 lines (44 loc) • 3.53 kB
JavaScript
class LOrbitalQuantum extends HTMLElement{static get observedAttributes(){return["count","color","radius","mode","quantum-delay","quantum-entropy"]}constructor(){super(),this.shadow=this.attachShadow({mode:"open"}),this._quantumInterval=null,this._orbs=[],this._rotator=null}connectedCallback(){this.render()}attributeChangedCallback(c,n,r){n!==r&&this.render()}clearQuantumInterval(){this._quantumInterval&&(clearInterval(this._quantumInterval),this._quantumInterval=null)}render(){const c=Math.max(1,parseInt(this.getAttribute("count"))||5),n=this.getAttribute("color")||"#00ffff",r=parseInt(this.getAttribute("radius"))||40,p=this.getAttribute("mode"),b=parseInt(this.getAttribute("quantum-delay"))||3e3,f=parseFloat(this.getAttribute("quantum-entropy"))||1.5;this.clearQuantumInterval(),this.shadow.innerHTML="",this._orbs=[];const h=document.createElement("div");h.className="orbital-wrapper";const u=document.createElement("div");u.className="orbital-center";const i=document.createElement("div");i.className="rotator",this._rotator=i;const m=document.createElement("style");m.textContent=`
.orbital-wrapper {
position: relative;
width: 100%; height: 100%;
min-height: 200px;
display: flex;
align-items: center;
justify-content: center;
pointer-events: none;
z-index: 2;
}
.orbital-center {
position: relative;
width: 200px; height: 200px;
}
.rotator {
width: 100%; height: 100%;
position: absolute;
top: 0; left: 0;
animation: rotateOrbit 6s linear infinite;
transform-origin: center center;
}
.orb {
position: absolute;
left: 50%; top: 50%;
transform: translate(0px, 0px);
}
.orb-inner {
width: 6px; height: 6px;
margin-left: -3px; margin-top: -3px;
border-radius: 50%;
background: ${n};
box-shadow: 0 0 6px ${n};
animation: pulseOrb 2s infinite ease-in-out;
}
rotateOrbit {
from { transform: rotate(0deg); }
to { transform: rotate(360deg); }
}
pulseOrb {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.3); }
}
`;for(let t=0;t<c;t++){const e=document.createElement("div");e.className="orb";const s=document.createElement("div");s.className="orb-inner",e.appendChild(s),this._orbs.push(e);const a=360/c*t,o=a*Math.PI/180,l=Math.sin(o)*r,d=-Math.cos(o)*r;e.style.transform=`translate(${l}px, ${d}px)`,e.dataset.baseAngle=a,i.appendChild(e)}u.appendChild(i),h.appendChild(u),this.shadow.appendChild(m),this.shadow.appendChild(h),p==="quantum"&&(this._quantumInterval=setInterval(()=>{if(!this._orbs.length)return;const t=this._orbs[Math.floor(Math.random()*this._orbs.length)],e=this._orbs[Math.floor(Math.random()*this._orbs.length)],s=t.querySelector(".orb-inner"),a=e.querySelector(".orb-inner");t.style.transition="opacity 0.3s, transform 0.3s",t.style.opacity="0",setTimeout(()=>{const o=Math.random()*360*f,l=o*Math.PI/180,d=Math.sin(l)*r,g=-Math.cos(l)*r;t.style.transform=`translate(${d}px, ${g}px)`,t.dataset.baseAngle=o,t.style.opacity="1",s.style.boxShadow=`0 0 15px ${n}`,setTimeout(()=>{s.style.boxShadow=`0 0 6px ${n}`},500)},300),a.style.transition="filter 0.3s",a.style.filter="brightness(1.8)",setTimeout(()=>a.style.filter="brightness(1)",500)},b))}disconnectedCallback(){this.clearQuantumInterval()}}customElements.define("l-orbital-quantum",LOrbitalQuantum);