tsparticles
Version:
Easily create highly customizable particle, confetti and fireworks animations and use them as animated backgrounds for your website. Ready to use components available also for React, Vue.js (2.x and 3.x), Angular, Svelte, jQuery, Preact, Riot.js, Inferno.
144 lines (143 loc) • 6.77 kB
JavaScript
import { bounceHorizontal, bounceVertical } from "./Utils";
import { calculateBounds, isPointInside } from "../../Utils";
export class OutOfCanvasUpdater {
constructor(container) {
this.container = container;
}
init() {
// nothing
}
isEnabled(particle) {
return !particle.destroyed && !particle.spawning;
}
update(particle, delta) {
var _a, _b, _c, _d;
const outModes = particle.options.move.outModes;
this.updateOutMode(particle, delta, (_a = outModes.bottom) !== null && _a !== void 0 ? _a : outModes.default, "bottom" /* bottom */);
this.updateOutMode(particle, delta, (_b = outModes.left) !== null && _b !== void 0 ? _b : outModes.default, "left" /* left */);
this.updateOutMode(particle, delta, (_c = outModes.right) !== null && _c !== void 0 ? _c : outModes.default, "right" /* right */);
this.updateOutMode(particle, delta, (_d = outModes.top) !== null && _d !== void 0 ? _d : outModes.default, "top" /* top */);
}
updateOutMode(particle, delta, outMode, direction) {
switch (outMode) {
case "bounce" /* bounce */:
case "bounce-vertical" /* bounceVertical */:
case "bounce-horizontal" /* bounceHorizontal */:
case "bounceVertical":
case "bounceHorizontal":
case "split" /* split */:
this.bounce(particle, delta, direction, outMode);
break;
case "destroy" /* destroy */:
this.destroy(particle, direction);
break;
case "out" /* out */:
this.out(particle, direction);
break;
case "none" /* none */:
default:
this.none(particle, direction);
break;
}
}
destroy(particle, direction) {
const container = this.container;
if (isPointInside(particle.position, container.canvas.size, particle.getRadius(), direction)) {
return;
}
container.particles.remove(particle, undefined, true);
}
out(particle, direction) {
const container = this.container;
if (isPointInside(particle.position, container.canvas.size, particle.getRadius(), direction)) {
return;
}
const wrap = particle.options.move.warp, canvasSize = container.canvas.size, newPos = {
bottom: canvasSize.height + particle.getRadius() + particle.offset.y,
left: -particle.getRadius() - particle.offset.x,
right: canvasSize.width + particle.getRadius() + particle.offset.x,
top: -particle.getRadius() - particle.offset.y,
}, sizeValue = particle.getRadius(), nextBounds = calculateBounds(particle.position, sizeValue);
if (direction === "right" /* right */ && nextBounds.left > canvasSize.width + particle.offset.x) {
particle.position.x = newPos.left;
particle.initialPosition.x = particle.position.x;
if (!wrap) {
particle.position.y = Math.random() * canvasSize.height;
particle.initialPosition.y = particle.position.y;
}
}
else if (direction === "left" /* left */ && nextBounds.right < -particle.offset.x) {
particle.position.x = newPos.right;
particle.initialPosition.x = particle.position.x;
if (!wrap) {
particle.position.y = Math.random() * canvasSize.height;
particle.initialPosition.y = particle.position.y;
}
}
if (direction === "bottom" /* bottom */ && nextBounds.top > canvasSize.height + particle.offset.y) {
if (!wrap) {
particle.position.x = Math.random() * canvasSize.width;
particle.initialPosition.x = particle.position.x;
}
particle.position.y = newPos.top;
particle.initialPosition.y = particle.position.y;
}
else if (direction === "top" /* top */ && nextBounds.bottom < -particle.offset.y) {
if (!wrap) {
particle.position.x = Math.random() * canvasSize.width;
particle.initialPosition.x = particle.position.x;
}
particle.position.y = newPos.bottom;
particle.initialPosition.y = particle.position.y;
}
}
bounce(particle, delta, direction, outMode) {
const container = this.container;
let handled = false;
for (const [, plugin] of container.plugins) {
if (plugin.particleBounce !== undefined) {
handled = plugin.particleBounce(particle, delta, direction);
}
if (handled) {
break;
}
}
if (handled) {
return;
}
const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = calculateBounds(pos, size), canvasSize = container.canvas.size;
bounceHorizontal({ particle, outMode, direction, bounds, canvasSize, offset, size });
bounceVertical({ particle, outMode, direction, bounds, canvasSize, offset, size });
}
none(particle, direction) {
if ((particle.options.move.distance.horizontal &&
(direction === "left" /* left */ || direction === "right" /* right */)) ||
(particle.options.move.distance.vertical &&
(direction === "top" /* top */ || direction === "bottom" /* bottom */))) {
return;
}
const gravityOptions = particle.options.move.gravity, container = this.container;
const canvasSize = container.canvas.size;
const pRadius = particle.getRadius();
if (!gravityOptions.enable) {
if ((particle.velocity.y > 0 && particle.position.y <= canvasSize.height + pRadius) ||
(particle.velocity.y < 0 && particle.position.y >= -pRadius) ||
(particle.velocity.x > 0 && particle.position.x <= canvasSize.width + pRadius) ||
(particle.velocity.x < 0 && particle.position.x >= -pRadius)) {
return;
}
if (!isPointInside(particle.position, container.canvas.size, pRadius, direction)) {
container.particles.remove(particle);
}
}
else {
const position = particle.position;
if ((!gravityOptions.inverse &&
position.y > canvasSize.height + pRadius &&
direction === "bottom" /* bottom */) ||
(gravityOptions.inverse && position.y < -pRadius && direction === "top" /* top */)) {
container.particles.remove(particle);
}
}
}
}