Vue js. Three js animation

Hello everyone. I need to make an animation for the background of the site where there will be a scene with water on which a ball falls and round waves diverge from this ball (then I want to change the ball to a drop). I can’t do it and I don’t understand why. The waves are simply not created by the falling ball.

my code:
https://codesandbox.io/p/sandbox/github/codesandbox/sandbox-templates/tree/main/vue-vite

<template>
  <div ref="container" class="scene-container"></div>
</template>

<script setup>
import * as THREE from 'three';
import { Water } from 'three/examples/jsm/objects/Water.js';
import { RGBELoader } from 'three/examples/jsm/loaders/RGBELoader.js';
import { onMounted, ref } from 'vue';

const container = ref(null);

onMounted(() => {
  // Scene initialization
  const scene = new THREE.Scene();
  const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
  camera.position.set(0, 5, 15);

  const renderer = new THREE.WebGLRenderer({ antialias: true });
  renderer.setSize(window.innerWidth, window.innerHeight);
  renderer.toneMapping = THREE.ACESFilmicToneMapping; // Improves contrast
  renderer.toneMappingExposure = 1.0;
  container.value.appendChild(renderer.domElement);

  // HDRI Environment
  new RGBELoader().load('/autumn_field_puresky_2k.hdr', (texture) => {
    texture.mapping = THREE.EquirectangularReflectionMapping;
    scene.environment = texture;
    scene.background = texture;
  });

  // Lighting setup
  const sunLight = new THREE.DirectionalLight(0xffffff, 3);
  sunLight.position.set(10, 20, 10);
  scene.add(sunLight);
  scene.add(new THREE.AmbientLight(0x404040)); // Soft ambient light

  // Water normal texture
  const waterNormals = new THREE.TextureLoader().load('/waternormals.jpg');
  waterNormals.wrapS = waterNormals.wrapT = THREE.RepeatWrapping;

  // Add realistic water
  const waterGeometry = new THREE.PlaneGeometry(100, 100);
  const water = new Water(waterGeometry, {
    textureWidth: 512,
    textureHeight: 512,
    waterNormals: waterNormals,
    sunDirection: new THREE.Vector3(),
    sunColor: 0xffffff,
    waterColor: 0x0077be,
    distortionScale: 3.7,
    fog: false,
    transparent: true,
    opacity: 0, // Initial transparency
  });

  // Check if uniforms exist
  if (!water.material.uniforms) {
    water.material.uniforms = {};
  }

  // Add ripple effects to water shader
  water.material.onBeforeCompile = (shader) => {
    shader.uniforms.rippleCenter = { value: new THREE.Vector2(0, 0) };
    shader.uniforms.rippleTime = { value: -1 };
    shader.uniforms.rippleStrength = { value: 1.5 }; // Increased ripple strength
    shader.uniforms.rippleColor = { value: new THREE.Color(0x333) }; // Ripple color

    // Add ripple logic to shader
    shader.vertexShader = shader.vertexShader.replace(
      '#include <common>',
      `
      #include <common>
      uniform vec2 rippleCenter;
      uniform float rippleTime;
      uniform float rippleStrength;
      uniform vec3 rippleColor;
      `
    );

    shader.vertexShader = shader.vertexShader.replace(
      '#include <begin_vertex>',
      `
      #include <begin_vertex>
      if (rippleTime >= 0.0) {
        float rippleDistance = distance(position.xz, rippleCenter);
        float rippleIntensity = max(0.0, 1.0 - rippleDistance / 15.0); // Increased ripple radius
        float rippleEffect = sin(rippleTime * 10.0 - rippleDistance * 2.0) * rippleIntensity * rippleStrength;
        transformed.y += rippleEffect;
      }
      `
    );

    shader.fragmentShader = shader.fragmentShader.replace(
      '#include <output_fragment>',
      `
      #include <output_fragment>
      if (rippleTime >= 0.0) {
        float rippleDistance = distance(vWorldPosition.xz, rippleCenter);
        float rippleIntensity = max(0.0, 1.0 - rippleDistance / 15.0); // Increased ripple radius
        gl_FragColor.rgb = mix(gl_FragColor.rgb, rippleColor, rippleIntensity * 0.5); // Color mixing
      }
      `
    );

    water.material.uniforms.rippleCenter = shader.uniforms.rippleCenter;
    water.material.uniforms.rippleTime = shader.uniforms.rippleTime;
    water.material.uniforms.rippleStrength = shader.uniforms.rippleStrength;
    water.material.uniforms.rippleColor = shader.uniforms.rippleColor;
  };

  water.rotation.x = -Math.PI / 2;
  scene.add(water);

  // Add sphere
  const ballGeometry = new THREE.SphereGeometry(0.5, 32, 32);
  const ballMaterial = new THREE.MeshStandardMaterial({ color: 0xff0000 });
  const ball = new THREE.Mesh(ballGeometry, ballMaterial);
  ball.visible = false;
  scene.add(ball);

  // Create wave effect function
  function createWave(position) {
    // Set ripple center
    water.material.uniforms.rippleCenter.value.set(position.x, position.z);

    // Activate ripple effect
    water.material.uniforms.rippleTime.value = 0;
  }

  // Ball drop animation
  function dropBall() {
    ball.position.set(Math.random() * 10 - 5, 15, Math.random() * 10 - 5);
    ball.visible = true;

    function animateBall() {
      ball.position.y -= 0.5;

      if (ball.position.y <= 0.5) {
        ball.visible = false;
        createWave(ball.position); // Create ripple effect
      } else {
        requestAnimationFrame(animateBall);
      }
    }

    animateBall();
  }

  // Ball drops every 3 seconds
  setInterval(dropBall, 3000);

  // Water transparency control
  let isWaterTransparent = false;

  // Toggle water transparency
  function toggleWaterTransparency() {
    isWaterTransparent = !isWaterTransparent;
    water.material.transparent = isWaterTransparent;
    water.material.opacity = isWaterTransparent ? 0.2 : 0.9; // Change opacity
  }

  // Add 'T' key event listener
  window.addEventListener('keydown', (event) => {
    if (event.key === 't' || event.key === 'T') {
      toggleWaterTransparency();
    }
  });

  // Main animation loop
  function animate() {
    requestAnimationFrame(animate);

    // Update water time uniform
    if (water.material.uniforms && water.material.uniforms.time) {
      water.material.uniforms.time.value += 0.02;
    }

    // Update ripple effects
    if (water.material.uniforms && water.material.uniforms.rippleTime) {
      water.material.uniforms.rippleTime.value += 0.05;

      // Disable finished ripples
      if (water.material.uniforms.rippleTime.value > 2) {
        water.material.uniforms.rippleTime.value = -1; // Disable ripple
      }
    }

    renderer.render(scene, camera);
  }
  animate();

  // Window resize handler
  window.addEventListener('resize', () => {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize(window.innerWidth, window.innerHeight);
  });
});
</script>

<style>
.scene-container {
  width: 100%;
  height: 100vh;
}
</style>