( function( $ ) {
    // Background Mousemove Effect
    function hoverFlowmapDeformation() {
        let els = $('.ripple');
        if (!els.length) return;
    
        const flowmapDeformation1 = (el) => {
            const elWidth = $(el).outerWidth();
            const elHeight = $(el).outerHeight();
            const imgSize = [elWidth, elHeight];
            const vertex = `
                attribute vec2 uv;
                attribute vec2 position;
                varying vec2 vUv;
                void main() {
                    vUv = uv;
                    gl_Position = vec4(position, 0, 1);
                }
            `;
            const fragment = `
                precision highp float;
                precision highp int;
                uniform sampler2D tWater;
                uniform sampler2D tFlow;
                uniform float uTime;
                varying vec2 vUv;
                uniform vec4 res;
    
                void main() {
                    vec3 flow = texture2D(tFlow, vUv).rgb;
                    vec2 uv = .5 * gl_FragCoord.xy / res.xy;
                    vec2 myUV = (uv - vec2(0.5)) * res.zw + vec2(0.5);
                    myUV -= flow.xy * (0.10 * 0.7);
                    vec2 myUV2 = (uv - vec2(0.5)) * res.zw + vec2(0.5);
                    myUV2 -= flow.xy * (0.075 * 0.7);
                    vec2 myUV3 = (uv - vec2(0.5)) * res.zw + vec2(0.5);
                    myUV3 -= flow.xy * (0.05 * 0.7);
                    vec3 tex = texture2D(tWater, myUV).rgb;
                    vec3 tex2 = texture2D(tWater, myUV2).rgb;
                    vec3 tex3 = texture2D(tWater, myUV3).rgb;
                    gl_FragColor = vec4(tex.r, tex2.g, tex3.b, 1.0);
                }
            `;
    
            const renderer = new ogl.Renderer({ dpr: 2 });
            const gl = renderer.gl;
    
            $(el).append(gl.canvas);
    
            let bgImage = $(el).css('background-image');
            bgImage = bgImage.replace(/^url\(["']?/, '').replace(/["']?\)$/, ''); // Loại bỏ 'url("")'
    
            const img = new Image();
            const texture = new ogl.Texture(gl, {
                minFilter: gl.LINEAR,
                magFilter: gl.LINEAR
            });
    
            img.onload = () => (texture.image = img);
            img.crossOrigin = "Anonymous";
            img.src = bgImage;
    
            let aspect = 1;
            const mouse = new ogl.Vec2(-1);
            const velocity = new ogl.Vec2();
    
            function resize() {
                const elRect = $(el).get(0).getBoundingClientRect();
                const elWidth = elRect.width;
                const elHeight = elRect.height;
    
                let a1, a2;
                const imageAspect = imgSize[1] / imgSize[0];
                if (elHeight / elWidth < imageAspect) {
                    a1 = 1;
                    a2 = elHeight / elWidth / imageAspect;
                } else {
                    a1 = (elWidth / elHeight) * imageAspect;
                    a2 = 1;
                }
    
                mesh.program.uniforms.res.value = new ogl.Vec4(
                    elWidth,
                    elHeight,
                    a1,
                    a2
                );
                renderer.setSize(elWidth, elHeight);
                aspect = elWidth / elHeight;
            }
    
            const flowmap = new ogl.Flowmap(gl);
            const geometry = new ogl.Geometry(gl, {
                position: {
                    size: 2,
                    data: new Float32Array([-1, -1, 3, -1, -1, 3])
                },
                uv: { size: 2, data: new Float32Array([0, 0, 2, 0, 0, 2]) }
            });
    
            const program = new ogl.Program(gl, {
                vertex,
                fragment,
                uniforms: {
                    uTime: { value: 0 },
                    tWater: { value: texture },
                    res: { value: new ogl.Vec4(elWidth, elHeight, 1, 1) },
                    tFlow: flowmap.uniform
                }
            });
    
            const mesh = new ogl.Mesh(gl, { geometry, program });
    
            window.addEventListener("resize", resize, false);
            resize();
    
            const isTouchCapable = "ontouchstart" in window;
            if (isTouchCapable) {
                $(el).on("touchstart", updateMouse);
                $(el).on("touchmove", updateMouse);
            } else {
                $(el).on("mousemove", updateMouse);
            }
    
            let lastTime;
            const lastMouse = new ogl.Vec2();
    
            function updateMouse(e) {
                e.preventDefault();
                let mouseX, mouseY;
    
                if (e.changedTouches && e.changedTouches.length) {
                    e.x = e.changedTouches[0].pageX;
                    e.y = e.changedTouches[0].pageY;
                }
    
                if (e.x === undefined) {
                    e.x = e.pageX;
                    e.y = e.pageY;
                }
    
                const rect = $(el).get(0).getBoundingClientRect();
                mouseX = e.pageX - (rect.left + window.scrollX);
                mouseY = e.pageY - (rect.top + window.scrollY);
    
                mouse.set(mouseX / rect.width, 1.0 - mouseY / rect.height);
    
                if (!lastTime) {
                    lastTime = performance.now();
                    lastMouse.set(e.x, e.y);
                }
    
                const deltaX = e.x - lastMouse.x;
                const deltaY = e.y - lastMouse.y;
                lastMouse.set(e.x, e.y);
                let time = performance.now();
                let delta = Math.max(10.4, time - lastTime);
                lastTime = time;
    
                velocity.x = deltaX / delta;
                velocity.y = deltaY / delta;
                velocity.needsUpdate = true;
            }
    
            requestAnimationFrame(update);
            function update(t) {
                requestAnimationFrame(update);
    
                if (!velocity.needsUpdate) {
                    mouse.set(-1);
                    velocity.set(0);
                }
    
                velocity.needsUpdate = false;
                flowmap.aspect = aspect;
                flowmap.mouse.copy(mouse);
                flowmap.velocity.lerp(velocity, velocity.len ? 0.15 : 0.1);
                flowmap.update();
                program.uniforms.uTime.value = t * 0.01;
                renderer.render({ scene: mesh });
            }
        };
    
        els.each(function (i, el) {
            flowmapDeformation1(el);
        });
    }
    

    $( window ).on( 'elementor/frontend/init', function() {
        hoverFlowmapDeformation()
        // elementorFrontend.hooks.addAction( `frontend/element_ready/pxl_background.default`, function( $scope ) {
        //     hoverFlowmapDeformation($scope);
        // });
    });
} )( jQuery );

