PageSourceSearch

https://distribb.io/static/js/hv4-hero-flow.js

js distribb.io collected 2026-10-10 00:50:10 UTC 6,909 bytes, 194 lines download raw bytes

1/**
2 * Hero V4 — energy flow lines (desktop only, width >= 1024px).
3 * Loaded with defer at end of page so it never blocks HTML parsing mid-<main>.
4 * Wrapped in try/catch so a SMIL/DOM edge case cannot hang the tab.
5 */
6(function () {
7    'use strict';
8
9    function clearFlow(svg) {
10        if (!svg) {
11            return;
12        }
13        var nodes = svg.querySelectorAll('[data-hv4-flow]');
14        for (var i = nodes.length - 1; i >= 0; i--) {
15            try {
16                if (nodes[i].parentNode === svg) {
17                    svg.removeChild(nodes[i]);
18                }
19            } catch (e) {
20                /* ignore stale nodes */
21            }
22        }
23    }
24
25    function init() {
26        try {
27            if (window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches) {
28                console.log('[hv4-hero-flow] prefers-reduced-motion: skip animation');
29                return;
30            }
31
32            if (window.innerWidth < 1024) {
33                return;
34            }
35
36            var root = document.querySelector('section.hero-v4');
37            if (!root) {
38                return;
39            }
40
41            var svg = root.querySelector('svg.hv4-lines');
42            var outer = root.querySelector('.hv4-outer');
43            var center = root.querySelector('.hv4-col-center');
44            if (!svg || !outer || !center) {
45                return;
46            }
47
48            var leftIcons = root.querySelectorAll('.hv4-col-left .hv4-icon');
49            var rightIcons = root.querySelectorAll('.hv4-col-right .hv4-icon');
50
51            function pos(el) {
52                var r = el.getBoundingClientRect();
53                var p = outer.getBoundingClientRect();
54                return { x: r.left - p.left + r.width / 2, y: r.top - p.top + r.height / 2 };
55            }
56
57            function draw() {
58                clearFlow(svg);
59                var cRect = center.getBoundingClientRect();
60                var pRect = outer.getBoundingClientRect();
61                var cx = cRect.left - pRect.left + cRect.width / 2;
62                var cy = cRect.top - pRect.top + cRect.height / 2;
63
64                if (!isFinite(cx) || !isFinite(cy)) {
65                    return;
66                }
67
68                var allIcons = [];
69                leftIcons.forEach(function (ic) {
70                    allIcons.push({ el: ic, side: 'left' });
71                });
72                rightIcons.forEach(function (ic) {
73                    allIcons.push({ el: ic, side: 'right' });
74                });
75
76                allIcons.forEach(function (item, i) {
77                    var p1 = pos(item.el);
78                    var cp1x;
79                    var cp2x;
80                    var startX;
81                    var startY;
82                    var endX;
83                    var endY;
84
85                    if (item.side === 'left') {
86                        startX = p1.x;
87                        startY = p1.y;
88                        endX = cx;
89                        endY = cy;
90                        cp1x = startX + (endX - startX) * 0.5;
91                        cp2x = endX - (endX - startX) * 0.15;
92                    } else {
93                        startX = cx;
94                        startY = cy;
95                        endX = p1.x;
96                        endY = p1.y;
97                        cp1x = startX + (endX - startX) * 0.15;
98                        cp2x = endX - (endX - startX) * 0.5;
99                    }
100
101                    if (!isFinite(startX) || !isFinite(endX) || !isFinite(startY) || !isFinite(endY)) {
102                        return;
103                    }
104
105                    var pathD =
106                        'M' +
107                        startX +
108                        ',' +
109                        startY +
110                        ' C' +
111                        cp1x +
112                        ',' +
113                        startY +
114                        ' ' +
115                        cp2x +
116                        ',' +
117                        endY +
118                        ' ' +
119                        endX +
120                        ',' +
121                        endY;
122
123                    var path = document.createElementNS('http://www.w3.org/2000/svg', 'path');
124                    path.setAttribute('data-hv4-flow', '1');
125                    path.setAttribute('d', pathD);
126                    path.setAttribute('fill', 'none');
127                    path.setAttribute('stroke', 'url(#hv4FlowGrad)');
128                    path.setAttribute('stroke-width', '1.5');
129                    path.setAttribute('opacity', '0.5');
130                    svg.appendChild(path);
131
132                    var dot = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
133                    dot.setAttribute('data-hv4-flow', '1');
134                    dot.setAttribute('r', '3');
135                    dot.setAttribute('fill', '#FF4500');
136                    dot.setAttribute('opacity', '0.38');
137                    svg.appendChild(dot);
138
139                    var anim = document.createElementNS('http://www.w3.org/2000/svg', 'animateMotion');
140                    anim.setAttribute('dur', 3 + i * 0.4 + 's');
141                    anim.setAttribute('repeatCount', 'indefinite');
142                    anim.setAttribute('path', pathD);
143                    dot.appendChild(anim);
144                });
145            }
146
147            function setup() {
148                if (window.innerWidth < 1024) {
149                    clearFlow(svg);
150                    return;
151                }
152                svg.setAttribute('width', String(outer.offsetWidth || 0));
153                svg.setAttribute('height', String(outer.offsetHeight || 0
153));
154                draw();
155            }
156
157            function scheduleSetup() {
158                window.requestAnimationFrame(function () {
159                    window.requestAnimationFrame(setup);
160                });
161            }
162
163            if (document.readyState === 'complete') {
164                scheduleSetup();
165            } else {
166                window.addEventListener('load', scheduleSetup);
167            }
168
169            var resizeTimer;
170            window.addEventListener(
171                'resize',
172                function () {
173                    clearTimeout(resizeTimer);
174                    resizeTimer = setTimeout(function () {
175                        if (window.innerWidth >= 1024) {
176                            scheduleSetup();
177                        } else {
178                            clearFlow(svg);
179                        }
180                    }, 200);
181                },
182                { passive: true }
183            );
184        } catch (err) {
185            console.warn('[hv4-hero-flow] disabled due to error:', err);
186        }
187    }
188
189    if (document.readyState === 'loading') {
190        document.addEventListener('DOMContentLoaded', init);
191    } else {
192        init();
193    }
194})();

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.