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
142 lines
3.6 KiB
JavaScript
2 years ago
|
|
||
|
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);
|
||
|
});
|
||
|
|