Created
April 27, 2022 20:05
-
-
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.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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> |
<!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
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
<!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>