(function (factory) { if (typeof module === "object" && typeof module.exports === "object") { var v = factory(require, exports); if (v !== undefined) module.exports = v; } else if (typeof define === "function" && define.amd) { define(["require", "exports", "tsparticles-engine", "./Options/Classes/Bubble"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Bubbler = void 0; const tsparticles_engine_1 = require("tsparticles-engine"); const Bubble_1 = require("./Options/Classes/Bubble"); function calculateBubbleValue(particleValue, modeValue, optionsValue, ratio) { if (modeValue >= optionsValue) { const value = particleValue + (modeValue - optionsValue) * ratio; return (0, tsparticles_engine_1.clamp)(value, particleValue, modeValue); } else if (modeValue < optionsValue) { const value = particleValue - (optionsValue - modeValue) * ratio; return (0, tsparticles_engine_1.clamp)(value, modeValue, particleValue); } } class Bubbler extends tsparticles_engine_1.ExternalInteractorBase { constructor(container) { super(container); if (!container.bubble) { container.bubble = {}; } this.handleClickMode = (mode) => { if (mode !== "bubble") { return; } if (!container.bubble) { container.bubble = {}; } container.bubble.clicking = true; }; } clear(particle, delta, force) { if (particle.bubble.inRange && !force) { return; } delete particle.bubble.div; delete particle.bubble.opacity; delete particle.bubble.radius; delete particle.bubble.color; } init() { const container = this.container, bubble = container.actualOptions.interactivity.modes.bubble; if (!bubble) { return; } container.retina.bubbleModeDistance = bubble.distance * container.retina.pixelRatio; if (bubble.size !== undefined) { container.retina.bubbleModeSize = bubble.size * container.retina.pixelRatio; } } async interact(delta) { const options = this.container.actualOptions, events = options.interactivity.events, onHover = events.onHover, onClick = events.onClick, hoverEnabled = onHover.enable, hoverMode = onHover.mode, clickEnabled = onClick.enable, clickMode = onClick.mode, divs = events.onDiv; if (hoverEnabled && (0, tsparticles_engine_1.isInArray)("bubble", hoverMode)) { this.hoverBubble(delta); } else if (clickEnabled && (0, tsparticles_engine_1.isInArray)("bubble", clickMode)) { this.clickBubble(delta); } else { (0, tsparticles_engine_1.divModeExecute)("bubble", divs, (selector, div) => this.singleSelectorHover(delta, selector, div)); } } isEnabled(particle) { var _a; const container = this.container, options = container.actualOptions, mouse = container.interactivity.mouse, events = ((_a = particle === null || particle === void 0 ? void 0 : particle.interactivity) !== null && _a !== void 0 ? _a : options.interactivity).events, divs = events.onDiv, divBubble = (0, tsparticles_engine_1.isDivModeEnabled)("bubble", divs); if (!(divBubble || (events.onHover.enable && mouse.position) || (events.onClick.enable && mouse.clickPosition))) { return false; } const hoverMode = events.onHover.mode; const clickMode = events.onClick.mode; return (0, tsparticles_engine_1.isInArray)("bubble", hoverMode) || (0, tsparticles_engine_1.isInArray)("bubble", clickMode) || divBubble; } loadModeOptions(options, ...sources) { if (!options.bubble) { options.bubble = new Bubble_1.Bubble(); } for (const source of sources) { options.bubble.load(source === null || source === void 0 ? void 0 : source.bubble); } } reset(particle) { particle.bubble.inRange = false; } clickBubble(delta) { var _a, _b; const container = this.container, options = container.actualOptions, mouseClickPos = container.interactivity.mouse.clickPosition, bubble = options.interactivity.modes.bubble; if (!bubble || !mouseClickPos) { return; } if (!container.bubble) { container.bubble = {}; } const distance = container.retina.bubbleModeDistance; if (!distance || distance < 0) { return; } const query = container.particles.quadTree.queryCircle(mouseClickPos, distance, (p) => this.isEnabled(p)); for (const particle of query) { if (!container.bubble.clicking) { continue; } particle.bubble.inRange = !container.bubble.durationEnd; const pos = particle.getPosition(), distMouse = (0, tsparticles_engine_1.getDistance)(pos, mouseClickPos), timeSpent = (new Date().getTime() - (container.interactivity.mouse.clickTime || 0)) / 1000; if (timeSpent > bubble.duration) { container.bubble.durationEnd = true; } if (timeSpent > bubble.duration * 2) { container.bubble.clicking = false; container.bubble.durationEnd = false; } const sizeData = { bubbleObj: { optValue: container.retina.bubbleModeSize, value: particle.bubble.radius, }, particlesObj: { optValue: (0, tsparticles_engine_1.getRangeMax)(particle.options.size.value) * container.retina.pixelRatio, value: particle.size.value, }, type: "size", }; this.process(particle, distMouse, timeSpent, sizeData); const opacityData = { bubbleObj: { optValue: bubble.opacity, value: particle.bubble.opacity, }, particlesObj: { optValue: (0, tsparticles_engine_1.getRangeMax)(particle.options.opacity.value), value: (_b = (_a = particle.opacity) === null || _a === void 0 ? void 0 : _a.value) !== null && _b !== void 0 ? _b : 1, }, type: "opacity", }; this.process(particle, distMouse, timeSpent, opacityData); if (!container.bubble.durationEnd) { if (distMouse <= distance) { this.hoverBubbleColor(particle, distMouse); } else { delete particle.bubble.color; } } else { delete particle.bubble.color; } } } hoverBubble(delta) { const container = this.container, mousePos = container.interactivity.mouse.position, distance = container.retina.bubbleModeDistance; if (!distance || distance < 0 || mousePos === undefined) { return; } const query = container.particles.quadTree.queryCircle(mousePos, distance, (p) => this.isEnabled(p)); for (const particle of query) { particle.bubble.inRange = true; const pos = particle.getPosition(), pointDistance = (0, tsparticles_engine_1.getDistance)(pos, mousePos), ratio = 1 - pointDistance / distance; if (pointDistance <= distance) { if (ratio >= 0 && container.interactivity.status === tsparticles_engine_1.mouseMoveEvent) { this.hoverBubbleSize(particle, ratio); this.hoverBubbleOpacity(particle, ratio); this.hoverBubbleColor(particle, ratio); } } else { this.reset(particle); } if (container.interactivity.status === tsparticles_engine_1.mouseLeaveEvent) { this.reset(particle); } } } hoverBubbleColor(particle, ratio, divBubble) { const options = this.container.actualOptions; const bubbleOptions = divBubble !== null && divBubble !== void 0 ? divBubble : options.interactivity.modes.bubble; if (!bubbleOptions) { return; } if (!particle.bubble.finalColor) { const modeColor = bubbleOptions.color; if (!modeColor) { return; } const bubbleColor = (0, tsparticles_engine_1.itemFromSingleOrMultiple)(modeColor); particle.bubble.finalColor = (0, tsparticles_engine_1.rangeColorToHsl)(bubbleColor); } if (!particle.bubble.finalColor) { return; } if (bubbleOptions.mix) { particle.bubble.color = undefined; const pColor = particle.getFillColor(); particle.bubble.color = pColor ? (0, tsparticles_engine_1.rgbToHsl)((0, tsparticles_engine_1.colorMix)(pColor, particle.bubble.finalColor, 1 - ratio, ratio)) : particle.bubble.finalColor; } else { particle.bubble.color = particle.bubble.finalColor; } } hoverBubbleOpacity(particle, ratio, divBubble) { var _a, _b, _c, _d; const container = this.container, options = container.actualOptions, modeOpacity = (_a = divBubble === null || divBubble === void 0 ? void 0 : divBubble.opacity) !== null && _a !== void 0 ? _a : (_b = options.interactivity.modes.bubble) === null || _b === void 0 ? void 0 : _b.opacity; if (!modeOpacity) { return; } const optOpacity = particle.options.opacity.value; const pOpacity = (_d = (_c = particle.opacity) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : 1; const opacity = calculateBubbleValue(pOpacity, modeOpacity, (0, tsparticles_engine_1.getRangeMax)(optOpacity), ratio); if (opacity !== undefined) { particle.bubble.opacity = opacity; } } hoverBubbleSize(particle, ratio, divBubble) { const container = this.container, modeSize = (divBubble === null || divBubble === void 0 ? void 0 : divBubble.size) ? divBubble.size * container.retina.pixelRatio : container.retina.bubbleModeSize; if (modeSize === undefined) { return; } const optSize = (0, tsparticles_engine_1.getRangeMax)(particle.options.size.value) * container.retina.pixelRatio; const pSize = particle.size.value; const size = calculateBubbleValue(pSize, modeSize, optSize, ratio); if (size !== undefined) { particle.bubble.radius = size; } } process(particle, distMouse, timeSpent, data) { const container = this.container, bubbleParam = data.bubbleObj.optValue, options = container.actualOptions, bubble = options.interactivity.modes.bubble; if (!bubble || bubbleParam === undefined) { return; } const bubbleDuration = bubble.duration, bubbleDistance = container.retina.bubbleModeDistance, particlesParam = data.particlesObj.optValue, pObjBubble = data.bubbleObj.value, pObj = data.particlesObj.value || 0, type = data.type; if (!bubbleDistance || bubbleDistance < 0 || bubbleParam === particlesParam) { return; } if (!container.bubble) { container.bubble = {}; } if (!container.bubble.durationEnd) { if (distMouse <= bubbleDistance) { const obj = pObjBubble !== null && pObjBubble !== void 0 ? pObjBubble : pObj; if (obj !== bubbleParam) { const value = pObj - (timeSpent * (pObj - bubbleParam)) / bubbleDuration; if (type === "size") { particle.bubble.radius = value; } if (type === "opacity") { particle.bubble.opacity = value; } } } else { if (type === "size") { delete particle.bubble.radius; } if (type === "opacity") { delete particle.bubble.opacity; } } } else if (pObjBubble) { if (type === "size") { delete particle.bubble.radius; } if (type === "opacity") { delete particle.bubble.opacity; } } } singleSelectorHover(delta, selector, div) { const container = this.container, selectors = document.querySelectorAll(selector), bubble = container.actualOptions.interactivity.modes.bubble; if (!bubble || !selectors.length) { return; } selectors.forEach((item) => { const elem = item, pxRatio = container.retina.pixelRatio, pos = { x: (elem.offsetLeft + elem.offsetWidth / 2) * pxRatio, y: (elem.offsetTop + elem.offsetHeight / 2) * pxRatio, }, repulseRadius = (elem.offsetWidth / 2) * pxRatio, area = div.type === "circle" ? new tsparticles_engine_1.Circle(pos.x, pos.y, repulseRadius) : new tsparticles_engine_1.Rectangle(elem.offsetLeft * pxRatio, elem.offsetTop * pxRatio, elem.offsetWidth * pxRatio, elem.offsetHeight * pxRatio), query = container.particles.quadTree.query(area, (p) => this.isEnabled(p)); for (const particle of query) { if (!area.contains(particle.getPosition())) { continue; } particle.bubble.inRange = true; const divs = bubble.divs; const divBubble = (0, tsparticles_engine_1.divMode)(divs, elem); if (!particle.bubble.div || particle.bubble.div !== elem) { this.clear(particle, delta, true); particle.bubble.div = elem; } this.hoverBubbleSize(particle, 1, divBubble); this.hoverBubbleOpacity(particle, 1, divBubble); this.hoverBubbleColor(particle, 1, divBubble); } }); } } exports.Bubbler = Bubbler; });