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;
}
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?
javascript css loops random css-animations
add a comment |
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?
javascript css loops random css-animations
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 changemy-element
tomyElement
.
– nick zoum
Feb 1 at 7:49
@nick did that, thanks!
– Garavani
Feb 1 at 7:53
add a comment |
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?
javascript css loops random css-animations
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
javascript css loops random css-animations
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 changemy-element
tomyElement
.
– nick zoum
Feb 1 at 7:49
@nick did that, thanks!
– Garavani
Feb 1 at 7:53
add a comment |
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 changemy-element
tomyElement
.
– 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
add a comment |
2 Answers
2
active
oldest
votes
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>
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 usecalc
you cannot do muliplication like wihout -->calc(var(--y0) * 1vw)
– Temani Afif
Feb 2 at 10:02
|
show 5 more comments
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
.
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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>
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 usecalc
you cannot do muliplication like wihout -->calc(var(--y0) * 1vw)
– Temani Afif
Feb 2 at 10:02
|
show 5 more comments
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>
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 usecalc
you cannot do muliplication like wihout -->calc(var(--y0) * 1vw)
– Temani Afif
Feb 2 at 10:02
|
show 5 more comments
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>
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>
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 usecalc
you cannot do muliplication like wihout -->calc(var(--y0) * 1vw)
– Temani Afif
Feb 2 at 10:02
|
show 5 more comments
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 usecalc
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
|
show 5 more comments
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
.
add a comment |
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
.
add a comment |
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
.
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
.
answered Feb 1 at 7:51


Michał PerłakowskiMichał Perłakowski
45.6k16106123
45.6k16106123
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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
tomyElement
.– nick zoum
Feb 1 at 7:49
@nick did that, thanks!
– Garavani
Feb 1 at 7:53