Switch up the animation direction after the vimeo video finishes playing

My video module has a splash screen that reveals a full-screen video when clicked for screen sizes 667+. I want to reverse the animation after the video ends and return to the splash screen. I'm unsure of how to approach this or if it's even possible. Any assistance would be greatly appreciated!

    $(function(){

    var $parent = $('.video-hero'),
            $video = $parent.find('iframe'),
            $playButton = $(".play"),
            $itemsToFadeOut = $(".vid-cap, .ghost"),
            f = $video[0],
            url = $video.attr('src').split('?')[0],
            activeVideoClass = "video-started";

            // setup fitVids
            $parent.fitVids();

            // handle play click
            $playButton.click(function(e){

                e.preventDefault();

                // grab height of video
                var videoHeight = $video.height();

                // add class to hero when video is triggered
                $parent.addClass(activeVideoClass);

                // fade out the play button
                $(this).fadeOut("fast");

                // fade out poster image, overlay, and heading
                $itemsToFadeOut.fadeOut();

                // toggle accessibility features
                $video.attr({
                    "aria-hidden" : "false",
                    "tabindex" : "0"
                });

                // set focus to video for accessibility control
                $video.focus();

                // set height of hero based on height of video
                $parent.css("max-height",videoHeight).height(videoHeight);

                // send play command to Vimeo api
                runCommand('play');

            });

            // send play to vimeo api
            var runCommand = function(cmd){
                var data = {method : cmd};
                f.contentWindow.postMessage(JSON.stringify(data), url);
            }

            // handle resize
            $(window).resize(function(){
                var videoHeight = $video.height();
                if($(".video-started").size() === 1){
                    $parent.height(videoHeight);
                }
            });

});

Don't forget to resize my JSFiddle to see the animation in action.

Answer №1

Exciting news, I have cracked the code! Let me break down each part of the code for better understanding and reference in the future.

Without utilizing the froogaloop cdn, I was able to achieve my goal by simply using fitvids.js. Here is a functioning fiddle showcasing my solutions.

In the JS sections below, focus on the answer to "reversing my function after video finishes." You will mainly need to pay attention to my Event Handlers, Connection to the API, and Player State Functions. By establishing the connection and detecting when the video ends, I used addClass(); and removeClass(); along with CSS Transitions to manage the transition between the play and ready (post finish) states.

I have tried to document and explain as thoroughly as possible, hoping that this can benefit someone down the line!

Assigning Variables

Nothing significant here, just the initial setup. Pay close attention to var url as it's crucial for utilizing listeners with the Vimeo API.

var parent = $('.video-hero'),
                 f = $('iframe'),
                 $playButton = $(".play"),
                 $itemsToFadeOut = $(".vid-cap, .ghost, .play"),
                 $video = f[0],
                 url = f.attr('src').split('?')[0],
                 activeVideoClass = "video-started", // Class for video playing state
           standardClass = "standard"; // Class for video finished/before play state

Event Listeners / Handlers

The listeners await messages from the api/player indicating if the video is ready, paused, finished, or playing.

listeners

// Listen for messages from the player
if (window.addEventListener){
    window.addEventListener('message', onMessageReceived, false);
}
else {
    window.attachEvent('onmessage', onMessageReceived, false);
}

The handlers determine how my functions are triggered based on the received state (case) from the API.

handlers

// Handle messages received from the player
function onMessageReceived(e) {
    var data = JSON.parse(e.data);

    switch (data.event) {
        case 'ready':
            onReady();
            break;

        case 'pause':
            onPause();
            break;

        case 'finish':
            onFinish();
            break;
    }
}

Connecting to the Vimeo API

This segment coordinates with my html play button and vimeo's api/player to execute, pause, and stop the video.

// send play to vimeo api
            var runCommand = function(cmd){
                var data = {method : cmd};
                f[0].contentWindow.postMessage(JSON.stringify(data), url);
            }


// Helper function for sending a message to the player
function post(action, value) {
    var data = { method: action };

    if (value) {
        data.value = value;
    }

    f[0].contentWindow.postMessage(JSON.stringify(data), url);
}

Player State Functions

Determining actions based on the player's current state or case.

function onReady() {
    post('addEventListener', 'finish');
}

function onPause() {
    console.log('paused');
}

function onFinish() {
    // Add class to hero when video is triggered
    parent.removeClass(activeVideoClass);
    parent.addClass(standardClass);         
    // Fade out the play button
    $(this).fadeIn("slow");
    // Fade out poster image, overlay, and heading
    $itemsToFadeOut.fadeIn();
}

Answer №2

If you want to detect the end of a video and execute JavaScript code, consider utilizing the Froogaloop library.

Check out this link for more information:

You can implement something like this:

var player = $f(iframe[0]);

player.addEvent('ready', function() {
    player.addEvent('finish', function() {
        // Execute animation here...
    });
});

For a list of different events, visit:

I used this approach on a recent project to close a modal window when a video ends:

Feel free to explore the unminified JS code here:

I wish I could offer more assistance, but hopefully, this will point you in the right direction.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

We encountered an error: The function setName is not defined

I am working on some code where I have defined a function, but it is still showing me errors related to setname, setemail, and password. import React, {useState} from 'react' import './Auth.css' import icon from '../../assets/logo. ...

What is the best way to toggle dropdown menu items using jQuery?

Upon clicking on an li, the dropdown menu associated with it slides down. If another adjacent li is clicked, its drop down menu will slide down while the previous one slides back up. However, if I click on the same li to open and close it, the drop down m ...

Saving a Coordinated Universal Time and showcasing it in the corresponding local timezone

In my upcoming MVC4 application that will have a global audience, one of the features involves recording the date and time when a transaction is added or modified. Since I am storing the transaction datetime in UTC format, what would be the most effective ...

What is the best way to create a PHP session variable upon clicking a button while remaining on the current page?

On my webpage, I've implemented a DIV element with a close button that, when clicked, triggers a jQuery animation to slide the DIV up. HTML: <div id="closeable"> <a id="close_button"></a> </div> jQuery: $('#close_bu ...

Is it possible to solve a mathematical equation entered into a text box that resembles an Excel cell, complete with an equal sign?

On my php website, I have text boxes within a form. I'm looking for a way to enter formulas like "=4*6" or "=5/12*30" (without the quotes) into the text box and have it calculate the result. I have an onchange event set up on the text box to trigger a ...

Transform seconds into an ISO 8601 duration using JavaScript

Dealing with ISO 8601 durations can be quite tricky. Efficiently converting seconds to durations is my current challenge, especially in JavaScript. Stay tuned for my solution and the Jest test script coming up next. ...

Altering the appearance of a different element with React

I'm new to using react and struggling to make a Component appear when I click on a button. Here's an example of the code I have so far: <Button>GO</Button> <CalendarIcon id="calendar visibility="hidden"/> and th ...

Is it possible to use a webcam to scan a QR code directly into a webpage?

Is it possible to enable users to input data on a webpage using QR code scanning? I'm unsure if there is a tool that can be integrated into the page or paired with a library to make this happen, or if I need to consider an external solution beyond th ...

send information via an ajax call to trigger a callback function

Can data be passed through an Ajax request to the Callback function without using global variables? For example, can the request function pass the passData through the callback function while also getting normal response data? function makeRequest(callba ...

Shopping cart has encountered an issue with storing the data correctly

While I've managed to successfully integrate another service, the challenge now lies in implementing the logic for correctly generating cart items. My goal is to increment the quantity of items in the cart by one with each function call, but it seems ...

Tips for deleting a text node preceding a div element?

Here's the HTML code snippet I am currently working with: <div id="wrapper"> <div id="some-id"></div> "this is some texxt" <div id="some-id-2"></div> </div> Is there a way to eliminate the text using CSS? ...

Sending Information from Node/Express to Client-Side JavaScript

I'm a bit confused about how to make this work, and my searches have not yielded the answer I need. Currently, I have been successfully passing data from a node and express server to my front end ejs. Now, I am attempting to integrate charts.js into m ...

Tips on customizing the navigation bar color in Bootstrap

Is there a way to update the CSS in Bootstrap 4 to customize the color of the navbar? I'm having issues with my code. Can you take a look at it? <nav class="navbar navbar-expand-lg navbar-dark bg-transparent"> <div class="container"> ...

Hover effect exclusively for specific child elements

Applying a hover effect to all divs inside a well can be done using the following code: .well:hover div { background-color:green } However, if you only want to apply the hover effect to specific divs inside the well, you can specify them in this way: ...

Adjust picture based on the MaterialUI slider's value

I want to incorporate a discrete Slider component from Material UI into my React web app. The goal is to have the user change a picture every time they adjust the slider value, with the new image displayed in a specific div. I am wondering how I can achiev ...

What is the best way to create a cornered button using CSS?

Is there a way to create a button using only CSS? https://i.stack.imgur.com/7mjVV.png This is the code I've come up with so far: .customButton { width: 100px; height: 100px; background: #6d1a3e; position: relative; transform: rotate(-90 ...

Utilizing Javascript for logging into Facebook

Feeling frustrated! I've been struggling to implement the Facebook Login pop-up on my website using the Facebook JavaScript API. Despite following tutorials, I can't seem to make the login pop-up appear. Instead, when I go through the login pro ...

The process of updating UseContext global state in React Native and ensuring that the change is reflected across all screens

Struggling with updating global state values using React useContext on different screens? Attempting to change theme color in the App, but changes only appear on the current screen and not carried over to others? Looking for assistance in resolving this ...

Tips for maintaining the data on a page continuously updating in AngularJS

I have this code snippet: $cookieStore.put('profileData', $scope.profileData); var profileData = $cookieStore.get('profileData'); $scope.init = function(){ var profileData = $cookieStore.get('pr ...

The ajax request does not support this method (the keydown event is only active during debugging)

I've encountered a strange issue with an AJAX request. The server-side code in app.py: #### app.py from flask import Flask, request, render_template app = Flask(__name__) app.debug = True @app.route("/myajax", methods=['GET', ...