PageSourceSearch

https://www.industrility.com/wp-content/plugins/uicore-animate/assets/js/animated-background.js?ver=2.2.4

js industrility.com collected 2026-09-24 09:43:11 UTC 15,224 bytes, 419 lines download raw bytes

1window.addEventListener('DOMContentLoaded', () => {
2  class animatedBackground extends elementorModules.frontend.handlers.Base {
3    onInit(...args) {
4      super.onInit(...args);
5      if (this.getElementSettings('section_fluid_on') !== 'yes') {
6        return;
7      }
8
9      // the beauty can be found in details :P
10      this.hasMouseStarted = false;
11      this.mouse = {
12        x: 0.5,
13        y: 0.5,
14        vx: 0,
15        vy: 0
16      };
17      this.targetMouse = {
18        x: 0.5,
19        y: 0.5
20      };
21      this.damping = 0.72;
22      this.stiffness = 0.12;
23      this.canvas = null;
24      this.updateMousePosition = this.updateMousePosition.bind(this);
25      this.initBackground();
26    }
27
28    /**
29     * Global resize handler for the fluid animation
30     */
31    resize() {
32      const el = this.$element[0];
33      const {
34        renderer,
35        program
36      } = el.animatedBackground;
37      renderer.setSize(el.offsetWidth, el.offsetHeight);
38      program.uniforms.uResolution.value = [el.offsetWidth, el.offsetHeight, el.offsetWidth / el.offsetHeight];
39    }
40
41    /**
42     * Global mouse position for the fluid animation
43     * @param {*} e
44     */
45    updateMousePosition(e) {
46      const rect = this.$element[0].getBoundingClientRect();
47      const x = (e.clientX - rect.left) / rect.width;
48      const y = (e.clientY - rect.top) / rect.height;
49
50      //fix initial jump
51      if (!this.hasMouseStarted) {
52        this.mouse.x = x;
53        this.mouse.y = y;
54        this.targetMouse.x = x;
55        this.targetMouse.y = y;
56        this.hasMouseStarted = true;
57        return;
58      }
59      this.targetMouse.x = x;
60      this.targetMouse.y = y;
61    }
62
63    /**
64     * Global animation loop
65     * @param {*} t
66     */
67    loop(t) {
68      const el = this.$element[0];
69      const {
70        renderer,
71        program,
72        mesh
73      } = el.animatedBackground;
74      this.$element[0].animationId = requestAnimationFrame(this.loop.bind(this));
75      program.uniforms.uTime.value = t * 0.001;
76      const dx = this.targetMouse.x - this.mouse.x;
77      const dy = this.targetMouse.y - this.mouse.y;
78
79      // acceleration toward target
80      this.mouse.vx += dx * this.stiffness;
81      this.mouse.vy += dy * this.stiffness;
82
83      // apply damping (friction)
84      this.mouse.vx *= this.damping;
85      this.mouse.vy *= this.damping;
86
87      // update position
88      this.mouse.x += this.mouse.vx;
89      this.mouse.y += this.mouse.vy;
90      program.uniforms.uMouse.value = [this.mouse.x, this.mouse.y];
91      renderer.render({
92        scene: mesh
93      });
94    }
95
96    /**
97     * Global destroy method
98     */
99    destroy() {
100      const {
101        gl,
102        program,
103        geometry,
104        mesh
105      } = this.$element[0].animatedBackground;
106
107      //stop animation loop
108      if (this.$element[0].animationId) {
109        cancelAnimationFrame(this.$element[0].animationId);
110      }
111      //remove event listeners
112      this.$element[0].removeEventListener('mousemove', this.updateMousePosition);
113      window.removeEventListener('resize', this.resize);
114
115      //clean up ogl resources
116      try {
117        var _mesh$delete;
118        mesh === null || mesh === void 0 || (_mesh$delete = mesh.delete) === null || _mesh$delete === void 0 || _mesh$delete.call(mesh);
119      } catch (e) {}
120      try {
121        gl.deleteProgram(program === null || program === void 0 ? void 0 : program.program);
122      } catch (e) {}
123      try {
124        var _geometry$attributes;
125        gl.deleteBuffer(geometry === null || geometry === void 0 || (_geometry$attributes = geometry.attributes) === null || _geometry$attributes === void 0 || (_geometry$attributes = _geometry$attributes.position) === null || _geometry$attributes === void 0 ? void 0 : _geometry$attributes.buffer);
126      } catch (e) {}
127      try {
128        gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
129      } catch (e) {}
130
131      //cleanup references
132      this.$element[0].animatedBackground = null;
133    }
134
135    /**
136     * Initialize the fluid animation
137     */
138    initBackground() {
139      var _this$$element$0$anim;
140      const animation = this.getElementSettings('uicore_fluid_animation') || null;
141      if (!animation) {
142        return;
143      }
144
145      // Get proper function name
146      const name = animation.replace('ui-fluid-', '').replace(/-([a-z])/g, g => g[1].toUpperCase());
147      const functionName = 'uiAnimated_' + name.charAt(0).toUpperCase() + name.slice(1);
148      this.createCanvas(animation);
149
150      // Css based animations only need canvas
151      if (typeof window[functionName] !== 'function') {
152        return;
153      }
154
155      // Try to destroy existing animation
156      if (this.$element[0].animatedBackground) {
157        this.destroy();
158      }
159      const settings = this.getBGSettings();
160      window[functionName](this.$element[0], this.canvas, settings); // Calls for the main animation function
161
162      // Start loop and resize listeners if not custom
163      if ((_this$$element$0$anim = this.$element[0].animatedBackground) !== null && _this$$element$0$anim !== void 0 && _this$$element$0$anim.custom) {
164        return;
165      }
166      requestAnimationFrame(this.loop.bind(this));
167      window.addEventListener("resize", this.resize.bind(this));
168      this.resize();
169      if (settings.mouseInteractive) {
170        this.$element[0].addEventListener('mousemove', this.updateMousePosition);
171      }
172    }
173
174    /**
175     * Create a canvas element for the fluid animation
176     * @param {string} animation
177     */
178    createCanvas(animation) {
179      let canvas = this.$element[0].querySelector('.ui-e-fluid-canvas');
180
181      //cleanup existing canvas
182      if (canvas) {
183        this.$element[0].removeChild(canvas);
184        canvas = null;
185      }
186
187      // Check if we actually need the `canvas` tag
188      const useDiv = animation.startsWith('ui-fluid-animation-') && animation !== 'ui-fluid-animation-6';
189      canvas = useDiv ? document.createElement('div') : document.createElement('canvas');
190      canvas.className = useDiv ? 'ui-fluid-gradient-wrapper ui-e-fluid-canvas' : 'ui-e-fluid-canvas';
191      this.$element[0].insertBefore(canvas, this.$element[0].firstChild);
192      if (useDiv) {
193        const canvasChild = document.createElement('div');
194        canvasChild.className = 'ui-fluid-gradient';
195        canvas.appendChild(canvasChild);
196      } else {
197        canvas.style.position = 'absolute';
198        canvas.style.inset = '0';
199        canvas.style.width = '100%';
200        canvas.style.height = '100%';
201        canvas.style.display = 'block';
202      }
203      this.canvas = canvas;
204    }
205    getBGColorSettings() {
206      const canvasStyle = getComputedStyle(this.canvas);
207      const colorArray = [canvasStyle.getPropertyValue("--ui-fluid-1") || "#b96d04", canvasStyle.getPropertyValue("--ui-fluid-2") || "#dd7301", canvasStyle.getPropertyValue("--ui-fluid-3") || "#f7c632", canvasStyle.getPropertyValue("--ui-fluid-4") || "#934b14"].map(color => this.getResolvedRGB(color));
208      const backgroundColor = this.getResolvedRGB(canvasStyle.getPropertyValue("--ui-fluid-bg") || "#000000");
209      return {
210        colorArray,
211        backgroundColor
212      };
213    }
214    getBGSettings() {
215      var _this$getElementSetti, _this$getElementSetti2, _this$getElementSetti3, _this$getElementSetti4, _this$getElementSetti5, _this$getElementSetti6, _this$getElementSetti7, _this$getElementSetti8;
216      // If settings popover is reset or not set yet, use default values
217      let settings = this.getElementSettings('section_fluid_settings') !== 'yes' ? {
218        ...this.getBGColorSettings(),
219        scale: 10,
220        intensity: 50,
221        speed: 20,
222        noise: 20,
223        angle: 0,
224        mouseInteractive: false,
225        progress: 10
226      } : {
227        ...this.getBGColorSettings(),
228        scale: (_this$getElementSetti = this.getElementSettings('section_fluid_scale')) !== null && _this$getElementSetti !== void 0 ? _this$getElementSetti : 10,
229        intensity: (_this$getElementSetti2 = this.getElementSettings('section_fluid_intensity')) !== null && _this$getElementSetti2 !== void 0 ? _this$getElementSetti2 : 50,
230        speed: this.getElementSettings('section_fluid_static') === 'yes' ? 0 : (_this$getElementSetti3 = this.getElementSettings('section_fluid_speed')) !== null && _this$getElementSetti3 !== void 0 ? _this$getElementSetti3 : 20,
231        noise: (_this$getElementSetti4 = this.getElementSettings('section_fluid_noise')) !== null && _this$getElementSetti4 !== void 0 ? _this$getElementSetti4 : 20,
232        angle: (_this$getElementSetti5 = this.getElementSettings('section_fluid_angle')) !== null && _this$getElementSetti5 !== void 0 ? _this$getElementSetti5 : 0,
233        mouseInteractive: this.getElementSettings('section_fluid_interactive') === 'yes',
234        progress: (_this$getElementSetti6 = this.getElementSettings('section_fluid_progress')) !== null && _this$getElementSetti6 !== void 0 ? _this$getElementSetti6 : 10,
235        texture: this.getElementSettings('section_fluid_texture') || null,
236        offsetX: (_this$getElementSetti7 = this.getElementSettings('section_fluid_offset_x')) !== null && _this$getElementSetti7 !== void 0 ? _this$getElementSetti7 : 0,
237        offsetY: (_this$getElementSetti8 = this.getElementSettings('section_fluid_offset_y')) !== null && _this$getElementSetti8 !== void 0 ? _this$getElementSetti8 : 0
238      };
239
240      // Fluid image should always be interactive
241      if (this.getElementSettings('uicore_fluid_animation') === 'liquid-image') {
242        settings.mouseInteractive = true;
243      }
244      return settings;
245    }
246    getResolvedRGB(color) {
247      const temp = document.createElement("div");
248      temp.style.color = color;
249      window.document.body.appendChild(temp);
250      const computed = getComputedStyle(temp).color;
251      window.document.body.removeChild(temp);
252      const [r, g, b] = computed.match(/\d+/g).map(Number);
253      return [r / 255, g / 255, b / 255];
254    }
255    updateSettings(propertyName) {
256      const map = {
257        'section_fluid_scale': {
258          key: 'scale',
259          default: 10
260        },
261        'section_fluid_intensity': {
262          key: 'intensity',
263          default: 50
264        },
265        'section_fluid_speed': {
266          key: 'speed',
267          default: 20
268        },
269        'section_fluid_noise': {
270          key: 'noise',
271          default: 0
272        },
273        'section_fluid_angle': {
274          key: 'angle',
275          default: 0
276        },
277        'section_fluid_interactive': {
278          key: 'mouseInteractive',
279          default: false
280        },
281        'section_fluid_static': {
282          key: 'static',
283          default: false
284        },
285        'section_fluid_progress': {
286          key: 'progress',
287          default: 10
288        },
289        'section_fluid_offset_x': {
290          key: 'offsetX',
291          default: 0
292        },
293        'section_fluid_offset_y': {
294          key: 'offsetY',
295          default: 0
296        }
297      };
298      let normalized;
299      const {
300        normalizeSettings,
301        program,
302        customUpdateSettings
303      }
303 = this.$element[0].animatedBackground;
304      if (map[propertyName]) {
305        const {
306          key,
307          default: defaultValue
308        } = map[propertyName];
309        let value = this.getElementSettings(propertyName);
310
311        // Object props check
312        if (typeof value === 'object' && value !== null) {
313          value = value.size === null || value.size === undefined || isNaN(value.size) ? defaultValue : value.size;
314          // Switch props check
315        } else if (key === 'mouseInteractive' || key === 'static') {
316          value = value.toLowerCase() === 'yes';
317          // Straight props check
318        } else if (value === '' || value === null || value === undefined || isNaN(value)) {
319          value = defaultValue;
320        }
321        normalized = normalizeSettings({
322          [key]: value
323        });
324      }
325
326      // Update colors (get them from css since those are not frontend settings)
327      if (propertyName.startsWith('section_fluid_color')) {
328        const {
329          colorArray,
330          backgroundColor
331        } = this.getBGColorSettings();
332        normalized = normalizeSettings({
333          colorArray,
334          backgroundColor
335        });
336      }
337      if (normalized) {
338        if (typeof customUpdateSettings === 'function') {
339          customUpdateSettings(normalized);
340          return;
341        }
342        for (const [k, v] of Object.entries(normalized)) {
343          switch (k) {
344            case "colorArray":
345              program.uniforms.uColorStops.value = v;
346              break;
347            case "backgroundColor":
348              program.uniforms.uBackgroundColor.value = v;
349              break;
350            case "speed":
351              program.uniforms.uSpeed.value = v;
352              break;
353            case "intensity":
354              program.uniforms.uIntensity.value = v;
355              break;
356            case "noise":
357              program.uniforms.uNoise.value = v;
358              break;
359            case "scale":
360              program.uniforms.uScale.value = v;
361              break;
362            case "angle":
363              program.uniforms.uAngle.value = v;
364              break;
365            case 'progress':
366              if (program.uniforms.uSpeed.value === 0) {
367                program.uniforms.uProgress.value = v;
368              }
369              break;
370            case 'mouseInteractive':
371              if (v) {
372                program.uniforms.uInteractive.value = 1;
373                this.$element[0].addEventListener('mousemove', this.updateMousePosition);
374              } else {
375                program.uniforms.uInteractive.value = 0;
376                this.$element[0].removeEventListener('mousemove', this.updateMousePosition);
377              }
378              break;
379            case 'static':
380              if (!v) {
381                const speedSetting = this.getElementSettings('section_fluid_speed');
382                program.uniforms.uSpeed.value = speedSetting ? normalizeSettings({
383                  speed: speedSetting
384                }) : 0.01;
385              } else {
386                program.uniforms.uSpeed.value = 0;
387              }
388              break;
389            case 'offsetX':
390              program.uniforms.uOffsetX.value = v;
391              break;
392            case 'offsetY':
393              program.uniforms.uOffsetY.value = v;
394              break;
395          }
396        }
397      }
398    }
399    onElementChange(propertyName) {
400      if (this.getElementSettings('section_fluid_on') !== 'yes' || ['animation-1', 'animation-2', 'animation-3', 'animation-4', 'animation-5'].some(suffix => propertyName.endsWith(suffix)) // Css based animations
401      ) {
402        return;
403      }
404      clearTimeout(this.updateTimeout);
405      this.updateTimeout = setTimeout(() => {
406        this.updateSettings(propertyName);
407      }, 50);
408    }
409  }
410  jQuery(window).on('elementor/frontend/init', () => {
411    const addHandler = $element => {
412      elementorFrontend.elementsHandler.addHandler(animatedBackground, {
413        $element
414      });
415    };
416    elementorFrontend.hooks.addAction('frontend/element_ready/section', addHandler);
417    elementorFrontend.hooks.addAction('frontend/element_ready/container', addHandler);
418  });
419}, false);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.