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>
Related
I have found the code below.
However, if you keep the key pressed, the animation continues.
What I'm trying to do is, press the key many times, and each time you press it, the animation moves a little.
If you keep the key pressed, you'd only move one frame, so to speak.
https://jsfiddle.net/hgalvan/1z0c2xjd/3/
Click here to focus, then press key "d" to animate!
<div id="ball">test</div>
#ball {
--size: 100px;
position: relative;
top: 40px;
width: var(--size);
height: var(--size);
line-height: var(--size);
border-radius: var(--size);
text-align: center;
background-color: rgb(114, 240, 214);
animation: roll 3s linear infinite alternate;
animation-play-state: paused;
}
#keyframes roll {
0% { transform: translateX(0px) rotate(0deg); }
100% { transform: translateX(300px) rotate(0deg); }
}
const elBall = document.querySelector("#ball");
const toggleRoll = (evt) => {
if (evt.key !== "d" || evt.repeat) return;
elBall.style.animationPlayState = evt.type === "keydown" ? "running" : "paused";
};
addEventListener("keydown", toggleRoll);
addEventListener("keyup", toggleRoll);
I guess triggering the animation only on keyup would work, but not sure how to do it yet.
This is my first question on SO, I hope I'm doing it well.
My goal is to have a "magical rune effect", where each letter of a text "floats around" its original position, as if it was suspended in mid-air on a magic parchment of some sort.
To put it simply, it will be used for a game. I know how to make something "float at random" on a page, like a hot air balloon; but this isn't what I'm trying to do : I want the letters to move around their original position.
So far, I've tried something (you can check my fiddle at https://jsfiddle.net/3as4omj2/ ), but I'm running into problems.
(don't worry about the default font and the ugly aqua background, it's used for positionning)
function float(element, range, speed) {
var position = $(element).offset();
$(element).attr( 'original_x', position.left);
$(element).attr( 'original_y', position.top);
$(element).attr( 'range', range );
$(element).attr( 'speed', speed );
drift(element);
}
function drift(element) {
var max = Number.parseInt($(element).attr('range'));
var speed = Number.parseInt($(element).attr('speed'));
var pos_x = Number.parseInt($(element).attr('original_x'));
var pos_y = Number.parseInt($(element).attr('original_y'));
var drift_x = max/2 - Math.floor(Math.random()*max);
var drift_y = max/2 - Math.floor(Math.random()*max);
var final_x = pos_x + drift_x;
var final_y = pos_y + drift_y;
var total_wait = Math.sqrt(drift_x*drift_x+drift_y*drift_y)*speed;
$(element).animate({
left : final_x+"px",
top : final_y+"px"
}, total_wait, /*"linear",*/ function(){
setTimeout(function () {
drift(element);
}, Math.abs(total_wait-Math.floor(Math.random()*150)));
});
}
$( "#go" ).click(function() {
float($("#t"),50, 10);
float($("#e"),50, 10);
float($("#s"),50, 10);
float($("#s"),50, 10);
float($("#t2"),50, 10);
})
Here's my problems and questions so far :
I can't line up my letters to form a word (like, "TEST" is seen vertically, I'd love to see it as an horizontal "TEST"); ideally, using spans, so I can dynamically add a word or remove it without creating dozens of elements.
The text moves bananas... and I don't seem to be understanding why. :(
I'd love to be able to "move the original position" along, so that I can animate the letters further (moving the general text left to right, for example).
Ultimately, is there a way to optimize the size of the font to the user's display ?
Can you guys give me some advice ?
Thank you in advance.
You could try using CSS3 animation instead, setting custom animation delay for every letter using :nth-of-type() selector. To better understand all the animation properties, see this docs. All the rest is the matter of tweaking translate values.
If you are determined enough, creating custom #keyframes for each letter is also an option.
.runes span {
position: relative;
display: inline-block;
padding: 10px;
background: aqua;
animation-duration: 2s;
animation-name: float;
animation-iteration-count: infinite;
animation-direction: alternate;
animation-timing-function: ease-in-out;
}
.runes span:nth-of-type(1) {
animation-delay: .3s;
}
.runes span:nth-of-type(2) {
animation-delay: .4s;
}
.runes span:nth-of-type(3) {
animation-delay: .5s;
}
.runes span:nth-of-type(4) {
animation-delay: .7s;
}
#keyframes float {
0% {
transform: translate(0, 0);
}
25% {
transform: translate(8px, 0);
}
50% {
transform: translate(0, 8px);
}
75% {
transform: translate(5px, 5px);
}
}
<section class="runes">
<span>T</span>
<span>E</span>
<span>S</span>
<span>T</span>
</section>
Here's my problem :
I'm developping a little animation with JS and CSS, and I would like this stop when the animation is over. Now, my animation go back to his basic state.
var
btn = document.getElementById("btn");
anim = document.getElementById("anim");
// button click event
btn.addEventListener("click", ToggleAnimation, false);
// apply all webkit events
anim.addEventListener("webkitAnimationStart", AnimationListener);
anim.addEventListener("webkitAnimationIteration", AnimationListener);
anim.addEventListener("webkitAnimationEnd", AnimationListener);
// and standard events
anim.addEventListener("animationstart", AnimationListener);
anim.addEventListener("animationiteration", AnimationListener);
anim.addEventListener("animationend", AnimationListener);
// handle animation events
function AnimationListener(e) {
if (e.type.toLowerCase().indexOf("animationend") >= 0) {
ToggleAnimation();
}
}
// start/stop animation
function ToggleAnimation(e) {
var on = (anim.className != "");
anim.className = (on ? "" : "enable");
};
#anim
{
display: block;
width: 150px;
height:150px;
background-color: #060;
}
#anim.enable
{
-webkit-animation: flash 1s ease;
animation: flash 1s ease;
animation-fill-mode: forwards;
-webkit-animation-fill-mode: forwards;
}
/* animation */
#-webkit-keyframes flash {
50% { margin-top:50px; }
}
#keyframes flash {
50% { margin-top:50px; }
}
<button id="btn">
Launch animation
</button>
<p><a id="anim" href="#"></a></p>
Here's my FIDDLE. I think the problem is in the function "ToggleAnimation" but I can't find what.
Thanks in advance and had a good day.
Azyme
I think I have achieved what you are trying to - changed the animation to have a start and end state (0% and 100%) and used jquery to add the class "enable" rather than toggle it
css
#-webkit-keyframes flash {
0% { margin-top: 0}
100% { margin-top:50px; }
}
#keyframes flash {
0% { margin-top: 0}
100% { margin-top:50px; }
}
jquery
$('#btn').click(function(){
$('#anim').addClass("enable");
})
hope thats helpful, made a codepen http://codepen.io/anon/pen/vLLKoZ
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';
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