Why doesn't onclick event affect CSS3 animation-duration property? - javascript

I am creating a small game, where an element bounces from the top to the bottom of its parent element, and vice versa. Once the user clicks the element, the speed increases JSFiddle.
I am using the following CSS properties to set values (I have omitted the prefixes):
#ball {
animation-name: bounce;
animation-duration: 2s;
animation-direction: alternate;
animation-iteration-count: infinite;
}
#keyframes bounce {
0% {
width: 80px;
height: 80px;
margin-top: 0;
}
100% {
width: 80px;
height: 80px;
margin-top: 420px;
}
}
The JavaScript code I am using to change the duration of the animation:
var ball = document.getElementById('ball');
ball.onclick = function() {
ball.style.WebkitAnimationDuration = '100ms';
ball.style.MozAnimationDuration = '100ms';
ball.style.OAnimationDuration = '100ms';
ball.style.animationDuration = '100ms';
};
My question is as follows: Why does the animation-duration not change?

This is the problem:
ball.style.animationDuration = '100ms';
It should be like so:
ball.style.AnimationDuration = '100ms';

Related

Why does the timing of these different animations get slower and out of order over time?

Here I have a Video that changes every few seconds with spinning animation + video getting small and big during the spinning.
But over time the timing gets out of order.
let degree = 720;
function rotateElement(){
let spin = `rotate(${degree}deg)`;
document.getElementById('myVideo').style.transform = spin;
document.getElementById('myVideo').style.transitionDuration = "1s";
degree += 720;
}
function smaller(){
document.getElementById('myVideo').style.maxWidth = "10px";
document.getElementById('myVideo').style.maxHeight = "10px";
document.getElementById('myVideo').style.transitionDuration = "1s";
}
function bigger(){
document.getElementById('myVideo').style.maxWidth = "30vw";
document.getElementById('myVideo').style.maxHeight = "19vw";
document.getElementById('myVideo').style.transitionDuration = "1s";
}
//setInterval(change, 5000);
window.onload = function () {
setInterval(change, 5000);
setInterval(rotateElement, 4900);
setInterval(smaller, 4850);
setInterval(bigger, 5050);
};
Not sure exactly what you want the animation to do with the rotate, but this is the basic idea of just doing it in CSS.
.test {
background-color: yellow;
/*animation: shrink 5s 3s ease infinite, rotate 50s steps(10, end) forwards infinite; */
animation: shrink 5s 3s ease infinite, rotate 50s forwards infinite;
transition: width 1s, height 1s;
overflow: hidden;
width: 30vw;
height: 19vh;
}
#keyframes shrink {
0%,
65%,
90%,
100% {
width: 30vw;
height: 19vh;
}
70% {
width: 14px;
height: 10px;
}
}
#keyframes rotate {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}
<img class="test" src="http://placekitten.com/200/100">

Javascript / CSS - Rotation after CSS animation

I'm messing around with CSS animations at the moment and there is this behaviour I came across that I don't understand.
I have a div container to which I set an infinite CSS animation. The animation will just rotate the div back and forth. At any given point I want to manually adjust the rotation of the div to a specific and absolute angle (-90 degress in my case).
The problem I'm experiencing is, that whenever I (or animejs) is trying to set the rotation to the fixed -90 degrees after the CSS animation has started, the following rotation somehow depends on the CSS animation changes. I also tried to pause the CSS animation before without success.
I just want to trigger an animejs animation that always goes smoothly to -90 degrees from its current state (given by the CSS animation).
Here is an example of what I'm talking about:
var div = document.getElementById('testdiv');
document.addEventListener('keypress', function onPress(event) {
div.style.animationPlayState = 'paused';
if (event.key == 'q') {
div.style.transform = 'rotate(-90deg)';
}
if(event.key == 'e') {
div.style.transform = 'rotate(180deg)';
}
if(event.key == 's') {
div.style.animationPlayState = 'running';
}
});
#keyframes animation {
to {
transform: rotate(15deg);
}
}
#testdiv {
position: absolute;
background-color: black;
margin: auto;
margin-top: 50px;
width: 200px;
height: 150px;
animation-name: animation;
animation-duration: 1s;
animation-direction: alternate;
animation-iteration-count: infinite;
animation-fill-mode: forwards;
animation-play-state: paused;
}
<div id="testdiv"></div>
https://jsfiddle.net/Ls1ytf4h/
<div id="testdiv"></div>
If you run this and press Q or E in its inital state, it will change its rotation to either -90 or 180 degrees. If you press S, it will start the inifite CSS animation. After the animation started, press Q or E again (switch multiple times from Q to E to see the difference).
As you can see it doesn't go back to the absolute -90 degrees. It seem to work relative to something, but I cannot figure out to what. animejs is working in the same weird way, when I try to smoothly go to the -90 degrees from its current state.
Is there some way to avoid this behaviour?
Btw. was my first question here, so I hope I didn't do something wrong ;)
Kind regards!
Try this out :
var div = document.getElementById('testdiv');
document.addEventListener('keypress', function onPress(event) {
div.style.animationPlayState = 'paused';
div.style.animationName = 'none';
if (event.key == 'q') {
div.style.transform = 'rotate(-90deg)';
}
if(event.key == 'e') {
div.style.transform = 'rotate(180deg)';
}
if(event.key == 's') {
div.style.animationName = 'animation';
div.style.animationPlayState = 'running';
}
});
#keyframes animation {
to {
transform: rotate(15deg);
}
}
#testdiv {
position: absolute;
background-color: black;
margin: auto;
margin-top: 50px;
width: 200px;
height: 150px;
animation-name: animation;
animation-duration: 1s;
animation-direction: alternate;
animation-iteration-count: infinite;
animation-fill-mode: forwards;
animation-play-state: paused;
}
<div id="testdiv"></div>

Countinue the animation when the element has been replaced with another element

If I have an element, which has a CSS animation.
After 3 seconds, the Javascript replace the element with another new element (but same div element).
I want the new element to continue the rest unfinished part of the animation but not restart the animation.
Is it possible to fulfill it?
function replaceDIV(){
var elm = document.getElementsByTagName("div")[0];
var new_elm = document.createElement("div");
new_elm.innerHTML = "New Element";
new_elm.style.backgroundColor = "green";
elm.parentNode.replaceChild(new_elm,elm);
}
setTimeout(function(){
replaceDIV();
}, 3000);
div {
color: #FFF;
width: 150px;
height: 150px;
position: relative;
-webkit-animation: mymove 8s linear forwards;
animation: mymove 8s linear forwards;
}
#-webkit-keyframes mymove {
from {left: 0px;}
to {left: 500px;}
}
#keyframes mymove {
from {left: 0px;}
to {left: 500px;}
}
<div style="background-color: red;">Original Element</div>
How can I continue the rest unfinished CSS animation after the DIV has changed into a new DIV?
Is it possible to fulfill it with only CSS? Or it must use Javascript?
Animating the container div and then swapping out the inner div will get you to the solution that you want.
The problem is that when you're swapping out the same dom element it effectively resets the CSS animation to the beginning -- but if you're animating the container and swapping out the inner element then nothing will be interrupted.
In the below snippet I:
Created.container-div
Updated CSS applied to that container div
Updated index of var elm declaration
function replaceDIV(){
var elm = document.getElementsByTagName("div")[1];
var new_elm = document.createElement("div");
new_elm.innerHTML = "New Element";
new_elm.style.backgroundColor = "green";
elm.parentNode.replaceChild(new_elm,elm);
}
setTimeout(function(){
replaceDIV();
}, 3000);
.container-div {
color: #FFF;
width: 150px;
height: 150px;
position: relative;
-webkit-animation: mymove 8s linear forwards;
animation: mymove 8s linear forwards;
}
#-webkit-keyframes mymove {
from {left: 0px;}
to {left: 500px;}
}
#keyframes mymove {
from {left: 0px;}
to {left: 500px;}
}
<div class="container-div"><div style="background-color: red;">Original Element</div></div>

CSS animations to toggle when in viewport with vanilla JS

So I have got different animations made in CSS, though the problem is that they start right away when the page loads (ofcourse). I do not want this though. Is there a way in Vanilla JavaScript to get the animation to fire up only when it is in the viewport?
I have searched in a lot of places, but I either find a plugin I need to use or jQuery.
HTML:
<div class="introduction">
<h1>I can do the following for you:</h1>
<ul>
<li>Create a custommade, new website.</li>
<li>Code a PSD template into a working website.</li>
<li>Rework an outdated website.</li>
<li>Clean up messy code of a website.</li>
</ul>
</div>
CSS:
#keyframes showOnLoad {
0% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.introduction li {
list-style-type: none;
margin-bottom: 5px;
text-align: center;
opacity: 0;
-webkit-animation: showOnLoad;
animation: showOnLoad;
-webkit-animation-duration: 2s;
animation-duration: 2s;
-webkit-animation-fill-mode: forwards;
animation-fill-mode: forwards;
}
.introduction li:nth-child(2) {
-webkit-animation-delay: 1s;
animation-delay: 1s;
}
.introduction li:nth-child(3) {
-webkit-animation-delay: 2s;
animation-delay: 2s;
}
.introduction li:nth-child(4) {
-webkit-animation-delay: 3s;
animation-delay: 3s;
}
This is the code you need.
window.addEventListener("scroll", onScroll);
function onScroll() {
for (var item of document.querySelectorAll(".introduction li")) {
elementVisible(item);
}
}
function elementVisible(el) {
let top = el.offsetTop;
let height = el.offsetHeight;
let bottom = top + height;
let IsOverBottom = top > (window.pageYOffset + window.innerHeight);
let IsBeforeTop = bottom < window.pageYOffset;
if (!IsOverBottom && !IsBeforeTop) {
el.classList.add("show");
}
}
And a bit of CSS
#keyframes slideIn {
0% {
opacity: 0;
transform: translateX(100%);
}
100% {
opacity: 1;
transform: translateX(0%);
}
}
.show {
animation: slideIn 5s ease-in-out;
}
This is a basic implementation but it gets you closer.
http://jsbin.com/hetapaj/1/edit?css,js,output

webkit animation play state: how to start/stop animation on demand with javascript

I'm working on a game and just found out about -webkit-animation-play-state CSS attribute. I want certain text to show itself as a short animation, then hide and show when called again (in javascript).
I figured out how to start animation when I want to in javascript, but after its finished, the text stays on the screen, which I don't want to.
HTML:
<p id="INFO">
TEST
</p>
CSS:
#-webkit-keyframes pulse {
from {
opacity: 0.0;
font-size: 100%;
}
to {
opacity: 1.0;
font-size: 400%;
}
}
#INFO {
position: absolute;
left: 400px;
top: 200px;
-webkit-animation-name: pulse;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
-webkit-animation-play-state:paused;
visibility: hidden;
}
JS:
var INFO = document.getElementById("INFO");
INFO.innerHTML = "WRONG";
INFO.style.color = "RED";
INFO.style.webkitAnimationPlayState = "running";
INFO.style.visibility = "visible";
I read some questions/answers about -webkit-animation-play-state on this site, but none regarding the issue I am having.
One thing I read about was that animation goes to its default values when its ended. But my default values say that animation is "hidden" ? source: how to stop my webkit frame animation?
If anyone can point me in the right direction I'd be grateful.
If I was not clear enough, ask for more info please.
Thank you
For what you are trying to do, you don't need to use -webkit-animation-play-state.
Instead, try starting the animation by applying a class with the animation properties set. Then use a JavaScript event listener to remove the class once the animation finishes.
You should also keep the element hidden with opacity instead of visibility:hidden since you are manipulating the opacity in the animation.
CSS:
#-webkit-keyframes pulse {
from {
opacity: 0.0;
font-size: 100%;
}
to {
opacity: 1.0;
font-size: 400%;
}
}
#INFO {
opacity:0;
position: absolute;
left: 400px;
top: 200px;
}
.pulse {
-webkit-animation-name: pulse;
-webkit-animation-duration: 1s;
-webkit-animation-iteration-count: 1;
-webkit-animation-timing-function: ease-in-out;
}
JS:
var INFO = document.getElementById("INFO");
INFO.innerHTML = "WRONG";
INFO.style.color = "RED";
INFO.addEventListener('webkitAnimationEnd', function (e) {
this.classList.remove('pulse');
});
DEMO >> CodePen

Categories

Resources