Custom Code Experiment •
DNA 1
Source Code View HTML / CSS / JavaScript
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<title>DNA Signal Loader</title>
<style>
:root{ --bg:#050505; }
:root:not([data-theme="light"]){ --bg:#050505; }
html,body{height:100%;margin:0;background:var(--bg);overflow:hidden;}
canvas{display:block;position:fixed;top:0;left:0;width:100%;height:100%;max-width:100%;}
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
(function(){
"use strict";
var TAU = Math.PI*2;
var cvs = document.getElementById('c');
var ctx = cvs.getContext('2d', {alpha:false});
var W=0,H=0,DPR=1,CX=0;
var calm = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var t0 = 0;
/* ---------- patterns ---------- */
var noiseTiles=[], scanPat=null;
function buildNoise(){
noiseTiles=[];
for(var n=0;n<4;n++){
var s=140, nc=document.createElement('canvas'); nc.width=nc.height=s;
var nx=nc.getContext('2d'), id=nx.createImageData(s,s), d=id.data;
for(var i=0;i<d.length;i+=4){
var v=Math.random()*255;
d[i]=v; d[i+1]=v; d[i+2]=v; d[i+3]=Math.random()*Math.random()*85;
}
nx.putImageData(id,0,0);
noiseTiles.push(ctx.createPattern(nc,'repeat'));
}
var sc=document.createElement('canvas'); sc.width=1; sc.height=3;
var sx=sc.getContext('2d');
sx.fillStyle='rgba(0,0,0,0.5)'; sx.fillRect(0,0,1,1);
scanPat=ctx.createPattern(sc,'repeat');
}
/* ---------- sizing ---------- */
var N=150, TURNS=5.2, R=120;
var px,pz,qx,qz,py;
function alloc(){
px=new Float32Array(N); pz=new Float32Array(N);
qx=new Float32Array(N); qz=new Float32Array(N);
py=new Float32Array(N);
}
function resize(){
var r=cvs.getBoundingClientRect();
W=Math.max(1, r.width || cvs.clientWidth || window.innerWidth || 800);
H=Math.max(1, r.height || cvs.clientHeight || window.innerHeight || 600);
DPR=Math.min(2, window.devicePixelRatio||1);
if(W*H>1400*900) DPR=Math.min(DPR,1.5);
cvs.width=Math.round(W*DPR); cvs.height=Math.round(H*DPR);
CX=W*0.5;
N = W<620 ? 104 : 150;
TURNS = Math.max(3.2, Math.min(7.5, (H/Math.max(240, Math.min(360, H*0.34)))*1.6));
R = Math.min(W*0.19, 155);
alloc();
buildNoise();
}
window.addEventListener('resize', resize);
/* ---------- signal ---------- */
var NB=56, bands=new Float32Array(NB), WV=256, wave=new Float32Array(WV);
function envelope(t){
var b=t*(calm?68:112)/60;
var kick=Math.exp(-(b%1)*6);
var snare=Math.exp(-((b+0.5)%2)*5)*0.5;
var hat=Math.exp(-((b*2)%1)*14)*0.22;
return Math.min(1.7, kick*0.85+snare+hat+0.14);
}
function updateSignal(t, amp){
for(var k=0;k<NB;k++){
var f=k/NB;
var v=(Math.sin(t*(1.7+k*0.41)+k*2.1)*0.5+0.5);
v*=Math.pow(1-f,1.15);
v=v*0.65+Math.random()*0.12;
v*=0.35+amp*0.8;
bands[k]=bands[k]*0.74+v*0.26;
}
for(var i=0;i<WV;i++){
var u=i/(WV-1), s=0;
s+=Math.sin(u*TAU*3+t*4.6)*0.52;
s+=Math.sin(u*TAU*7.3-t*3.1)*0.27;
s+=Math.sin(u*TAU*17.7+t*9.4)*0.13;
s+=(Math.random()-0.5)*0.18;
wave[i]=s*amp;
}
}
/* ---------- glitch state ---------- */
var g=0, gUntil=0, dropUntil=0, nextDrop=4;
function updateGlitch(t, amp){
if(t>gUntil && Math.random()<(calm?0.006:0.03)){
gUntil=t+0.05+Math.random()*(calm?0.14:0.38);
g=Math.max(g, (calm?0.25:0.35)+Math.random()*(calm?0.3:0.65));
}
if(amp>1.25 && Math.random()<0.5) g=Math.max(g, calm?0.25:0.55);
if(t>gUntil) g*=0.86;
if(g<0.004) g=0;
if(!calm && t>nextDrop){
dropUntil=t+0.05+Math.random()*0.16;
nextDrop=t+5+Math.random()*7;
}
}
/* ---------- geometry ---------- */
function computeGeo(t, amp){
var top=-50, bot=H+50, span=bot-top;
for(var i=0;i<N;i++){
var u=i/(N-1);
var ph=u*TURNS*TAU + t*(calm?0.6:1.25);
var rr=R*(0.80+0.20*Math.sin(u*5.1-t*1.9))*(0.88+0.26*amp);
var jitter=Math.sin(u*23.7+t*7)*4.5*amp*(0.4+g*2.2);
px[i]=CX+Math.sin(ph)*rr+jitter;
pz[i]=Math.cos(ph);
qx[i]=CX+Math.sin(ph+Math.PI)*rr-jitter;
qz[i]=Math.cos(ph+Math.PI);
py[i]=top+span*u;
}
}
/* ---------- drawing ---------- */
function strandPath(xs, dx){
ctx.beginPath();
ctx.moveTo(xs[0]+dx, py[0]);
for(var i=1;i<N;i++){
var mx=(xs[i-1]+xs[i])*0.5+dx, my=(py[i-1]+py[i])*0.5;
ctx.quadraticCurveTo(xs[i-1]+dx, py[i-1], mx, my);
}
ctx.lineTo(xs[N-1]+dx, py[N-1]);
}
function ghostPass(dx, a){
ctx.globalCompositeOperation='lighter';
ctx.strokeStyle='#ffffff'; ctx.globalAlpha=a; ctx.lineWidth=1.5;
strandPath(px, dx); ctx.stroke();
strandPath(qx, dx); ctx.stroke();
ctx.lineWidth=1;
ctx.beginPath();
for(var i=0;i<N;i+=3){
ctx.moveTo(px[i]+dx, py[i]);
ctx.lineTo(qx[i]+dx, py[i]);
}
ctx.stroke();
ctx.globalAlpha=1;
}
function mainPass(t, amp){
ctx.globalCompositeOperation='lighter';
/* soft bloom under the strands */
ctx.lineWidth=7; ctx.globalAlpha=0.07; ctx.strokeStyle='#ffffff';
strandPath(px,0); ctx.stroke();
strandPath(qx,0); ctx.stroke();
/* depth-shaded strand segments */
for(var i=1;i<N;i++){
var za=(pz[i]+1)*0.5, zb=(qz[i]+1)*0.5;
ctx.globalAlpha=0.16+za*0.78;
ctx.lineWidth=0.7+za*2.0;
ctx.strokeStyle='#ffffff';
ctx.beginPath(); ctx.moveTo(px[i-1],py[i-1]); ctx.lineTo(px[i],py[i]); ctx.stroke();
ctx.globalAlpha=(0.16+zb*0.78)*0.72;
ctx.lineWidth=0.7+zb*2.0;
ctx.strokeStyle='#d6d6d6';
ctx.beginPath(); ctx.moveTo(qx[i-1],py[i-1]); ctx.lineTo(qx[i],py[i]); ctx.stroke();
}
/* base pairs drawn as little waveforms */
for(var j=0;j<N;j+=3){
var zz=((pz[j]+qz[j])*0.5+1)*0.5;
var x1=px[j], x2=qx[j], y=py[j], w=x2-x1;
var broken = ((j*37+((t*7)|0)*13)%97)/97 < g*0.55;
var ticks=8;
var base=(4+bands[(j*3)%NB]*20)*(0.45+zz*0.9);
ctx.globalAlpha=0.14+zz*0.6;
ctx.lineWidth=1+zz;
ctx.strokeStyle='#ffffff';
ctx.beginPath();
for(var k=0;k<=ticks;k++){
if(broken && (k%3===1)) continue;
var f=k/ticks;
var xx=x1+w*f;
var s=wave[((k*29+j*7+((t*60)|0))%WV+WV)%WV];
var hgt=base*(0.25+Math.abs(Math.sin(f*Math.PI)))*(0.5+Math.abs(s));
ctx.moveTo(xx, y-hgt*0.5);
ctx.lineTo(xx, y+hgt*0.5);
}
ctx.stroke();
/* connective hairline */
ctx.globalAlpha=(0.08+zz*0.26)*(broken?0.25:1);
ctx.lineWidth=0.6;
ctx.beginPath(); ctx.moveTo(x1,y); ctx.lineTo(x2,y); ctx.stroke();
/* backbone nodes */
var ns=1.2+zz*2.6;
ctx.globalAlpha=0.3+zz*0.6;
ctx.fillStyle='#ffffff';
ctx.fillRect(px[j]-ns*0.5, y-ns*0.5, ns, ns);
ctx.globalAlpha=(0.3+zz*0.6)*0.7;
ctx.fillRect(qx[j]-ns*0.5, y-ns*0.5, ns, ns);
}
ctx.globalAlpha=1;
}
/* ---------- background & overlays ---------- */
var bgGrad=null, bgKey='';
function backdrop(t, amp){
ctx.globalCompositeOperation='source-over';
ctx.fillStyle='#050505'; ctx.fillRect(0,0,W,H);
var key=W+'x'+H;
if(key!==bgKey){
bgGrad=ctx.createRadialGradient(CX,H*0.5,0,CX,H*0.5,Math.max(W,H)*0.7);
bgGrad.addColorStop(0,'rgba(255,255,255,0.10)');
bgGrad.addColorStop(0.55,'rgba(255,255,255,0.035)');
bgGrad.addColorStop(1,'rgba(255,255,255,0)');
bgKey=key;
}
ctx.globalAlpha=0.6+amp*0.15;
ctx.fillStyle=bgGrad; ctx.fillRect(0,0,W,H);
ctx.globalAlpha=1;
}
function glitchPost(){
if(g<=0) return;
var cw=cvs.width, ch=cvs.height;
ctx.save();
ctx.setTransform(1,0,0,1,0,0);
ctx.globalCompositeOperation='source-over';
var n=1+((g*14)|0);
for(var i=0;i<n;i++){
var sy=Math.random()*ch;
var sh=(2+Math.random()*44)*DPR;
var dx=(Math.random()-0.5)*g*190*DPR;
ctx.drawImage(cvs, 0,sy,cw,sh, dx,sy,cw,sh);
}
var b=((g*8)|0);
for(var j=0;j<b;j++){
var bw=(30+Math.random()*180)*DPR, bh=(6+Math.random()*60)*DPR;
var sx=Math.random()*(cw-bw), sy2=Math.random()*(ch-bh);
var ox=(Math.random()-0.5)*g*120*DPR, oy=(Math.random()-0.5)*g*26*DPR;
ctx.drawImage(cvs, sx,sy2,bw,bh, sx+ox,sy2+oy,bw,bh);
}
if(g>0.45){
var s=g*9*DPR;
ctx.globalCompositeOperation='lighter';
ctx.globalAlpha=0.18;
ctx.drawImage(cvs,-s,0);
ctx.drawImage(cvs, s,0);
ctx.globalAlpha=1;
}
ctx.restore();
}
function signalDrop(){
ctx.save();
ctx.setTransform(1,0,0,1,0,0);
var cw=cvs.width, ch=cvs.height;
ctx.globalCompositeOperation='source-over';
ctx.fillStyle='rgba(5,5,5,0.72)';
ctx.fillRect(0,0,cw,ch);
for(var i=0;i<70;i++){
var y=Math.random()*ch, h=(1+Math.random()*10)*DPR;
ctx.globalAlpha=0.08+Math.random()*0.38;
ctx.fillStyle= Math.random()<0.5 ? '#2a2a2a' : '#1a1a1a';
ctx.fillRect(0,y,cw,h);
}
ctx.globalAlpha=1;
ctx.restore();
}
function overlays(){
ctx.save();
ctx.setTransform(1,0,0,1,0,0);
var cw=cvs.width, ch=cvs.height;
ctx.globalCompositeOperation='screen';
ctx.globalAlpha=0.26+g*0.32;
ctx.fillStyle=noiseTiles[(Math.random()*noiseTiles.length)|0];
ctx.save();
ctx.translate((Math.random()*140)|0,(Math.random()*140)|0);
ctx.fillRect(-160,-160,cw+320,ch+320);
ctx.restore();
ctx.globalCompositeOperation='multiply';
ctx.globalAlpha=0.32;
ctx.fillStyle=scanPat;
ctx.fillRect(0,0,cw,ch);
ctx.globalCompositeOperation='source-over';
ctx.globalAlpha=1;
var vg=ctx.createRadialGradient(cw*0.5,ch*0.5,Math.min(cw,ch)*0.25,cw*0.5,ch*0.5,Math.max(cw,ch)*0.72);
vg.addColorStop(0,'rgba(0,0,0,0)');
vg.addColorStop(1,'rgba(0,0,0,0.82)');
ctx.fillStyle=vg; ctx.fillRect(0,0,cw,ch);
ctx.restore();
}
/* ---------- loop ---------- */
function frame(now){
var cr=cvs.getBoundingClientRect();
if(cr.width && cr.height && (Math.abs(cr.width-W)>1 || Math.abs(cr.height-H)>1)) resize();
var t=(now-t0)/1000;
var amp=envelope(t);
updateSignal(t, amp);
updateGlitch(t, amp);
computeGeo(t, amp);
ctx.setTransform(DPR,0,0,DPR,0,0);
backdrop(t, amp);
var split=(1.5+g*16+amp*2.2);
ghostPass(-split, 0.22);
ghostPass( split, 0.22);
mainPass(t, amp);
glitchPost();
if(t<dropUntil) signalDrop();
overlays();
requestAnimationFrame(frame);
}
resize();
requestAnimationFrame(function(n){ t0=n; frame(n); });
})();
</script>
</body>
</html>