Trigger CSS Animations in JavaScript

Viewed 104651

I don't know how to use JQuery, so I need a method which could trigger an animation using JavaScript only.

I need to call/trigger CSS Animation when the user scrolls the page.

function start() {
  document.getElementById('logo').style.animation = "anim 2s 2s forward";
  document.getElementById('earthlogo').style.animation = "anim2 2s 2s forward";
}
* {
  margin: 0px;
}

#logo {
  position: fixed;
  top: 200px;
  height: 200px;
  width: 1000px;
  left: 5%;
  z-index: 4;
  opacity: 0.8;
}

#earthlogo {
  position: fixed;
  top: 200px;
  height: 120px;
  align-self: center;
  left: 5%;
  margin-left: 870px;
  margin-top: 60px;
  z-index: 4;
  opacity: 0.9;
}

@keyframes anim {
  50% {
    filter: blur(10px);
    transform: rotate(-15deg);
    box-shadow: 0px 0px 10px 3px;
  }
  100% {
    height: 100px;
    width: 500px;
    left: 10px;
    top: 10px;
    box-shadow: 0px 0px 15px 5px rgba(0, 0, 0, 0.7);
    background-color: rgba(0, 0, 1, 0.3);
    opacity: 0.7;
  }
}

@keyframes anim2 {
  50% {
    filter: blur(40px);
    transform: rotate(-15deg);
  }
  100% {
    height: 60px;
    width: 60px;
    left: 10px;
    top: 10px;
    margin-left: 435px;
    margin-top: 30px;
    opacity: 0.8;
  }
}

#backstar {
  position: fixed;
  width: 100%;
  z-index: 1;
}

#earth {
  position: absolute;
  width: 100%;
  z-index: 2;
  top: 300px;
}
<img src="logo.png" id="logo" onclick="start();">
<img src="earthlogo.gif" id="earthlogo" onscroll="start();">
<img src="earth.png" id="earth">
<img src="stars.jpg" id="backstar">

10 Answers

This is how you can use vanilla JavaScript to change/trigger an animation associated with an HTML element.

First, you define your animations in CSS.

@keyframes spin1 { 100% { transform:rotate(360deg); } }
@keyframes spin2 { 100% { transform:rotate(-360deg); } }
@keyframes idle { 100% {} }

Then you use javascript to switch between animations.

document.getElementByID('yourElement').style.animation="spin2 4s linear infinite";

Note: 'yourElement' is the target HTML element that you wish to animate.

For example: <div id="yourElement"> ... </div>

Adding and removing the animation class does not work in a function. The delay is simply too little. As suggested by this article you can request the browser to reflow and then add the class. The delay isn't an issue in that case. Hence, you can use this code:

element.classList.remove("animation")
element.offsetWidth
element.classList.add("animation")

The best thing is, this works everywhere. All credit goes to the article.

I have a similar problem. The best answer didn’t work for me, but when I added the delay it worked. The following is my solution.

CSS

.circle_ani1,
.circle_ani2 {
    animation-duration: 1s;
    animation-iteration-count: 1;
}

.circle_ani1 {
    animation-name: circle1;
}

.circle_ani2 {
    animation-name: circle2;
}

JS

let temp_circle1 = $('.TimeCountdown_circle1').removeClass('circle_ani1');
let temp_circle2 = $('.TimeCountdown_circle2').removeClass('circle_ani2');
window.setTimeout(function() {
    temp_circle1.addClass('circle_ani1');
    temp_circle2.addClass('circle_ani2');
}, 50);

A more idiomatic solution is to use the Web Animations API.

Here is the example from MDN:

document.getElementById("alice").animate(
  [
    { transform: 'rotate(0) translate3D(-50%, -50%, 0)', color: '#000' },
    { color: '#431236', offset: 0.3 },
    { transform: 'rotate(360deg) translate3D(-50%, -50%, 0)', color: '#000' }
  ], {
    duration: 3000,
    iterations: Infinity
  }
);

OP's example:

document.getElementById('logo').animate(
    [
        {},
        {
            filter: 'blur(10px)',
            transform: 'rotate(-15deg)',
            box-shadow: '0px 0px 10px 3px',
        },
        {
            height: '100px',
            width: '500px',
            left: '10px',
            top: '10px',
            box-shadow: '0px 0px 15px 5px rgba(0, 0, 0, 0.7)',
            background-color: 'rgba(0, 0, 1, 0.3)',
            opacity: '0.7',
        },
    ],
    {
        duration: 2000,
        delay: 2000,
        fill: 'forwards',
    },
)

At the time of writing, it's supported in all major browsers except IE. Supported browsers

Here's the main code:

HTML:

<img id="myImg">

CSS:

#myImg {
    //properties
    animation: animate 2s linear infinite //infinite is important!
}
@keyframes animate {
    //animation base
}

JS:

document.getElementById("myImg").style.webkitAnimationPlayState = "paused";
window.addEventListener("scroll", function() {
    document.getElementById("myImg").style.webkitAnimationPlayState = "running";
    setTimeout(function() {
        document.getElementById("myImg").style.webkitAnimationPlayState = "paused";
    }, 2000);
});

If you want Animations i recommend you create a CSS class which you toggle on a Condition whit JS: CSS

.animation {
 animation: anim 2s ease infinite;
 transition: .2s
}

JS

// Select your Element

$element.document.querySelector(".yourElement");
$element.addEventListner('click', () => {
 $element.classList.toggle("animation")
})

You could use animation-play-state (Mdn docs) like this

element.style.animationPlayState = "paused/running"

Code snippet:

function play() {
  document.getElementById("div").style.animationPlayState = "running";
}

function pause() {
  document.getElementById("div").style.animationPlayState = "paused";
}
.animation {
  width: 50px;
  height: 50px;
  background-color: red;
  position: relative;
  animation-name: example;
  animation-duration: 2s;
  animation-play-state: paused;
  animation-iteration-count: infinite;
}

@keyframes example {
  0% {
    background-color: red;
    left: 0px;
    top: 0px;
  }
  25% {
    background-color: yellow;
    left: 50px;
    top: 0px;
  }
  50% {
    background-color: blue;
    left: 50px;
    top: 50px;
  }
  75% {
    background-color: green;
    left: 0px;
    top: 50px;
  }
  100% {
    background-color: red;
    left: 0px;
    top: 0px;
  }
}
<button onclick="play()">Play</button>
<button onclick="pause()">Pause</button><br><br>
<div id="div" class="animation"></div>

Related