2023-02-17 11:06:01 +01:00

152 lines
6.8 KiB
JavaScript

import { Vector, calcPositionOrRandomFromSize, calcPositionOrRandomFromSizeRanged, getDistance, getDistances, getRandom, getRangeValue, getStyleFromRgb, isPointInside, rangeColorToRgb, } from "tsparticles-engine";
import { Absorber } from "./Options/Classes/Absorber";
export class AbsorberInstance {
constructor(absorbers, container, options, position) {
var _a, _b, _c;
this.absorbers = absorbers;
this.container = container;
this.initialPosition = position ? Vector.create(position.x, position.y) : undefined;
if (options instanceof Absorber) {
this.options = options;
}
else {
this.options = new Absorber();
this.options.load(options);
}
this.dragging = false;
this.name = this.options.name;
this.opacity = this.options.opacity;
this.size = getRangeValue(this.options.size.value) * container.retina.pixelRatio;
this.mass = this.size * this.options.size.density * container.retina.reduceFactor;
const limit = this.options.size.limit;
this.limit = {
radius: limit.radius * container.retina.pixelRatio * container.retina.reduceFactor,
mass: limit.mass,
};
this.color = (_a = rangeColorToRgb(this.options.color)) !== null && _a !== void 0 ? _a : {
b: 0,
g: 0,
r: 0,
};
this.position = (_c = (_b = this.initialPosition) === null || _b === void 0 ? void 0 : _b.copy()) !== null && _c !== void 0 ? _c : this.calcPosition();
}
attract(particle) {
const container = this.container, options = this.options;
if (options.draggable) {
const mouse = container.interactivity.mouse;
if (mouse.clicking && mouse.downPosition) {
const mouseDist = getDistance(this.position, mouse.downPosition);
if (mouseDist <= this.size) {
this.dragging = true;
}
}
else {
this.dragging = false;
}
if (this.dragging && mouse.position) {
this.position.x = mouse.position.x;
this.position.y = mouse.position.y;
}
}
const pos = particle.getPosition(), { dx, dy, distance } = getDistances(this.position, pos), v = Vector.create(dx, dy);
v.length = (this.mass / Math.pow(distance, 2)) * container.retina.reduceFactor;
if (distance < this.size + particle.getRadius()) {
const sizeFactor = particle.getRadius() * 0.033 * container.retina.pixelRatio;
if ((this.size > particle.getRadius() && distance < this.size - particle.getRadius()) ||
(particle.absorberOrbit !== undefined && particle.absorberOrbit.length < 0)) {
if (options.destroy) {
particle.destroy();
}
else {
particle.needsNewPosition = true;
this.updateParticlePosition(particle, v);
}
}
else {
if (options.destroy) {
particle.size.value -= sizeFactor;
}
this.updateParticlePosition(particle, v);
}
if (this.limit.radius <= 0 || this.size < this.limit.radius) {
this.size += sizeFactor;
}
if (this.limit.mass <= 0 || this.mass < this.limit.mass) {
this.mass += sizeFactor * this.options.size.density * container.retina.reduceFactor;
}
}
else {
this.updateParticlePosition(particle, v);
}
}
draw(context) {
context.translate(this.position.x, this.position.y);
context.beginPath();
context.arc(0, 0, this.size, 0, Math.PI * 2, false);
context.closePath();
context.fillStyle = getStyleFromRgb(this.color, this.opacity);
context.fill();
}
resize() {
const initialPosition = this.initialPosition;
this.position =
initialPosition && isPointInside(initialPosition, this.container.canvas.size, Vector.origin)
? initialPosition
: this.calcPosition();
}
calcPosition() {
const exactPosition = calcPositionOrRandomFromSizeRanged({
size: this.container.canvas.size,
position: this.options.position,
});
return Vector.create(exactPosition.x, exactPosition.y);
}
updateParticlePosition(particle, v) {
var _a;
if (particle.destroyed) {
return;
}
const container = this.container, canvasSize = container.canvas.size;
if (particle.needsNewPosition) {
const newPosition = calcPositionOrRandomFromSize({ size: canvasSize });
particle.position.setTo(newPosition);
particle.velocity.setTo(particle.initialVelocity);
particle.absorberOrbit = undefined;
particle.needsNewPosition = false;
}
if (this.options.orbits) {
if (particle.absorberOrbit === undefined) {
particle.absorberOrbit = Vector.create(0, 0);
particle.absorberOrbit.length = getDistance(particle.getPosition(), this.position);
particle.absorberOrbit.angle = getRandom() * Math.PI * 2;
}
if (particle.absorberOrbit.length <= this.size && !this.options.destroy) {
const minSize = Math.min(canvasSize.width, canvasSize.height);
particle.absorberOrbit.length = minSize * (1 + (getRandom() * 0.2 - 0.1));
}
if (particle.absorberOrbitDirection === undefined) {
particle.absorberOrbitDirection =
particle.velocity.x >= 0 ? "clockwise" : "counter-clockwise";
}
const orbitRadius = particle.absorberOrbit.length, orbitAngle = particle.absorberOrbit.angle, orbitDirection = particle.absorberOrbitDirection;
particle.velocity.setTo(Vector.origin);
const updateFunc = {
x: orbitDirection === "clockwise" ? Math.cos : Math.sin,
y: orbitDirection === "clockwise" ? Math.sin : Math.cos,
};
particle.position.x = this.position.x + orbitRadius * updateFunc.x(orbitAngle);
particle.position.y = this.position.y + orbitRadius * updateFunc.y(orbitAngle);
particle.absorberOrbit.length -= v.length;
particle.absorberOrbit.angle +=
((((_a = particle.retina.moveSpeed) !== null && _a !== void 0 ? _a : 0) * container.retina.pixelRatio) / 100) *
container.retina.reduceFactor;
}
else {
const addV = Vector.origin;
addV.length = v.length;
addV.angle = v.angle;
particle.velocity.addTo(addV);
}
}
}