1 | "use strict";
|
2 | Object.defineProperty(exports, "__esModule", { value: true });
|
3 | exports.Canvas = void 0;
|
4 | const Utils_1 = require("../Utils");
|
5 | const Utils_2 = require("../Utils");
|
6 | class Canvas {
|
7 | constructor(container) {
|
8 | this.container = container;
|
9 | this.size = {
|
10 | height: 0,
|
11 | width: 0,
|
12 | };
|
13 | this.context = null;
|
14 | this.generatedCanvas = false;
|
15 | }
|
16 | init() {
|
17 | this.resize();
|
18 | this.initStyle();
|
19 | this.initCover();
|
20 | this.initTrail();
|
21 | this.initBackground();
|
22 | this.paint();
|
23 | }
|
24 | loadCanvas(canvas, generatedCanvas) {
|
25 | var _a;
|
26 | if (!canvas.className) {
|
27 | canvas.className = Utils_1.Constants.canvasClass;
|
28 | }
|
29 | if (this.generatedCanvas) {
|
30 | (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
|
31 | }
|
32 | this.generatedCanvas = generatedCanvas !== null && generatedCanvas !== void 0 ? generatedCanvas : this.generatedCanvas;
|
33 | this.element = canvas;
|
34 | this.originalStyle = (0, Utils_1.deepExtend)({}, this.element.style);
|
35 | this.size.height = canvas.offsetHeight;
|
36 | this.size.width = canvas.offsetWidth;
|
37 | this.context = this.element.getContext("2d");
|
38 | this.container.retina.init();
|
39 | this.initBackground();
|
40 | }
|
41 | destroy() {
|
42 | var _a;
|
43 | if (this.generatedCanvas) {
|
44 | (_a = this.element) === null || _a === void 0 ? void 0 : _a.remove();
|
45 | }
|
46 | this.draw((ctx) => {
|
47 | (0, Utils_2.clear)(ctx, this.size);
|
48 | });
|
49 | }
|
50 | paint() {
|
51 | const options = this.container.actualOptions;
|
52 | this.draw((ctx) => {
|
53 | if (options.backgroundMask.enable && options.backgroundMask.cover && this.coverColor) {
|
54 | (0, Utils_2.clear)(ctx, this.size);
|
55 | this.paintBase((0, Utils_1.getStyleFromRgb)(this.coverColor, this.coverColor.a));
|
56 | }
|
57 | else {
|
58 | this.paintBase();
|
59 | }
|
60 | });
|
61 | }
|
62 | clear() {
|
63 | const options = this.container.actualOptions;
|
64 | const trail = options.particles.move.trail;
|
65 | if (options.backgroundMask.enable) {
|
66 | this.paint();
|
67 | }
|
68 | else if (trail.enable && trail.length > 0 && this.trailFillColor) {
|
69 | this.paintBase((0, Utils_1.getStyleFromRgb)(this.trailFillColor, 1 / trail.length));
|
70 | }
|
71 | else {
|
72 | this.draw((ctx) => {
|
73 | (0, Utils_2.clear)(ctx, this.size);
|
74 | });
|
75 | }
|
76 | }
|
77 | windowResize() {
|
78 | if (!this.element) {
|
79 | return;
|
80 | }
|
81 | const container = this.container;
|
82 | this.resize();
|
83 | const needsRefresh = container.updateActualOptions();
|
84 | container.particles.setDensity();
|
85 | for (const [, plugin] of container.plugins) {
|
86 | if (plugin.resize !== undefined) {
|
87 | plugin.resize();
|
88 | }
|
89 | }
|
90 | if (needsRefresh) {
|
91 | container.refresh();
|
92 | }
|
93 | }
|
94 | resize() {
|
95 | if (!this.element) {
|
96 | return;
|
97 | }
|
98 | const container = this.container;
|
99 | const pxRatio = container.retina.pixelRatio;
|
100 | const size = container.canvas.size;
|
101 | const oldSize = {
|
102 | width: size.width,
|
103 | height: size.height,
|
104 | };
|
105 | size.width = this.element.offsetWidth * pxRatio;
|
106 | size.height = this.element.offsetHeight * pxRatio;
|
107 | this.element.width = size.width;
|
108 | this.element.height = size.height;
|
109 | if (this.container.started) {
|
110 | this.resizeFactor = {
|
111 | width: size.width / oldSize.width,
|
112 | height: size.height / oldSize.height,
|
113 | };
|
114 | }
|
115 | }
|
116 | drawConnectLine(p1, p2) {
|
117 | this.draw((ctx) => {
|
118 | var _a;
|
119 | const lineStyle = this.lineStyle(p1, p2);
|
120 | if (!lineStyle) {
|
121 | return;
|
122 | }
|
123 | const pos1 = p1.getPosition();
|
124 | const pos2 = p2.getPosition();
|
125 | (0, Utils_1.drawConnectLine)(ctx, (_a = p1.retina.linksWidth) !== null && _a !== void 0 ? _a : this.container.retina.linksWidth, lineStyle, pos1, pos2);
|
126 | });
|
127 | }
|
128 | drawGrabLine(particle, lineColor, opacity, mousePos) {
|
129 | const container = this.container;
|
130 | this.draw((ctx) => {
|
131 | var _a;
|
132 | const beginPos = particle.getPosition();
|
133 | (0, Utils_1.drawGrabLine)(ctx, (_a = particle.retina.linksWidth) !== null && _a !== void 0 ? _a : container.retina.linksWidth, beginPos, mousePos, lineColor, opacity);
|
134 | });
|
135 | }
|
136 | drawParticle(particle, delta) {
|
137 | var _a, _b, _c, _d, _e, _f;
|
138 | if (particle.spawning || particle.destroyed) {
|
139 | return;
|
140 | }
|
141 | const pfColor = particle.getFillColor();
|
142 | const psColor = (_a = particle.getStrokeColor()) !== null && _a !== void 0 ? _a : pfColor;
|
143 | if (!pfColor && !psColor) {
|
144 | return;
|
145 | }
|
146 | let [fColor, sColor] = this.getPluginParticleColors(particle);
|
147 | const pOptions = particle.options;
|
148 | const twinkle = pOptions.twinkle.particles;
|
149 | const twinkling = twinkle.enable && Math.random() < twinkle.frequency;
|
150 | if (!fColor || !sColor) {
|
151 | const twinkleRgb = (0, Utils_1.colorToHsl)(twinkle.color);
|
152 | if (!fColor) {
|
153 | fColor = twinkling && twinkleRgb !== undefined ? twinkleRgb : pfColor ? pfColor : undefined;
|
154 | }
|
155 | if (!sColor) {
|
156 | sColor = twinkling && twinkleRgb !== undefined ? twinkleRgb : psColor ? psColor : undefined;
|
157 | }
|
158 | }
|
159 | const options = this.container.actualOptions;
|
160 | const zIndexOptions = particle.options.zIndex;
|
161 | const zOpacityFactor = (1 - particle.zIndexFactor) ** zIndexOptions.opacityRate;
|
162 | const radius = particle.getRadius();
|
163 | const opacity = twinkling ? twinkle.opacity : (_d = (_b = particle.bubble.opacity) !== null && _b !== void 0 ? _b : (_c = particle.opacity) === null || _c === void 0 ? void 0 : _c.value) !== null && _d !== void 0 ? _d : 1;
|
164 | const strokeOpacity = (_f = (_e = particle.stroke) === null || _e === void 0 ? void 0 : _e.opacity) !== null && _f !== void 0 ? _f : opacity;
|
165 | const zOpacity = opacity * zOpacityFactor;
|
166 | const fillColorValue = fColor ? (0, Utils_1.getStyleFromHsl)(fColor, zOpacity) : undefined;
|
167 | if (!fillColorValue && !sColor) {
|
168 | return;
|
169 | }
|
170 | this.draw((ctx) => {
|
171 | const zSizeFactor = (1 - particle.zIndexFactor) ** zIndexOptions.sizeRate;
|
172 | const zStrokeOpacity = strokeOpacity * zOpacityFactor;
|
173 | const strokeColorValue = sColor ? (0, Utils_1.getStyleFromHsl)(sColor, zStrokeOpacity) : fillColorValue;
|
174 | if (radius <= 0) {
|
175 | return;
|
176 | }
|
177 | const container = this.container;
|
178 | for (const updater of container.particles.updaters) {
|
179 | if (updater.beforeDraw) {
|
180 | updater.beforeDraw(particle);
|
181 | }
|
182 | }
|
183 | (0, Utils_1.drawParticle)(this.container, ctx, particle, delta, fillColorValue, strokeColorValue, options.backgroundMask.enable, options.backgroundMask.composite, radius * zSizeFactor, zOpacity, particle.options.shadow, particle.gradient);
|
184 | for (const updater of container.particles.updaters) {
|
185 | if (updater.afterDraw) {
|
186 | updater.afterDraw(particle);
|
187 | }
|
188 | }
|
189 | });
|
190 | }
|
191 | drawPlugin(plugin, delta) {
|
192 | this.draw((ctx) => {
|
193 | (0, Utils_1.drawPlugin)(ctx, plugin, delta);
|
194 | });
|
195 | }
|
196 | drawParticlePlugin(plugin, particle, delta) {
|
197 | this.draw((ctx) => {
|
198 | (0, Utils_1.drawParticlePlugin)(ctx, plugin, particle, delta);
|
199 | });
|
200 | }
|
201 | initBackground() {
|
202 | const options = this.container.actualOptions;
|
203 | const background = options.background;
|
204 | const element = this.element;
|
205 | const elementStyle = element === null || element === void 0 ? void 0 : element.style;
|
206 | if (!elementStyle) {
|
207 | return;
|
208 | }
|
209 | if (background.color) {
|
210 | const color = (0, Utils_1.colorToRgb)(background.color);
|
211 | elementStyle.backgroundColor = color ? (0, Utils_1.getStyleFromRgb)(color, background.opacity) : "";
|
212 | }
|
213 | else {
|
214 | elementStyle.backgroundColor = "";
|
215 | }
|
216 | elementStyle.backgroundImage = background.image || "";
|
217 | elementStyle.backgroundPosition = background.position || "";
|
218 | elementStyle.backgroundRepeat = background.repeat || "";
|
219 | elementStyle.backgroundSize = background.size || "";
|
220 | }
|
221 | draw(cb) {
|
222 | if (!this.context) {
|
223 | return;
|
224 | }
|
225 | return cb(this.context);
|
226 | }
|
227 | initCover() {
|
228 | const options = this.container.actualOptions;
|
229 | const cover = options.backgroundMask.cover;
|
230 | const color = cover.color;
|
231 | const coverRgb = (0, Utils_1.colorToRgb)(color);
|
232 | if (coverRgb) {
|
233 | this.coverColor = {
|
234 | r: coverRgb.r,
|
235 | g: coverRgb.g,
|
236 | b: coverRgb.b,
|
237 | a: cover.opacity,
|
238 | };
|
239 | }
|
240 | }
|
241 | initTrail() {
|
242 | const options = this.container.actualOptions;
|
243 | const trail = options.particles.move.trail;
|
244 | const fillColor = (0, Utils_1.colorToRgb)(trail.fillColor);
|
245 | if (fillColor) {
|
246 | const trail = options.particles.move.trail;
|
247 | this.trailFillColor = {
|
248 | r: fillColor.r,
|
249 | g: fillColor.g,
|
250 | b: fillColor.b,
|
251 | a: 1 / trail.length,
|
252 | };
|
253 | }
|
254 | }
|
255 | getPluginParticleColors(particle) {
|
256 | let fColor;
|
257 | let sColor;
|
258 | for (const [, plugin] of this.container.plugins) {
|
259 | if (!fColor && plugin.particleFillColor) {
|
260 | fColor = (0, Utils_1.colorToHsl)(plugin.particleFillColor(particle));
|
261 | }
|
262 | if (!sColor && plugin.particleStrokeColor) {
|
263 | sColor = (0, Utils_1.colorToHsl)(plugin.particleStrokeColor(particle));
|
264 | }
|
265 | if (fColor && sColor) {
|
266 | break;
|
267 | }
|
268 | }
|
269 | return [fColor, sColor];
|
270 | }
|
271 | initStyle() {
|
272 | const element = this.element, options = this.container.actualOptions;
|
273 | if (!element) {
|
274 | return;
|
275 | }
|
276 | const originalStyle = this.originalStyle;
|
277 | if (options.fullScreen.enable) {
|
278 | this.originalStyle = (0, Utils_1.deepExtend)({}, element.style);
|
279 | element.style.position = "fixed";
|
280 | element.style.zIndex = options.fullScreen.zIndex.toString(10);
|
281 | element.style.top = "0";
|
282 | element.style.left = "0";
|
283 | element.style.width = "100%";
|
284 | element.style.height = "100%";
|
285 | }
|
286 | else if (originalStyle) {
|
287 | element.style.position = originalStyle.position;
|
288 | element.style.zIndex = originalStyle.zIndex;
|
289 | element.style.top = originalStyle.top;
|
290 | element.style.left = originalStyle.left;
|
291 | element.style.width = originalStyle.width;
|
292 | element.style.height = originalStyle.height;
|
293 | }
|
294 | }
|
295 | paintBase(baseColor) {
|
296 | this.draw((ctx) => {
|
297 | (0, Utils_1.paintBase)(ctx, this.size, baseColor);
|
298 | });
|
299 | }
|
300 | lineStyle(p1, p2) {
|
301 | return this.draw((ctx) => {
|
302 | const options = this.container.actualOptions;
|
303 | const connectOptions = options.interactivity.modes.connect;
|
304 | return (0, Utils_1.gradient)(ctx, p1, p2, connectOptions.links.opacity);
|
305 | });
|
306 | }
|
307 | }
|
308 | exports.Canvas = Canvas;
|