skip to Main Content

I want the animation of the hovered ball to pause, others should keep animating. Chat GPT has no clue. According to css hover should also reveal the 2nd image – > this only works when i remove javascript altogether.

Here’s the codepen

const balls = document.querySelectorAll('.ball');

// Function to animate the sway of a ball
function swayBall(ball, offsetAngle) {
    const amplitude = Math.random() * 1 + 1; 
    const speed = Math.random() * 0.02 + 0.01; 

    let angle = offsetAngle; 
    let isHovered = false; 
    let animationId; // 

    function animate() {
        if (!isHovered) {
            angle += speed; 
            const swayAngle = Math.sin(angle) * amplitude; 
            ball.style.transform = `rotate(${swayAngle}deg)`; 
        }
        animationId = requestAnimationFrame(animate); 
    }

    // Start animation
    animate();

    // Stop animation on hover
    ball.addEventListener('mouseenter', () => {
        isHovered = true; // Stop animation
        cancelAnimationFrame(animationId); 
        ball.style.transform = ''; 
        console.log(`Hover started on:`, ball); 
    });

    // Resume animation on mouse leave
    ball.addEventListener('mouseleave', () => {
        isHovered = false; 
        animate(); 
        console.log(`Hover ended on:`, ball); 
    });
}

balls.forEach((ball, index) => {
    const offsetAngle = Math.random() * Math.PI * 2; 
    swayBall(ball, offsetAngle);
});

Animation works fine, but it does not stop on hover, nor does it reveal the image below.

2

Answers


  1. that’s happening because "hanging-balls" div has no height at all. So in reality you are not hovering to the balls. you could just give it a fixed height or 100%. I’m pretty sure that’s the problem

    Login or Signup to reply.
  2. Your code and animation looks fine to me. But the angle is lost on hover. The reveal is working as I am seeing it.

    I removed three lines of code and the pendulum keeps its angle.

    1. In your "mouseenter" event listener
    //cancelAnimationFrame(animationId); 
    //ball.style.transform = ''; 
    
    1. In your "mouseleave" event listener
    //animate(); 
    
    const balls = document.querySelectorAll('.ball');
    
    // Function to animate the sway of a ball
    function swayBall(ball, offsetAngle) {
        const amplitude = Math.random() * 1 + 1; 
        const speed = Math.random() * 0.02 + 0.01; 
    
        let angle = offsetAngle; 
        let isHovered = false; 
        let animationId; // 
    
        function animate() {
            if (!isHovered) {
                angle += speed; 
                const swayAngle = Math.sin(angle) * amplitude; 
                ball.style.transform = `rotate(${swayAngle}deg)`; 
            }
            animationId = requestAnimationFrame(animate); 
        }
    
        // Start animation
        animate();
    
        // Stop animation on hover
        ball.addEventListener('mouseenter', () => {
            isHovered = true; // Stop animation
            //cancelAnimationFrame(animationId); 
            //ball.style.transform = ''; 
            console.log(`Hover started on:`, ball); 
        });
    
        // Resume animation on mouse leave
        ball.addEventListener('mouseleave', () => {
            isHovered = false; 
            //animate(); 
            console.log(`Hover ended on:`, ball); 
        });
    }
    
    balls.forEach((ball, index) => {
        const offsetAngle = Math.random() * Math.PI * 2; 
        swayBall(ball, offsetAngle);
    });
    .video-banner {
        position: relative;
        width: 1600px;
        height: 600px;
        border-radius: 20px;
        overflow: hidden;
        box-shadow: 0 8px 20px rgba(0, 0, 0, 0.3);
    }
    
    .video-banner video {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }
    
    .hanging-balls {
       
        top: 0;
        left: 0;
        width: 100%;
        display: flex;
        justify-content: space-evenly;
        align-items: flex-start;
        pointer-events: none;
    }
    
    .ball {
        position: relative;
        width: 16%;
        transform-origin: top center;
        pointer-events: auto; /* Allow hover */
    }
    
    .ball img {
        width: 100%;
        height: auto;
        position: absolute;
        top: 0;
        left: 0;
        transition: opacity 0.3s ease-in-out;
    }
    
    .ball img.default {
        z-index: 1; /* Default image starts on top */
    }
    
    .ball img.reveal {
        z-index: 2; /* Reveal image appears above */
        opacity: 0; /* Initially invisible */
        pointer-events: none; /* Prevent interaction when not visible */
    }
    
    .ball:hover img.default {
        opacity: 0; /* Fade out the default image */
    }
    
    .ball:hover img.reveal {
        opacity: 1; /* Fade in the reveal image */
    }
    <div class="video-banner">
        <div class="hanging-balls">
            <div class="ball">
                <img class="default" src="https://i.ibb.co/ZJsMGhn/ball1.png" alt="Red Ball">
                <img class="reveal" src="https://i.ibb.co/yVBdBG1/ball1-reveal.png" alt="Red Ball Reveal">
            </div>
            <div class="ball">
                <img class="default" src="https://i.ibb.co/Hnm7NL5/ball2.png" alt="Green Ball">
                <img class="reveal" src="https://i.ibb.co/N9gmg85/ball2-reveal.png" alt="Green Ball Reveal">
            </div>
            <div class="ball">
                <img class="default" src="https://i.ibb.co/mGxgyPb/ball3.png" alt="Blue Ball">
                <img class="reveal" src=https://i.ibb.co/hDwJvbG/ball3-reveal.png" alt="Blue Ball Reveal">
            </div>
            <div class="ball">
                <img class="default" src="https://i.ibb.co/4fx06NW/ball4.png" alt="Gold Ball">
                <img class="reveal" src="https://i.ibb.co/xf5DWh0/ball4-reveal.png" alt="Gold Ball Reveal">
            </div>
        </div>
        <video autoplay muted playsinline id="banner-video" poster="https://i.ibb.co/QjnMSLG/bground.jpg" >
            <source src="https://i.ibb.co/QjnMSLG/bground.jpg" type="video/mp4">
            Your browser does not support the video tag.
        </video>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search