UNPKG

@tsparticles/interaction-external-bounce

Version:

tsParticles bounce external interaction

209 lines (201 loc) 12.5 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); /* External Interaction v4.3.2 */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@tsparticles/plugin-interactivity'), require('@tsparticles/engine')) : typeof define === 'function' && define.amd ? define(['exports', '@tsparticles/plugin-interactivity', '@tsparticles/engine'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.__tsParticlesInternals = global.__tsParticlesInternals || {}, global.__tsParticlesInternals.interactions = global.__tsParticlesInternals.interactions || {}, global.__tsParticlesInternals.interactions.externalBounce = global.__tsParticlesInternals.interactions.externalBounce || {}), global.__tsParticlesInternals.plugins.interactivity, global.__tsParticlesInternals.engine)); })(this, (function (exports, pluginInteractivity, engine) { 'use strict'; const halfPI = Math.PI * engine.half, toleranceFactor = 10; function processBounce(container, position, radius, area, enabledCb) { const query = container.particles.grid.query(area, enabledCb); for (const particle of query) { if (area instanceof engine.Circle) { engine.circleBounce(engine.circleBounceDataFromParticle(particle), { position, radius, mass: radius ** engine.squareExp * halfPI, velocity: engine.Vector.origin, factor: engine.Vector.origin, }); } else if (area instanceof engine.Rectangle) { rectBounce(particle, engine.calculateBounds(position, radius)); } } } function singleSelectorBounce(container, selector, div, bounceCb) { const query = engine.safeDocument().querySelectorAll(selector); if (!query.length) { return; } query.forEach(item => { const elem = item, pxRatio = container.retina.pixelRatio, pos = { x: (elem.offsetLeft + elem.offsetWidth * engine.half) * pxRatio, y: (elem.offsetTop + elem.offsetHeight * engine.half) * pxRatio, }, radius = elem.offsetWidth * engine.half * pxRatio, tolerance = toleranceFactor * pxRatio, area = div.type === pluginInteractivity.DivType.circle ? new engine.Circle(pos.x, pos.y, radius + tolerance) : new engine.Rectangle(elem.offsetLeft * pxRatio - tolerance, elem.offsetTop * pxRatio - tolerance, elem.offsetWidth * pxRatio + tolerance * engine.double, elem.offsetHeight * pxRatio + tolerance * engine.double); bounceCb(pos, radius, area); }); } function divBounce(container, divs, bounceMode, enabledCb) { pluginInteractivity.divModeExecute(bounceMode, divs, (selector, div) => { singleSelectorBounce(container, selector, div, (pos, radius, area) => { processBounce(container, pos, radius, area, enabledCb); }); }); } function mouseBounce(container, interactivityData, enabledCb) { const pxRatio = container.retina.pixelRatio, tolerance = toleranceFactor * pxRatio, mousePos = interactivityData.mouse.position, radius = container.retina.bounceModeDistance; if (!radius || radius < engine.minRadius || !mousePos) { return; } processBounce(container, mousePos, radius, new engine.Circle(mousePos.x, mousePos.y, radius + tolerance), enabledCb); } function rectSideBounce(data) { const res = { bounced: false }, { pSide, pOtherSide, rectSide, rectOtherSide, velocity, factor } = data; if (pOtherSide.min < rectOtherSide.min || pOtherSide.min > rectOtherSide.max || pOtherSide.max < rectOtherSide.min || pOtherSide.max > rectOtherSide.max) { return res; } if ((pSide.max >= rectSide.min && pSide.max <= (rectSide.max + rectSide.min) * engine.half && velocity > engine.minVelocity) || (pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) * engine.half && velocity < engine.minVelocity)) { res.velocity = velocity * -factor; res.bounced = true; } return res; } function rectBounce(particle, divBounds) { const pPos = particle.getPosition(), size = particle.getRadius(), bounds = engine.calculateBounds(pPos, size), bounceOptions = particle.options.bounce, resH = rectSideBounce({ pSide: { min: bounds.left, max: bounds.right, }, pOtherSide: { min: bounds.top, max: bounds.bottom, }, rectSide: { min: divBounds.left, max: divBounds.right, }, rectOtherSide: { min: divBounds.top, max: divBounds.bottom, }, velocity: particle.velocity.x, factor: engine.getRangeValue(bounceOptions.horizontal.value), }); if (resH.bounced) { if (resH.velocity !== undefined) { particle.velocity.x = resH.velocity; } if (resH.position !== undefined) { particle.position.x = resH.position; } } const resV = rectSideBounce({ pSide: { min: bounds.top, max: bounds.bottom, }, pOtherSide: { min: bounds.left, max: bounds.right, }, rectSide: { min: divBounds.top, max: divBounds.bottom, }, rectOtherSide: { min: divBounds.left, max: divBounds.right, }, velocity: particle.velocity.y, factor: engine.getRangeValue(bounceOptions.vertical.value), }); if (resV.bounced) { if (resV.velocity !== undefined) { particle.velocity.y = resV.velocity; } if (resV.position !== undefined) { particle.position.y = resV.position; } } } class Bounce { distance = 200; load(data) { if (engine.isNull(data)) { return; } engine.loadProperty(this, "distance", data.distance); } } const bounceMode = "bounce"; class Bouncer extends pluginInteractivity.ExternalInteractorBase { #maxDistance; constructor(container) { super(container); this.#maxDistance = 0; } get maxDistance() { return this.#maxDistance; } clear() { } init() { const container = this.container, bounce = container.actualOptions.interactivity?.modes.bounce; if (!bounce) { return; } this.#maxDistance = bounce.distance; container.retina.bounceModeDistance = bounce.distance * container.retina.pixelRatio; } interact(interactivityData) { const container = this.container, options = container.actualOptions, events = options.interactivity?.events, mouseMoveStatus = interactivityData.status === pluginInteractivity.mouseMoveEvent; if (!events) { return; } const hoverEnabled = events.onHover.enable, hoverMode = events.onHover.mode, divs = events.onDiv; if (mouseMoveStatus && hoverEnabled && engine.isInArray(bounceMode, hoverMode)) { mouseBounce(this.container, interactivityData, p => this.isEnabled(interactivityData, p)); } else { divBounce(this.container, divs, bounceMode, p => this.isEnabled(interactivityData, p)); } } isEnabled(interactivityData, particle) { const container = this.container, options = container.actualOptions, mouse = interactivityData.mouse, events = (particle?.interactivity ?? options.interactivity)?.events; if (!events) { return false; } const divs = events.onDiv; return ((!!mouse.position && events.onHover.enable && engine.isInArray(bounceMode, events.onHover.mode)) || pluginInteractivity.isDivModeEnabled(bounceMode, divs)); } loadModeOptions(options, ...sources) { engine.loadOptionProperty(options, "bounce", Bounce, ...sources); } reset() { } } async function loadExternalBounceInteraction(engine) { engine.checkVersion("4.3.2"); await engine.pluginManager.register((e) => { pluginInteractivity.ensureInteractivityPluginLoaded(e); e.pluginManager.addInteractor?.("externalBounce", container => { return Promise.resolve(new Bouncer(container)); }); }); } const globalObject = globalThis; globalObject.__tsParticlesInternals = globalObject.__tsParticlesInternals ?? {}; globalObject.loadExternalBounceInteraction = loadExternalBounceInteraction; exports.Bounce = Bounce; exports.loadExternalBounceInteraction = loadExternalBounceInteraction; })); Object.assign(globalThis.window || globalThis, { loadExternalBounceInteraction: (globalThis.__tsParticlesInternals.interactions.externalBounce || {}).loadExternalBounceInteraction }); delete (globalThis.window || globalThis).tsparticlesInternalExports;