UNPKG

@tsparticles/updater-out-modes

Version:

tsParticles particles out modes updater

365 lines (354 loc) 21.6 kB
(function(g){g.__tsParticlesInternals=g.__tsParticlesInternals||{};g.__tsParticlesInternals.bundles=g.__tsParticlesInternals.bundles||{};g.__tsParticlesInternals.effects=g.__tsParticlesInternals.effects||{};g.__tsParticlesInternals.engine=g.__tsParticlesInternals.engine||{};g.__tsParticlesInternals.interactions=g.__tsParticlesInternals.interactions||{};g.__tsParticlesInternals.palettes=g.__tsParticlesInternals.palettes||{};g.__tsParticlesInternals.paths=g.__tsParticlesInternals.paths||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins=g.__tsParticlesInternals.plugins||{};g.__tsParticlesInternals.plugins.emittersShapes=g.__tsParticlesInternals.plugins.emittersShapes||{};g.__tsParticlesInternals.presets=g.__tsParticlesInternals.presets||{};g.__tsParticlesInternals.shapes=g.__tsParticlesInternals.shapes||{};g.__tsParticlesInternals.updaters=g.__tsParticlesInternals.updaters||{};g.__tsParticlesInternals.utils=g.__tsParticlesInternals.utils||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas=g.__tsParticlesInternals.canvas||{};g.__tsParticlesInternals.canvas.utils=g.__tsParticlesInternals.canvas.utils||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path=g.__tsParticlesInternals.path||{};g.__tsParticlesInternals.path.utils=g.__tsParticlesInternals.path.utils||{};var __tsProxyFactory=typeof Proxy!=="undefined"?function(obj){return new Proxy(obj,{get:function(target,key){if(!(key in target)){target[key]={};}return target[key];}});}:function(obj){return obj;};g.__tsParticlesInternals.bundles=__tsProxyFactory(g.__tsParticlesInternals.bundles);g.__tsParticlesInternals.effects=__tsProxyFactory(g.__tsParticlesInternals.effects);g.__tsParticlesInternals.interactions=__tsProxyFactory(g.__tsParticlesInternals.interactions);g.__tsParticlesInternals.palettes=__tsProxyFactory(g.__tsParticlesInternals.palettes);g.__tsParticlesInternals.paths=__tsProxyFactory(g.__tsParticlesInternals.paths);g.__tsParticlesInternals.plugins=__tsProxyFactory(g.__tsParticlesInternals.plugins);g.__tsParticlesInternals.plugins.emittersShapes=__tsProxyFactory(g.__tsParticlesInternals.plugins.emittersShapes);g.__tsParticlesInternals.presets=__tsProxyFactory(g.__tsParticlesInternals.presets);g.__tsParticlesInternals.shapes=__tsProxyFactory(g.__tsParticlesInternals.shapes);g.__tsParticlesInternals.updaters=__tsProxyFactory(g.__tsParticlesInternals.updaters);g.__tsParticlesInternals.utils=__tsProxyFactory(g.__tsParticlesInternals.utils);g.__tsParticlesInternals.canvas=__tsProxyFactory(g.__tsParticlesInternals.canvas);g.__tsParticlesInternals.path=__tsProxyFactory(g.__tsParticlesInternals.path);g.tsparticlesInternalExports=g.tsparticlesInternalExports||{};})(typeof globalThis!=="undefined"?globalThis:typeof window!=="undefined"?window:this); /* Updater v4.1.1 */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tsparticles/engine')) : typeof define === 'function' && define.amd ? define(['exports', '@tsparticles/engine'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.__tsParticlesInternals = global.__tsParticlesInternals || {}, global.__tsParticlesInternals.updaters = global.__tsParticlesInternals.updaters || {}, global.__tsParticlesInternals.updaters.outModes = global.__tsParticlesInternals.updaters.outModes || {}), global.__tsParticlesInternals.engine)); })(this, (function (exports, engine) { 'use strict'; const minVelocity$3 = 0, boundsMin = 0; function bounceHorizontal(data) { if ((data.outMode !== engine.OutMode.bounce && data.outMode !== engine.OutMode.split) || (data.direction !== engine.OutModeDirection.left && data.direction !== engine.OutModeDirection.right)) { return; } if (data.bounds.right < boundsMin && data.direction === engine.OutModeDirection.left) { data.particle.position.x = data.size + data.offset.x; } else if (data.bounds.left > data.canvasSize.width && data.direction === engine.OutModeDirection.right) { data.particle.position.x = data.canvasSize.width - data.size - data.offset.x; } const velocity = data.particle.velocity.x; let bounced = false; if (data.outOfCanvas && ((data.direction === engine.OutModeDirection.right && velocity > minVelocity$3) || (data.direction === engine.OutModeDirection.left && velocity < minVelocity$3))) { const newVelocity = engine.getRangeValue(data.particle.options.bounce.horizontal.value); data.particle.velocity.x *= -newVelocity; bounced = true; } if (!bounced) { return; } const minPos = data.offset.x + data.size; if (data.outOfCanvas && data.direction === engine.OutModeDirection.right) { data.particle.position.x = data.canvasSize.width - minPos; } else if (data.outOfCanvas && data.direction === engine.OutModeDirection.left) { data.particle.position.x = minPos; } if (data.outMode === engine.OutMode.split) { data.particle.destroy(); } } function bounceVertical(data) { if ((data.outMode !== engine.OutMode.bounce && data.outMode !== engine.OutMode.split) || (data.direction !== engine.OutModeDirection.bottom && data.direction !== engine.OutModeDirection.top)) { return; } if (data.bounds.bottom < boundsMin && data.direction === engine.OutModeDirection.top) { data.particle.position.y = data.size + data.offset.y; } else if (data.bounds.top > data.canvasSize.height && data.direction === engine.OutModeDirection.bottom) { data.particle.position.y = data.canvasSize.height - data.size - data.offset.y; } const velocity = data.particle.velocity.y; let bounced = false; if (data.outOfCanvas && ((data.direction === engine.OutModeDirection.bottom && velocity > minVelocity$3) || (data.direction === engine.OutModeDirection.top && velocity < minVelocity$3))) { const newVelocity = engine.getRangeValue(data.particle.options.bounce.vertical.value); data.particle.velocity.y *= -newVelocity; bounced = true; } if (!bounced) { return; } const minPos = data.offset.y + data.size; if (data.outOfCanvas && data.direction === engine.OutModeDirection.bottom) { data.particle.position.y = data.canvasSize.height - minPos; } else if (data.outOfCanvas && data.direction === engine.OutModeDirection.top) { data.particle.position.y = minPos; } if (data.outMode === engine.OutMode.split) { data.particle.destroy(); } } class BounceOutMode { modes; #container; #particleBouncePlugins; constructor(container) { this.#container = container; this.modes = [ engine.OutMode.bounce, engine.OutMode.split, ]; this.#particleBouncePlugins = container.plugins.filter(p => p.particleBounce !== undefined); } update(particle, direction, delta, outMode) { if (!this.modes.includes(outMode)) { return; } const container = this.#container; let handled = false; for (const plugin of this.#particleBouncePlugins) { handled = plugin.particleBounce?.(particle, delta, direction) ?? false; if (handled) { break; } } if (handled) { return; } const pos = particle.getPosition(), offset = particle.offset, size = particle.getRadius(), bounds = engine.calculateBounds(pos, size), canvasSize = container.canvas.size, outOfCanvas = !particle.isInsideCanvasForOutMode(outMode, direction); bounceHorizontal({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size }); bounceVertical({ particle, outMode, direction, bounds, canvasSize, offset, outOfCanvas, size }); } } const minVelocity$2 = 0; class DestroyOutMode { modes; constructor(_container) { this.modes = [engine.OutMode.destroy]; } update(particle, direction, _delta, outMode) { if (!this.modes.includes(outMode)) { return; } switch (particle.outType) { case engine.ParticleOutType.normal: case engine.ParticleOutType.outside: if (particle.isInsideCanvasForOutMode(outMode, direction)) { return; } break; case engine.ParticleOutType.inside: { const { dx, dy } = engine.getDistances(particle.position, particle.moveCenter), { x: vx, y: vy } = particle.velocity; if ((vx < minVelocity$2 && dx > particle.moveCenter.radius) || (vy < minVelocity$2 && dy > particle.moveCenter.radius) || (vx >= minVelocity$2 && dx < -particle.moveCenter.radius) || (vy >= minVelocity$2 && dy < -particle.moveCenter.radius)) { return; } break; } } particle.destroy(true); } } const minVelocity$1 = 0; class NoneOutMode { modes; #container; constructor(container) { this.#container = container; this.modes = [engine.OutMode.none]; } update(particle, direction, _delta, outMode) { if (!this.modes.includes(outMode)) { return; } if ((particle.options.move.distance.horizontal && (direction === engine.OutModeDirection.left || direction === engine.OutModeDirection.right)) ?? (particle.options.move.distance.vertical && (direction === engine.OutModeDirection.top || direction === engine.OutModeDirection.bottom))) { return; } const gravityOptions = particle.options.move.gravity, container = this.#container, canvasSize = container.canvas.size, pRadius = particle.getRadius(); if (!gravityOptions.enable) { if ((particle.velocity.y > minVelocity$1 && particle.position.y <= canvasSize.height + pRadius) || (particle.velocity.y < minVelocity$1 && particle.position.y >= -pRadius) || (particle.velocity.x > minVelocity$1 && particle.position.x <= canvasSize.width + pRadius) || (particle.velocity.x < minVelocity$1 && particle.position.x >= -pRadius)) { return; } if (!engine.isPointInside(particle.position, container.canvas.size, engine.originPoint, pRadius, direction)) { particle.destroy(); } } else { const position = particle.position; if ((!gravityOptions.inverse && position.y > canvasSize.height + pRadius && direction === engine.OutModeDirection.bottom) || (gravityOptions.inverse && position.y < -pRadius && direction === engine.OutModeDirection.top)) { particle.destroy(); } } } } const minVelocity = 0, minDistance = 0, updateVector = engine.Vector.origin; class OutOutMode { modes; #container; constructor(container) { this.#container = container; this.modes = [engine.OutMode.out]; } update(particle, direction, _delta, outMode) { if (!this.modes.includes(outMode)) { return; } const container = this.#container; switch (particle.outType) { case engine.ParticleOutType.inside: { const { x: vx, y: vy } = particle.velocity; updateVector.setTo(engine.originPoint); updateVector.length = particle.moveCenter.radius; updateVector.angle = particle.velocity.angle + Math.PI; updateVector.addTo(particle.moveCenter); const { dx, dy } = engine.getDistances(particle.position, updateVector); if ((vx <= minVelocity && dx >= minDistance) || (vy <= minVelocity && dy >= minDistance) || (vx >= minVelocity && dx <= minDistance) || (vy >= minVelocity && dy <= minDistance)) { return; } particle.position.x = Math.floor(engine.randomInRangeValue({ min: 0, max: container.canvas.size.width, })); particle.position.y = Math.floor(engine.randomInRangeValue({ min: 0, max: container.canvas.size.height, })); const { dx: newDx, dy: newDy } = engine.getDistances(particle.position, particle.moveCenter); particle.direction = Math.atan2(-newDy, -newDx); particle.velocity.angle = particle.direction; particle.justWarped = true; break; } default: { if (particle.isInsideCanvasForOutMode(outMode, direction)) { return; } switch (particle.outType) { case engine.ParticleOutType.outside: { particle.position.x = Math.floor(engine.randomInRangeValue({ min: -particle.moveCenter.radius, max: particle.moveCenter.radius, })) + particle.moveCenter.x; particle.position.y = Math.floor(engine.randomInRangeValue({ min: -particle.moveCenter.radius, max: particle.moveCenter.radius, })) + particle.moveCenter.y; const { dx, dy } = engine.getDistances(particle.position, particle.moveCenter); if (particle.moveCenter.radius) { particle.direction = Math.atan2(dy, dx); particle.velocity.angle = particle.direction; } particle.justWarped = true; break; } case engine.ParticleOutType.normal: { const warp = 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 = engine.calculateBounds(particle.position, sizeValue); if (direction === engine.OutModeDirection.right && nextBounds.left > canvasSize.width + particle.offset.x) { particle.position.x = newPos.left; particle.initialPosition.x = particle.position.x; if (!warp) { particle.position.y = engine.getRandom() * canvasSize.height; particle.initialPosition.y = particle.position.y; } particle.justWarped = true; } else if (direction === engine.OutModeDirection.left && nextBounds.right < -particle.offset.x) { particle.position.x = newPos.right; particle.initialPosition.x = particle.position.x; if (!warp) { particle.position.y = engine.getRandom() * canvasSize.height; particle.initialPosition.y = particle.position.y; } particle.justWarped = true; } if (direction === engine.OutModeDirection.bottom && nextBounds.top > canvasSize.height + particle.offset.y) { if (!warp) { particle.position.x = engine.getRandom() * canvasSize.width; particle.initialPosition.x = particle.position.x; } particle.position.y = newPos.top; particle.initialPosition.y = particle.position.y; particle.justWarped = true; } else if (direction === engine.OutModeDirection.top && nextBounds.bottom < -particle.offset.y) { if (!warp) { particle.position.x = engine.getRandom() * canvasSize.width; particle.initialPosition.x = particle.position.x; } particle.position.y = newPos.bottom; particle.initialPosition.y = particle.position.y; particle.justWarped = true; } break; } } break; } } } } const checkOutMode = (outModes, outMode) => { return (outModes.default === outMode || outModes.bottom === outMode || outModes.left === outMode || outModes.right === outMode || outModes.top === outMode); }; class OutOfCanvasUpdater { updaters; #container; constructor(container) { this.#container = container; this.updaters = new Map(); } init(particle) { this.#addUpdaterIfMissing(particle, engine.OutMode.bounce, container => new BounceOutMode(container)); this.#addUpdaterIfMissing(particle, engine.OutMode.out, container => new OutOutMode(container)); this.#addUpdaterIfMissing(particle, engine.OutMode.destroy, container => new DestroyOutMode(container)); this.#addUpdaterIfMissing(particle, engine.OutMode.none, container => new NoneOutMode(container)); } isEnabled(particle) { return !particle.destroyed && !particle.spawning; } update(particle, delta) { const outModes = particle.options.move.outModes; particle.justWarped = false; this.#updateOutMode(particle, delta, outModes.bottom ?? outModes.default, engine.OutModeDirection.bottom); this.#updateOutMode(particle, delta, outModes.left ?? outModes.default, engine.OutModeDirection.left); this.#updateOutMode(particle, delta, outModes.right ?? outModes.default, engine.OutModeDirection.right); this.#updateOutMode(particle, delta, outModes.top ?? outModes.default, engine.OutModeDirection.top); } #addUpdaterIfMissing = (particle, outMode, getUpdater) => { const outModes = particle.options.move.outModes; if (!this.updaters.has(outMode) && checkOutMode(outModes, outMode)) { this.updaters.set(outMode, getUpdater(this.#container)); } }; #updateOutMode = (particle, delta, outMode, direction) => { for (const updater of this.updaters.values()) { updater.update(particle, direction, delta, outMode); } }; } async function loadOutModesUpdater(engine) { engine.checkVersion("4.1.1"); await engine.pluginManager.register(e => { e.pluginManager.addParticleUpdater("outModes", container => { return Promise.resolve(new OutOfCanvasUpdater(container)); }); }); } const globalObject = globalThis; globalObject.__tsParticlesInternals = globalObject.__tsParticlesInternals ?? {}; globalObject.loadOutModesUpdater = loadOutModesUpdater; exports.loadOutModesUpdater = loadOutModesUpdater; })); Object.assign(globalThis.window || globalThis, { loadOutModesUpdater: (globalThis.__tsParticlesInternals.updaters.outModes || {}).loadOutModesUpdater }); delete (globalThis.window || globalThis).tsparticlesInternalExports;