PageSourceSearch

https://trachtmanpoler.com/wp-content/themes/polerlegal/js/branding.js?v=1791584082

js trachtmanpoler.com collected 2026-10-09 22:14:51 UTC 8,402 bytes, 268 lines download raw bytes

1// 1. Get references
2const page = document.getElementById('page');
3const svg = document.getElementById('sine-svg');
4const wavePath = document.getElementById('sine-path');
5
6const emilyAnchor = document.getElementById('a-emily');
7const emilyPhoto = document.getElementById('photo-emily');
8const lauraAnchor = document.getElementById('a-laura');
9const lauraPhoto = document.getElementById('photo-laura');
10const photoYOffset = 100;
11
12// Sine wave params
13const phase = Math.random() * 2 * Math.PI;  // random start
14const offsetX = 180;
15const amplitude = 75;
16const wavelength = 1800;
17const maxDotSize = 70;
18const spacing = 400;
19// Extend the path above and below the visible area
20let yMin = 0;
21let yMax = 0;
22
23// We'll track all our dot sets here
24let dotSets = [];
25let canvW = 0;
26let canvH = 0;
27
28// Keep track of path length
29let totalLength = 0;
30
31// 1) Build the vertical sine wave path to fill the screen
32function buildSineWave() {
33  canvW = page.offsetWidth;
34  canvH = page.offsetHeight;
35  // console.log('canvH', canvH);
36  // Adjust the viewBox so the coordinates match window size
37  // svg.setAttribute('viewBox', `0 -${maxDotSize * 0.5} ${width} ${canvH + maxDotSize}`);
38  svg.setAttribute('viewBox', `0 0 ${canvW} ${canvH}`);
39  svg.style.width = `${canvW}px`;
40  svg.style.height = `${canvH}px`;  
41
42  yMin = -maxDotSize;        // e.g. -25 for a 50px diameter dot
43  yMax = canvH + maxDotSize; // e.g. height + 25  
44
45  // Build the path from yMin to yMax
46  let d = `M ${offsetX + amplitude * Math.sin((yMin / wavelength) * 2 * Math.PI + phase)} ${yMin}`;
47  for (let y = yMin + 1; y <= yMax; y++) {
48    const x = offsetX + amplitude * Math.sin((y / wavelength) * 2 * Math.PI + phase);
49    d += ` L ${x} ${y}`;
50  }
51
52  wavePath.setAttribute('d', d);
53
54  let xAbsolute, yAbsolute, yOffset, left = 0;
55
56  // Position the portrait photos
57  if(emilyAnchor && emilyPhoto) {
58    const emilyRect = emilyAnchor.getBoundingClientRect();
59    const emilyPhotoRect = emilyPhoto.getBoundingClientRect();
60    xAbsolute = emilyRect.left + window.scrollX;
61    yAbsolute = emilyRect.top + window.scrollY;
62    yOffset = emilyPhotoRect.height * 0.5;
63    left = getXOfSinewave(yAbsolute + yOffset + photoYOffset);
64    emilyPhoto.style.top = `${yAbsolute + yOffset - (emilyPhotoRect.height * 0.5) + photoYOffset}px`;
65    emilyPhoto.style.left = `${left - (emilyPhotoRect.width * 0.5)}px`;
66    emilyPhoto.style.opacity = 1;
67  }
68
69  if(lauraAnchor && lauraPhoto) {
70    const lauraRect = lauraAnchor.getBoundingClientRect();
71    const lauraPhotoRect = lauraPhoto.getBoundingClientRect();
72    xAbsolute = lauraRect.left + window.scrollX;
73    yAbsolute = lauraRect.top + window.scrollY;
74    yOffset = lauraPhotoRect.height * 0.5;
75    left = getXOfSinewave(yAbsolute + yOffset + photoYOffset);
76    lauraPhoto.style.top = `${yAbsolute + yOffset - (lauraPhotoRect.height * 0.5) + photoYOffset}px`;
77    lauraPhoto.style.left = `${left - (lauraPhotoRect.width * 0.5)}px`;
78    lauraPhoto.style.opacity = 1;
79  }
80
81  // Measure total length of the path
82  totalLength = wavePath.getTotalLength();
83}
84
85function getXOfSinewave(y) {
86  return offsetX + amplitude * Math.sin((y / wavelength) * 2 * Math.PI + phase);
87}
88
89
90// 2) Helper to create a single dot (circle) in the SVG
91function createDot(color, diameter) {
92  // create a new circle in the SVG namespace
93  const circle = document.createElementNS('http://www.w3.org/2000/svg', 'circle');
94  circle.setAttribute('fill', color);
95  circle.setAttribute('r', diameter / 2); // radius = diameter/2
96  circle.setAttribute('class', 'color-dot');
97  svg.appendChild(circle);
98  return circle;
99}
100
101// 3) Helper to create a triple-dot set
102function createDotSet(options) {
103  // options might look like:
104  // {
105  //   dot1Color: 'red', dot1Diameter: 50,
106  //   dot2Color: 'blue', dot2Diameter: 33,
107  //   dot3Color: 'green', dot3Diameter: 27,
108  //   speed: 2, gap12: 30, gap23: 50
109  // }
110
111  const dot1 = createDot(options.dot1Color, options.dot1Diameter);
112  const dot2 = createDot(options.dot2Color, options.dot2Diameter);
113  const dot3 = createDot(options.dot3Color, options.dot3Diameter);
114
115  // We'll store offsets, which we can update each frame
116  // The baseOffset controls the leading dot (dot1)
117  return {
118    dot1,
119    dot2,
120    dot3,
121    speed: options.speed,
122    gap12: options.gap12,
123    gap23: options.gap23,
124    baseOffset: options.baseOffset // initial offset for the first dot
125  };
126}
127
128// 4) Animation loop
129function animate() {
130  // Reassign dotSets by filtering out those that are “done”
131  dotSets = dotSets.filter(set => {
132    // 1) Increment the leading dot’s offset (no modulo!)
133    set.baseOffset += set.speed;
134
135    // 2) Calculate each dot’s offset
136    const offset1 = set.baseOffset;
137    const offset2 = offset1 - set.gap12;
138    const offset3 = offset2 - set.gap23;
139
140    // 3) Check if the trailing dot is beyond the path length
141    if (offset3 > totalLength) {
142      // This means the last dot is off the path (below the bottom).
143      // Remove the actual <circle> elements from the DOM so they disappear.
144      svg.removeChild(set.dot1);
145      svg.removeChild(set.dot2);
146      svg.removeChild(set.dot3);
147      return false; // Exclude from dotSets
148    }
149
150    // 4) If still on screen, position them as usual
151    if (offset1 >= 0 && offset1 <= totalLength) {
152      const p1 = wavePath.getPointAtLength(offset1);
153      set.dot1.setAttribute('cx', p1.x);
154      set.dot1.setAttribute('cy', p1.y);
155    } else {
156      // If offset is < 0 or > totalLength, the dot is “off-path,”
157      // so you could optionally hide or not update it.
158      set.dot1.setAttribute('cx', -9999); // move offscreen
159      set.dot1.setAttribute('cy', -9999);
160    }
161
162    if (offset2 >= 0 && offset2 <= totalLength) {
163      const p2 = wavePath.getPointAtLength(offset2);
164      set.dot2.setAttribute('cx', p2.x);
165      set.dot2.setAttribute('cy', p2.y);
166    } else {
167      set.dot2.setAttribute('cx', -9999);
168      set.dot2.setAttribute('cy', -9999);
169    }
170
171    if (offset3 >= 0 && offset3 <= totalLength) {
172      const p3 = wavePath.getPointAtLength(offset3);
173      set.dot3.setAttribute('cx', p3.x);
174      set.dot3.setAttribute('cy', p3.y);
175    } else {
176      set.dot3.setAttribute('cx', -9999);
177      set.dot3.setAttribute('cy', -9999);
178    }
179
180    // 5) Keep this set in the array
181    return true;
182  });
183
184  // Continue animation
185  // requestAnimationFrame(animate);
186}
187
188const blueSet = {
189  dot1Color: 'rgb(16, 95, 168)',
190  dot1Diameter: maxDotSize,
191  dot2Color: 'rgb(37, 144, 205)',
192  dot2Diameter: 40,
193  dot3Color: 'rgb(114, 186, 231)',
194  dot3Diameter: 25,
195  speed: 2,
196  gap12: 35,
197  gap23: 60,
198  baseOffset: 0
199};
200
201const yellowSet = {
202  dot1Color: 'rgb(253, 211, 0)',
203  dot1Diameter: maxDotSize,
204  dot2Color: 'rgb(255, 224, 95)',
205  dot2Diameter: 40,
206  dot3Color: 'rgb(255, 234, 146)',
207  dot3Diameter: 25,
208  speed: 2,
209  gap12: 35,
210  gap23: 60,
211  baseOffset: 0
212};
213
214let whichSet = 0;
215
216// 5) Initialize
217window.addEventListener('load', () => {
218  // Build the sine wave path
219  setTimeout(() => {
220    buildSineWave();
221        
222    const c = canvH / spacing;
223    let baseOffset = 0;
224
225    for(let i = 0; i <= c; i++) {
226      let baseSet = (i % 2 === 0) ? blueSet : yellowSet;
227
228      const dot1Diameter = baseSet.dot1Diameter - (baseSet.dot1Diameter * Math.random() * 0.2);
229      const dot2Diameter = baseSet.dot2Diameter - (baseSet.dot2Diameter * Math.random() * 0.2);
230      const dot3Diameter = baseSet.dot3Diameter - (baseSet.dot3Diameter * Math.random() * 0.2);
231      const gap12 = baseSet.gap12 - (baseSet.gap12 * Math.random() * 0.2);
232      const gap23 = baseSet.gap23 - (baseSet.gap23 * Math.random() * 0.2);
233      baseOffset += spacing + (spacing * (Math.random() + 0.5) * 0.2);
234      
235      const nextSet = {
236        ...baseSet,
237        dot1Diameter,
238        dot2Diameter,
239        dot3Diameter,
240        gap12,
241        gap23,
242        baseOffset
243      };
244
245      dotSets.push(createDotSet(nextSet));
246    }
247    // Start animation
248    animate();
249  }, 100);
250
251  // add a new triple-dot set every 3 seconds
252  // setInterval(() => {
253  //   if(whichSet == 0) {
254  //     dotSets.push(createDotSet(blueSet));
255  //     whichSet = 1;
256  //   } else {
257  //     dotSets.push(createDotSet(yellowSet));
258  //     whichSet = 0;
259  //   }
260  // }, 6000);
261
262});
263
264// Handle window resizing to rebuild the path
265window.addEventListener('resize', () => {
266  buildSineWave();
267  // The offsets might shift, but the animation will keep going
268});

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.