PageSourceSearch

https://docs.smartwireless.de/wp-content/themes/smartwireless_docs/svg_animations.js?ver=1.0

js smartwireless.de collected 2026-10-01 14:16:11 UTC 13,150 bytes, 424 lines download raw bytes

1// --- Slide controller registry ---
2const controllers = new WeakMap(); // slideEl -> { play, stop }
3
4function registerSlideController(slideEl, controller) {
5  console.log("registerSlideController:", { slideEl, controller });
6  controllers.set(slideEl, controller);
7}
8
9// --- Respond to slide changes (page 3 only) ---
10document.addEventListener("slide:change", (e) => {
11  const { prev, next } = e.detail || {};
12  console.log("slide change:", { prev, next });
13  console.log(controllers, controllers.get(next))
14  if (prev) controllers.get(prev)?.stop?.();
15  if (next) controllers.get(next)?.play?.();
16});
17
18document.addEventListener("DOMContentLoaded", () => {
19
20  /**
21  * ------ locks nearby detected - geofence radius fixed -------
22  */
23
24  // in app help for overlapping geofences where geofence radius editing is not possible
25  // mogn_: map-overlapping-geofences-no
26  const mogn_geofences = gsap.utils.toArray("#mogn_geofence_1, #mogn_geofence_2");
27  const mogn_intersection = document.getElementById("mogn_intersection");
28
29  if (mogn_geofences.length && mogn_intersection) {
30
31    // Configure defaults once so you can focus on creative timing
32    gsap.defaults({
33      ease: "power1.inOut",
34      duration: 1,
35    });
36
37    gsap.set(mogn_geofences, {
38      opacity: 0,
39      scale: 1,
40      transformOrigin: "70px 70px",
41    });
42
43
44    gsap.set(mogn_intersection, { opacity: 0 });
45
46    // TimelineMax is still provided for older GSAP syntax, but gsap.timeline is the modern API
47    const tl = gsap.timeline({ paused: true, repeat: -1, repeatDelay: 1 });
48
49    tl.to(mogn_geofences, { opacity: 0.6, duration: 1 }) // 1. fade in geofences
50      .to(mogn_intersection, { opacity: 0.5, duration: 0.4 }, "+=1") // 2. show intersection
51      .to(
52        mogn_intersection,
53        {
54          opacity: 0,
55          repeat: 3,
56          yoyo: true,
57          duration: 0.4,
58        },
59      ) // 3. blink the intersection twice
60      .to(
61        mogn_intersection,
62        { opacity: 0, duration: 0.4 },
63      ) // 4. fade out intersection
64      .to(
65        mogn_geofences,
66        { scale: 0.7, duration: 1 },
67        "-=0.1",
68      ) // 4. scale geofences down from center
69      .to(mogn_geofences, { opacity: 0, duration: 1 }, "+=1") // 5. hide geofences
70      .set(mogn_geofences, { scale: 1 }); // reset for loop
71
72    tl.play();
73
74    // replayBtn?.addEventListener("click", () => {
75    //   tl.restart();
76    // });
77
78  }
79
80
81 /**
82  * ------ locks nearby detected - geofence radius limited -------
83  */
84
85
86  // in app help for overlapping geofences where geofence radius editing is possible but limited
87  // mogl_: map-overlapping-geofences-limited
88  const mogl_geofences = gsap.utils.toArray("#mogl_geofence_1, #mogl_geofence_2");
89  const mogle_intersection = document.getElementById("mogl_intersection");
90
91  if (mogl_geofences.length && mogle_intersection) {
92
93    // Configure defaults once so you can focus on creative timing
94    gsap.defaults({
95      ease: "power1.inOut",
96      duration: 1,
97    });
98
99    gsap.set(mogl_geofences, {
100      opacity: 0,
101      scale: 1,
102      transformOrigin: "70px 70px",
103    });
104
105
106    gsap.set("#mogl_circle_highlighted", { x: 86 });
107    gsap.set("#mogl_slider", { opacity: 0 });
108    gsap.set("#mogl_line", { scaleX: 1.5, transformOrigin: "left center" });
109
110
111    gsap.set(mogle_intersection, { opacity: 0 });
112
113    // TimelineMax is still provided for older GSAP syntax, but gsap.timeline is the modern API
114    const tl = gsap.timeline({ paused: true, repeat: -1, repeatDelay: 1 });
115
116    tl.to(mogl_geofences, { opacity: 0.6, duration: 1 }) // 1. fade in geofences
117        .to(
118        "#mogl_slider",
119        { opacity: 1, duration: 1 },
120        "<",
121      ) // show the slider
122
123      .to(mogle_intersection, { opacity: 0.5, duration: 0.4 }, "+=1") // 2. show intersection
124      .to(
125        mogle_intersection,
126        {
127          opacity: 0,
128          repeat: 3,
129          yoyo: true,
130          duration: 0.4,
131        },
132      ) // 3. blink the intersection twice
133      .to(
134        mogle_intersection,
135        { opacity: 0, duration: 0.4 },
136      ) // 4. fade out intersection
137      .to(
138        mogl_geofences,
139        { scale: 0.7, duration: 1 },
140        "-=0.1",
141      ) // 4. scale geofences down from center
142      .to(
143        "#mogl_circle_highlighted",
144        { x: 0, duration: 1 },
145        "<",
146      ) // 5. move dot in slider to the left
147      .to(
148        "#mogl_line",
149        { scaleX: 1, duration: 1 },
150        "<",
151      ) // 6. simultanious scale the line back to original
152          .to(
153        "#mogl_line_dashed",
154        {
155          stroke: "#FF0000",
156          repeat: 4,
157          yoyo: true,
158          duration: 0.4,
159        },
160      ) // blink the dashed line
161          .to(
162        "#mogl_circle_outlined > path",
163        {
164          fill: "#FF0000",
165          repeat: 4,
166          yoyo: true,
167          duration: 0.4,
168        },
169        "<"
170      ) // simultanious change color of outlined circle
171
172      .to(mogl_geofences, { opacity: 0, duration: 1 }, "+=1") // 5. hide geofences
173      .to(
174        "#mogl_slider",
175        { opacity: 0, duration: 1 },
176        "<",
177      ) // fade out the slider
178      .set(mogl_geofences, { scale: 1 }); // reset for loop
179
180    // Include extra GSAP plugins before app.js if your SVG animation needs them
181    tl.play();
182  }
183
184
185
186
187
188
189  /**
190    * ------ merged geofencee section -------
191    */
192
193
194  /**
195   * ------ section 1: map merged geofence merging (mmgm) -------
196   */
197
198  const mmgmGeofence1 = document.getElementById("mmgm-geofence_1");
199  const mmgmGeofence2 = document.getElementById("mmgm-geofence_2");
200  const mmgmMergedGeofence = document.getElementById("mmgm-merged_geofence");
201  const mmgmIntersection = document.getElementById("mmgm-intersection");
202  if (
203    mmgmGeofence1 &&
204    mmgmGeofence2 &&
205    mmgmMergedGeofence &&
206    mmgmIntersection &&
207    window.MorphSVGPlugin
208  ) {
209
210    /**
211     * if the animation is part of a slide, we need to find the slide element to register play/stop controllers.
212     * initially the animation is paused, so it won't play until the slide is active.
213     * otherwise the animation might be part of a different page not containing a slide
214     * in this case the animation will play as soon as the DOM is loaded
215     */
216
217    const slideEl1 = mmgmGeofence1.closest(".sw-inapp-help-page");  // goes upwards in the DOM tree to find the parent with class .sw-inapp-help-page
218
219    let mmgmTlPaused = true; // start paused until we confirm the slide exists and register controllers
220
221    if (!slideEl1) {  // slide not found - start playing the animation immediately for non-sli
221de content
222      mmgmTlPaused = false;
223    }
224
225    gsap.set([mmgmGeofence1, mmgmGeofence2, mmgmMergedGeofence, mmgmIntersection], { autoAlpha: 0 });
226
227    const mmgmTl = gsap.timeline({ paused: mmgmTlPaused, repeat: -1, defaults: { ease: "power1.inOut" } });
228
229    mmgmTl.to([mmgmGeofence1, mmgmGeofence2], { autoAlpha: 1, duration: 1}) // 1. fade in geofences
230      .to(
231        mmgmIntersection,
232        {
233          autoAlpha: 1,
234          repeat: 3,
235          yoyo: true,
236          duration: 0.4,
237        },
238      ) // 3. blink the intersection twice
239      .to(
240        [mmgmGeofence1, mmgmGeofence2, mmgmIntersection],
241        { autoAlpha: 0, duration: 0.4 },
242      ) // 4. fade out intersection + geofences
243      .to(
244        mmgmMergedGeofence,
245        { autoAlpha: 1, duration: 1 },
246        "-=1"
247      ) // 5. show merged geofence
248      .to(
249        mmgmMergedGeofence,
250        { autoAlpha: 0, duration: 1 },
251        "+=1"
252      );
253
254    if (slideEl1) {  // slide found - register controllers to play/pause the animation based on slide visibility
255      registerSlideController(slideEl1, {
256        play: () => mmgmTl.restart(true),
257        stop: () => mmgmTl.pause(0),
258      });
259    }
260
261  }
262
263
264  /**
265   * ------ section 2: map merged geofence notifications (mmgn) -------
266   */
267  const mmgnManikinCircle = document.getElementById("mmgn-manikin_circle");
268  const mmgnBellFlag = document.getElementById("mmgn-bell_icon_flag");
269  const mmgnBellIcon = document.getElementById("mmgn-bell_icon");
270  const mmgnManikinLegsStart = document.getElementById("mmgn-manikin-legs-start");
271  const mmgnManikinLegsEnd = document.getElementById("mmgn-manikin-legs-end");
272  if (
273    mmgnManikinCircle &&
274    mmgnBellFlag &&
275    mmgnBellIcon &&
276    mmgnManikinLegsStart &&
277    mmgnManikinLegsEnd &&
278    window.MorphSVGPlugin
279  ) {
280
281    const slideEl2 = mmgnManikinCircle.closest(".sw-inapp-help-page");
282    // if (!slideEl2) return;
283
284    let mmgnTlPaused = true; // start paused until we confirm the slide exists and register controllers
285
286    if (!slideEl2) {  // slide not found - start playing the animation immediately for non-slide content
287      mmgnTlPaused = false;
288    }
289
290
291    gsap.set(mmgnManikinCircle, { x: 80, autoAlpha: 0 });
292    gsap.set(mmgnBellFlag, { autoAlpha: 0 });
293    gsap.set(mmgnBellIcon, {
294      transformOrigin: "50% 15%",
295    });
296    gsap.set(mmgnManikinLegsEnd, { autoAlpha: 0 });
297    const walkLoop = gsap.timeline({
298      paused: true,
299      repeat: -1,
300      yoyo: true,
301      defaults: { duration: 0.5, ease: "power1.inOut" },
302    });
303    walkLoop.to(mmgnManikinLegsStart, { morphSVG: mmgnManikinLegsEnd });
304
305    const mmgnTl = gsap.timeline({ paused: mmgnTlPaused, repeat: -1, defaults: { ease: "power1.inOut" } });
306
307    mmgnTl.to(mmgnManikinCircle, { autoAlpha: 1, duration: 1}) // 1. fade in
308      .to(
309        mmgnManikinCircle,
310        {
311          x: 0,
312          duration: 2,
313          onStart: () => walkLoop.play(),
314          onComplete: () => walkLoop.pause(0),
315          ease: "power1.inOut",
316        },
317        "-=0.5"
318      ) // 2. move while walking
319      .to(mmgnBellFlag, { autoAlpha: 1, duration: 0.5 }) // 3. show flag
320      .to(
321        mmgnBellIcon,
322        { rotation: 10, duration: 0.12 }
323      )
324      .to(
325        mmgnBellIcon,
326        { rotation: -10, repeat: 2, yoyo: true, duration: 0.15 }
327      )
328      .to(
329        mmgnBellIcon,
330        { rotation: 0, duration: 0.12 }
331      )
332      // 4. ring twice
333      .to([mmgnManikinCircle, mmgnBellFlag], { autoAlpha: 0, duration: 1 }, "+=1") // 5. fade out
334      .set(mmgnManikinCircle, { x: 80 });
335
336    if (slideEl2) {  // slide found - register controllers to play/pause the animation based on slide visibility
337      registerSlideController(slideEl2, {
338        play: () => mmgnTl.restart(true),
339        stop: () => mmgnTl.pause(0),
340      });
341    }
342
343  }
344
345
346  /**
347   * ------ section 3: map merged geofence keyless entry (mmgke) -------
348   */
349  const mmgkeManikinCircle = document.getElementById("mmgke-manikin_circle");
350  const mmgkeCircleTick = document.getElementById("mmgke-circle_tick");
351  const mmgkeCircleX = document.getElementById("mmgke-circle_x");
352  const mmgkeManikinLegsStart = document.getElementById("mmgke-manikin-legs-start");
353  const mmgkeManikinLegsEnd = document.getElementById("mmgke-manikin-legs-end");
354  const mmgkeDoor1 = document.getElementById("mmgke-poi_1");
355  const mmgkeDoor2 = document.getElementById("mmgke-poi_2");
356  if (
357    mmgkeManikinCircle &&
358    mmgkeCircleTick &&
359    mmgkeCircleX &&
360    mmgkeManikinLegsStart &&
361    mmgkeManikinLegsEnd &&
362    window.MorphSVGPlugin
363  ) {
364
365    const slideEl3 = mmgkeDoor2.closest(".sw-inapp-help-page");
366    // if (!slideEl3) return;
367    let mmgkeTlPaused = true; // start paused until we confirm the slide exists and register controllers
368
369    if (!slideEl3) {  // slide not found - start playing the animation immediately for non-sli
369de content
370      mmgkeTlPaused = false;
371    }
372
373
374    gsap.set(mmgkeManikinCircle, { x: 80, autoAlpha: 0 });
375    gsap.set([mmgkeCircleTick, mmgkeCircleX], { autoAlpha: 0 });
376    gsap.set(mmgkeManikinLegsEnd, { autoAlpha: 0 });
377
378    const walkLoop = gsap.timeline({
379      paused: true,
380      repeat: -1,
381      yoyo: true,
382      defaults: { duration: 0.5, ease: "power1.inOut" },
383    });
384    walkLoop.to(mmgkeManikinLegsStart, { morphSVG: mmgkeManikinLegsEnd });
385
386    const mmgkeTl = gsap.timeline({ paused: mmgkeTlPaused, repeat: -1, defaults: { ease: "power1.inOut" } });
387
388    mmgkeTl.to(mmgkeManikinCircle, { autoAlpha: 1, duration: 1}) // 1. fade in
389      .to(
390        mmgkeManikinCircle,
391        {
392          x: 0,
393          duration: 2,
394          onStart: () => walkLoop.play(),
395          onComplete: () => walkLoop.pause(0),
396          ease: "power1.inOut",
397        },
398        "-=0.5"
399      ) // 2. move while walking
400      .to(
401        mmgkeDoor2,
402        { scale: 1.1, repeat: 3, yoyo: true, duration: 0.3, transformOrigin: "50% 100%" }
403      )
404
405      .to(mmgkeCircleTick, { autoAlpha: 1, duration: 0.5 }) // 3. show flag
406      .to(
407        mmgkeDoor1,
408        { rotate: 10, repeat: 3, yoyo: true, duration: 0.3, transformOrigin: "50% 100%" }
409      )
410
411      .to(mmgkeCircleX, { autoAlpha: 1, duration: 0.5 }) // 3. show flag
412      .to([mmgkeManikinCircle, mmgkeCircleTick, mmgkeCircleX], { autoAlpha: 0, duration: 1 }, "+=1") // 5. fade out
413      .set(mmgkeManikinCircle, { x: 80 });
414
415    if(slideEl3){
416      registerSlideController(slideEl3, {
417        play: () => mmgkeTl.restart(true),
418        stop: () => mmgkeTl.pause(0),
419      });
420    }
421  }
422
423
424});

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.