How can I restart a CSS animation with random values in a loop?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







13















I have an element which is randomly animated with CSS and JS with the help of CSS custom properties in the following way:






var myElement = document.querySelector('#my-element');

function setProperty(number) {
myElement.style.setProperty('--animation-name', 'vibrate-' + number);
}

function changeAnimation() {
var number = Math.floor(Math.random() * 3) + 1;
setProperty(number);
/* restart the animation */
var clone = myElement.cloneNode(true);
myElement.parentNode.replaceChild(clone, myElement);
}

myElement.addEventListener('animationend', changeAnimation, false);

#my-element {
width: 50px;
height: 50px;
background: #333;
}

:root {
--animation-name: vibrate-1;
}

#my-element {
animation: 3.3s 1 alternate var(--animation-name);
}

@keyframes vibrate-1 {
0% {
opacity: 0;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.9);
}
}

@keyframes vibrate-2 {
0% {
opacity: 0;
transform: scale(0.5);
}
50% {
opacity: 1;
transform: scale(0.9);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}

@keyframes vibrate-3 {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.8);
}
}

<div id="my-element"></div>





The idea behind is to have a set of animations which switch on each animation’s end randomly to another one. (that for the opacity in the end is always 0 to make a smooth invisible switch.)



Now, surprisingly, this code above runs just fine, except that it does only once and then stop.



I now there are JS loop techniques but I have no idea how to exactly implement them inside this workflow.



Can someone help me?










share|improve this question

























  • Do you have a JsFiddle/Codepen of this? Or maybe the missing HTML part?

    – molamk
    Feb 1 at 7:40






  • 2





    @Garavani, this is a somewhat irrelevant note, but JS naming convention is camelCase, so you should change my-element to myElement.

    – nick zoum
    Feb 1 at 7:49













  • @nick did that, thanks!

    – Garavani
    Feb 1 at 7:53


















13















I have an element which is randomly animated with CSS and JS with the help of CSS custom properties in the following way:






var myElement = document.querySelector('#my-element');

function setProperty(number) {
myElement.style.setProperty('--animation-name', 'vibrate-' + number);
}

function changeAnimation() {
var number = Math.floor(Math.random() * 3) + 1;
setProperty(number);
/* restart the animation */
var clone = myElement.cloneNode(true);
myElement.parentNode.replaceChild(clone, myElement);
}

myElement.addEventListener('animationend', changeAnimation, false);

#my-element {
width: 50px;
height: 50px;
background: #333;
}

:root {
--animation-name: vibrate-1;
}

#my-element {
animation: 3.3s 1 alternate var(--animation-name);
}

@keyframes vibrate-1 {
0% {
opacity: 0;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.9);
}
}

@keyframes vibrate-2 {
0% {
opacity: 0;
transform: scale(0.5);
}
50% {
opacity: 1;
transform: scale(0.9);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}

@keyframes vibrate-3 {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.8);
}
}

<div id="my-element"></div>





The idea behind is to have a set of animations which switch on each animation’s end randomly to another one. (that for the opacity in the end is always 0 to make a smooth invisible switch.)



Now, surprisingly, this code above runs just fine, except that it does only once and then stop.



I now there are JS loop techniques but I have no idea how to exactly implement them inside this workflow.



Can someone help me?










share|improve this question

























  • Do you have a JsFiddle/Codepen of this? Or maybe the missing HTML part?

    – molamk
    Feb 1 at 7:40






  • 2





    @Garavani, this is a somewhat irrelevant note, but JS naming convention is camelCase, so you should change my-element to myElement.

    – nick zoum
    Feb 1 at 7:49













  • @nick did that, thanks!

    – Garavani
    Feb 1 at 7:53














13












13








13


1






I have an element which is randomly animated with CSS and JS with the help of CSS custom properties in the following way:






var myElement = document.querySelector('#my-element');

function setProperty(number) {
myElement.style.setProperty('--animation-name', 'vibrate-' + number);
}

function changeAnimation() {
var number = Math.floor(Math.random() * 3) + 1;
setProperty(number);
/* restart the animation */
var clone = myElement.cloneNode(true);
myElement.parentNode.replaceChild(clone, myElement);
}

myElement.addEventListener('animationend', changeAnimation, false);

#my-element {
width: 50px;
height: 50px;
background: #333;
}

:root {
--animation-name: vibrate-1;
}

#my-element {
animation: 3.3s 1 alternate var(--animation-name);
}

@keyframes vibrate-1 {
0% {
opacity: 0;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.9);
}
}

@keyframes vibrate-2 {
0% {
opacity: 0;
transform: scale(0.5);
}
50% {
opacity: 1;
transform: scale(0.9);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}

@keyframes vibrate-3 {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.8);
}
}

<div id="my-element"></div>





The idea behind is to have a set of animations which switch on each animation’s end randomly to another one. (that for the opacity in the end is always 0 to make a smooth invisible switch.)



Now, surprisingly, this code above runs just fine, except that it does only once and then stop.



I now there are JS loop techniques but I have no idea how to exactly implement them inside this workflow.



Can someone help me?










share|improve this question
















I have an element which is randomly animated with CSS and JS with the help of CSS custom properties in the following way:






var myElement = document.querySelector('#my-element');

function setProperty(number) {
myElement.style.setProperty('--animation-name', 'vibrate-' + number);
}

function changeAnimation() {
var number = Math.floor(Math.random() * 3) + 1;
setProperty(number);
/* restart the animation */
var clone = myElement.cloneNode(true);
myElement.parentNode.replaceChild(clone, myElement);
}

myElement.addEventListener('animationend', changeAnimation, false);

#my-element {
width: 50px;
height: 50px;
background: #333;
}

:root {
--animation-name: vibrate-1;
}

#my-element {
animation: 3.3s 1 alternate var(--animation-name);
}

@keyframes vibrate-1 {
0% {
opacity: 0;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.9);
}
}

@keyframes vibrate-2 {
0% {
opacity: 0;
transform: scale(0.5);
}
50% {
opacity: 1;
transform: scale(0.9);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}

@keyframes vibrate-3 {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.8);
}
}

<div id="my-element"></div>





The idea behind is to have a set of animations which switch on each animation’s end randomly to another one. (that for the opacity in the end is always 0 to make a smooth invisible switch.)



Now, surprisingly, this code above runs just fine, except that it does only once and then stop.



I now there are JS loop techniques but I have no idea how to exactly implement them inside this workflow.



Can someone help me?






var myElement = document.querySelector('#my-element');

function setProperty(number) {
myElement.style.setProperty('--animation-name', 'vibrate-' + number);
}

function changeAnimation() {
var number = Math.floor(Math.random() * 3) + 1;
setProperty(number);
/* restart the animation */
var clone = myElement.cloneNode(true);
myElement.parentNode.replaceChild(clone, myElement);
}

myElement.addEventListener('animationend', changeAnimation, false);

#my-element {
width: 50px;
height: 50px;
background: #333;
}

:root {
--animation-name: vibrate-1;
}

#my-element {
animation: 3.3s 1 alternate var(--animation-name);
}

@keyframes vibrate-1 {
0% {
opacity: 0;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.9);
}
}

@keyframes vibrate-2 {
0% {
opacity: 0;
transform: scale(0.5);
}
50% {
opacity: 1;
transform: scale(0.9);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}

@keyframes vibrate-3 {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.8);
}
}

<div id="my-element"></div>





var myElement = document.querySelector('#my-element');

function setProperty(number) {
myElement.style.setProperty('--animation-name', 'vibrate-' + number);
}

function changeAnimation() {
var number = Math.floor(Math.random() * 3) + 1;
setProperty(number);
/* restart the animation */
var clone = myElement.cloneNode(true);
myElement.parentNode.replaceChild(clone, myElement);
}

myElement.addEventListener('animationend', changeAnimation, false);

#my-element {
width: 50px;
height: 50px;
background: #333;
}

:root {
--animation-name: vibrate-1;
}

#my-element {
animation: 3.3s 1 alternate var(--animation-name);
}

@keyframes vibrate-1 {
0% {
opacity: 0;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.9);
}
}

@keyframes vibrate-2 {
0% {
opacity: 0;
transform: scale(0.5);
}
50% {
opacity: 1;
transform: scale(0.9);
}
100% {
opacity: 0;
transform: scale(0.5);
}
}

@keyframes vibrate-3 {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1);
}
100% {
opacity: 0;
transform: scale(0.8);
}
}

<div id="my-element"></div>






javascript css loops random css-animations






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Feb 1 at 12:39









Temani Afif

82.7k104795




82.7k104795










asked Feb 1 at 7:34









GaravaniGaravani

437623




437623













  • Do you have a JsFiddle/Codepen of this? Or maybe the missing HTML part?

    – molamk
    Feb 1 at 7:40






  • 2





    @Garavani, this is a somewhat irrelevant note, but JS naming convention is camelCase, so you should change my-element to myElement.

    – nick zoum
    Feb 1 at 7:49













  • @nick did that, thanks!

    – Garavani
    Feb 1 at 7:53



















  • Do you have a JsFiddle/Codepen of this? Or maybe the missing HTML part?

    – molamk
    Feb 1 at 7:40






  • 2





    @Garavani, this is a somewhat irrelevant note, but JS naming convention is camelCase, so you should change my-element to myElement.

    – nick zoum
    Feb 1 at 7:49













  • @nick did that, thanks!

    – Garavani
    Feb 1 at 7:53

















Do you have a JsFiddle/Codepen of this? Or maybe the missing HTML part?

– molamk
Feb 1 at 7:40





Do you have a JsFiddle/Codepen of this? Or maybe the missing HTML part?

– molamk
Feb 1 at 7:40




2




2





@Garavani, this is a somewhat irrelevant note, but JS naming convention is camelCase, so you should change my-element to myElement.

– nick zoum
Feb 1 at 7:49







@Garavani, this is a somewhat irrelevant note, but JS naming convention is camelCase, so you should change my-element to myElement.

– nick zoum
Feb 1 at 7:49















@nick did that, thanks!

– Garavani
Feb 1 at 7:53





@nick did that, thanks!

– Garavani
Feb 1 at 7:53












2 Answers
2






active

oldest

votes


















6














Another simple idea is to rely on animationiteration and make the animation to run infinite then you no more need to clone the element. You simply change the animation name each iteration and you will have the needed effect:






var myElement = document.querySelector('#my-element');

function setProperty(number) {
myElement.style.setProperty('--animation-name', 'vibrate-' + number);
}

function changeAnimation() {
var number = Math.floor(Math.random() * 3) + 1;
setProperty(number);
}

myElement.addEventListener('animationiteration', changeAnimation, false);

#my-element {
width: 50px;
height: 50px;
background: #333;
}

#my-element {
animation: 3.3s alternate infinite var(--animation-name,vibrate-1);
}

@keyframes vibrate-1 {
0% {
opacity: 0;
transform: scale(0.95);
}
50% {
opacity: 1;
transform: scale(1);
background:green;
}
100% {
opacity: 0;
transform: scale(0.9);
}
}

@keyframes vibrate-2 {
0% {
opacity: 0;
transform: scale(0.5);
}
50% {
opacity: 1;
transform: scale(0.9);
background:red;
}
100% {
opacity: 0;
transform: scale(0.5);
}
}

@keyframes vibrate-3 {
0% {
opacity: 0;
transform: scale(0.3);
}
50% {
opacity: 1;
transform: scale(1);
background:blue;
}
100% {
opacity: 0;
transform: scale(0.8);
}
}

<div id="my-element"></div>





Another way is to simply keep one animation and adjust the scale values (or any other values) and you will have a better random behavior.






var myElement = document.querySelector('#my-element');

function changeAnimation() {
var n1 = Math.random();
myElement.style.setProperty('--s1',n1);
var n2 = Math.random();
myElement.style.setProperty('--s2',n2);
var c1 = Math.floor(Math.random()*255);
myElement.style.setProperty('--c1',c1);
var c2 = Math.floor(Math.random()*255);
myElement.style.setProperty('--c2',c2);
}

myElement.addEventListener('animationiteration', changeAnimation, false);

#my-element {
width: 50px;
height: 50px;
background: #333;
}

#my-element {
animation: 3.3s alternate infinite vibrate;
}

@keyframes vibrate {
0% {
opacity: 0;
transform: scale(var(--s1,0.95));
}
50% {
opacity: 1;
transform: scale(1);
background:rgb(255,var(--c1,0),var(--c2,0));
}
100% {
opacity: 0;
transform: scale(var(--s2,0.9));
}
}

<div id="my-element"></div>








share|improve this answer





















  • 1





    Wow! In fact, the code above didn’t really work, at all. After the second run I was struggling with this Error: TypeError: null is not an object (evaluating 'myElement.parentNode.replaceChild') probably because the original element is no longer existent. Your code works much better!

    – Garavani
    Feb 1 at 10:19













  • I discovered that in the second solution the variables are not really inserted into the keyframe values. The animation just uses the defaults. They do not seem to be supposed to be dynamic as I read here: stackoverflow.com/questions/18481550/… (first answer)

    – Garavani
    Feb 2 at 9:21













  • @Garavani that answer has nothing to do with CSS variable. And if you check well the animation you see the color changing which means that the value are changing. Here is another example with the same thing working fine : stackoverflow.com/a/49750566/8620333 ... it's probably hard to notice the difference for the scale

    – Temani Afif
    Feb 2 at 9:36






  • 1





    @Garavani no, don't edit the question since actually it's answered and you accepted the answer so you should avoid changing the meaning of your initial issue. Use this : jsfiddle.net and put your code there and send me the link

    – Temani Afif
    Feb 2 at 9:43






  • 1





    @Garavani you need to use calc you cannot do muliplication like wihout --> calc(var(--y0) * 1vw)

    – Temani Afif
    Feb 2 at 10:02





















8














When you replace the element with the cloned element, you should reassign the animationend event listener:



var clone = myElement.cloneNode(true);
clone.addEventListener('animationend', changeAnimation, false);
myElement.parentNode.replaceChild(clone, myElement);


By the way, variables in JavaScript can't contain -, so my-element should be myElement.






share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54474893%2fhow-can-i-restart-a-css-animation-with-random-values-in-a-loop%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    6














    Another simple idea is to rely on animationiteration and make the animation to run infinite then you no more need to clone the element. You simply change the animation name each iteration and you will have the needed effect:






    var myElement = document.querySelector('#my-element');

    function setProperty(number) {
    myElement.style.setProperty('--animation-name', 'vibrate-' + number);
    }

    function changeAnimation() {
    var number = Math.floor(Math.random() * 3) + 1;
    setProperty(number);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite var(--animation-name,vibrate-1);
    }

    @keyframes vibrate-1 {
    0% {
    opacity: 0;
    transform: scale(0.95);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:green;
    }
    100% {
    opacity: 0;
    transform: scale(0.9);
    }
    }

    @keyframes vibrate-2 {
    0% {
    opacity: 0;
    transform: scale(0.5);
    }
    50% {
    opacity: 1;
    transform: scale(0.9);
    background:red;
    }
    100% {
    opacity: 0;
    transform: scale(0.5);
    }
    }

    @keyframes vibrate-3 {
    0% {
    opacity: 0;
    transform: scale(0.3);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:blue;
    }
    100% {
    opacity: 0;
    transform: scale(0.8);
    }
    }

    <div id="my-element"></div>





    Another way is to simply keep one animation and adjust the scale values (or any other values) and you will have a better random behavior.






    var myElement = document.querySelector('#my-element');

    function changeAnimation() {
    var n1 = Math.random();
    myElement.style.setProperty('--s1',n1);
    var n2 = Math.random();
    myElement.style.setProperty('--s2',n2);
    var c1 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c1',c1);
    var c2 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c2',c2);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite vibrate;
    }

    @keyframes vibrate {
    0% {
    opacity: 0;
    transform: scale(var(--s1,0.95));
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:rgb(255,var(--c1,0),var(--c2,0));
    }
    100% {
    opacity: 0;
    transform: scale(var(--s2,0.9));
    }
    }

    <div id="my-element"></div>








    share|improve this answer





















    • 1





      Wow! In fact, the code above didn’t really work, at all. After the second run I was struggling with this Error: TypeError: null is not an object (evaluating 'myElement.parentNode.replaceChild') probably because the original element is no longer existent. Your code works much better!

      – Garavani
      Feb 1 at 10:19













    • I discovered that in the second solution the variables are not really inserted into the keyframe values. The animation just uses the defaults. They do not seem to be supposed to be dynamic as I read here: stackoverflow.com/questions/18481550/… (first answer)

      – Garavani
      Feb 2 at 9:21













    • @Garavani that answer has nothing to do with CSS variable. And if you check well the animation you see the color changing which means that the value are changing. Here is another example with the same thing working fine : stackoverflow.com/a/49750566/8620333 ... it's probably hard to notice the difference for the scale

      – Temani Afif
      Feb 2 at 9:36






    • 1





      @Garavani no, don't edit the question since actually it's answered and you accepted the answer so you should avoid changing the meaning of your initial issue. Use this : jsfiddle.net and put your code there and send me the link

      – Temani Afif
      Feb 2 at 9:43






    • 1





      @Garavani you need to use calc you cannot do muliplication like wihout --> calc(var(--y0) * 1vw)

      – Temani Afif
      Feb 2 at 10:02


















    6














    Another simple idea is to rely on animationiteration and make the animation to run infinite then you no more need to clone the element. You simply change the animation name each iteration and you will have the needed effect:






    var myElement = document.querySelector('#my-element');

    function setProperty(number) {
    myElement.style.setProperty('--animation-name', 'vibrate-' + number);
    }

    function changeAnimation() {
    var number = Math.floor(Math.random() * 3) + 1;
    setProperty(number);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite var(--animation-name,vibrate-1);
    }

    @keyframes vibrate-1 {
    0% {
    opacity: 0;
    transform: scale(0.95);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:green;
    }
    100% {
    opacity: 0;
    transform: scale(0.9);
    }
    }

    @keyframes vibrate-2 {
    0% {
    opacity: 0;
    transform: scale(0.5);
    }
    50% {
    opacity: 1;
    transform: scale(0.9);
    background:red;
    }
    100% {
    opacity: 0;
    transform: scale(0.5);
    }
    }

    @keyframes vibrate-3 {
    0% {
    opacity: 0;
    transform: scale(0.3);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:blue;
    }
    100% {
    opacity: 0;
    transform: scale(0.8);
    }
    }

    <div id="my-element"></div>





    Another way is to simply keep one animation and adjust the scale values (or any other values) and you will have a better random behavior.






    var myElement = document.querySelector('#my-element');

    function changeAnimation() {
    var n1 = Math.random();
    myElement.style.setProperty('--s1',n1);
    var n2 = Math.random();
    myElement.style.setProperty('--s2',n2);
    var c1 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c1',c1);
    var c2 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c2',c2);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite vibrate;
    }

    @keyframes vibrate {
    0% {
    opacity: 0;
    transform: scale(var(--s1,0.95));
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:rgb(255,var(--c1,0),var(--c2,0));
    }
    100% {
    opacity: 0;
    transform: scale(var(--s2,0.9));
    }
    }

    <div id="my-element"></div>








    share|improve this answer





















    • 1





      Wow! In fact, the code above didn’t really work, at all. After the second run I was struggling with this Error: TypeError: null is not an object (evaluating 'myElement.parentNode.replaceChild') probably because the original element is no longer existent. Your code works much better!

      – Garavani
      Feb 1 at 10:19













    • I discovered that in the second solution the variables are not really inserted into the keyframe values. The animation just uses the defaults. They do not seem to be supposed to be dynamic as I read here: stackoverflow.com/questions/18481550/… (first answer)

      – Garavani
      Feb 2 at 9:21













    • @Garavani that answer has nothing to do with CSS variable. And if you check well the animation you see the color changing which means that the value are changing. Here is another example with the same thing working fine : stackoverflow.com/a/49750566/8620333 ... it's probably hard to notice the difference for the scale

      – Temani Afif
      Feb 2 at 9:36






    • 1





      @Garavani no, don't edit the question since actually it's answered and you accepted the answer so you should avoid changing the meaning of your initial issue. Use this : jsfiddle.net and put your code there and send me the link

      – Temani Afif
      Feb 2 at 9:43






    • 1





      @Garavani you need to use calc you cannot do muliplication like wihout --> calc(var(--y0) * 1vw)

      – Temani Afif
      Feb 2 at 10:02
















    6












    6








    6







    Another simple idea is to rely on animationiteration and make the animation to run infinite then you no more need to clone the element. You simply change the animation name each iteration and you will have the needed effect:






    var myElement = document.querySelector('#my-element');

    function setProperty(number) {
    myElement.style.setProperty('--animation-name', 'vibrate-' + number);
    }

    function changeAnimation() {
    var number = Math.floor(Math.random() * 3) + 1;
    setProperty(number);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite var(--animation-name,vibrate-1);
    }

    @keyframes vibrate-1 {
    0% {
    opacity: 0;
    transform: scale(0.95);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:green;
    }
    100% {
    opacity: 0;
    transform: scale(0.9);
    }
    }

    @keyframes vibrate-2 {
    0% {
    opacity: 0;
    transform: scale(0.5);
    }
    50% {
    opacity: 1;
    transform: scale(0.9);
    background:red;
    }
    100% {
    opacity: 0;
    transform: scale(0.5);
    }
    }

    @keyframes vibrate-3 {
    0% {
    opacity: 0;
    transform: scale(0.3);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:blue;
    }
    100% {
    opacity: 0;
    transform: scale(0.8);
    }
    }

    <div id="my-element"></div>





    Another way is to simply keep one animation and adjust the scale values (or any other values) and you will have a better random behavior.






    var myElement = document.querySelector('#my-element');

    function changeAnimation() {
    var n1 = Math.random();
    myElement.style.setProperty('--s1',n1);
    var n2 = Math.random();
    myElement.style.setProperty('--s2',n2);
    var c1 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c1',c1);
    var c2 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c2',c2);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite vibrate;
    }

    @keyframes vibrate {
    0% {
    opacity: 0;
    transform: scale(var(--s1,0.95));
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:rgb(255,var(--c1,0),var(--c2,0));
    }
    100% {
    opacity: 0;
    transform: scale(var(--s2,0.9));
    }
    }

    <div id="my-element"></div>








    share|improve this answer















    Another simple idea is to rely on animationiteration and make the animation to run infinite then you no more need to clone the element. You simply change the animation name each iteration and you will have the needed effect:






    var myElement = document.querySelector('#my-element');

    function setProperty(number) {
    myElement.style.setProperty('--animation-name', 'vibrate-' + number);
    }

    function changeAnimation() {
    var number = Math.floor(Math.random() * 3) + 1;
    setProperty(number);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite var(--animation-name,vibrate-1);
    }

    @keyframes vibrate-1 {
    0% {
    opacity: 0;
    transform: scale(0.95);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:green;
    }
    100% {
    opacity: 0;
    transform: scale(0.9);
    }
    }

    @keyframes vibrate-2 {
    0% {
    opacity: 0;
    transform: scale(0.5);
    }
    50% {
    opacity: 1;
    transform: scale(0.9);
    background:red;
    }
    100% {
    opacity: 0;
    transform: scale(0.5);
    }
    }

    @keyframes vibrate-3 {
    0% {
    opacity: 0;
    transform: scale(0.3);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:blue;
    }
    100% {
    opacity: 0;
    transform: scale(0.8);
    }
    }

    <div id="my-element"></div>





    Another way is to simply keep one animation and adjust the scale values (or any other values) and you will have a better random behavior.






    var myElement = document.querySelector('#my-element');

    function changeAnimation() {
    var n1 = Math.random();
    myElement.style.setProperty('--s1',n1);
    var n2 = Math.random();
    myElement.style.setProperty('--s2',n2);
    var c1 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c1',c1);
    var c2 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c2',c2);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite vibrate;
    }

    @keyframes vibrate {
    0% {
    opacity: 0;
    transform: scale(var(--s1,0.95));
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:rgb(255,var(--c1,0),var(--c2,0));
    }
    100% {
    opacity: 0;
    transform: scale(var(--s2,0.9));
    }
    }

    <div id="my-element"></div>








    var myElement = document.querySelector('#my-element');

    function setProperty(number) {
    myElement.style.setProperty('--animation-name', 'vibrate-' + number);
    }

    function changeAnimation() {
    var number = Math.floor(Math.random() * 3) + 1;
    setProperty(number);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite var(--animation-name,vibrate-1);
    }

    @keyframes vibrate-1 {
    0% {
    opacity: 0;
    transform: scale(0.95);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:green;
    }
    100% {
    opacity: 0;
    transform: scale(0.9);
    }
    }

    @keyframes vibrate-2 {
    0% {
    opacity: 0;
    transform: scale(0.5);
    }
    50% {
    opacity: 1;
    transform: scale(0.9);
    background:red;
    }
    100% {
    opacity: 0;
    transform: scale(0.5);
    }
    }

    @keyframes vibrate-3 {
    0% {
    opacity: 0;
    transform: scale(0.3);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:blue;
    }
    100% {
    opacity: 0;
    transform: scale(0.8);
    }
    }

    <div id="my-element"></div>





    var myElement = document.querySelector('#my-element');

    function setProperty(number) {
    myElement.style.setProperty('--animation-name', 'vibrate-' + number);
    }

    function changeAnimation() {
    var number = Math.floor(Math.random() * 3) + 1;
    setProperty(number);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite var(--animation-name,vibrate-1);
    }

    @keyframes vibrate-1 {
    0% {
    opacity: 0;
    transform: scale(0.95);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:green;
    }
    100% {
    opacity: 0;
    transform: scale(0.9);
    }
    }

    @keyframes vibrate-2 {
    0% {
    opacity: 0;
    transform: scale(0.5);
    }
    50% {
    opacity: 1;
    transform: scale(0.9);
    background:red;
    }
    100% {
    opacity: 0;
    transform: scale(0.5);
    }
    }

    @keyframes vibrate-3 {
    0% {
    opacity: 0;
    transform: scale(0.3);
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:blue;
    }
    100% {
    opacity: 0;
    transform: scale(0.8);
    }
    }

    <div id="my-element"></div>





    var myElement = document.querySelector('#my-element');

    function changeAnimation() {
    var n1 = Math.random();
    myElement.style.setProperty('--s1',n1);
    var n2 = Math.random();
    myElement.style.setProperty('--s2',n2);
    var c1 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c1',c1);
    var c2 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c2',c2);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite vibrate;
    }

    @keyframes vibrate {
    0% {
    opacity: 0;
    transform: scale(var(--s1,0.95));
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:rgb(255,var(--c1,0),var(--c2,0));
    }
    100% {
    opacity: 0;
    transform: scale(var(--s2,0.9));
    }
    }

    <div id="my-element"></div>





    var myElement = document.querySelector('#my-element');

    function changeAnimation() {
    var n1 = Math.random();
    myElement.style.setProperty('--s1',n1);
    var n2 = Math.random();
    myElement.style.setProperty('--s2',n2);
    var c1 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c1',c1);
    var c2 = Math.floor(Math.random()*255);
    myElement.style.setProperty('--c2',c2);
    }

    myElement.addEventListener('animationiteration', changeAnimation, false);

    #my-element {
    width: 50px;
    height: 50px;
    background: #333;
    }

    #my-element {
    animation: 3.3s alternate infinite vibrate;
    }

    @keyframes vibrate {
    0% {
    opacity: 0;
    transform: scale(var(--s1,0.95));
    }
    50% {
    opacity: 1;
    transform: scale(1);
    background:rgb(255,var(--c1,0),var(--c2,0));
    }
    100% {
    opacity: 0;
    transform: scale(var(--s2,0.9));
    }
    }

    <div id="my-element"></div>






    share|improve this answer














    share|improve this answer



    share|improve this answer








    edited Feb 1 at 12:33

























    answered Feb 1 at 9:46









    Temani AfifTemani Afif

    82.7k104795




    82.7k104795








    • 1





      Wow! In fact, the code above didn’t really work, at all. After the second run I was struggling with this Error: TypeError: null is not an object (evaluating 'myElement.parentNode.replaceChild') probably because the original element is no longer existent. Your code works much better!

      – Garavani
      Feb 1 at 10:19













    • I discovered that in the second solution the variables are not really inserted into the keyframe values. The animation just uses the defaults. They do not seem to be supposed to be dynamic as I read here: stackoverflow.com/questions/18481550/… (first answer)

      – Garavani
      Feb 2 at 9:21













    • @Garavani that answer has nothing to do with CSS variable. And if you check well the animation you see the color changing which means that the value are changing. Here is another example with the same thing working fine : stackoverflow.com/a/49750566/8620333 ... it's probably hard to notice the difference for the scale

      – Temani Afif
      Feb 2 at 9:36






    • 1





      @Garavani no, don't edit the question since actually it's answered and you accepted the answer so you should avoid changing the meaning of your initial issue. Use this : jsfiddle.net and put your code there and send me the link

      – Temani Afif
      Feb 2 at 9:43






    • 1





      @Garavani you need to use calc you cannot do muliplication like wihout --> calc(var(--y0) * 1vw)

      – Temani Afif
      Feb 2 at 10:02
















    • 1





      Wow! In fact, the code above didn’t really work, at all. After the second run I was struggling with this Error: TypeError: null is not an object (evaluating 'myElement.parentNode.replaceChild') probably because the original element is no longer existent. Your code works much better!

      – Garavani
      Feb 1 at 10:19













    • I discovered that in the second solution the variables are not really inserted into the keyframe values. The animation just uses the defaults. They do not seem to be supposed to be dynamic as I read here: stackoverflow.com/questions/18481550/… (first answer)

      – Garavani
      Feb 2 at 9:21













    • @Garavani that answer has nothing to do with CSS variable. And if you check well the animation you see the color changing which means that the value are changing. Here is another example with the same thing working fine : stackoverflow.com/a/49750566/8620333 ... it's probably hard to notice the difference for the scale

      – Temani Afif
      Feb 2 at 9:36






    • 1





      @Garavani no, don't edit the question since actually it's answered and you accepted the answer so you should avoid changing the meaning of your initial issue. Use this : jsfiddle.net and put your code there and send me the link

      – Temani Afif
      Feb 2 at 9:43






    • 1





      @Garavani you need to use calc you cannot do muliplication like wihout --> calc(var(--y0) * 1vw)

      – Temani Afif
      Feb 2 at 10:02










    1




    1





    Wow! In fact, the code above didn’t really work, at all. After the second run I was struggling with this Error: TypeError: null is not an object (evaluating 'myElement.parentNode.replaceChild') probably because the original element is no longer existent. Your code works much better!

    – Garavani
    Feb 1 at 10:19







    Wow! In fact, the code above didn’t really work, at all. After the second run I was struggling with this Error: TypeError: null is not an object (evaluating 'myElement.parentNode.replaceChild') probably because the original element is no longer existent. Your code works much better!

    – Garavani
    Feb 1 at 10:19















    I discovered that in the second solution the variables are not really inserted into the keyframe values. The animation just uses the defaults. They do not seem to be supposed to be dynamic as I read here: stackoverflow.com/questions/18481550/… (first answer)

    – Garavani
    Feb 2 at 9:21







    I discovered that in the second solution the variables are not really inserted into the keyframe values. The animation just uses the defaults. They do not seem to be supposed to be dynamic as I read here: stackoverflow.com/questions/18481550/… (first answer)

    – Garavani
    Feb 2 at 9:21















    @Garavani that answer has nothing to do with CSS variable. And if you check well the animation you see the color changing which means that the value are changing. Here is another example with the same thing working fine : stackoverflow.com/a/49750566/8620333 ... it's probably hard to notice the difference for the scale

    – Temani Afif
    Feb 2 at 9:36





    @Garavani that answer has nothing to do with CSS variable. And if you check well the animation you see the color changing which means that the value are changing. Here is another example with the same thing working fine : stackoverflow.com/a/49750566/8620333 ... it's probably hard to notice the difference for the scale

    – Temani Afif
    Feb 2 at 9:36




    1




    1





    @Garavani no, don't edit the question since actually it's answered and you accepted the answer so you should avoid changing the meaning of your initial issue. Use this : jsfiddle.net and put your code there and send me the link

    – Temani Afif
    Feb 2 at 9:43





    @Garavani no, don't edit the question since actually it's answered and you accepted the answer so you should avoid changing the meaning of your initial issue. Use this : jsfiddle.net and put your code there and send me the link

    – Temani Afif
    Feb 2 at 9:43




    1




    1





    @Garavani you need to use calc you cannot do muliplication like wihout --> calc(var(--y0) * 1vw)

    – Temani Afif
    Feb 2 at 10:02







    @Garavani you need to use calc you cannot do muliplication like wihout --> calc(var(--y0) * 1vw)

    – Temani Afif
    Feb 2 at 10:02















    8














    When you replace the element with the cloned element, you should reassign the animationend event listener:



    var clone = myElement.cloneNode(true);
    clone.addEventListener('animationend', changeAnimation, false);
    myElement.parentNode.replaceChild(clone, myElement);


    By the way, variables in JavaScript can't contain -, so my-element should be myElement.






    share|improve this answer




























      8














      When you replace the element with the cloned element, you should reassign the animationend event listener:



      var clone = myElement.cloneNode(true);
      clone.addEventListener('animationend', changeAnimation, false);
      myElement.parentNode.replaceChild(clone, myElement);


      By the way, variables in JavaScript can't contain -, so my-element should be myElement.






      share|improve this answer


























        8












        8








        8







        When you replace the element with the cloned element, you should reassign the animationend event listener:



        var clone = myElement.cloneNode(true);
        clone.addEventListener('animationend', changeAnimation, false);
        myElement.parentNode.replaceChild(clone, myElement);


        By the way, variables in JavaScript can't contain -, so my-element should be myElement.






        share|improve this answer













        When you replace the element with the cloned element, you should reassign the animationend event listener:



        var clone = myElement.cloneNode(true);
        clone.addEventListener('animationend', changeAnimation, false);
        myElement.parentNode.replaceChild(clone, myElement);


        By the way, variables in JavaScript can't contain -, so my-element should be myElement.







        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Feb 1 at 7:51









        Michał PerłakowskiMichał Perłakowski

        45.6k16106123




        45.6k16106123






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54474893%2fhow-can-i-restart-a-css-animation-with-random-values-in-a-loop%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            MongoDB - Not Authorized To Execute Command

            How to fix TextFormField cause rebuild widget in Flutter

            in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith