Dennington-bear
Dennington-bear

Reputation: 1782

Changing css animation in javascript

I have a blinking red box in my html it uses css animations. I want to to be able to change it from blinking red and white to green and white. I know this can be done on id elements by using getElementbyId but how would get access to the green aminated box in the css. The red box looks like this:

@-webkit-keyframes 'noConnection' 
{
    1% { background-color: red; }
    33% { background: white; }
    66% { background: red; }
    100% { background: white; }
}

The green is this:

@-webkit-keyframes 'Connection' 
{
    1% { background-color: green; }
    33% { background: white; }
    66% { background: green; }
    100% { background: white; }
}

The animate looks like this:

#animate { 
    height: 15px; 
    width: 15px;
}
.cssanimations #animate {
    -webkit-animation-direction: normal;
    -webkit-animation-duration: 5s;
    -webkit-animation-iteration-count: infinite;
    -webkit-animation-name: Connection;
    -webkit-animation-timing-function: ease;   

and I think I have to change the attribute -webkit-animation-name: from javascript to do this but I dont know how to get a handle on it to change it. Or would I be better off creating a duplicate #animate and renaming it using the getElementById?

Upvotes: 2

Views: 7888

Answers (2)

Mike Gashler
Mike Gashler

Reputation: 669

Here is a simple web page that demonstrates how to use Javascript to modify a CSS animation. It contains a simple div, and a little Javascript causes the div to move randomly around the page.

In your specific case, you just need to touch up the line that calls "insertRule" to insert your new blinking rule.

<html><head><style></style></head>
<body>
    <div id="mymovingdiv">
        <h1>Moving Div</h1>
        <p>And some little text too</p>
    </div>

<script>
function animatedMove(id, xStart, yStart, xEnd, yEnd, secs)
{
    // Remove any CSS rules inserted by a previous call to this method
    let rulename = `AnimMove${id}`;
    let ss = document.styleSheets; // all stylesheets
    for (let i = 0; i < ss.length; ++i) { // for each stylesheet...
        for (let j = ss[i].cssRules.length - 1; j > 0; j--) { // for each rule...
            if (ss[i].cssRules[j].name === rulename) { // does the name match?
                ss[i].deleteRule(j);
            }
        }
    }

    // Insert a CSS rule for this animation
    document.styleSheets[0].insertRule(`@keyframes ${rulename} { 0% { left: ${xStart}px; top: ${yStart}px; } 100% { left: ${xEnd}px; top: ${yEnd}px } }`);

    // Remove any CSS rules inserted by a previous call to this method
    for (let i = 0; i < ss.length; ++i) { // for each stylesheet...
        for (let j = ss[i].cssRules.length - 1; j > 0; j--) { // for each rule...
            if (ss[i].cssRules[j].name === rulename) { // does the name match?
                ss[i].deleteRule(j);
            }
        }
    }

    // Insert a CSS rule for this animation
    document.styleSheets[0].insertRule(`@keyframes ${rulename} { 0% { left: ${xStart}px; top: ${yStart}px; } 100% { left: ${xEnd}px; top: ${yEnd}px } }`);

    // assign the animation to our element
    let el = document.getElementById(id);
    el.style.position = 'absolute';
    el.style.animation = `${rulename} ${secs}s`;

    // Make the element stay where the animation ends
    el.style.left = `${xEnd}px`;
    el.style.top = `${yEnd}px`;

    // Re-clone the element, to reset the animation
    el.parentNode.replaceChild(el.cloneNode(true), el);
}

let x = 0;
let y = 0;

function randomMove()
{
    let newX = Math.floor(Math.random() * 800);
    let newY = Math.floor(Math.random() * 600);
    animatedMove('mymovingdiv', x, y, newX, newY, 1);
    x = newX;
    y = newY;
}

setInterval(randomMove, 1000);
</script>
</body>
</html>

Upvotes: 1

Aweary
Aweary

Reputation: 2312

The easiest way to do this is to created two classes in CSS and then toggle between the two.

So something like:

.connection {
  animation: 'Connection' 5s ease infinite
}


.no-connection {
  animation 'noConnection' 5s ease infinite
}

And then use Javascript to toggle between the two

function toggleConnectionStatus(){
 var element = document.getElementById('animate');
 if(/* connection is active */) element.className = 'connection';
 else element.className = 'no-connection'

}

Upvotes: 0

Related Questions