(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", "./NumberUtils", "../Core/Utils/Vector"], factory); } })(function (require, exports) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.findItemFromSingleOrMultiple = exports.itemFromSingleOrMultiple = exports.executeOnSingleOrMultiple = exports.rectBounce = exports.circleBounce = exports.circleBounceDataFromParticle = exports.divMode = exports.singleDivModeExecute = exports.divModeExecute = exports.isDivModeEnabled = exports.deepExtend = exports.calculateBounds = exports.areBoundsInside = exports.isPointInside = exports.itemFromArray = exports.arrayRandomIndex = exports.loadFont = exports.isInArray = exports.cancelAnimation = exports.animate = exports.safeMatchMedia = exports.hasMatchMedia = exports.isSsr = void 0; const NumberUtils_1 = require("./NumberUtils"); const Vector_1 = require("../Core/Utils/Vector"); function rectSideBounce(pSide, pOtherSide, rectSide, rectOtherSide, velocity, factor) { const res = { bounced: false }; 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) / 2 && velocity > 0) || (pSide.min <= rectSide.max && pSide.min > (rectSide.max + rectSide.min) / 2 && velocity < 0)) { res.velocity = velocity * -factor; res.bounced = true; } return res; } function checkSelector(element, selectors) { const res = executeOnSingleOrMultiple(selectors, (selector) => { return element.matches(selector); }); return res instanceof Array ? res.some((t) => t) : res; } function isSsr() { return typeof window === "undefined" || !window || typeof window.document === "undefined" || !window.document; } exports.isSsr = isSsr; function hasMatchMedia() { return !isSsr() && typeof matchMedia !== "undefined"; } exports.hasMatchMedia = hasMatchMedia; function safeMatchMedia(query) { if (!hasMatchMedia()) { return; } return matchMedia(query); } exports.safeMatchMedia = safeMatchMedia; function animate() { return isSsr() ? (callback) => setTimeout(callback) : (callback) => (requestAnimationFrame || setTimeout)(callback); } exports.animate = animate; function cancelAnimation() { return isSsr() ? (handle) => clearTimeout(handle) : (handle) => (cancelAnimationFrame || clearTimeout)(handle); } exports.cancelAnimation = cancelAnimation; function isInArray(value, array) { return value === array || (array instanceof Array && array.indexOf(value) > -1); } exports.isInArray = isInArray; async function loadFont(font, weight) { try { await document.fonts.load(`${weight !== null && weight !== void 0 ? weight : "400"} 36px '${font !== null && font !== void 0 ? font : "Verdana"}'`); } catch (_a) { } } exports.loadFont = loadFont; function arrayRandomIndex(array) { return Math.floor((0, NumberUtils_1.getRandom)() * array.length); } exports.arrayRandomIndex = arrayRandomIndex; function itemFromArray(array, index, useIndex = true) { return array[index !== undefined && useIndex ? index % array.length : arrayRandomIndex(array)]; } exports.itemFromArray = itemFromArray; function isPointInside(point, size, offset, radius, direction) { return areBoundsInside(calculateBounds(point, radius !== null && radius !== void 0 ? radius : 0), size, offset, direction); } exports.isPointInside = isPointInside; function areBoundsInside(bounds, size, offset, direction) { let inside = true; if (!direction || direction === "bottom") { inside = bounds.top < size.height + offset.x; } if (inside && (!direction || direction === "left")) { inside = bounds.right > offset.x; } if (inside && (!direction || direction === "right")) { inside = bounds.left < size.width + offset.y; } if (inside && (!direction || direction === "top")) { inside = bounds.bottom > offset.y; } return inside; } exports.areBoundsInside = areBoundsInside; function calculateBounds(point, radius) { return { bottom: point.y + radius, left: point.x - radius, right: point.x + radius, top: point.y - radius, }; } exports.calculateBounds = calculateBounds; function deepExtend(destination, ...sources) { for (const source of sources) { if (source === undefined || source === null) { continue; } if (typeof source !== "object") { destination = source; continue; } const sourceIsArray = Array.isArray(source); if (sourceIsArray && (typeof destination !== "object" || !destination || !Array.isArray(destination))) { destination = []; } else if (!sourceIsArray && (typeof destination !== "object" || !destination || Array.isArray(destination))) { destination = {}; } for (const key in source) { if (key === "__proto__") { continue; } const sourceDict = source, value = sourceDict[key], isObject = typeof value === "object", destDict = destination; destDict[key] = isObject && Array.isArray(value) ? value.map((v) => deepExtend(destDict[key], v)) : deepExtend(destDict[key], value); } } return destination; } exports.deepExtend = deepExtend; function isDivModeEnabled(mode, divs) { return !!findItemFromSingleOrMultiple(divs, (t) => t.enable && isInArray(mode, t.mode)); } exports.isDivModeEnabled = isDivModeEnabled; function divModeExecute(mode, divs, callback) { executeOnSingleOrMultiple(divs, (div) => { const divMode = div.mode, divEnabled = div.enable; if (divEnabled && isInArray(mode, divMode)) { singleDivModeExecute(div, callback); } }); } exports.divModeExecute = divModeExecute; function singleDivModeExecute(div, callback) { const selectors = div.selectors; executeOnSingleOrMultiple(selectors, (selector) => { callback(selector, div); }); } exports.singleDivModeExecute = singleDivModeExecute; function divMode(divs, element) { if (!element || !divs) { return; } return findItemFromSingleOrMultiple(divs, (div) => { return checkSelector(element, div.selectors); }); } exports.divMode = divMode; function circleBounceDataFromParticle(p) { return { position: p.getPosition(), radius: p.getRadius(), mass: p.getMass(), velocity: p.velocity, factor: Vector_1.Vector.create((0, NumberUtils_1.getValue)(p.options.bounce.horizontal), (0, NumberUtils_1.getValue)(p.options.bounce.vertical)), }; } exports.circleBounceDataFromParticle = circleBounceDataFromParticle; function circleBounce(p1, p2) { const { x: xVelocityDiff, y: yVelocityDiff } = p1.velocity.sub(p2.velocity), [pos1, pos2] = [p1.position, p2.position], { dx: xDist, dy: yDist } = (0, NumberUtils_1.getDistances)(pos2, pos1); if (xVelocityDiff * xDist + yVelocityDiff * yDist < 0) { return; } const angle = -Math.atan2(yDist, xDist), m1 = p1.mass, m2 = p2.mass, u1 = p1.velocity.rotate(angle), u2 = p2.velocity.rotate(angle), v1 = (0, NumberUtils_1.collisionVelocity)(u1, u2, m1, m2), v2 = (0, NumberUtils_1.collisionVelocity)(u2, u1, m1, m2), vFinal1 = v1.rotate(-angle), vFinal2 = v2.rotate(-angle); p1.velocity.x = vFinal1.x * p1.factor.x; p1.velocity.y = vFinal1.y * p1.factor.y; p2.velocity.x = vFinal2.x * p2.factor.x; p2.velocity.y = vFinal2.y * p2.factor.y; } exports.circleBounce = circleBounce; function rectBounce(particle, divBounds) { const pPos = particle.getPosition(), size = particle.getRadius(), bounds = calculateBounds(pPos, size), resH = rectSideBounce({ min: bounds.left, max: bounds.right, }, { min: bounds.top, max: bounds.bottom, }, { min: divBounds.left, max: divBounds.right, }, { min: divBounds.top, max: divBounds.bottom, }, particle.velocity.x, (0, NumberUtils_1.getValue)(particle.options.bounce.horizontal)); if (resH.bounced) { if (resH.velocity !== undefined) { particle.velocity.x = resH.velocity; } if (resH.position !== undefined) { particle.position.x = resH.position; } } const resV = rectSideBounce({ min: bounds.top, max: bounds.bottom, }, { min: bounds.left, max: bounds.right, }, { min: divBounds.top, max: divBounds.bottom, }, { min: divBounds.left, max: divBounds.right, }, particle.velocity.y, (0, NumberUtils_1.getValue)(particle.options.bounce.vertical)); if (resV.bounced) { if (resV.velocity !== undefined) { particle.velocity.y = resV.velocity; } if (resV.position !== undefined) { particle.position.y = resV.position; } } } exports.rectBounce = rectBounce; function executeOnSingleOrMultiple(obj, callback) { return obj instanceof Array ? obj.map((item, index) => callback(item, index)) : callback(obj, 0); } exports.executeOnSingleOrMultiple = executeOnSingleOrMultiple; function itemFromSingleOrMultiple(obj, index, useIndex) { return obj instanceof Array ? itemFromArray(obj, index, useIndex) : obj; } exports.itemFromSingleOrMultiple = itemFromSingleOrMultiple; function findItemFromSingleOrMultiple(obj, callback) { return obj instanceof Array ? obj.find((t, index) => callback(t, index)) : callback(obj, 0) ? obj : undefined; } exports.findItemFromSingleOrMultiple = findItemFromSingleOrMultiple; });