Skip to content

Instantly share code, notes, and snippets.

@shurane
Created April 27, 2022 20:05
Show Gist options
  • Save shurane/dc35cdfa3ca9281f6d1a72797979185f to your computer and use it in GitHub Desktop.
Save shurane/dc35cdfa3ca9281f6d1a72797979185f to your computer and use it in GitHub Desktop.
data:text/html, <html contenteditable> with some extra styling to make it easier to use. Just copy/paste the code in your browser and type away. Or make it a bookmarklet.
data:text/html;charset=utf-8,<title>TextEditor</title><style>body{background:#fbfbfb;color:#333;margin:0%50auto;width:100%}textarea{background:#fbfbfb;border:0;color:#333;font-family:sans-serif;font-size:2rem;height:98%;line-height:1.4;margin:0%20auto;outline:0;padding:4rem;width:100%}button{background-color:#fbfbfb;border:1px%20#ccc%20solid;color:#999;cursor:pointer;float:right;margin:10px%200;padding:5px%2010px}@media%20(max-width:100%){body{width:100%;padding:0}textarea{padding:10px}button{float:none}}</style><body><button%20onclick="sM();%20return%20false">Email%20this</button><textarea%20contenteditable%20id=TE%20spellcheck=false%20placeholder=Write...%20autofocus></textarea><script>function%20sM(){var%20a="mailto:?subject="+escape("Text%20from%20TextEditor")+"&body="+escape(document.getElementById("TE").value);window.location.href=a};</script>
@HA7A7
Copy link

HA7A7 commented Oct 30, 2025

<!doctype html>

<title>Particle Background</title> <style> html,body{height:100%;margin:0;background:#000;overflow:hidden} #canvas{display:block;position:fixed;inset:0;z-index:0} .controls{position:fixed;left:12px;bottom:12px;z-index:10;background:rgba(255,255,255,0.06);backdrop-filter:blur(6px);padding:8px;border-radius:10px;color:#fff;font-family:system-ui;font-size:13px} .btn{background:rgba(255,255,255,0.08);border:0;padding:6px 10px;border-radius:8px;color:#fff;cursor:pointer} .btn:active{transform:scale(0.98)} </style> Pause Density <script> (() => { const c = document.getElementById('canvas'); const ctx = c.getContext('2d', { alpha: true }); let DPR = Math.max(1, window.devicePixelRatio || 1); function resize() { DPR = Math.max(1, window.devicePixelRatio || 1); c.width = Math.floor(innerWidth * DPR); c.height = Math.floor(innerHeight * DPR); c.style.width = innerWidth + 'px'; c.style.height = innerHeight + 'px'; ctx.setTransform(DPR,0,0,DPR,0,0); } addEventListener('resize', resize); resize(); // Config const palette = ['#FFD54A','#FF6B6B','#9FA8DA','#B39DDB','#90CAF9']; // yellow, red, blue, purple... let PARTICLE_COUNT = 900; // adjustable by slider const MAX_SPEED = 0.35; const GRAVITY = 0.0005; const FRICTION = 0.9999; // helper: gaussian random for cluster function gaussian(mean=0, std=1){ // Box-Muller let u=0,v=0; while(u===0) u=Math.random(); while(v===0) v=Math.random(); return mean + std*Math.sqrt(-2*Math.log(u)) * Math.cos(2*Math.PI*v); } class Particle { constructor(cx,cy){ this.reset(cx,cy); } reset(cx,cy){ // spawn radius small with gaussian to make dense center const r = Math.abs(gaussian(0, 60)); // pixels const angle = Math.random()*Math.PI*2; this.x = cx + r * Math.cos(angle); this.y = cy + r * Math.sin(angle); // velocity radial outward with slight randomness const speed = Math.max(0.02, Math.abs(gaussian(0.25, 0.4))); const dir = angle; this.vx = Math.cos(dir) * speed * (0.6 + Math.random()*1.4); this.vy = Math.sin(dir) * speed * (0.6 + Math.random()*1.4); // color and visual this.size = 1 + Math.random()*3.4; this.color = palette[Math.floor(Math.random()*palette.length)]; this.life = 80 + Math.random()*240; this.ttl = this.life; this.shape = Math.random() < 0.8 ? 'dot' : 'square'; this.alpha = 1; } step(dt){ // simple physics this.vy += GRAVITY * dt; this.vx *= FRICTION; this.vy *= FRICTION; this.x += this.vx * dt; this.y += this.vy * dt; this.ttl -= dt * 0.5; this.alpha = Math.max(0, this.ttl / this.life); // respawn if dead or off-screen if(this.ttl <= 0 || this.x < -100 || this.x > innerWidth+100 || this.y < -100 || this.y > innerHeight+100){ this.reset(innerWidth/2, innerHeight/2 - 40); // center slightly up } } draw(ctx){ ctx.globalAlpha = Math.min(1, this.alpha + 0.05); if(this.shape === 'square'){ // draw crisp square ctx.fillStyle = this.color; const s = Math.max(1, this.size); ctx.fillRect(this.x - s/2, this.y - s/2, s, s); } else { // circle with soft glow const g = ctx.createRadialGradient(this.x,this.y,0,this.x,this.y,this.size*3); g.addColorStop(0, this.color); g.addColorStop(1, 'rgba(0,0,0,0)'); ctx.fillStyle = g; ctx.beginPath(); ctx.arc(this.x, this.y, this.size*2.2, 0, Math.PI*2); ctx.fill(); } ctx.globalAlpha = 1; } } // create particles let particles = []; function createParticles(n){ particles = []; const cx = innerWidth/2, cy = innerHeight/2 - 40; for(let i=0;i { running = !running; if(running){ last = performance.now(); requestAnimationFrame(loop); toggle.textContent = 'Pause'; } else { toggle.textContent = 'Play'; } }); density.addEventListener('input', (e) => { PARTICLE_COUNT = parseInt(e.target.value,10); createParticles(PARTICLE_COUNT); }); // optional: click to burst c.addEventListener('click', (ev) => { const rect = c.getBoundingClientRect(); const cx = (ev.clientX - rect.left); const cy = (ev.clientY - rect.top); // create a temporary mini-explosion by moving some particles for(let i=0;i<40 && i

@HA7A7
Copy link

HA7A7 commented Oct 30, 2025

Wow, thanks for taking the time to make a more readable version! This is very helpful. Great contribution!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment