2023-02-17 11:06:01 +01:00

252 lines
11 KiB
JavaScript

(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;
});