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

441 lines
18 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", "../Utils/CanvasUtils", "../Utils/Utils", "../Utils/ColorUtils", "./Utils/Constants"], factory);
}
})(function (require, exports) {
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Canvas = void 0;
const CanvasUtils_1 = require("../Utils/CanvasUtils");
const Utils_1 = require("../Utils/Utils");
const ColorUtils_1 = require("../Utils/ColorUtils");
const Constants_1 = require("./Utils/Constants");
function setTransformValue(factor, newFactor, key) {
var _a;
const newValue = newFactor[key];
if (newValue !== undefined) {
factor[key] = ((_a = factor[key]) !== null && _a !== void 0 ? _a : 1) * newValue;
}
}
class Canvas {
constructor(container) {
this.container = container;
this.size = {
height: 0,
width: 0,
};
this._context = null;
this._generated = false;
this._preDrawUpdaters = [];
this._postDrawUpdaters = [];
this._resizePlugins = [];
this._colorPlugins = [];
this._mutationObserver =
!(0, Utils_1.isSsr)() && typeof MutationObserver !== "undefined"
? new MutationObserver((records) => {
for (const record of records) {
if (record.type === "attributes" && record.attributeName === "style") {
this._repairStyle();
}
}
})
: undefined;
}
get _fullScreen() {
return this.container.actualOptions.fullScreen.enable;
}
clear() {
const options = this.container.actualOptions, trail = options.particles.move.trail, trailFill = this._trailFill;
if (options.backgroundMask.enable) {
this.paint();
}
else if (trail.enable && trail.length > 0 && trailFill) {
if (trailFill.color) {
this._paintBase((0, ColorUtils_1.getStyleFromRgb)(trailFill.color, trailFill.opacity));
}
else if (trailFill.image) {
this._paintImage(trailFill.image, trailFill.opacity);
}
}
else {
this.draw((ctx) => {
(0, CanvasUtils_1.clear)(ctx, this.size);
});
}
}
destroy() {
var _a, _b;
(_a = this._mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
if (this._generated) {
(_b = this.element) === null || _b === void 0 ? void 0 : _b.remove();
}
else {
this._resetOriginalStyle();
}
this.draw((ctx) => {
(0, CanvasUtils_1.clear)(ctx, this.size);
});
this._preDrawUpdaters = [];
this._postDrawUpdaters = [];
this._resizePlugins = [];
this._colorPlugins = [];
}
draw(cb) {
if (!this._context) {
return;
}
return cb(this._context);
}
drawParticle(particle, delta) {
var _a;
if (particle.spawning || particle.destroyed) {
return;
}
const radius = particle.getRadius();
if (radius <= 0) {
return;
}
const pfColor = particle.getFillColor(), psColor = (_a = particle.getStrokeColor()) !== null && _a !== void 0 ? _a : pfColor;
let [fColor, sColor] = this._getPluginParticleColors(particle);
if (!fColor) {
fColor = pfColor;
}
if (!sColor) {
sColor = psColor;
}
if (!fColor && !sColor) {
return;
}
this.draw((ctx) => {
var _a, _b, _c, _d;
const options = this.container.actualOptions, zIndexOptions = particle.options.zIndex, zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate, opacity = (_c = (_a = particle.bubble.opacity) !== null && _a !== void 0 ? _a : (_b = particle.opacity) === null || _b === void 0 ? void 0 : _b.value) !== null && _c !== void 0 ? _c : 1, strokeOpacity = (_d = particle.strokeOpacity) !== null && _d !== void 0 ? _d : opacity, zOpacity = opacity * zOpacityFactor, zStrokeOpacity = strokeOpacity * zOpacityFactor, transform = {}, colorStyles = {
fill: fColor ? (0, ColorUtils_1.getStyleFromHsl)(fColor, zOpacity) : undefined,
};
colorStyles.stroke = sColor ? (0, ColorUtils_1.getStyleFromHsl)(sColor, zStrokeOpacity) : colorStyles.fill;
this._applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform);
(0, CanvasUtils_1.drawParticle)({
container: this.container,
context: ctx,
particle,
delta,
colorStyles,
backgroundMask: options.backgroundMask.enable,
composite: options.backgroundMask.composite,
radius: radius * (1 - particle.zIndexFactor) ** zIndexOptions.sizeRate,
opacity: zOpacity,
shadow: particle.options.shadow,
transform,
});
this._applyPostDrawUpdaters(particle);
});
}
drawParticlePlugin(plugin, particle, delta) {
this.draw((ctx) => {
(0, CanvasUtils_1.drawParticlePlugin)(ctx, plugin, particle, delta);
});
}
drawPlugin(plugin, delta) {
this.draw((ctx) => {
(0, CanvasUtils_1.drawPlugin)(ctx, plugin, delta);
});
}
async init() {
var _a;
this.resize();
this._initStyle();
this._initCover();
try {
await this._initTrail();
}
catch (e) {
console.error(e);
}
this.initBackground();
if (this.element) {
(_a = this._mutationObserver) === null || _a === void 0 ? void 0 : _a.observe(this.element, { attributes: true });
}
this.initUpdaters();
this.initPlugins();
this.paint();
}
initBackground() {
const options = this.container.actualOptions, background = options.background, element = this.element, elementStyle = element === null || element === void 0 ? void 0 : element.style;
if (!elementStyle) {
return;
}
if (background.color) {
const color = (0, ColorUtils_1.rangeColorToRgb)(background.color);
elementStyle.backgroundColor = color ? (0, ColorUtils_1.getStyleFromRgb)(color, background.opacity) : "";
}
else {
elementStyle.backgroundColor = "";
}
elementStyle.backgroundImage = background.image || "";
elementStyle.backgroundPosition = background.position || "";
elementStyle.backgroundRepeat = background.repeat || "";
elementStyle.backgroundSize = background.size || "";
}
initPlugins() {
this._resizePlugins = [];
for (const [, plugin] of this.container.plugins) {
if (plugin.resize) {
this._resizePlugins.push(plugin);
}
if (plugin.particleFillColor || plugin.particleStrokeColor) {
this._colorPlugins.push(plugin);
}
}
}
initUpdaters() {
this._preDrawUpdaters = [];
this._postDrawUpdaters = [];
for (const updater of this.container.particles.updaters) {
if (updater.afterDraw) {
this._postDrawUpdaters.push(updater);
}
if (updater.getColorStyles || updater.getTransformValues || updater.beforeDraw) {
this._preDrawUpdaters.push(updater);
}
}
}
loadCanvas(canvas) {
var _a, _b;
if (this._generated) {
(_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
}
this._generated =
canvas.dataset && Constants_1.generatedAttribute in canvas.dataset
? canvas.dataset[Constants_1.generatedAttribute] === "true"
: this._generated;
this.element = canvas;
this.element.ariaHidden = "true";
this._originalStyle = (0, Utils_1.deepExtend)({}, this.element.style);
this.size.height = canvas.offsetHeight;
this.size.width = canvas.offsetWidth;
this._context = this.element.getContext("2d");
(_b = this._mutationObserver) === null || _b === void 0 ? void 0 : _b.observe(this.element, { attributes: true });
this.container.retina.init();
this.initBackground();
}
paint() {
const options = this.container.actualOptions;
this.draw((ctx) => {
if (options.backgroundMask.enable && options.backgroundMask.cover) {
(0, CanvasUtils_1.clear)(ctx, this.size);
this._paintBase(this._coverColorStyle);
}
else {
this._paintBase();
}
});
}
resize() {
if (!this.element) {
return;
}
const container = this.container, pxRatio = container.retina.pixelRatio, size = container.canvas.size, newSize = {
width: this.element.offsetWidth * pxRatio,
height: this.element.offsetHeight * pxRatio,
};
if (newSize.height === size.height &&
newSize.width === size.width &&
newSize.height === this.element.height &&
newSize.width === this.element.width) {
return;
}
const oldSize = Object.assign({}, size);
this.element.width = size.width = this.element.offsetWidth * pxRatio;
this.element.height = size.height = this.element.offsetHeight * pxRatio;
if (this.container.started) {
this.resizeFactor = {
width: size.width / oldSize.width,
height: size.height / oldSize.height,
};
}
}
async windowResize() {
if (!this.element) {
return;
}
this.resize();
const container = this.container, needsRefresh = container.updateActualOptions();
container.particles.setDensity();
this._applyResizePlugins();
if (needsRefresh) {
await container.refresh();
}
}
_applyPostDrawUpdaters(particle) {
var _a;
for (const updater of this._postDrawUpdaters) {
(_a = updater.afterDraw) === null || _a === void 0 ? void 0 : _a.call(updater, particle);
}
}
_applyPreDrawUpdaters(ctx, particle, radius, zOpacity, colorStyles, transform) {
var _a;
for (const updater of this._preDrawUpdaters) {
if (updater.getColorStyles) {
const { fill, stroke } = updater.getColorStyles(particle, ctx, radius, zOpacity);
if (fill) {
colorStyles.fill = fill;
}
if (stroke) {
colorStyles.stroke = stroke;
}
}
if (updater.getTransformValues) {
const updaterTransform = updater.getTransformValues(particle);
for (const key in updaterTransform) {
setTransformValue(transform, updaterTransform, key);
}
}
(_a = updater.beforeDraw) === null || _a === void 0 ? void 0 : _a.call(updater, particle);
}
}
_applyResizePlugins() {
for (const plugin of this._resizePlugins) {
if (plugin.resize) {
plugin.resize();
}
}
}
_getPluginParticleColors(particle) {
let fColor, sColor;
for (const plugin of this._colorPlugins) {
if (!fColor && plugin.particleFillColor) {
fColor = (0, ColorUtils_1.rangeColorToHsl)(plugin.particleFillColor(particle));
}
if (!sColor && plugin.particleStrokeColor) {
sColor = (0, ColorUtils_1.rangeColorToHsl)(plugin.particleStrokeColor(particle));
}
if (fColor && sColor) {
break;
}
}
return [fColor, sColor];
}
_initCover() {
const options = this.container.actualOptions, cover = options.backgroundMask.cover, color = cover.color, coverRgb = (0, ColorUtils_1.rangeColorToRgb)(color);
if (coverRgb) {
const coverColor = {
r: coverRgb.r,
g: coverRgb.g,
b: coverRgb.b,
a: cover.opacity,
};
this._coverColorStyle = (0, ColorUtils_1.getStyleFromRgb)(coverColor, coverColor.a);
}
}
_initStyle() {
const element = this.element, options = this.container.actualOptions;
if (!element) {
return;
}
if (this._fullScreen) {
this._originalStyle = (0, Utils_1.deepExtend)({}, element.style);
this._setFullScreenStyle();
}
else {
this._resetOriginalStyle();
}
for (const key in options.style) {
if (!key || !options.style) {
continue;
}
const value = options.style[key];
if (!value) {
continue;
}
element.style.setProperty(key, value, "important");
}
}
async _initTrail() {
const options = this.container.actualOptions, trail = options.particles.move.trail, trailFill = trail.fill;
if (!trail.enable) {
return;
}
if (trailFill.color) {
const fillColor = (0, ColorUtils_1.rangeColorToRgb)(trailFill.color);
if (!fillColor) {
return;
}
const trail = options.particles.move.trail;
this._trailFill = {
color: Object.assign({}, fillColor),
opacity: 1 / trail.length,
};
}
else {
await new Promise((resolve, reject) => {
if (!trailFill.image) {
return;
}
const img = document.createElement("img");
img.addEventListener("load", () => {
this._trailFill = {
image: img,
opacity: 1 / trail.length,
};
resolve();
});
img.addEventListener("error", (evt) => {
reject(evt.error);
});
img.src = trailFill.image;
});
}
}
_paintBase(baseColor) {
this.draw((ctx) => {
(0, CanvasUtils_1.paintBase)(ctx, this.size, baseColor);
});
}
_paintImage(image, opacity) {
this.draw((ctx) => {
(0, CanvasUtils_1.paintImage)(ctx, this.size, image, opacity);
});
}
_repairStyle() {
var _a, _b;
const element = this.element;
if (!element) {
return;
}
(_a = this._mutationObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
this._initStyle();
this.initBackground();
(_b = this._mutationObserver) === null || _b === void 0 ? void 0 : _b.observe(element, { attributes: true });
}
_resetOriginalStyle() {
const element = this.element, originalStyle = this._originalStyle;
if (!(element && originalStyle)) {
return;
}
element.style.position = originalStyle.position;
element.style.zIndex = originalStyle.zIndex;
element.style.top = originalStyle.top;
element.style.left = originalStyle.left;
element.style.width = originalStyle.width;
element.style.height = originalStyle.height;
}
_setFullScreenStyle() {
const element = this.element;
if (!element) {
return;
}
const priority = "important";
element.style.setProperty("position", "fixed", priority);
element.style.setProperty("z-index", this.container.actualOptions.fullScreen.zIndex.toString(10), priority);
element.style.setProperty("top", "0", priority);
element.style.setProperty("left", "0", priority);
element.style.setProperty("width", "100%", priority);
element.style.setProperty("height", "100%", priority);
}
}
exports.Canvas = Canvas;
});