UNPKG

tsparticles

Version:

Porting of the abandoned Vincent Garreau's particles.js, converted in TypeScript. Added many new cool features and various bug fixes.

1,641 lines (1,361 loc) 152 kB
(function(e, a) { for(var i in a) e[i] = a[i]; }(window, /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { enumerable: true, get: getter }); /******/ } /******/ }; /******/ /******/ // define __esModule on exports /******/ __webpack_require__.r = function(exports) { /******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) { /******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' }); /******/ } /******/ Object.defineProperty(exports, '__esModule', { value: true }); /******/ }; /******/ /******/ // create a fake namespace object /******/ // mode & 1: value is a module id, require it /******/ // mode & 2: merge all properties of value into the ns /******/ // mode & 4: return value when already ns object /******/ // mode & 8|1: behave like require /******/ __webpack_require__.t = function(value, mode) { /******/ if(mode & 1) value = __webpack_require__(value); /******/ if(mode & 8) return value; /******/ if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value; /******/ var ns = Object.create(null); /******/ __webpack_require__.r(ns); /******/ Object.defineProperty(ns, 'default', { enumerable: true, value: value }); /******/ if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key)); /******/ return ns; /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; // ESM COMPAT FLAG __webpack_require__.r(__webpack_exports__); // EXPORTS __webpack_require__.d(__webpack_exports__, "tsParticles", function() { return /* binding */ tsParticles; }); // CONCATENATED MODULE: ./dist/Classes/Utils/Constants.js class Constants {} Constants.canvasClass = "tsparticles-canvas-el"; Constants.randomColorValue = "random"; Constants.touchEndEvent = "touchend"; Constants.mouseUpEvent = "mouseup"; Constants.mouseMoveEvent = "mousemove"; Constants.touchStartEvent = "touchstart"; Constants.touchMoveEvent = "touchmove"; Constants.mouseLeaveEvent = "mouseleave"; Constants.touchCancelEvent = "touchcancel"; Constants.resizeEvent = "resize"; Constants.visibilityChangeEvent = "visibilitychange"; // CONCATENATED MODULE: ./dist/Enums/MoveDirection.js var MoveDirection; (function (MoveDirection) { MoveDirection["bottom"] = "bottom"; MoveDirection["bottomLeft"] = "bottom-left"; MoveDirection["bottomRight"] = "bottom-right"; MoveDirection["left"] = "left"; MoveDirection["none"] = "none"; MoveDirection["right"] = "right"; MoveDirection["top"] = "top"; MoveDirection["topLeft"] = "top-left"; MoveDirection["topRight"] = "top-right"; })(MoveDirection || (MoveDirection = {})); // CONCATENATED MODULE: ./dist/Classes/Utils/Utils.js var __awaiter = undefined && undefined.__awaiter || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; class Utils_Utils { static clamp(num, min, max) { return Math.min(Math.max(num, min), max); } static isInArray(value, array) { return value === array || array.indexOf(value) > -1; } static mix(comp1, comp2, weight1, weight2) { return (comp1 * weight1 + comp2 * weight2) / (weight1 + weight2); } static getParticleBaseVelocity(options) { let velocityBase; switch (options.particles.move.direction) { case MoveDirection.top: velocityBase = { x: 0, y: -1 }; break; case MoveDirection.topRight: velocityBase = { x: 0.5, y: -0.5 }; break; case MoveDirection.right: velocityBase = { x: 1, y: -0 }; break; case MoveDirection.bottomRight: velocityBase = { x: 0.5, y: 0.5 }; break; case MoveDirection.bottom: velocityBase = { x: 0, y: 1 }; break; case MoveDirection.bottomLeft: velocityBase = { x: -0.5, y: 1 }; break; case MoveDirection.left: velocityBase = { x: -1, y: 0 }; break; case MoveDirection.topLeft: velocityBase = { x: -0.5, y: -0.5 }; break; default: velocityBase = { x: 0, y: 0 }; break; } return velocityBase; } static getDistanceBetweenCoordinates(pointA, pointB) { const dx = pointA.x - pointB.x; const dy = pointA.y - pointB.y; return Math.sqrt(dx * dx + dy * dy); } static loadFont(character) { return __awaiter(this, void 0, void 0, function* () { try { yield document.fonts.load(`${character.weight} 36px '${character.font}'`); } catch (_a) {} }); } static arrayRandomIndex(array) { return Math.floor(Math.random() * array.length); } static itemFromArray(array, index) { return array[index !== undefined ? index : this.arrayRandomIndex(array)]; } static randomInRange(min, max) { return Math.random() * (max - min) + min; } static isPointInside(point, size, radius) { return this.areBoundsInside(this.calculateBounds(point, radius !== null && radius !== void 0 ? radius : 0), size); } static areBoundsInside(bounds, size) { return bounds.left < size.width && bounds.right > 0 && bounds.top < size.height && bounds.bottom > 0; } static calculateBounds(point, radius) { return { bottom: point.y + radius, left: point.x - radius, right: point.x + radius, top: point.y - radius }; } } // CONCATENATED MODULE: ./dist/Classes/Utils/ShapeUtils.js class ShapeUtils { static addShapeDrawer(type, drawer) { if (!this.drawers[type]) { this.drawers[type] = drawer; } } static drawShape(context, particle, radius, opacity) { if (!particle.shape) { return; } const drawer = this.drawers[particle.shape]; if (!drawer) { return; } drawer.draw(context, particle, radius, opacity); } } ShapeUtils.drawers = {}; // CONCATENATED MODULE: ./dist/Classes/Utils/ColorUtils.js class ColorUtils_ColorUtils { static colorToRgb(color) { let res; if (typeof color.value === "string") { if (color.value === Constants.randomColorValue) { res = { b: Math.floor(Math.random() * 256), g: Math.floor(Math.random() * 256), r: Math.floor(Math.random() * 256) }; } else { res = ColorUtils_ColorUtils.stringToRgb(color.value); } } else { if (color.value instanceof Array) { const colorSelected = Utils_Utils.itemFromArray(color.value); res = ColorUtils_ColorUtils.stringToRgb(colorSelected); } else { const rgbColor = color.value; if (rgbColor.r !== undefined) { res = rgbColor; } const hslColor = color.value; if (hslColor.h !== undefined) { res = ColorUtils_ColorUtils.hslToRgb(hslColor); } } } return res; } static stringToAlpha(input) { var _a; return (_a = ColorUtils_ColorUtils.stringToRgba(input)) === null || _a === void 0 ? void 0 : _a.a; } static stringToRgb(input) { return ColorUtils_ColorUtils.stringToRgba(input); } static hslToRgb(hsl) { const result = { b: 0, g: 0, r: 0 }; if (hsl.s === 0) { result.b = hsl.l; result.g = hsl.l; result.r = hsl.l; } else { const q = hsl.l < 0.5 ? hsl.l * (1 + hsl.s) : hsl.l + hsl.s - hsl.l * hsl.s; const p = 2 * hsl.l - q; result.r = ColorUtils_ColorUtils.hue2rgb(p, q, hsl.h + 1 / 3); result.g = ColorUtils_ColorUtils.hue2rgb(p, q, hsl.h); result.b = ColorUtils_ColorUtils.hue2rgb(p, q, hsl.h - 1 / 3); } result.r = Math.round(result.r * 255); result.g = Math.round(result.g * 255); result.b = Math.round(result.b * 255); return result; } static hslaToRgba(hsla) { const rgbResult = ColorUtils_ColorUtils.hslToRgb(hsla); return { a: hsla.a, b: rgbResult.b, g: rgbResult.g, r: rgbResult.r }; } static getRandomRgbColor(min) { var _a; const fixedMin = min || 0; const minColor = fixedMin + fixedMin * Math.pow(16, 2) + fixedMin * Math.pow(16, 4); const maxColor = minColor ^ 0xFFFFFF; const randomColor = (Math.random() * maxColor + minColor).toString(16); return (_a = this.stringToRgb(`#${randomColor}`)) !== null && _a !== void 0 ? _a : { b: 0, g: 0, r: 0 }; } static getStyleFromColor(color, opacity) { const opacityValue = opacity !== null && opacity !== void 0 ? opacity : 1; return `rgba(${Math.round(color.r)}, ${Math.round(color.g)}, ${Math.round(color.b)}, ${opacityValue})`; } static hue2rgb(p, q, t) { let tCalc = t; if (tCalc < 0) { tCalc += 1; } if (tCalc > 1) { tCalc -= 1; } if (tCalc < 1 / 6) { return p + (q - p) * 6 * tCalc; } if (tCalc < 1 / 2) { return q; } if (tCalc < 2 / 3) { return p + (q - p) * (2 / 3 - tCalc) * 6; } return p; } static stringToRgba(input) { if (input.startsWith('rgb')) { const regex = /rgba?\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(,\s*([\d\.]+)\s*)?\)/i; const result = regex.exec(input); return result ? { a: result.length > 4 ? parseFloat(result[5]) : 1, b: parseInt(result[3]), g: parseInt(result[2]), r: parseInt(result[1]) } : undefined; } else if (input.startsWith('hsl')) { const regex = /hsla?\(\s*(\d+)\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(,\s*([\d\.]+)\s*)?\)/i; const result = regex.exec(input); return result ? ColorUtils_ColorUtils.hslaToRgba({ a: result.length > 4 ? parseFloat(result[5]) : 1, h: parseInt(result[1]), l: parseInt(result[3]), s: parseInt(result[2]) }) : undefined; } else { const shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])([a-f\d])?$/i; const hexFixed = input.replace(shorthandRegex, (_m, r, g, b, a) => { return r + r + g + g + b + b + (a ? a + a : ""); }); const regex = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i; const result = regex.exec(hexFixed); return result ? { a: parseInt(result[4], 16) / 0xFF, b: parseInt(result[3], 16), g: parseInt(result[2], 16), r: parseInt(result[1], 16) } : undefined; } } } // CONCATENATED MODULE: ./dist/Classes/Utils/CanvasUtils.js class CanvasUtils_CanvasUtils { static paintBase(context, dimension, baseColor) { context.save(); context.fillStyle = baseColor !== null && baseColor !== void 0 ? baseColor : "rgba(0,0,0,0)"; context.fillRect(0, 0, dimension.width, dimension.height); context.restore(); } static clear(context, dimension) { context.clearRect(0, 0, dimension.width, dimension.height); } static drawPolygonMask(context, rawData, stroke) { const color = typeof stroke.color === "string" ? ColorUtils_ColorUtils.stringToRgb(stroke.color) : ColorUtils_ColorUtils.colorToRgb(stroke.color); if (color) { context.save(); context.beginPath(); context.moveTo(rawData[0].x, rawData[0].y); for (let i = 1; i < rawData.length; i++) { context.lineTo(rawData[i].x, rawData[i].y); } context.closePath(); context.strokeStyle = ColorUtils_ColorUtils.getStyleFromColor(color); context.lineWidth = stroke.width; context.stroke(); context.restore(); } } static drawPolygonMaskPath(context, path, stroke, position) { context.save(); context.translate(position.x, position.y); const color = typeof stroke.color === "string" ? ColorUtils_ColorUtils.stringToRgb(stroke.color) : ColorUtils_ColorUtils.colorToRgb(stroke.color); if (color) { context.strokeStyle = ColorUtils_ColorUtils.getStyleFromColor(color, stroke.opacity); context.lineWidth = stroke.width; context.stroke(path); } context.restore(); } static drawLineLinked(context, width, begin, end, backgroundMask, colorLine, opacity, shadow) { context.save(); if (backgroundMask) { context.globalCompositeOperation = 'destination-out'; } if (colorLine) { context.strokeStyle = ColorUtils_ColorUtils.getStyleFromColor(colorLine, opacity); ; } context.lineWidth = width; context.beginPath(); const color = typeof shadow.color === "string" ? ColorUtils_ColorUtils.stringToRgb(shadow.color) : ColorUtils_ColorUtils.colorToRgb(shadow.color); if (shadow.enable && color) { context.shadowBlur = shadow.blur; context.shadowColor = ColorUtils_ColorUtils.getStyleFromColor(color); } context.moveTo(begin.x, begin.y); context.lineTo(end.x, end.y); context.stroke(); context.closePath(); context.restore(); } static drawConnectLine(context, width, lineStyle, begin, end) { context.save(); context.beginPath(); context.lineWidth = width; context.strokeStyle = lineStyle; context.moveTo(begin.x, begin.y); context.lineTo(end.x, end.y); context.stroke(); context.closePath(); context.restore(); } static gradient(context, p1, p2, midColor, opacity) { const gradStop = Math.floor(p2.radius / p1.radius); if (!p1.color || !p2.color) { return; } const sourcePos = p1.position; const destPos = p2.position; const grad = context.createLinearGradient(sourcePos.x, sourcePos.y, destPos.x, destPos.y); grad.addColorStop(0, ColorUtils_ColorUtils.getStyleFromColor(p1.color, opacity)); grad.addColorStop(gradStop > 1 ? 1 : gradStop, ColorUtils_ColorUtils.getStyleFromColor(midColor, opacity)); grad.addColorStop(1, ColorUtils_ColorUtils.getStyleFromColor(p2.color, opacity)); return grad; } static drawGrabLine(context, width, begin, end, colorLine, opacity) { context.save(); context.strokeStyle = ColorUtils_ColorUtils.getStyleFromColor(colorLine, opacity); context.lineWidth = width; context.beginPath(); context.moveTo(begin.x, begin.y); context.lineTo(end.x, end.y); context.stroke(); context.closePath(); context.restore(); } static drawParticle(context, particle, colorValue, backgroundMask, radius, opacity) { context.save(); const shadow = particle.container.options.particles.shadow; const shadowColor = particle.shadowColor; if (shadow.enable && shadowColor) { context.shadowBlur = shadow.blur; context.shadowColor = ColorUtils_ColorUtils.getStyleFromColor(shadowColor); context.shadowOffsetX = shadow.offset.x; context.shadowOffsetY = shadow.offset.y; } context.fillStyle = colorValue; const pos = { x: particle.position.x + particle.offset.x, y: particle.position.y + particle.offset.y }; context.translate(pos.x, pos.y); context.beginPath(); if (particle.angle !== 0) { context.rotate(particle.angle * Math.PI / 180); } if (backgroundMask) { context.globalCompositeOperation = "destination-out"; } const stroke = particle.stroke; if (stroke.width > 0 && particle.strokeColor) { context.strokeStyle = ColorUtils_ColorUtils.getStyleFromColor(particle.strokeColor, particle.stroke.opacity); context.lineWidth = stroke.width; } ShapeUtils.drawShape(context, particle, radius, opacity); if (particle.close) { context.closePath(); } if (stroke.width > 0 && particle.strokeColor) { context.stroke(); } if (particle.fill) { context.fill(); } context.restore(); } } // CONCATENATED MODULE: ./dist/Classes/Canvas.js class Canvas_Canvas { constructor(container) { this.container = container; this.dimension = { height: 0, width: 0 }; this.context = null; this.generatedCanvas = false; } init() { this.size(); const container = this.container; const options = container.options; const cover = options.backgroundMask.cover; const trail = options.particles.move.trail; this.coverColor = ColorUtils_ColorUtils.colorToRgb(cover.color !== undefined ? cover.color : options.backgroundMask.cover); this.trailFillColor = typeof trail.fillColor === "string" ? ColorUtils_ColorUtils.stringToRgb(trail.fillColor) : ColorUtils_ColorUtils.colorToRgb(trail.fillColor); this.paint(); } loadCanvas(canvas, generatedCanvas) { var _a; if (!canvas.className) { canvas.className = Constants.canvasClass; } if (this.generatedCanvas) { (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove(); } this.generatedCanvas = generatedCanvas !== null && generatedCanvas !== void 0 ? generatedCanvas : false; this.element = canvas; this.dimension.height = canvas.offsetHeight; this.dimension.width = canvas.offsetWidth; this.context = this.element.getContext("2d"); this.container.retina.init(); this.initBackground(); } destroy() { var _a; if (this.generatedCanvas) { (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove(); } if (this.context) { CanvasUtils_CanvasUtils.clear(this.context, this.dimension); } } size() { if (this.element) { this.element.width = this.dimension.width; this.element.height = this.dimension.height; } } paint() { const container = this.container; const options = container.options; if (this.context) { if (options.backgroundMask.enable && options.backgroundMask.cover) { if (this.coverColor) { this.paintBase(ColorUtils_ColorUtils.getStyleFromColor(this.coverColor)); } else { this.paintBase(); } } else { this.paintBase(); } } } clear() { const container = this.container; const options = container.options; const trail = options.particles.move.trail; if (options.backgroundMask.enable) { this.paint(); } else if (trail.enable && trail.length > 0 && this.trailFillColor) { this.paintBase(ColorUtils_ColorUtils.getStyleFromColor(this.trailFillColor, 1 / trail.length)); } else if (this.context) { CanvasUtils_CanvasUtils.clear(this.context, this.dimension); } } isPointInPath(path, point) { var _a, _b; return (_b = (_a = this.context) === null || _a === void 0 ? void 0 : _a.isPointInPath(path, point.x, point.y)) !== null && _b !== void 0 ? _b : false; } drawPolygonMask() { const container = this.container; const options = container.options; const context = this.context; const polygonDraw = options.polygon.draw; const polygon = container.polygon; const rawData = polygon.raw; const path = polygon.polygonPath; const path2dSupported = polygon.path2DSupported; if (context) { if (path2dSupported && path && polygon.offset) { CanvasUtils_CanvasUtils.drawPolygonMaskPath(context, path, polygonDraw.stroke, polygon.offset); } else if (rawData) { CanvasUtils_CanvasUtils.drawPolygonMask(context, rawData, polygonDraw.stroke); } } } drawLinkedLine(p1, p2, pos1, pos2, opacity) { const container = this.container; const options = container.options; const ctx = this.context; if (!ctx) { return; } let colorLine; if (container.particles.lineLinkedColor === Constants.randomColorValue) { colorLine = ColorUtils_ColorUtils.getRandomRgbColor(); } else if (container.particles.lineLinkedColor == "mid" && p1.color && p2.color) { const sourceColor = p1.color; const destColor = p2.color; colorLine = { b: Math.floor(Utils_Utils.mix(sourceColor.b, destColor.b, p1.radius, p2.radius)), g: Math.floor(Utils_Utils.mix(sourceColor.g, destColor.g, p1.radius, p2.radius)), r: Math.floor(Utils_Utils.mix(sourceColor.r, destColor.r, p1.radius, p2.radius)) }; } else { colorLine = container.particles.lineLinkedColor; } const width = container.retina.lineLinkedWidth; CanvasUtils_CanvasUtils.drawLineLinked(ctx, width, pos1, pos2, options.backgroundMask.enable, colorLine, opacity, options.particles.lineLinked.shadow); } drawConnectLine(p1, p2) { const lineStyle = this.lineStyle(p1, p2); if (!lineStyle) { return; } const ctx = this.context; if (!ctx) { return; } CanvasUtils_CanvasUtils.drawConnectLine(ctx, this.container.retina.lineLinkedWidth, lineStyle, p1.position, p2.position); } drawGrabLine(particle, opacity, mousePos) { const container = this.container; const options = container.options; const optColor = options.particles.lineLinked.color; let lineColor = container.particles.lineLinkedColor || (typeof optColor === "string" ? ColorUtils_ColorUtils.stringToRgb(optColor) : ColorUtils_ColorUtils.colorToRgb(optColor)); if (lineColor == Constants.randomColorValue) { lineColor = ColorUtils_ColorUtils.getRandomRgbColor(); } container.particles.lineLinkedColor = lineColor; let colorLine = { r: 127, g: 127, b: 127 }; const ctx = container.canvas.context; if (!ctx) { return; } if (container.particles.lineLinkedColor == Constants.randomColorValue) { colorLine = ColorUtils_ColorUtils.getRandomRgbColor() || colorLine; } else { colorLine = container.particles.lineLinkedColor || colorLine; } const beginPos = { x: particle.position.x + particle.offset.x, y: particle.position.y + particle.offset.y }; CanvasUtils_CanvasUtils.drawGrabLine(ctx, container.retina.lineLinkedWidth, beginPos, mousePos, colorLine, opacity); } drawParticle(particle) { const container = this.container; const options = container.options; let colorValue; const radius = particle.bubbler.radius !== undefined ? particle.bubbler.radius : particle.radius; const opacity = particle.bubbler.opacity !== undefined ? particle.bubbler.opacity : particle.opacity.value; if (particle.color) { colorValue = ColorUtils_ColorUtils.getStyleFromColor(particle.color, opacity); } if (!this.context || !colorValue) { return; } CanvasUtils_CanvasUtils.drawParticle(this.context, particle, colorValue, options.backgroundMask.enable, radius, opacity); } paintBase(baseColor) { if (this.context) { CanvasUtils_CanvasUtils.paintBase(this.context, this.dimension, baseColor); } } lineStyle(p1, p2) { const container = this.container; const options = container.options; const connectOptions = options.interactivity.modes.connect; if (p1.color && p2.color) { const sourceRgb = p1.color; const destRgb = p2.color; const midRgb = { b: Utils_Utils.mix(sourceRgb.b, destRgb.b, p1.radius, p2.radius), g: Utils_Utils.mix(sourceRgb.g, destRgb.g, p1.radius, p2.radius), r: Utils_Utils.mix(sourceRgb.r, destRgb.r, p1.radius, p2.radius) }; if (this.context) { return CanvasUtils_CanvasUtils.gradient(this.context, p1, p2, midRgb, connectOptions.lineLinked.opacity); } } } initBackground() { const container = this.container; const options = container.options; const background = options.background; const element = this.element; if (!element) { return; } const elementStyle = element.style; if (background.color) { const color = typeof background.color === "string" ? ColorUtils_ColorUtils.stringToRgb(background.color) : ColorUtils_ColorUtils.colorToRgb(background.color); if (color) { elementStyle.backgroundColor = ColorUtils_ColorUtils.getStyleFromColor(color, background.opacity); } } if (background.image) { elementStyle.backgroundImage = background.image; } if (background.position) { elementStyle.backgroundPosition = background.position; } if (background.repeat) { elementStyle.backgroundRepeat = background.repeat; } if (background.size) { elementStyle.backgroundSize = background.size; } } } // CONCATENATED MODULE: ./dist/Enums/Modes/ClickMode.js var ClickMode; (function (ClickMode) { ClickMode["bubble"] = "bubble"; ClickMode["push"] = "push"; ClickMode["remove"] = "remove"; ClickMode["repulse"] = "repulse"; })(ClickMode || (ClickMode = {})); // CONCATENATED MODULE: ./dist/Enums/InteractivityDetect.js var InteractivityDetect; (function (InteractivityDetect) { InteractivityDetect["canvas"] = "canvas"; InteractivityDetect["parent"] = "parent"; InteractivityDetect["window"] = "window"; })(InteractivityDetect || (InteractivityDetect = {})); // CONCATENATED MODULE: ./dist/Enums/PolygonMaskType.js var PolygonMaskType; (function (PolygonMaskType) { PolygonMaskType["inline"] = "inline"; PolygonMaskType["inside"] = "inside"; PolygonMaskType["outside"] = "outside"; PolygonMaskType["none"] = "none"; })(PolygonMaskType || (PolygonMaskType = {})); // CONCATENATED MODULE: ./dist/Classes/Utils/EventListeners.js class EventListeners_EventListeners { constructor(container) { this.container = container; this.canPush = true; this.mouseMoveHandler = e => this.mouseTouchMove(e); this.touchStartHandler = e => this.mouseTouchMove(e); this.touchMoveHandler = e => this.mouseTouchMove(e); this.touchEndHandler = () => this.mouseTouchFinish(); this.mouseLeaveHandler = () => this.mouseTouchFinish(); this.touchCancelHandler = () => this.mouseTouchFinish(); this.touchEndClickHandler = e => this.mouseTouchClick(e); this.mouseUpHandler = e => this.mouseTouchClick(e); this.visibilityChangeHandler = () => this.handleVisibilityChange(); this.resizeHandler = () => this.handleWindowResize(); } addListeners() { this.manageListeners(true); } removeListeners() { this.manageListeners(false); } manageListeners(add) { const container = this.container; const options = container.options; if (options.interactivity.detectsOn === InteractivityDetect.window) { container.interactivity.element = window; } else if (options.interactivity.detectsOn === InteractivityDetect.parent && container.canvas.element) { container.interactivity.element = container.canvas.element.parentNode; } else { container.interactivity.element = container.canvas.element; } const interactivityEl = container.interactivity.element; if (interactivityEl && (options.interactivity.events.onHover.enable || options.interactivity.events.onClick.enable)) { this.manageListener(interactivityEl, Constants.mouseMoveEvent, this.mouseMoveHandler, add); this.manageListener(interactivityEl, Constants.touchStartEvent, this.touchStartHandler, add); this.manageListener(interactivityEl, Constants.touchMoveEvent, this.touchMoveHandler, add); if (!options.interactivity.events.onClick.enable) { this.manageListener(interactivityEl, Constants.touchEndEvent, this.touchEndHandler, add); } this.manageListener(interactivityEl, Constants.mouseLeaveEvent, this.mouseLeaveHandler, add); this.manageListener(interactivityEl, Constants.touchCancelEvent, this.touchCancelHandler, add); } if (options.interactivity.events.onClick.enable && interactivityEl) { this.manageListener(interactivityEl, Constants.touchEndEvent, this.touchEndClickHandler, add); this.manageListener(interactivityEl, Constants.mouseUpEvent, this.mouseUpHandler, add); } if (options.interactivity.events.resize) { this.manageListener(window, Constants.resizeEvent, this.resizeHandler, add); } if (document) { this.manageListener(document, Constants.visibilityChangeEvent, this.visibilityChangeHandler, add, false); } } manageListener(element, event, handler, add, options) { if (add) { this.addListener(element, event, handler, options); } else { this.removeListener(element, event, handler, options); } } addListener(element, event, handler, options) { element.addEventListener(event, handler, options); } removeListener(element, event, handler, options) { element.removeEventListener(event, handler, options); } handleWindowResize() { const container = this.container; const options = container.options; if (!container.canvas.element) { return; } container.canvas.dimension.width = container.canvas.element.offsetWidth; container.canvas.dimension.height = container.canvas.element.offsetHeight; if (container.retina.isRetina) { container.canvas.dimension.width *= container.retina.pxRatio; container.canvas.dimension.height *= container.retina.pxRatio; } container.canvas.element.width = container.canvas.dimension.width; container.canvas.element.height = container.canvas.dimension.height; if (!options.particles.move.enable) { container.particles.redraw(); } container.densityAutoParticles(); container.polygon.redraw(); } handleVisibilityChange() { const container = this.container; const options = container.options; if (!options.pauseOnBlur) { return; } if (document === null || document === void 0 ? void 0 : document.hidden) { container.pageHidden = true; container.pause(); } else { container.pageHidden = false; container.play(); } } mouseTouchMove(e) { var _a, _b, _c; const container = this.container; const options = container.options; let pos; if (e.type.startsWith("mouse")) { this.canPush = true; const mouseEvent = e; if (container.interactivity.element === window && container.canvas.element) { const clientRect = container.canvas.element.getBoundingClientRect(); pos = { x: mouseEvent.clientX - clientRect.left, y: mouseEvent.clientY - clientRect.top }; } else if (options.interactivity.detectsOn === InteractivityDetect.parent) { const source = mouseEvent.target; const target = mouseEvent.currentTarget; if (source && target) { const sourceRect = source.getBoundingClientRect(); const targetRect = target.getBoundingClientRect(); pos = { x: mouseEvent.offsetX + sourceRect.left - targetRect.left, y: mouseEvent.offsetY + sourceRect.top - targetRect.top }; } else { pos = { x: mouseEvent.offsetX || mouseEvent.clientX, y: mouseEvent.offsetY || mouseEvent.clientY }; } } else { pos = { x: mouseEvent.offsetX || mouseEvent.clientX, y: mouseEvent.offsetY || mouseEvent.clientY }; } } else { this.canPush = e.type !== "touchmove"; const touchEvent = e; const lastTouch = touchEvent.touches[touchEvent.touches.length - 1]; const canvasRect = (_a = container.canvas.element) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect(); pos = { x: lastTouch.clientX - ((_b = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.left) !== null && _b !== void 0 ? _b : 0), y: lastTouch.clientY - ((_c = canvasRect === null || canvasRect === void 0 ? void 0 : canvasRect.top) !== null && _c !== void 0 ? _c : 0) }; } container.interactivity.mouse.position = pos; if (container.retina.isRetina) { container.interactivity.mouse.position.x *= container.retina.pxRatio; container.interactivity.mouse.position.y *= container.retina.pxRatio; } container.interactivity.status = Constants.mouseMoveEvent; } mouseTouchFinish() { const container = this.container; delete container.interactivity.mouse.position; container.interactivity.status = Constants.mouseLeaveEvent; } mouseTouchClick(e) { const container = this.container; const options = container.options; if (options.polygon.enable && options.polygon.type !== PolygonMaskType.none && options.polygon.type !== PolygonMaskType.inline) { if (container.polygon.checkInsidePolygon(container.interactivity.mouse.position)) { this.doMouseTouchClick(e); } } else { this.doMouseTouchClick(e); } } doMouseTouchClick(e) { const container = this.container; const options = container.options; if (this.canPush) { if (container.interactivity.mouse.position) { container.interactivity.mouse.clickPosition = { x: container.interactivity.mouse.position.x, y: container.interactivity.mouse.position.y }; } container.interactivity.mouse.clickTime = new Date().getTime(); const pushNb = options.interactivity.modes.push.quantity; const removeNb = options.interactivity.modes.remove.quantity; switch (options.interactivity.events.onClick.mode) { case ClickMode.push: if (options.particles.move.enable) { container.particles.push(pushNb, container.interactivity.mouse); } else { if (options.interactivity.modes.push.quantity === 1) { container.particles.push(pushNb, container.interactivity.mouse); } else if (options.interactivity.modes.push.quantity > 1) { container.particles.push(pushNb); } } break; case ClickMode.remove: container.particles.removeQuantity(removeNb); break; case ClickMode.bubble: container.bubble.clicking = true; break; case ClickMode.repulse: container.repulse.clicking = true; container.repulse.count = 0; container.repulse.finish = false; setTimeout(() => { if (!container.destroyed) { container.repulse.clicking = false; } }, options.interactivity.modes.repulse.duration * 1000); break; } } e.preventDefault(); if (e.type === "touchend") { setTimeout(() => this.mouseTouchFinish(), 500); } e.preventDefault(); } } // CONCATENATED MODULE: ./dist/Enums/ProcessBubbleType.js var ProcessBubbleType; (function (ProcessBubbleType) { ProcessBubbleType["opacity"] = "opacity"; ProcessBubbleType["size"] = "size"; })(ProcessBubbleType || (ProcessBubbleType = {})); // CONCATENATED MODULE: ./dist/Enums/Modes/HoverMode.js var HoverMode; (function (HoverMode) { HoverMode["bubble"] = "bubble"; HoverMode["connect"] = "connect"; HoverMode["grab"] = "grab"; HoverMode["repulse"] = "repulse"; HoverMode["slow"] = "slow"; })(HoverMode || (HoverMode = {})); // CONCATENATED MODULE: ./dist/Classes/Particle/Bubbler.js class Bubbler_Bubbler { constructor(container, particle) { this.container = container; this.particle = particle; } bubble() { const container = this.container; const options = container.options; const hoverEnabled = options.interactivity.events.onHover.enable; const hoverMode = options.interactivity.events.onHover.mode; const clickEnabled = options.interactivity.events.onClick.enable; const clickMode = options.interactivity.events.onClick.mode; if (hoverEnabled && Utils_Utils.isInArray(HoverMode.bubble, hoverMode)) { this.hoverBubble(); } else if (clickEnabled && Utils_Utils.isInArray(ClickMode.bubble, clickMode)) { this.clickBubble(); } } init() { const particle = this.particle; this.opacity = particle.opacity.value; this.radius = particle.radius; } process(distMouse, timeSpent, data) { const container = this.container; const options = container.options; const bubbleDuration = options.interactivity.modes.bubble.duration; const bubbleParam = data.bubbleObj.optValue; const bubbleDistance = container.retina.bubbleModeDistance; const particlesParam = data.particlesObj.optValue; const pObjBubble = data.bubbleObj.value; const pObj = data.particlesObj.value || 0; const type = data.type; if (bubbleParam !== particlesParam) { 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 === ProcessBubbleType.size) { this.radius = value; } if (type === ProcessBubbleType.opacity) { this.opacity = value; } } } else { if (type === ProcessBubbleType.size) { this.radius = undefined; } if (type === ProcessBubbleType.opacity) { this.opacity = undefined; } } } else if (pObjBubble) { const value = bubbleParam * 2 - pObj - timeSpent * (pObj - bubbleParam) / bubbleDuration; if (type === ProcessBubbleType.size) { this.radius = value; } if (type === ProcessBubbleType.opacity) { this.opacity = value; } } } } clickBubble() { const container = this.container; const options = container.options; const particle = this.particle; const mouseClickPos = container.interactivity.mouse.clickPosition || { x: 0, y: 0 }; const distMouse = Utils_Utils.getDistanceBetweenCoordinates(particle.position, mouseClickPos); const timeSpent = (new Date().getTime() - (container.interactivity.mouse.clickTime || 0)) / 1000; if (container.bubble.clicking) { if (timeSpent > options.interactivity.modes.bubble.duration) { container.bubble.durationEnd = true; } if (timeSpent > options.interactivity.modes.bubble.duration * 2) { container.bubble.clicking = false; container.bubble.durationEnd = false; } const sizeData = { bubbleObj: { optValue: container.retina.bubbleModeSize, value: this.radius }, particlesObj: { optValue: container.retina.sizeValue, value: this.particle.radius }, type: ProcessBubbleType.size }; this.process(distMouse, timeSpent, sizeData); const opacityData = { bubbleObj: { optValue: options.interactivity.modes.bubble.opacity, value: this.opacity }, particlesObj: { optValue: options.particles.opacity.value, value: this.particle.opacity.value }, type: ProcessBubbleType.opacity }; this.process(distMouse, timeSpent, opacityData); } } hoverBubble() { const container = this.container; const particle = this.particle; const mousePos = container.interactivity.mouse.position || { x: 0, y: 0 }; const distMouse = Utils_Utils.getDistanceBetweenCoordinates(particle.position, mousePos); const ratio = 1 - distMouse / container.retina.bubbleModeDistance; if (distMouse <= container.retina.bubbleModeDistance) { if (ratio >= 0 && container.interactivity.status === Constants.mouseMoveEvent) { this.hoverBubbleSize(ratio); this.hoverBubbleOpacity(ratio); } } else { this.init(); } if (container.interactivity.status === Constants.mouseLeaveEvent) { this.init(); } } hoverBubbleSize(ratio) { const container = this.container; const options = container.options; const particle = this.particle; const modeSize = options.interactivity.modes.bubble.size; const optSize = options.particles.size.value; const pSize = particle.radius; if (container.retina.bubbleModeSize > container.retina.sizeValue) { const size = pSize + modeSize * ratio; if (size > pSize && size <= modeSize) { this.radius = size; } } else if (container.retina.bubbleModeSize < container.retina.sizeValue) { const size = pSize - (optSize - modeSize) * ratio; if (size < pSize && size >= modeSize) { this.radius = size; } } } hoverBubbleOpacity(ratio) { const container = this.container; const options = container.options; const particle = this.particle; const modeOpacity = options.interactivity.modes.bubble.opacity; const optOpacity = options.particles.opacity.value; const pOpacity = particle.opacity.value; if (modeOpacity > optOpacity) { const opacity = pOpacity + modeOpacity * ratio; if (opacity > pOpacity && opacity <= modeOpacity) { this.opacity = opacity; } } else if (modeOpacity < optOpacity) { const opacity = pOpacity - (optOpacity - modeOpacity) * ratio; if (opacity < pOpacity && opacity >= modeOpacity) { this.opacity = opacity; } } } } // CONCATENATED MODULE: ./dist/Classes/Particle/Drawer.js class Drawer { constructor(container, particle) { this.container = container; this.particle = particle; } draw() { const container = this.container; const particle = this.particle; container.canvas.drawParticle(particle); } } // CONCATENATED MODULE: ./dist/Classes/Particle/Grabber.js class Grabber_Grabber { constructor(container, particle) { this.container = container; this.particle = particle; } grab() { const container = this.container; const options = container.options; const particle = this.particle; const interactivity = options.interactivity; if (interactivity.events.onHover.enable && container.interactivity.status === Constants.mouseMoveEvent) { const mousePos = container.interactivity.mouse.position || { x: 0, y: 0 }; const distMouse = Utils_Utils.getDistanceBetweenCoordinates(particle.position, mousePos); if (distMouse <= container.retina.grabModeDistance) { const lineOpacity = interactivity.modes.grab.lineLinked.opacity; const grabDistance = container.retina.grabModeDistance; const opacityLine = lineOpacity - distMouse * lineOpacity / grabDistance; if (opacityLine > 0) { container.canvas.drawGrabLine(particle, opacityLine, mousePos); } } } } } // CONCATENATED MODULE: ./dist/Enums/OutMode.js var OutMode; (function (OutMode) { OutMode["bounce"] = "bounce"; OutMode["bounceHorizontal"] = "bounce-horizontal"; OutMode["bounceVertical"] = "bounce-vertical"; OutMode["out"] = "out"; OutMode["destroy"] = "destroy"; })(OutMode || (OutMode = {})); // CONCATENATED MODULE: ./dist/Enums/Modes/DivMode.js var DivMode; (function (DivMode) { DivMode["repulse"] = "repulse"; })(DivMode || (DivMode = {})); // CONCATENATED MODULE: ./dist/Classes/Particle/Repulser.js class Repulser_Repulser { constructor(container, particle) { this.container = container; this.particle = particle; } repulse() { const container = this.container; const options = container.options; const hoverEnabled = options.interactivity.events.onHover.enable; const clickEnabled = options.interactivity.events.onClick.enable; const mouseMoveStatus = container.interactivity.status === Constants.mouseMoveEvent; const hoverMode = options.interactivity.events.onHover.mode; const clickMode = options.interactivity.events.onClick.mode; const divMode = options.interactivity.events.onDiv.mode; if (mouseMoveStatus && hoverEnabled && Utils_Utils.isInArray(HoverMode.repulse, hoverMode)) { this.hoverRepulse(); } else if (clickEnabled && Utils_Utils.isInArray(ClickMode.repulse, clickMode)) { this.clickRepulse(); } else if (options.interactivity.events.onDiv.enable && Utils_Utils.isInArray(DivMode.repulse, divMode)) { this.divRepulse(); } } divRepulse() { const container = this.container; const options = container.options; const particle = this.particle; const elem = document.getElementById(options.interactivity.events.onDiv.elementId); const pos = { x: elem.offsetLeft + elem.offsetWidth / 2, y: elem.offsetTop + elem.offsetHeight / 2 }; let divWidth = elem.offsetWidth / 2; if (container.retina.isRetina) { pos.x *= container.retina.pxRatio; pos.y *= container.retina.pxRatio; divWidth *= container.retina.pxRatio; } const dxDiv = particle.position.x - pos.x; const dyDiv = particle.position.y - pos.y; const distDiv = Math.sqrt(dxDiv * dxDiv + dyDiv * dyDiv); const normVec = { x: dxDiv / distDiv, y: dyDiv / distDiv }; const repulseRadius = divWidth; const velocity = 100; const repulseFactor = Utils_Utils.clamp((-Math.pow(distDiv / repulseRadius, 4) + 1) * velocity, 0, 50); this.particle.position.x += normVec.x * repulseFactor; this.particle.position.y += normVec.y * repulseFactor; } clickRepulse() { const container = this.container; const particle = this.particle; if (!container.repulse.finish) { if (!container.repulse.count) { container.repulse.count = 0; } container.repulse.count++; if (container.repulse.count === container.particles.count) { container.repulse.finish = true; } } if (container.repulse.clicking) { const repulseDistance = container.retina.repulseModeDistance; const repulseRadius = Math.pow(repulseDistance / 6, 3); const mouseClickPos = container.interactivity.mouse.clickPosition || { x: 0, y: 0 }; const dx = mouseClickPos.x - particle.position.x; const dy = mouseClickPos.y - particle.position.y; const d = dx * dx + dy * dy; const force = -repulseRadius / d; if (d <= repulseRadius) { this.processRepulse(dx, dy, force); } } else if (container.repulse.clicking === false) { particle.velocity.horizontal = particle.initialVelocity.horizontal; particle.velocity.vertical = particle.initialVelocity.vertical; } } hoverRepulse() { const container = this.container; const options = container.options; const particle = this.particle; const mousePos = container.interactivity.mouse.position || { x: 0, y: 0 }; const dxMouse = particle.position.x - mousePos.x; const dyMouse = particle.position.y - mousePos.y; const distMouse = Math.sqrt(dxMouse * dxMouse + dyMouse * dyMouse); const normVec = { x: dxMouse / distMouse, y: dyMouse / distMouse }; const repulseRadius = container.retina.repulseModeDistance; const velocity = 100; const repulseFactor = Utils_Utils.clamp((1 - Math.pow(distMouse / repulseRadius, 2)) * velocity, 0, 50); const pos = { x: particle.position.x + normVec.x * repulseFactor,