ES6
let canvas = document.getElementById("canvas");
let ctx = canvas.getContext('2d');
let context = ctx;
let width = 500;
let height = 500;
let bubblesNum = 200;
let magnetH = 5;
let centerX = width / 2;
let centerY = height / 2;
let bubbles = [];
let state;
canvas.width = width;
canvas.height = height;
function animate() {
window.requestAnimationFrame(animate);
render();
}
function init() {
for (let id = 0; id < bubblesNum; id++) {
let r = random(5, 25);
let x = id * 3 + random(-20, 50);
let y = height - random(0, 20);
let c = '#333745';
bubbles.push({
x,
y,
r,
c,
id
});
}
state = {
moved: {},
movedSize: 0,
movingIds: {},
moving: [],
falledSize: 0,
falledIds: {},
fallingIds: {},
falling: []
};
}
function render() {
ctx.clearRect(0, 0, width, height);
// draw scene
drawMagnet();
drawStaticBublbes();
moveBubblesUp();
moveBubblesDown();
if (state.falledSize === bubblesNum) {
state.fallingIds = {};
state.moved = {};
state.movedSize = 0;
state.movingIds = {};
state.moving = [];
state.falledSize = 0;
state.falledIds = {};
state.fallingIds = {};
state.falling = [];
}
}
function drawMagnet() {
ctx.beginPath();
ctx.rect(0, 0, width, magnetH);
ctx.fillStyle = '#FE5F55';
ctx.fill();
}
function drawStaticBublbes() {
for (let i = 0, l = bubbles.length; i < l; i++) {
let b = bubbles[i];
if (state.moved[b.id] && !state.fallingIds[b.id]) {
state.fallingIds[b.id] = true;
b.c = '#FE5F55';
state.falling.push(b);
}
circle(b);
}
}
function moveBubblesUp() {
function getB() {
let i = random(0, bubbles.length - 1);
return bubbles[i];
}
function move(b) {
if (!state.moved[b.id]) {
if (!(b.x <= 0 || b.x >= width)) {
b.x += random(-1, 1);
}
if (b.y <= b.r + magnetH) {
state.moved[b.id] = true;
state.movedSize += 1;
} else {
b.y -= 2;
}
}
}
for (let i = 0; i < state.moving.length; i++) {
move(state.moving[i]);
}
if (Date.now() % 2 === 0) {
let newB = getB();
if (!state.movingIds[newB.id]) {
state.moving.push(newB);
state.movingIds[newB.id] = true;
}
}
}
function moveBubblesDown() {
for (let i = 0; i < state.falling.length; i++) {
let b = state.falling[i];
if (!state.falledIds[b.id]) {
if (b.y >= height) {
b.c = '#333745';
state.falledSize += 1;
state.falledIds[b.id] = true;
} else {
b.y += 1;
}
}
}
}
init();
animate();
function circle(b) {
ctx.beginPath();
ctx.arc(b.x, b.y, b.r, 0, 2 * Math.PI, false);
ctx.fillStyle = b.c;
ctx.fill();
}
function random(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}