Liveloop

An interactive timeline for social media. Every post is a tiny app you can play, save, and remix.

Product

  • Feed
  • Create
  • Claude Code plugin
  • Blog

Legal

  • Privacy Policy
  • Terms of Service
  • Cookie Policy
  • DMCA

Project

  • Templates
© 2026 Liveloop. All rights reserved.
LiveloopVersion history

v1Current

@haru_calm · 6/9/2026, 9:37:40 PM

Initial version — all lines are new.

+<style>
+ html,body{height:100%;margin:0;overflow:hidden;background:#0c2128;}
+ *{box-sizing:border-box;}
+ #wrap{position:relative;height:100%;width:100%;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;-webkit-tap-highlight-color:transparent;touch-action:none;user-select:none;-webkit-user-select:none;}
+ canvas{display:block;width:100%;height:100%;position:absolute;inset:0;}
+ #head{position:absolute;top:0;left:0;right:0;z-index:2;padding:1.15rem 1.25rem;pointer-events:none;}
+ #head h1{margin:0;font-family:"Instrument Serif",Georgia,"Times New Roman",serif;font-weight:400;font-size:2.35rem;line-height:1;color:#EAF6F2;}
+ #head p{margin:.2rem 0 0;font-size:.8rem;color:#8fb8ad;font-weight:500;}
+ #hint{position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);z-index:2;pointer-events:none;font-family:"Instrument Serif",Georgia,serif;font-size:1.25rem;color:#8fb8ad;opacity:.85;transition:opacity .6s;text-align:center;}
+</style>
+<div id="wrap">
+ <canvas id="cv"></canvas>
+ <div id="head">
+ <div><h1>Ripple Pond</h1><p>Tap the water. Watch the koi.</p></div>
+ </div>
+ <div id="hint">tap anywhere</div>
+</div>
+<script>
+(function(){
+ var LL=window.liveloop||null;
+ var muted = LL ? LL.muted : true;
+ if(LL && LL.onMute){ try{ LL.onMute(function(m){ muted=m; }); }catch(e){} }
+ if(LL && LL.declareMedia){ try{ LL.declareMedia({sound:true}); }catch(e){} }
+ var _ac=null;
+ function actx(){ if(!_ac){ try{ _ac=new (window.AudioContext||window.webkitAudioContext)(); }catch(e){ _ac=null; } } return _ac; }
+ // a water "plink": a sine that falls in pitch, like a drop
+ function plink(y){
+ if(muted) return; var c=actx(); if(!c) return;
+ var t=c.currentTime, o=c.createOscillator(), g=c.createGain();
+ var f0=560+(1-y)*420+Math.random()*60;
+ o.type='sine'; o.frequency.setValueAtTime(f0,t);
+ o.frequency.exponentialRampToValueAtTime(f0*0.45,t+0.22);
+ g.gain.setValueAtTime(0.0001,t); g.gain.exponentialRampToValueAtTime(0.12,t+0.012);
+ g.gain.exponentialRampToValueAtTime(0.0001,t+0.5);
+ o.connect(g); g.connect(c.destination); o.start(t); o.stop(t+0.55);
+ }
+
+ var wrap=document.getElementById('wrap');
+ var cv=document.getElementById('cv'), ctx=cv.getContext('2d');
+ var hint=document.getElementById('hint');
+ var W=0,H=0,dpr=1,T=0,paused=false;
+ var ripples=[], koi=[], pads=[];
+
+ function size(){
+ var r=wrap.getBoundingClientRect();
+ W=Math.max(180,r.width); H=Math.max(240,r.height);
+ dpr=Math.min(window.devicePixelRatio||1,2.5);
+ cv.width=Math.round(W*dpr); cv.height=Math.round(H*dpr);
+ ctx.setTransform(dpr,0,0,dpr,0,0);
+ pads=[]; var i;
+ for(i=0;i<4;i++){ pads.push({x:(0.12+0.76*Math.random())*W, y:(0.2+0.65*Math.random())*H, r:(0.05+Math.random()*0.035)*Math.min(W,H), a:Math.random()*Math.PI*2}); }
+ }
+ function mkKoi(){
+ koi=[];
+ var cols=[['#FF7A33','#FFF4E4'],['#F8F3E6','#FF7A33'],['#FFB05C','#FFF4E4']];
+ for(var i=0;i<3;i++){
+ koi.push({x:(0.2+0.6*Math.random())*W, y:(0.3+0.5*Math.random())*H,
+ a:Math.random()*Math.PI*2, sp:0.018+Math.random()*0.012,
+ len:34+Math.random()*16, ph:Math.random()*7, turn:0,
+ body:cols[i][0], patch:cols[i][1]});
+ }
+ }
+
+ function bg(){
+ var g=ctx.createLinearGradient(0,0,0,H);
+ g.addColorStop(0,'#10303a'); g.addColorStop(0.6,'#0c2630'); g.addColorStop(1,'#081c24');
+ ctx.fillStyle=g; ctx.fillRect(0,0,W,H);
+ // moon shimmer — a soft warm column of light, top right
+ var mg=ctx.createRadialGradient(W*0.74,H*0.16,0,W*0.74,H*0.16,Math.min(W,H)*0.5);
+ mg.addColorStop(0,'rgba(255,222,160,0.13)'); mg.addColorStop(1,'rgba(255,222,160,0)');
+ ctx.fillStyle=mg; ctx.fillRect(0,0,W,H);
+ // lily pads
+ for(var i=0;i<pads.length;i++){
+ var p=pads[i];
+ ctx.save(); ctx.translate(p.x,p.y); ctx.rotate(p.a);
+ ctx.fillStyle='rgba(34,84,64,0.9)';
+ ctx.beginPath(); ctx.ellipse(0,0,p.r,p.r*0.82,0,0.35,Math.PI*2-0.15); ctx.lineTo(0,0); ctx.fill();
+ ctx.fillStyle='rgba(70,130,98,0.35)';
+ ctx.beginPath(); ctx.ellipse(-p.r*0.2,-p.r*0.15,p.r*0.5,p.r*0.36,0,0,Math.PI*2); ctx.fill();
+ ctx.restore();
+ }
+ }
+
+ function drawKoi(f){
+ ctx.save(); ctx.translate(f.x,f.y); ctx.rotate(f.a);
+ var w=Math.sin(f.ph)*0.3;
+ ctx.globalAlpha=0.92;
+ // tail
+ ctx.fillStyle=f.body;
+ ctx.beginPath();
+ ctx.moveTo(-f.len*0.4,0);
+ ctx.quadraticCurveTo(-f.len*0.75,w*f.len*0.5,-f.len*0.98,w*f.len*0.85);
+ ctx.quadraticCurveTo(-f.len*0.7,w*f.len*0.35+f.len*0.16,-f.len*0.38,5);
+ ctx.closePath(); ctx.fill();
+ // body
+ ctx.beginPath(); ctx.ellipse(0,0,f.len*0.5,f.len*0.19,0,0,Math.PI*2);
+ ctx.fillStyle=f.body; ctx.fill();
+ // patch (clipped to the body)
+ ctx.save(); ctx.clip();
+ ctx.fillStyle=f.patch;
+ ctx.beginPath(); ctx.ellipse(f.len*0.14,-f.len*0.05,f.len*0.22,f.len*0.13,0.4,0,Math.PI*2); ctx.fill();
+ ctx.beginPath(); ctx.ellipse(-f.len*0.2,f.len*0.06,f.len*0.14,f.len*0.09,-0.3,0,Math.PI*2); ctx.fill();
+ ctx.restore();
+ ctx.globalAlpha=1;
+ ctx.restore();
+ }
+
+ function stepKoi(f,dt,now){
+ f.ph+=f.sp*dt*9;
+ f.turn+= (Math.random()-0.5)*0.012*dt;
+ f.turn=Math.max(-0.02,Math.min(0.02,f.turn));
+ var steer=f.turn;
+ // shy away from fresh ripples
+ for(var i=0;i<ripples.length;i++){
+ var r=ripples[i], age=now-r.t; if(age>1100) continue;
+ var dx=f.x-r.x, dy=f.y-r.y, d=Math.hypot(dx,dy);
+ if(d<150&&d>1){
+ var away=Math.atan2(dy,dx), diff=away-f.a;
+ while(diff>Math.PI) diff-=Math.PI*2; while(diff<-Math.PI) diff+=Math.PI*2;
+ steer+=diff*0.02*(1-d/150); f.ph+=0.15*dt;
+ }
+ }
+ // keep inside the pond
+ var m=46;
+ if(f.x<m||f.x>W-m||f.y<m+60||f.y>H-m){
+ var toC=Math.atan2(H*0.55-f.y,W*0.5-f.x), diff2=toC-f.a;
+ while(diff2>Math.PI) diff2-=Math.PI*2; while(diff2<-Math.PI) diff2+=Math.PI*2;
+ steer+=diff2*0.03;
+ }
+ f.a+=steer*dt;
+ f.x+=Math.cos(f.a)*f.sp*f.len*dt; f.y+=Math.sin(f.a)*f.sp*f.len*dt;
+ }
+
+ function drawRipples(now){
+ for(var i=ripples.length-1;i>=0;i--){
+ var r=ripples[i], age=(now-r.t)/1400;
+ if(age>=1){ ripples.splice(i,1); continue; }
+ for(var k=0;k<3;k++){
+ var a2=age-k*0.09; if(a2<0) continue;
+ var rad=18+a2*r.max, al=(1-a2)*0.4;
+ ctx.strokeStyle='rgba(208,240,228,'+al.toFixed(3)+')';
+ ctx.lineWidth=1.6-k*0.4;
+ ctx.beginPath(); ctx.ellipse(r.x,r.y,rad,rad*0.62,0,0,Math.PI*2); ctx.stroke();
+ }
+ }
+ }
+
+ var T0=0;
+ function tick(now){
+ requestAnimationFrame(tick);
+ if(paused) return;
+ var dt=Math.min(2.4,(now-T0)/16.67); T0=now;
+ bg();
+ for(var i=0;i<koi.length;i++){ stepKoi(koi[i],dt,now); drawKoi(koi[i]); }
+ drawRipples(now);
+ }
+
+ var lastDrip=0;
+ function splash(e,big){
+ var r=cv.getBoundingClientRect(), t=e.touches?e.touches[0]:e;
+ var x=t.clientX-r.left, y=t.clientY-r.top;
+ ripples.push({x:x,y:y,t:performance.now(),max:big?Math.min(W,H)*0.38:Math.min(W,H)*0.16});
+ plink(y/H);
+ if(hint.style.opacity!=='0') hint.style.opacity='0';
+ }
+ wrap.addEventListener('pointerdown',function(e){ splash(e,true); });
+ wrap.addEventListener('pointermove',function(e){
+ if(!(e.buttons||e.pressure>0)) return;
+ e.preventDefault();
+ var now=performance.now();
+ if(now-lastDrip>160){ lastDrip=now; splash(e,false); }
+ });
+
+ if(LL && LL.onPause){ try{ LL.onPause(function(p){ paused=p; if(!p) T0=performance.now(); }); }catch(e){} }
+ document.addEventListener('visibilitychange',function(){ paused=document.hidden; if(!paused) T0=performance.now(); });
+ window.addEventListener('resize',function(){ size(); });
+ size(); mkKoi();
+ T0=performance.now(); requestAnimationFrame(tick);
+})();
+</script>

v1Current

@haru_calm · 6/9/2026, 9:37:40 PM

Initial version — all lines are new.

+<style>
+ html,body{height:100%;margin:0;overflow:hidden;background:#0c2128;}
+ *{box-sizing:border-box;}
+ #wrap{position:relative;height:100%;width:100%;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;-webkit-tap-highlight-color:transparent;touch-action:none;user-select:none;-webkit-user-select:none;}
+ canvas{display:block;width:100%;height:100%;position:absolute;inset:0;}
+ #head{position:absolute;top:0;left:0;right:0;z-index:2;padding:1.15rem 1.25rem;pointer-events:none;}
+ #head h1{margin:0;font-family:"Instrument Serif",Georgia,"Times New Roman",serif;font-weight:400;font-size:2.35rem;line-height:1;color:#EAF6F2;}
+ #head p{margin:.2rem 0 0;font-size:.8rem;color:#8fb8ad;font-weight:500;}
+ #hint{position:absolute;left:50%;top:52%;transform:translate(-50%,-50%);z-index:2;pointer-events:none;font-family:"Instrument Serif",Georgia,serif;font-size:1.25rem;color:#8fb8ad;opacity:.85;transition:opacity .6s;text-align:center;}
+</style>
+<div id="wrap">
+ <canvas id="cv"></canvas>
+ <div id="head">
+ <div><h1>Ripple Pond</h1><p>Tap the water. Watch the koi.</p></div>
+ </div>
+ <div id="hint">tap anywhere</div>
+</div>
+<script>
+(function(){
+ var LL=window.liveloop||null;
+ var muted = LL ? LL.muted : true;
+ if(LL && LL.onMute){ try{ LL.onMute(function(m){ muted=m; }); }catch(e){} }
+ if(LL && LL.declareMedia){ try{ LL.declareMedia({sound:true}); }catch(e){} }
+ var _ac=null;
+ function actx(){ if(!_ac){ try{ _ac=new (window.AudioContext||window.webkitAudioContext)(); }catch(e){ _ac=null; } } return _ac; }
+ // a water "plink": a sine that falls in pitch, like a drop
+ function plink(y){
+ if(muted) return; var c=actx(); if(!c) return;
+ var t=c.currentTime, o=c.createOscillator(), g=c.createGain();
+ var f0=560+(1-y)*420+Math.random()*60;
+ o.type='sine'; o.frequency.setValueAtTime(f0,t);
+ o.frequency.exponentialRampToValueAtTime(f0*0.45,t+0.22);
+ g.gain.setValueAtTime(0.0001,t); g.gain.exponentialRampToValueAtTime(0.12,t+0.012);
+ g.gain.exponentialRampToValueAtTime(0.0001,t+0.5);
+ o.connect(g); g.connect(c.destination); o.start(t); o.stop(t+0.55);
+ }
+
+ var wrap=document.getElementById('wrap');
+ var cv=document.getElementById('cv'), ctx=cv.getContext('2d');
+ var hint=document.getElementById('hint');
+ var W=0,H=0,dpr=1,T=0,paused=false;
+ var ripples=[], koi=[], pads=[];
+
+ function size(){
+ var r=wrap.getBoundingClientRect();
+ W=Math.max(180,r.width); H=Math.max(240,r.height);
+ dpr=Math.min(window.devicePixelRatio||1,2.5);
+ cv.width=Math.round(W*dpr); cv.height=Math.round(H*dpr);
+ ctx.setTransform(dpr,0,0,dpr,0,0);
+ pads=[]; var i;
+ for(i=0;i<4;i++){ pads.push({x:(0.12+0.76*Math.random())*W, y:(0.2+0.65*Math.random())*H, r:(0.05+Math.random()*0.035)*Math.min(W,H), a:Math.random()*Math.PI*2}); }
+ }
+ function mkKoi(){
+ koi=[];
+ var cols=[['#FF7A33','#FFF4E4'],['#F8F3E6','#FF7A33'],['#FFB05C','#FFF4E4']];
+ for(var i=0;i<3;i++){
+ koi.push({x:(0.2+0.6*Math.random())*W, y:(0.3+0.5*Math.random())*H,
+ a:Math.random()*Math.PI*2, sp:0.018+Math.random()*0.012,
+ len:34+Math.random()*16, ph:Math.random()*7, turn:0,
+ body:cols[i][0], patch:cols[i][1]});
+ }
+ }
+
+ function bg(){
+ var g=ctx.createLinearGradient(0,0,0,H);
+ g.addColorStop(0,'#10303a'); g.addColorStop(0.6,'#0c2630'); g.addColorStop(1,'#081c24');
+ ctx.fillStyle=g; ctx.fillRect(0,0,W,H);
+ // moon shimmer — a soft warm column of light, top right
+ var mg=ctx.createRadialGradient(W*0.74,H*0.16,0,W*0.74,H*0.16,Math.min(W,H)*0.5);
+ mg.addColorStop(0,'rgba(255,222,160,0.13)'); mg.addColorStop(1,'rgba(255,222,160,0)');
+ ctx.fillStyle=mg; ctx.fillRect(0,0,W,H);
+ // lily pads
+ for(var i=0;i<pads.length;i++){
+ var p=pads[i];
+ ctx.save(); ctx.translate(p.x,p.y); ctx.rotate(p.a);
+ ctx.fillStyle='rgba(34,84,64,0.9)';
+ ctx.beginPath(); ctx.ellipse(0,0,p.r,p.r*0.82,0,0.35,Math.PI*2-0.15); ctx.lineTo(0,0); ctx.fill();
+ ctx.fillStyle='rgba(70,130,98,0.35)';
+ ctx.beginPath(); ctx.ellipse(-p.r*0.2,-p.r*0.15,p.r*0.5,p.r*0.36,0,0,Math.PI*2); ctx.fill();
+ ctx.restore();
+ }
+ }
+
+ function drawKoi(f){
+ ctx.save(); ctx.translate(f.x,f.y); ctx.rotate(f.a);
+ var w=Math.sin(f.ph)*0.3;
+ ctx.globalAlpha=0.92;
+ // tail
+ ctx.fillStyle=f.body;
+ ctx.beginPath();
+ ctx.moveTo(-f.len*0.4,0);
+ ctx.quadraticCurveTo(-f.len*0.75,w*f.len*0.5,-f.len*0.98,w*f.len*0.85);
+ ctx.quadraticCurveTo(-f.len*0.7,w*f.len*0.35+f.len*0.16,-f.len*0.38,5);
+ ctx.closePath(); ctx.fill();
+ // body
+ ctx.beginPath(); ctx.ellipse(0,0,f.len*0.5,f.len*0.19,0,0,Math.PI*2);
+ ctx.fillStyle=f.body; ctx.fill();
+ // patch (clipped to the body)
+ ctx.save(); ctx.clip();
+ ctx.fillStyle=f.patch;
+ ctx.beginPath(); ctx.ellipse(f.len*0.14,-f.len*0.05,f.len*0.22,f.len*0.13,0.4,0,Math.PI*2); ctx.fill();
+ ctx.beginPath(); ctx.ellipse(-f.len*0.2,f.len*0.06,f.len*0.14,f.len*0.09,-0.3,0,Math.PI*2); ctx.fill();
+ ctx.restore();
+ ctx.globalAlpha=1;
+ ctx.restore();
+ }
+
+ function stepKoi(f,dt,now){
+ f.ph+=f.sp*dt*9;
+ f.turn+= (Math.random()-0.5)*0.012*dt;
+ f.turn=Math.max(-0.02,Math.min(0.02,f.turn));
+ var steer=f.turn;
+ // shy away from fresh ripples
+ for(var i=0;i<ripples.length;i++){
+ var r=ripples[i], age=now-r.t; if(age>1100) continue;
+ var dx=f.x-r.x, dy=f.y-r.y, d=Math.hypot(dx,dy);
+ if(d<150&&d>1){
+ var away=Math.atan2(dy,dx), diff=away-f.a;
+ while(diff>Math.PI) diff-=Math.PI*2; while(diff<-Math.PI) diff+=Math.PI*2;
+ steer+=diff*0.02*(1-d/150); f.ph+=0.15*dt;
+ }
+ }
+ // keep inside the pond
+ var m=46;
+ if(f.x<m||f.x>W-m||f.y<m+60||f.y>H-m){
+ var toC=Math.atan2(H*0.55-f.y,W*0.5-f.x), diff2=toC-f.a;
+ while(diff2>Math.PI) diff2-=Math.PI*2; while(diff2<-Math.PI) diff2+=Math.PI*2;
+ steer+=diff2*0.03;
+ }
+ f.a+=steer*dt;
+ f.x+=Math.cos(f.a)*f.sp*f.len*dt; f.y+=Math.sin(f.a)*f.sp*f.len*dt;
+ }
+
+ function drawRipples(now){
+ for(var i=ripples.length-1;i>=0;i--){
+ var r=ripples[i], age=(now-r.t)/1400;
+ if(age>=1){ ripples.splice(i,1); continue; }
+ for(var k=0;k<3;k++){
+ var a2=age-k*0.09; if(a2<0) continue;
+ var rad=18+a2*r.max, al=(1-a2)*0.4;
+ ctx.strokeStyle='rgba(208,240,228,'+al.toFixed(3)+')';
+ ctx.lineWidth=1.6-k*0.4;
+ ctx.beginPath(); ctx.ellipse(r.x,r.y,rad,rad*0.62,0,0,Math.PI*2); ctx.stroke();
+ }
+ }
+ }
+
+ var T0=0;
+ function tick(now){
+ requestAnimationFrame(tick);
+ if(paused) return;
+ var dt=Math.min(2.4,(now-T0)/16.67); T0=now;
+ bg();
+ for(var i=0;i<koi.length;i++){ stepKoi(koi[i],dt,now); drawKoi(koi[i]); }
+ drawRipples(now);
+ }
+
+ var lastDrip=0;
+ function splash(e,big){
+ var r=cv.getBoundingClientRect(), t=e.touches?e.touches[0]:e;
+ var x=t.clientX-r.left, y=t.clientY-r.top;
+ ripples.push({x:x,y:y,t:performance.now(),max:big?Math.min(W,H)*0.38:Math.min(W,H)*0.16});
+ plink(y/H);
+ if(hint.style.opacity!=='0') hint.style.opacity='0';
+ }
+ wrap.addEventListener('pointerdown',function(e){ splash(e,true); });
+ wrap.addEventListener('pointermove',function(e){
+ if(!(e.buttons||e.pressure>0)) return;
+ e.preventDefault();
+ var now=performance.now();
+ if(now-lastDrip>160){ lastDrip=now; splash(e,false); }
+ });
+
+ if(LL && LL.onPause){ try{ LL.onPause(function(p){ paused=p; if(!p) T0=performance.now(); }); }catch(e){} }
+ document.addEventListener('visibilitychange',function(){ paused=document.hidden; if(!paused) T0=performance.now(); });
+ window.addEventListener('resize',function(){ size(); });
+ size(); mkKoi();
+ T0=performance.now(); requestAnimationFrame(tick);
+})();
+</script>
← Version history