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

@ko_studio · 6/9/2026, 10:51:32 PM

Initial version — all lines are new.

+<style>
+ html,body{height:100%;margin:0;overflow:hidden;background:#E8D9BD;}
+ *{box-sizing:border-box;}
+ #wrap{position:relative;height:100%;width:100%;display:flex;flex-direction:column;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:linear-gradient(160deg,#EFE2C8 0%,#E4D2B0 100%);-webkit-tap-highlight-color:transparent;touch-action:none;user-select:none;-webkit-user-select:none;}
+ #head{padding:1.15rem 1.25rem .2rem;z-index:2;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:#5a4630;}
+ #head p{margin:.2rem 0 0;font-size:.8rem;color:#9b855f;font-weight:500;}
+ #board{flex:1;position:relative;min-height:0;}
+ .pol{position:absolute;width:152px;background:#FFFDF6;padding:8px 8px 0;box-shadow:0 10px 22px rgba(80,60,20,.28);cursor:grab;touch-action:none;}
+ .pol img{display:block;width:100%;height:138px;object-fit:cover;background:#ddd;pointer-events:none;}
+ .pol .tape{position:absolute;left:50%;top:-9px;transform:translateX(-50%) rotate(-3deg);width:54px;height:18px;background:rgba(124,92,255,.35);border-radius:2px;}
+ .pol input{width:100%;border:0;background:transparent;text-align:center;font-family:"Instrument Serif",Georgia,serif;font-style:italic;font-size:16px;color:#5a4630;padding:.45rem 0 .55rem;outline:none;}
+ .pol input::placeholder{color:#c4b291;}
+ #hint{position:absolute;left:50%;top:46%;transform:translate(-50%,-50%);pointer-events:none;font-family:"Instrument Serif",Georgia,serif;font-size:1.2rem;color:#9b855f;opacity:.85;transition:opacity .5s;text-align:center;line-height:1.5;}
+ #foot{display:flex;gap:10px;justify-content:center;padding:.6rem 1.1rem 1.15rem;z-index:2;}
+ #foot button{border:0;border-radius:999px;font-weight:700;font-size:.85rem;padding:.7rem 1.2rem;cursor:pointer;}
+ #add{background:linear-gradient(135deg,#7C5CFF,#FF5A1F);color:#fff;box-shadow:0 8px 20px rgba(124,92,255,.3);}
+ #snap{background:#5a4630;color:#FFF6E4;display:none;}
+ #clear{background:rgba(255,255,255,.65);color:#6a5440;border:1px solid rgba(120,90,50,.25);display:none;}
+ #file{display:none;}
+ #resWrap{position:absolute;inset:0;z-index:5;display:none;flex-direction:column;align-items:center;justify-content:center;background:rgba(60,45,20,.55);backdrop-filter:blur(5px);padding:1.2rem;}
+ #res{max-width:92%;max-height:70%;border-radius:10px;box-shadow:0 18px 44px rgba(0,0,0,.4);}
+ #resWrap p{color:#FFF3DC;font-size:.78rem;font-weight:600;margin:.8rem 0 .5rem;}
+ #back{border:0;border-radius:999px;background:rgba(255,255,255,.92);color:#5a4630;font-weight:700;font-size:.85rem;padding:.65rem 1.3rem;cursor:pointer;}
+</style>
+<div id="wrap">
+ <div id="head"><h1>Polaroid Wall</h1><p>Pin up to 4 photos. Drag them around. Caption each.</p></div>
+ <div id="board"><div id="hint">add a photo to start<br>it never leaves your phone</div></div>
+ <div id="foot">
+ <button id="add">+ photo</button>
+ <button id="snap">snapshot &#128248;</button>
+ <button id="clear">clear</button>
+ </div>
+ <input id="file" type="file" accept="image/*">
+ <div id="resWrap">
+ <img id="res" alt="your wall">
+ <p>press &amp; hold to save your wall</p>
+ <button id="back">back to the board</button>
+ </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; }
+ function thunk(f){ // soft cork "pin" sound
+ if(muted) return; var c=actx(); if(!c) return;
+ var t=c.currentTime, o=c.createOscillator(), g=c.createGain();
+ o.type='triangle'; o.frequency.setValueAtTime(f||240,t);
+ o.frequency.exponentialRampToValueAtTime((f||240)*0.6,t+0.08);
+ g.gain.setValueAtTime(0.0001,t); g.gain.exponentialRampToValueAtTime(0.16,t+0.008);
+ g.gain.exponentialRampToValueAtTime(0.0001,t+0.16);
+ o.connect(g); g.connect(c.destination); o.start(t); o.stop(t+0.18);
+ }
+
+ var board=document.getElementById('board');
+ var hint=document.getElementById('hint');
+ var addBtn=document.getElementById('add'), snapBtn=document.getElementById('snap'), clearBtn=document.getElementById('clear');
+ var fileIn=document.getElementById('file');
+ var resWrap=document.getElementById('resWrap'), resImg=document.getElementById('res'), backBtn=document.getElementById('back');
+ var pols=[]; // {el, img(dataURL canvas), x, y, rot}
+ var MAXP=4;
+
+ function spot(i){
+ var r=board.getBoundingClientRect();
+ var cols=[[0.08,0.06],[0.5,0.12],[0.12,0.46],[0.46,0.5]];
+ var p=cols[i%4];
+ return { x:p[0]*r.width + (Math.random()*16-8), y:p[1]*r.height + (Math.random()*16-8) };
+ }
+
+ function addPol(srcCanvas){
+ var i=pols.length, pos=spot(i), rot=(Math.random()*10-5);
+ var el=document.createElement('div'); el.className='pol';
+ el.style.left=pos.x+'px'; el.style.top=pos.y+'px';
+ el.style.transform='rotate('+rot+'deg)';
+ el.style.zIndex=String(10+i);
+ var tape=document.createElement('span'); tape.className='tape';
+ var hues=['rgba(124,92,255,.35)','rgba(255,90,31,.35)','rgba(225,76,143,.35)','rgba(246,169,59,.4)'];
+ tape.style.background=hues[i%4];
+ var im=document.createElement('img'); im.src=srcCanvas.toDataURL('image/jpeg',0.85); im.alt='';
+ var cap=document.createElement('input'); cap.maxLength=28; cap.placeholder='caption…';
+ el.appendChild(tape); el.appendChild(im); el.appendChild(cap);
+ board.appendChild(el);
+ var rec={el:el, x:pos.x, y:pos.y, rot:rot, cap:cap, img:srcCanvas};
+ pols.push(rec);
+
+ // drag (pointer events; taps on the input still focus it)
+ var sx=0,sy=0,ox=0,oy=0,drag=false;
+ el.addEventListener('pointerdown',function(e){
+ if(e.target===cap) return;
+ drag=true; sx=e.clientX; sy=e.clientY; ox=rec.x; oy=rec.y;
+ el.style.zIndex=String(100+(++zTop));
+ try{ el.setPointerCapture(e.pointerId); }catch(x){}
+ e.preventDefault();
+ });
+ el.addEventListener('pointermove',function(e){
+ if(!drag) return;
+ rec.x=ox+(e.clientX-sx); rec.y=oy+(e.clientY-sy);
+ el.style.left=rec.x+'px'; el.style.top=rec.y+'px';
+ e.preventDefault();
+ });
+ el.addEventListener('pointerup',function(){ if(drag){ drag=false; thunk(200); } });
+ el.addEventListener('pointercancel',function(){ drag=false; });
+
+ hint.style.opacity='0';
+ snapBtn.style.display='block'; clearBtn.style.display='block';
+ if(pols.length>=MAXP) addBtn.style.display='none';
+ thunk(280);
+ }
+ var zTop=0;
+
+ function load(file){
+ var rd=new FileReader();
+ rd.onload=function(){
+ var im=new Image();
+ im.onload=function(){
+ var S=600, sc=Math.max(S/im.width,S/im.height);
+ var c2=document.createElement('canvas'); c2.width=S; c2.height=S;
+ var cc=c2.getContext('2d');
+ var w=im.width*sc, h=im.height*sc;
+ cc.drawImage(im,(S-w)/2,(S-h)/2,w,h);
+ addPol(c2);
+ };
+ im.src=rd.result;
+ };
+ rd.readAsDataURL(file);
+ }
+ addBtn.addEventListener('click',function(){ if(pols.length<MAXP) fileIn.click(); });
+ fileIn.addEventListener('change',function(){ if(fileIn.files && fileIn.files[0]){ load(fileIn.files[0]); fileIn.value=''; } });
+
+ clearBtn.addEventListener('click',function(){
+ pols.forEach(function(p){ board.removeChild(p.el); });
+ pols=[]; addBtn.style.display='block';
+ snapBtn.style.display='none'; clearBtn.style.display='none';
+ hint.style.opacity='.85';
+ });
+
+ snapBtn.addEventListener('click',function(){
+ if(!pols.length) return;
+ var br=board.getBoundingClientRect();
+ var W=900, H=Math.round(W*br.height/br.width), k=W/br.width;
+ var out=document.createElement('canvas'); out.width=W; out.height=H;
+ var oc=out.getContext('2d');
+ var bg=oc.createLinearGradient(0,0,W*0.3,H);
+ bg.addColorStop(0,'#EFE2C8'); bg.addColorStop(1,'#E4D2B0');
+ oc.fillStyle=bg; oc.fillRect(0,0,W,H);
+ pols.forEach(function(p){
+ var pw=152*k, ph=(138+8+36)*k+8*k;
+ var cx=(p.x+76)*k, cy=(p.y+95)*k;
+ oc.save(); oc.translate(cx,cy); oc.rotate(p.rot*Math.PI/180);
+ oc.shadowColor='rgba(80,60,20,.3)'; oc.shadowBlur=18*k/1.5; oc.shadowOffsetY=8;
+ oc.fillStyle='#FFFDF6'; oc.fillRect(-pw/2,-ph/2,pw,ph);
+ oc.shadowColor='transparent';
+ oc.drawImage(p.img,-pw/2+8*k,-ph/2+8*k,pw-16*k,138*k);
+ var ctext=(p.cap.value||'').trim();
+ if(ctext){
+ oc.fillStyle='#5a4630'; oc.textAlign='center';
+ oc.font='italic '+Math.round(15*k)+'px Georgia,"Times New Roman",serif';
+ oc.fillText(ctext,0,ph/2-12*k,pw-20*k);
+ }
+ oc.restore();
+ });
+ oc.fillStyle='rgba(90,70,48,.55)'; oc.textAlign='right';
+ oc.font='italic '+Math.round(13*k)+'px Georgia,serif';
+ var d=new Date();
+ oc.fillText(d.toLocaleDateString(undefined,{month:'short',day:'numeric',year:'numeric'}),W-18,H-16);
+ resImg.src=out.toDataURL('image/jpeg',0.9);
+ resWrap.style.display='flex';
+ thunk(330);
+ });
+ backBtn.addEventListener('click',function(){ resWrap.style.display='none'; });
+})();
+</script>

v1Current

@ko_studio · 6/9/2026, 10:51:32 PM

Initial version — all lines are new.

+<style>
+ html,body{height:100%;margin:0;overflow:hidden;background:#E8D9BD;}
+ *{box-sizing:border-box;}
+ #wrap{position:relative;height:100%;width:100%;display:flex;flex-direction:column;font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif;background:linear-gradient(160deg,#EFE2C8 0%,#E4D2B0 100%);-webkit-tap-highlight-color:transparent;touch-action:none;user-select:none;-webkit-user-select:none;}
+ #head{padding:1.15rem 1.25rem .2rem;z-index:2;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:#5a4630;}
+ #head p{margin:.2rem 0 0;font-size:.8rem;color:#9b855f;font-weight:500;}
+ #board{flex:1;position:relative;min-height:0;}
+ .pol{position:absolute;width:152px;background:#FFFDF6;padding:8px 8px 0;box-shadow:0 10px 22px rgba(80,60,20,.28);cursor:grab;touch-action:none;}
+ .pol img{display:block;width:100%;height:138px;object-fit:cover;background:#ddd;pointer-events:none;}
+ .pol .tape{position:absolute;left:50%;top:-9px;transform:translateX(-50%) rotate(-3deg);width:54px;height:18px;background:rgba(124,92,255,.35);border-radius:2px;}
+ .pol input{width:100%;border:0;background:transparent;text-align:center;font-family:"Instrument Serif",Georgia,serif;font-style:italic;font-size:16px;color:#5a4630;padding:.45rem 0 .55rem;outline:none;}
+ .pol input::placeholder{color:#c4b291;}
+ #hint{position:absolute;left:50%;top:46%;transform:translate(-50%,-50%);pointer-events:none;font-family:"Instrument Serif",Georgia,serif;font-size:1.2rem;color:#9b855f;opacity:.85;transition:opacity .5s;text-align:center;line-height:1.5;}
+ #foot{display:flex;gap:10px;justify-content:center;padding:.6rem 1.1rem 1.15rem;z-index:2;}
+ #foot button{border:0;border-radius:999px;font-weight:700;font-size:.85rem;padding:.7rem 1.2rem;cursor:pointer;}
+ #add{background:linear-gradient(135deg,#7C5CFF,#FF5A1F);color:#fff;box-shadow:0 8px 20px rgba(124,92,255,.3);}
+ #snap{background:#5a4630;color:#FFF6E4;display:none;}
+ #clear{background:rgba(255,255,255,.65);color:#6a5440;border:1px solid rgba(120,90,50,.25);display:none;}
+ #file{display:none;}
+ #resWrap{position:absolute;inset:0;z-index:5;display:none;flex-direction:column;align-items:center;justify-content:center;background:rgba(60,45,20,.55);backdrop-filter:blur(5px);padding:1.2rem;}
+ #res{max-width:92%;max-height:70%;border-radius:10px;box-shadow:0 18px 44px rgba(0,0,0,.4);}
+ #resWrap p{color:#FFF3DC;font-size:.78rem;font-weight:600;margin:.8rem 0 .5rem;}
+ #back{border:0;border-radius:999px;background:rgba(255,255,255,.92);color:#5a4630;font-weight:700;font-size:.85rem;padding:.65rem 1.3rem;cursor:pointer;}
+</style>
+<div id="wrap">
+ <div id="head"><h1>Polaroid Wall</h1><p>Pin up to 4 photos. Drag them around. Caption each.</p></div>
+ <div id="board"><div id="hint">add a photo to start<br>it never leaves your phone</div></div>
+ <div id="foot">
+ <button id="add">+ photo</button>
+ <button id="snap">snapshot &#128248;</button>
+ <button id="clear">clear</button>
+ </div>
+ <input id="file" type="file" accept="image/*">
+ <div id="resWrap">
+ <img id="res" alt="your wall">
+ <p>press &amp; hold to save your wall</p>
+ <button id="back">back to the board</button>
+ </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; }
+ function thunk(f){ // soft cork "pin" sound
+ if(muted) return; var c=actx(); if(!c) return;
+ var t=c.currentTime, o=c.createOscillator(), g=c.createGain();
+ o.type='triangle'; o.frequency.setValueAtTime(f||240,t);
+ o.frequency.exponentialRampToValueAtTime((f||240)*0.6,t+0.08);
+ g.gain.setValueAtTime(0.0001,t); g.gain.exponentialRampToValueAtTime(0.16,t+0.008);
+ g.gain.exponentialRampToValueAtTime(0.0001,t+0.16);
+ o.connect(g); g.connect(c.destination); o.start(t); o.stop(t+0.18);
+ }
+
+ var board=document.getElementById('board');
+ var hint=document.getElementById('hint');
+ var addBtn=document.getElementById('add'), snapBtn=document.getElementById('snap'), clearBtn=document.getElementById('clear');
+ var fileIn=document.getElementById('file');
+ var resWrap=document.getElementById('resWrap'), resImg=document.getElementById('res'), backBtn=document.getElementById('back');
+ var pols=[]; // {el, img(dataURL canvas), x, y, rot}
+ var MAXP=4;
+
+ function spot(i){
+ var r=board.getBoundingClientRect();
+ var cols=[[0.08,0.06],[0.5,0.12],[0.12,0.46],[0.46,0.5]];
+ var p=cols[i%4];
+ return { x:p[0]*r.width + (Math.random()*16-8), y:p[1]*r.height + (Math.random()*16-8) };
+ }
+
+ function addPol(srcCanvas){
+ var i=pols.length, pos=spot(i), rot=(Math.random()*10-5);
+ var el=document.createElement('div'); el.className='pol';
+ el.style.left=pos.x+'px'; el.style.top=pos.y+'px';
+ el.style.transform='rotate('+rot+'deg)';
+ el.style.zIndex=String(10+i);
+ var tape=document.createElement('span'); tape.className='tape';
+ var hues=['rgba(124,92,255,.35)','rgba(255,90,31,.35)','rgba(225,76,143,.35)','rgba(246,169,59,.4)'];
+ tape.style.background=hues[i%4];
+ var im=document.createElement('img'); im.src=srcCanvas.toDataURL('image/jpeg',0.85); im.alt='';
+ var cap=document.createElement('input'); cap.maxLength=28; cap.placeholder='caption…';
+ el.appendChild(tape); el.appendChild(im); el.appendChild(cap);
+ board.appendChild(el);
+ var rec={el:el, x:pos.x, y:pos.y, rot:rot, cap:cap, img:srcCanvas};
+ pols.push(rec);
+
+ // drag (pointer events; taps on the input still focus it)
+ var sx=0,sy=0,ox=0,oy=0,drag=false;
+ el.addEventListener('pointerdown',function(e){
+ if(e.target===cap) return;
+ drag=true; sx=e.clientX; sy=e.clientY; ox=rec.x; oy=rec.y;
+ el.style.zIndex=String(100+(++zTop));
+ try{ el.setPointerCapture(e.pointerId); }catch(x){}
+ e.preventDefault();
+ });
+ el.addEventListener('pointermove',function(e){
+ if(!drag) return;
+ rec.x=ox+(e.clientX-sx); rec.y=oy+(e.clientY-sy);
+ el.style.left=rec.x+'px'; el.style.top=rec.y+'px';
+ e.preventDefault();
+ });
+ el.addEventListener('pointerup',function(){ if(drag){ drag=false; thunk(200); } });
+ el.addEventListener('pointercancel',function(){ drag=false; });
+
+ hint.style.opacity='0';
+ snapBtn.style.display='block'; clearBtn.style.display='block';
+ if(pols.length>=MAXP) addBtn.style.display='none';
+ thunk(280);
+ }
+ var zTop=0;
+
+ function load(file){
+ var rd=new FileReader();
+ rd.onload=function(){
+ var im=new Image();
+ im.onload=function(){
+ var S=600, sc=Math.max(S/im.width,S/im.height);
+ var c2=document.createElement('canvas'); c2.width=S; c2.height=S;
+ var cc=c2.getContext('2d');
+ var w=im.width*sc, h=im.height*sc;
+ cc.drawImage(im,(S-w)/2,(S-h)/2,w,h);
+ addPol(c2);
+ };
+ im.src=rd.result;
+ };
+ rd.readAsDataURL(file);
+ }
+ addBtn.addEventListener('click',function(){ if(pols.length<MAXP) fileIn.click(); });
+ fileIn.addEventListener('change',function(){ if(fileIn.files && fileIn.files[0]){ load(fileIn.files[0]); fileIn.value=''; } });
+
+ clearBtn.addEventListener('click',function(){
+ pols.forEach(function(p){ board.removeChild(p.el); });
+ pols=[]; addBtn.style.display='block';
+ snapBtn.style.display='none'; clearBtn.style.display='none';
+ hint.style.opacity='.85';
+ });
+
+ snapBtn.addEventListener('click',function(){
+ if(!pols.length) return;
+ var br=board.getBoundingClientRect();
+ var W=900, H=Math.round(W*br.height/br.width), k=W/br.width;
+ var out=document.createElement('canvas'); out.width=W; out.height=H;
+ var oc=out.getContext('2d');
+ var bg=oc.createLinearGradient(0,0,W*0.3,H);
+ bg.addColorStop(0,'#EFE2C8'); bg.addColorStop(1,'#E4D2B0');
+ oc.fillStyle=bg; oc.fillRect(0,0,W,H);
+ pols.forEach(function(p){
+ var pw=152*k, ph=(138+8+36)*k+8*k;
+ var cx=(p.x+76)*k, cy=(p.y+95)*k;
+ oc.save(); oc.translate(cx,cy); oc.rotate(p.rot*Math.PI/180);
+ oc.shadowColor='rgba(80,60,20,.3)'; oc.shadowBlur=18*k/1.5; oc.shadowOffsetY=8;
+ oc.fillStyle='#FFFDF6'; oc.fillRect(-pw/2,-ph/2,pw,ph);
+ oc.shadowColor='transparent';
+ oc.drawImage(p.img,-pw/2+8*k,-ph/2+8*k,pw-16*k,138*k);
+ var ctext=(p.cap.value||'').trim();
+ if(ctext){
+ oc.fillStyle='#5a4630'; oc.textAlign='center';
+ oc.font='italic '+Math.round(15*k)+'px Georgia,"Times New Roman",serif';
+ oc.fillText(ctext,0,ph/2-12*k,pw-20*k);
+ }
+ oc.restore();
+ });
+ oc.fillStyle='rgba(90,70,48,.55)'; oc.textAlign='right';
+ oc.font='italic '+Math.round(13*k)+'px Georgia,serif';
+ var d=new Date();
+ oc.fillText(d.toLocaleDateString(undefined,{month:'short',day:'numeric',year:'numeric'}),W-18,H-16);
+ resImg.src=out.toDataURL('image/jpeg',0.9);
+ resWrap.style.display='flex';
+ thunk(330);
+ });
+ backBtn.addEventListener('click',function(){ resWrap.style.display='none'; });
+})();
+</script>
← Version history