PageSourceSearch

https://ajsrp.com/wp-content/plugins/techto-addons/assets/js/frontend.js?ver=1790927361

js ajsrp.com collected 2026-10-02 07:49:49 UTC 6,271 bytes, 165 lines download raw bytes

1(function ($) {
2    "use strict";
3
4    // Function to handle "rs-lettering-text"
5    const letteringTextHandler = function () {
6        if ($(".rs-lettering-text").length) {
7            $(".rs-lettering-text").each(function () {
8                const sentence = $(this).text().trim();
9                let wrappedSentence = "";
10                const useEm = !$(this).hasClass("style2");
11
12                for (let i = 0; i < sentence.length; i++) {
13                    wrappedSentence += useEm 
14                        ? `<span><em>${sentence[i]}</em></span>` 
15                        : `<span class="char${[i]}">${sentence[i]}</span>`;
16                }
17
18                $(this).html(wrappedSentence);
19            });
20        }
21    };
22
23    // Function for handling "draw-line" elements
24    const headingJsHandler = function ($scope, $) {
25        const drawLines = $scope.find(".draw-line");
26        if (!drawLines.length) return;
27
28        const observer = new IntersectionObserver((entries) => {
29            entries.forEach((entry) => {
30                if (entry.isIntersecting) {
31                    setTimeout(() => {
32                        entry.target.classList.add("start-draw");
33                    }, 300);
34                } else {
35                    entry.target.classList.remove("start-draw");
36                }
37            });
38        }, { threshold: 0.1 });
39
40        drawLines.each((_, drawLine) => observer.observe(drawLine));
41    };
42
43    // Function for handling "rs-highlight" elements
44    const handleHighlight = () => {
45        const sections = document.querySelectorAll(".rs-highlight");
46        if (!sections.length) return;
47
48        sections.forEach((section) => {
49            const thresholdClass = [...section.classList].find(cls => cls.startsWith("threshold-"));
50            const threshold = thresholdClass ? parseFloat(thresholdClass.split("-")[1]) : 0.4;
51
52            const observer = new IntersectionObserver((entries) => {
53                entries.forEach((entry) => {
54                    if (entry.isIntersecting) {
55                        entry.target.classList.add("in-view");
56                    } else {
57                        entry.target.classList.remove("in-view");
58                    }
59                });
60            }, { root: null, threshold });
61
62            observer.observe(section);
63        });
64    };
65
66    // Function to mouse move parallax effect
67    const handleParallax = () => {
68        if ($('.rs-parallax-parent').length) {
69            $(".rs-parallax-parent").each(function () {
70                var $wrapper = $(this);
71
72                if ($wrapper.hasClass("parallax-initialized")) return;
73                $wrapper.addClass("parallax-initialized");
74
75                let $elements = $wrapper.find(".rs-parallax-child");
76
77                $elements.each(function () {
78                    let $original = $(this);
79                    let depthClass = ($original.attr("class").match(/parallax-depth-(\d+)/) || [])[1];
80                    let movement = parseInt(depthClass, 10) || 30;
81
82                    let $element = $original;
83
84                    if ($original.hasClass("elementor-widget")) {
85                        const inner = $original.find(".elementor-widget-container > div");
86                        if (inner.length) {
87                            $element = inner;
88                        }
89                    }
90                    
91                    let targetX = 0, targetY = 0;
92                    let currentX = 0, currentY = 0;
93                    let isHovering = false;
94
95                    function animate() {
96                        if (!isHovering) return;
97                        currentX += (targetX - currentX) * 0.1;
98                        currentY += (targetY - currentY) * 0.1;
99                        $element.css("transform", `translate(${currentX}px, ${currentY}px)`);
100                        requestAnimationFrame(animate);
101                    }
102
103                    $wrapper.on("mouseenter", function () {
104                        isHovering = true;
105                        requestAnimationFrame(animate);
106                    });
107
108                    $wrapper.on("mousemove", function (e) {
109                        const offset = $wrapper.offset();
110                        const width = $wrapper.outerWidth();
111                        const height = $wrapper.outerHeight();
112                        const relX = e.pageX - offset.left;
113                        const relY = e.pageY - offset.top;
114                        targetX = ((relX - width / 2) / width) * movement;
115                        targetY = ((relY - height / 2) / height) * movement;
116                    });
117
118                    $wrapper.on("mouseleave", function () {
119                        isHovering = false;
120                        const resetInterval = setInterval(() => {
121                            currentX += (0 - currentX) * 0.1;
122                            currentY += (0 - currentY) * 0.1;
123                            $element.css("transform", `translate(${currentX}px, ${currentY}px)`);
124                            if (Math.abs(currentX) < 0.5 && Math.abs(currentY) < 0.5) {
125                                clearInterval(resetInterval);
126                                $element.css("transform", "translate3d(0px, 0px, 0)");
127                            }
128                        }, 16);
129                    });
130                });
131
132            });
133        }
134    };
135
136    // Initialize all functions
137    const initObservers = () => {
138        letteringTextHandler();
139        handleHighlight();
140    };
141
142    // Elementor hooks for frontend and editor
143    $(window).on("elementor/frontend/init", () => {
144        const isEditMode = elementorFrontend.isEditMode();
145
146        elementorFrontend.hooks.addAction("frontend/element_ready/rs-heading.default", headingJsHandler);
147
148        if (isEditMode) {
149            elementorFrontend.hooks.addAction("frontend/element_ready/global", () => {
150                initObservers();
151
152                $(document).ready( function() {
153                    handleParallax();
154                });
155            });
156        } else {
157            $(document).ready( function() {
158                initObservers();
159                handleParallax();
160            });
161        }
162    });
163
164})(jQuery);
165

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.