bubbles: added

This commit is contained in:
Sheldan
2025-08-08 22:01:36 +02:00
parent eb7e98b384
commit 0de74e11a3
10 changed files with 1094 additions and 0 deletions

137
bubbles/src/js/main.js Normal file
View File

@@ -0,0 +1,137 @@
import {
createRainbowColors, docReady, pointDistance, randomInteger
} from "canvas-common";
var imageData = {};
var ctx = {};
var canvas = {};
var config = {
size: {
width: window.innerWidth,
height: window.innerHeight
},
buBbles: {
tileSize: 100,
growFactorDivider: 5,
radiusFactor: 1,
bubbleChance: 0.5
}
};
var rainbow = createRainbowColors(1/16);
// max distance from top left corner
var max = Math.sqrt(Math.pow(config.size.width + config.buBbles.tileSize, 2) + Math.pow(config.size.height + config.buBbles.tileSize, 2));
var startOffset = (rainbow.length * Math.random()) << 0;
function getRandomPoint(x, y) {
var distance = Math.sqrt(x * x + y * y);
var index = ((startOffset + distance / max * 100) << 0) % rainbow.length;
var color = rainbow[index];
color.a = 255;
return {
x: x + Math.random() * config.buBbles.tileSize,
y: y + Math.random() * config.buBbles.tileSize,
factor: Math.random() / config.buBbles.growFactorDivider,
radius: Math.random() * config.buBbles.radiusFactor,
color: color
};
}
function getTilePoints(){
var points = [];
for(var x = 0; x < config.size.width; x += config.buBbles.tileSize){
for(var y = 0; y < config.size.height; y += config.buBbles.tileSize){
points.push(getRandomPoint(x, y));
}
}
return points;
}
docReady(function () {
canvas = document.getElementById('canvas')
ctx = canvas.getContext("2d");
canvas.width = config.size.width;
canvas.height = config.size.height;
var pointsOfInterest = getTilePoints();
removeIntersecting(pointsOfInterest);
updateCanvas(pointsOfInterest);
});
function grow(points){
for(var i = 0; i < points.length; i++){
var currentPoint = points[i];
if(!intersectsAnotherPoint(currentPoint, points)){
currentPoint.radius += currentPoint.factor;
} else if(!currentPoint.spawnedAnother){
currentPoint.spawnedAnother = true;
currentPoint.radius += currentPoint.factor;
addAnotherRandomPoint(points);
}
}
if(Math.random() < config.buBbles.bubbleChance){
addAnotherRandomPoint(points);
}
}
function addAnotherRandomPoint(points){
var probablePoint = getRandomPoint(randomInteger(config.size.width), randomInteger(config.size.height));
if(!intersectsAnotherPoint(probablePoint, points)){
points.push(probablePoint);
}
}
function intersectsAnotherPoint(point, points){
var intersects = false;
points.forEach(function(pointToLookAt){
if(intersects) return;
var pointDist = pointDistance(point, pointToLookAt);
if(pointDist > 0 && pointDist < (point.radius + pointToLookAt.radius)){
intersects = true;
}
});
return intersects;
}
function updateCanvas(points){
ctx.clearRect(0, 0, config.size.width, config.size.height);
grow(points);
paintPoints(points, function(){
requestAnimationFrame(function(){
updateCanvas(points);
});
});
}
function removeIntersecting(points){
for(var i = 0; i < points.length; ){
if(intersectsAnotherPoint(points[i], points)){
points.splice(i, 1);
} else {
i++;
}
}
}
function paintPoints(points, cb){
for(var i = 0; i < points.length; i++){
var point = points[i];
if(point.radius < 0) continue;
ctx.beginPath();
ctx.fillStyle = point.color.styleRGB;
ctx.arc(point.x, point.y, point.radius, 0, 2 * Math.PI);
ctx.fill();
}
cb();
}

24
bubbles/src/js/plugins.js Normal file
View File

@@ -0,0 +1,24 @@
// Avoid `console` errors in browsers that lack a console.
(function() {
var method;
var noop = function () {};
var methods = [
'assert', 'clear', 'count', 'debug', 'dir', 'dirxml', 'error',
'exception', 'group', 'groupCollapsed', 'groupEnd', 'info', 'log',
'markTimeline', 'profile', 'profileEnd', 'table', 'time', 'timeEnd',
'timeline', 'timelineEnd', 'timeStamp', 'trace', 'warn'
];
var length = methods.length;
var console = (window.console = window.console || {});
while (length--) {
method = methods[length];
// Only stub undefined methods.
if (!console[method]) {
console[method] = noop;
}
}
}());
// Place any jQuery/helper plugins in here.