CSS Animation Forward then Backward Flickering - javascript

I'm trying to create a CSS animation that when a user clicks an element it animates to the right then when they click it again it animates to the left. The problem I have is that it is introducing flickering. I know the reason, but I'm not sure the best way to fix it. I want the most elegant solution for this problem.
I setup a jsFiddle (WebKit only) here: http://jsfiddle.net/4Ad5c/2/
The CSS:
.animateRight{
-webkit-animation: goRightLeft 1s;
-webkit-animation-fill-mode: forwards;
}
.animateLeft{
-webkit-animation: goRightLeft 1s;
-webkit-animation-fill-mode: backwards;
-webkit-animation-direction: reverse;
}
#-webkit-keyframes goRightLeft {
0%{margin-left: 0px;}
100%{margin-left: 100px;}
}
The JavaScript:
this.animateBox = function(className){
var box = document.getElementsByClassName('box')[0];
box.className = "box";
setTimeout(function(){
box.className = "box " + className;
},1);
};
When you click the Animate Right it works as expected, but when you click the Animate Left it will flicker to the left and then animate as expected. The reason is that you have to remove the class and add another in order to get the animate to run again, but I don't know the best way to get this working. I figure I could add a class when removing the previous animation that has it in its current state, but that seems wrong to me.
Thanks for the help!

Reason for flickering:
You are applying class box on click before setting the next animationClass which makes the box go to left abruptly. and then you are applying the animation to go reverse. So it causes flickering while it abrupty goes left (removal of class) and adding class in timeout causes revereses animation according to the fillmode and direction in animateLeft class and makes it even more worser as goRightLeft again adds margin pulls it to right due to the margin in the rule and webkit-animation-fill-mode: backwards; pushes to to the left. So one approach i mentioned here is to do the reverse (adding/reducing) the margin.
Here is one solution for this:
For real reverse animation you need to apply margin decresing from 100px to 0 as you do while forward animation. So just add keyframes for LeftToRight and apply that in animation.
Css
.animateRight{
-webkit-animation: goRightLeft 1s;
-webkit-animation-fill-mode: forwards;
}
.animateLeft{
-webkit-animation: goLeftRight 1s; /* Note the goLeftRight animation */
-webkit-animation-fill-mode: backwards;
}
#-webkit-keyframes goRightLeft {
0%{margin-left: 0px;}
100%{margin-left: 100px;}
}
#-webkit-keyframes goLeftRight { /* Note the new keyframes rule for reverse animation*/
0%{margin-left: 100px;}
100%{margin-left: 0px;}
}
Script
this.animateBox = function(className){
var box = document.getElementsByClassName('box')[0];
box.className = "box " + className;
};
Demo

Related

Removing and adding a class through javascript smoothly

I am trying to create this animation where the title is visible in the page initially then when you scroll down you trigger the title to slowly fade away and a subtitle fades in right after. I have the title part working but I can't seem to get the subtitle to appear with a smooth transition. At first I have my subtitle at "visibility:hidden" then when I scroll and the javascript adds the transition in class, it just abruptly comes in disregarding the transition property I gave it. Here is the fiddler I set up. Below is the javascript and css (respectively) i'm using to get this animation to work. Of course if there area any easier ways to achieve this feel free to let me know. Any advice or help will be GREATLY appreciated I have been researching and trying things to no avail.
Javascript
const element = document.getElementById('title');
const element2 = document.getElementById('subtitle');
window.onscroll = function() {
console.log("document element");
console.log(document.documentElement.scrollTop);
console.log("scrolling elemnent");
if (window.scrollY > 0) {
element.classList.add('fadeout');
element2.classList.add('fadein');
console.log("hello");
}
}
.fadeout {
visibility: hidden;
opacity: 0;
transition: visibility 0s 2s, opacity 2s linear;
}
.two {
visibility: hidden;
}
#subtitle {
transition: opacity 2s linear;
}
.fadein {
visibility: visible;
opacity: 1;
transition: opacity 2s linear;
}
Currently your subtitle is at full opacity when you are fading it in (Because the visibility property does not set the opacity it just makes the element invisible)
Add opacity:0; to the .two CSS so that it will fade in.
Updated fiddle https://jsfiddle.net/s2cban6q (line 32 of CSS changed)

CSS Animation Is Not Staying

I have a page that has an input field and a "next" button. When the user clicks next, I want to shrink the input field and remove the "next" button. I have it mostly working as seen in this Bootply. My CSS animations look like this:
.default {
transition: all 1.0s ease;
}
.exit {
padding-left:5rem;
padding-right:5rem;
}
.remove-button {
animation: animate-remove-button 1.0s;
}
#keyframes animate-remove-button {
from {
transform:scaleX(1.0);
opacity: 1.0;
}
to {
transform:scaleX(0);
opacity: 0;
}
}
The animation runs. However, after the animation has completed, the button reappears. In addition, I basically want the width of the button to shrink all the way to 0 so that the text field grows. But, as you can see in the Bootply, that's not really happening, even though it kind of looks like it is.
What am I missing?
.remove-button {
animation: animate-remove-button 1.0s;
animation-fill-mode: forwards;
}
animation fill mode: forwards tell to keep the last state of animation.
Documentation: https://developer.mozilla.org/en/docs/Web/CSS/animation-fill-mode

Make multiple progress bars animate when scrolled past anchor point

Here is my site.
http://www.colleenbowes.com/#skills
I have messed around with this a lot that I kind of gave up. I still want it to animate but I am confused as to how. All I want is for my skill bars to animate when you scroll past an anchor point.
This is my animation:
Heres whats my css animation would look like on each bar (different widths though)
-webkit-animation: slide 3s forwards;
-webkit-animation-delay: 3s;
animation: slide 3s forwards;
animation-delay: 3s;
#-webkit-keyframes slide {
from {width: 0%;}
to { width: 90%; }
}
#keyframes slide {
from {width: 0%;}
to { width: 90%; }
}
Thanks.
How about this:
var target = $("#skills").offset().top;
var interval = setInterval(function() {
if ($(window).scrollTop() >= target) {
// do your animation
clearInterval(interval);
}
}, 350);
Keep in mind that this is designed to run just the first time it is visible... no sure if this is expected. Also, since you do not describe your animation, I've just added the code that should detect your scrolling. If you add a bit more detail on your animation, I could extend the answer.
Hope this helps.

easeInOutQuad with a fade in

I have searched for a couple hours now and cant seem to find the correct solution to this. I need to fade in a background image after its loaded. The loading and fadeIn() works with the code i have pasted but it is choppy. So i want to use easeInOutQuad with fadeIn() to see if its smoother. (the reason it is choppy is because there is other script at work doing other things at the same time).I tried this:
$(".wings-wrapper").fadeIn(2000, 'easeInOutQuad', function(){});
But it did not work .
var backgroundImage = $(currentWing).data("background-url");
var bgimage = new Image();
bgimage.src = backgroundImage;
$(bgimage).load(function(){
$(".wings-wrapper").css("background-image","url("+$(this).attr("src")+")").fadeIn(1000);
});
It seems you are looking to load an image with fade-in effect.
You may do this either with javascript or with CSS
Javascript:
Simply hide the image once loaded and use fadeIn() to make it appear again with a fade effect.
$(".jsfade").hide(0).delay(500).fadeIn(3000)
Where .jsfade is the class attached to an image
CSS:
You can also use CSS animations to change the opacity of the image to create a fadeIn effect. For an image with .fade class,
<img src="image.jpg" class="fade" />
You can define the css classes as follows
.fade {
opacity: 1;
animation: fadein 2s;
-moz-animation: fadein 2s; /* Firefox */
-webkit-animation: fadein 2s; /* Safari and Chrome */
-o-animation: fadein 2s; /* Opera */
}
#keyframes fadein {
from {
opacity:0;
}
to {
opacity:1;
}
}
#-moz-keyframes fadein { /* Firefox */
from {
opacity:0;
}
to {
opacity:1;
}
}
#-webkit-keyframes fadein { /* Safari and Chrome */
from {
opacity:0;
}
to {
opacity:1;
}
}
#-o-keyframes fadein { /* Opera */
from {
opacity:0;
}
to {
opacity: 1;
}
}
.fade:hover {
opacity: 0.5;
}
UPDATE:
jQuery UI specifies the following signature for show/hide/fadeIn functions
.show( [duration,] [easing,] [callback] )
Having said that, following is the code with different easing options
$(".jsfade").fadeIn(3000, 'linear') //WITH LINEAR AS EASING OPTION
$(".jsfadeEaseinOutQuad").fadeIn(3000,'easeInOutQuad') //with easeInOutQuad as the easing option.
So, the reason why $(".wings-wrapper").fadeIn(2000, 'easeInOutQuad', function(){}); doesnt seem to work is because your content is probably already visible and hence fadeIn() will essentially do nothing. To See the effect, you need to hide the elements first and then apply the fadeIn().
Use the css property display:none to hide .wings-wrapper
Here's the UPDATED plunkr with both approaches.

Webkit not rendering transformation transitions

So a friend and I are having a bit of trouble with webkit. We're trying to animate a specific div to do a 720° rotation and using transition to animate the container itself, with the rotation being triggered by a javascript function.
This works absolutely fine in Firefox and IE, but once we switch over to a webkit-based browser, the rotation transition doesn't work.
When monitoring the page through the developer tools, we can see that the specific properties are assigned to the div, only the transition isn't being rendered.
The javascript is as such:
function projtheme() {
var proj_title = document.getElementById("ring_1");
proj_title.style.animation = "none";
proj_title.style.WebkitAnimation = "none";
proj_title.style.transform = "rotate(720deg)";
proj_title.style.WebkitTransform = "rotate(720deg)";
proj_title.style.opacity = "0.1";
}
function projtheme_exit() {
var proj_title = document.getElementById("ring_1");
proj_title.style.animation = "spin_cw 60s linear infinite";
proj_title.style.WebkitAnimation = "spin_cw 60s linear infinite";
proj_title.style.transform = "rotate(0deg)";
proj_title.style.WebkitTransform = "rotate(0deg)";
proj_title.style.opacity = "0.6";
}
And said javascript functions are called in this way:
<span id="projbtn" onmouseout="projtheme_exit();" onmouseover="projtheme();"></span>
The CSS of the animated div has the properties it needs set to it (namely the transition properties):
#ring_1{
position: absolute;
top: 50%;
left: 50%;
margin-top: -160px;
margin-left: -150px;
opacity: 0.6;
display:block;
animation: spin_cw 60s linear infinite;
-webkit-animation: spin_cw 60s linear infinite;
transition: all 0.5s ease;
}
Help on this would be much appreciated, thanks!
UPDATE: Removing the animation function on said div seems to fix the issue, and the transition runs. The problem is, that animation needs to stay.
UPDATE 2: Inserting an alert between the lines that set the animation styles and those that set the transform properties inside of the script seems to make the transition work.

Categories