You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
3.6 KiB
JavaScript

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("<bubble>");
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("</bubble>");
}
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);
});