function randint (low, high) { return low + Math.floor(Math.random()*(high + 1 - low)); } function rand (low, high) { return low + Math.random()*(high - low); } function pick (elts) { let ri = randint(0, elts.length-1); // console.log("elts", ri, elts.length); return elts[ri]; } let bubble_size = 80; function nextFrame() { return new Promise( resolve => requestAnimationFrame(resolve) ); } function sleep (secs) { return new Promise( resolve => window.setTimeout(resolve, secs*1000)) } function rect_intersects (r1, r2) { return (r1.bottom > r2.top && r1.right > r2.left && r1.top < r2.bottom && r1.left < r2.right); } function inPage (elt) { let html = document.getElementsByTagName("html")[0]; let html_rect = html.getBoundingClientRect(); let elt_rect = elt.getBoundingClientRect(); return rect_intersects(html_rect, elt_rect); } function getPageRect () { let html = document.getElementsByTagName("html")[0]; return html.getBoundingClientRect(); } let bubble_border = 100; let audio_pops = document.querySelectorAll(".audio_pop"); let did_link = false; async function blow () { // console.log(""); let svg_template = document.querySelector("svg#bubble"); let svg = svg_template.cloneNode(true); svg.removeAttribute("id"); let div = document.createElement("div"); let anchor = document.createElement("a"); anchor.setAttribute("href", "https://worm.org/production/opening-experimental-publishing-graduation-show-shop-2023-making-things-bubblic-%f0%9f%ab%a7/"); anchor.setAttribute("target", "worm"); let pop = false; anchor.addEventListener("click", e => { pop = true; pick(audio_pops).play(); if (did_link) { e.preventDefault(); return; } did_link = true; }); div.appendChild(anchor); div.classList.add("bubble"); document.body.appendChild(div); anchor.appendChild(svg); const edge = (randint(0, 3) == 0); let x = 0; let y = 500; let page_rect = getPageRect(); let angle = 0; if (edge == 0) { y = bubble_border + (page_rect.height - bubble_size - bubble_border) * Math.random(); x = -bubble_size; angle = 0; angle = rand(-(Math.PI/4), Math.PI/4); } else if (edge == 2) { y = bubble_border + (page_rect.height - bubble_size - bubble_border) * Math.random(); x = page_right.width + bubble_border; angle = rand(Math.PI*0.75, Math.PI*1.25); // angle = -Math.PI; } else if (edge == 1) { // top x = 100 // x = bubble_border + (page_rect.width - bubble_size - bubble_border) * Math.random(); y = -bubble_size - bubble_border; angle = rand(Math.PI * 1.25, Math.PI * 1.75); } else { // bottom x = bubble_border + (page_rect.width - bubble_size - bubble_border) * Math.random(); y = bubble_size + page_rect.height + bubble_border; angle = rand(Math.PI * 0.25, Math.PI * 0.75); } let speed = rand(0.01, 2.5); let count = 0; let in_body = false; while (count < 10000) { div.style.left = `${x}px`; div.style.top = `${y}px`; x += speed * Math.cos(angle); y += speed * -Math.sin(angle); await nextFrame(); count += 1; let in_body_now = inPage(div); if (!in_body) { if (in_body_now) { in_body = true; } } else { if (!in_body_now) { break; } } if (pop) { break; } // console.log(`bubble loop ${count} x:${x}, xspeed: ${speed * Math.cos(angle)}`); } document.body.removeChild(div); //console.log(""); } async function blow_bubbles_periodically () { while (true) { blow(); let w = rand(1, 10); await sleep(w); } } // console.log("bubbles2"); window.addEventListener("DOMContentLoaded", e => { // console.log("DOMContentLoaded*"); window.setTimeout(blow_bubbles_periodically, 500); });