Smooth animation start - javascript

I've got an animation that just moves from top to the bottom.
0 - top
25 - middle
50 - bottom
75 - middle
100 - top
I've made it endless using javascript but every time it stops and starts again it blinks (disappears and appears for 1 second).
Is there a way to make this action smooth without blinking at start?

Without seeing your code it's difficult to know, but I'd imagine it may have something to do with the way you've set up your #keyframes. For an infinite looping animation with no glitch, try something like this:
HTML:
div {
width: 100px;
height: 100px;
background: red;
position: relative;
-webkit-animation: mymove 2s infinite; /* Safari 4.0 - 8.0 */
animation: mymove 2s infinite;
}
CSS:
/* Safari 4.0 - 8.0 */
#-webkit-keyframes mymove {
0% {top: 0px;}
50% {top: 100px;}
100% {top: 0px;}
}
/* Standard syntax */
#keyframes mymove {
0% {top: 0px;}
50% {top: 100px;}
100% {top: 0px;}
}
Hope this helps 👍

Related

CSS animation relative to current screen position

I'm trying to implement some CSS Keyframe animations on my application, which get triggered on different events.
The animation consists of a unicorn flying up from the bottom of the screen, stopping in the middle for a second, and then moving up out of the screen. The problem comes when different users have different amounts on content on the page, making the page height bigger.
I want the animation to stop for a second relative to users position, in the middle of the users view, not relative to the page height.
This is my code so far:
<img src="../***" v-if="aCounter === 1" class="unicornUp" alt="Unicorn">
.unicornUp {
position:absolute;
width:50%;
height:50%;
right:20%;
opacity: 0;
z-index:99;
animation-name: unicornMoveUp;
animation-duration: 3s;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
animation-iteration-count: 1;
animation-delay: 0.5s;
}
#keyframes unicornMoveUp {
from { bottom: 0; opacity: 1;}
20% {bottom:20%;opacity: 1;transform: rotate(5deg);}
40% {bottom: 50%;opacity: 1;}
60% {bottom: 50%;opacity: 1; transform: rotate(-5deg);}
80% {bottom: 60%; opacity: 1;}
100% {bottom: 90%; opacity: 0;}
}
I've been thinking about a sticky parent div, but I'm not sure if this is even correct and where to start. Any help would be appreciated!
Try position: fixed instead, as as opposed to position: absolute which is relative to the entire document, fixed is relative to the viewport i.e. the screen

CSS sprite animation with a large sprite freezes at the start

I have 2 sprite animations in which there are a lot of frames:
Idle - 5632x5632 pixels (678 Kb)
Action - 7168x7168 pixels (879 kb)
My CSS:
.idle {
--animFrames: 11;
--animDuration: 4s;
background-image: url("idle.png");
animation: idlev var(--animDuration) steps(var(--animFrames)) infinite, idleh calc(var(--animDuration) / var(--animFrames)) steps(var(--animFrames)) infinite;
}
#keyframes idlev {
0% {background-position-y: 0px;}
100% {background-position-y: -5632px;}
}
#keyframes idleh {
0% {background-position-x: 0px;}
100% {background-position-x: -5632px;}
}
.action {
--animFrames: 14;
--animDuration: 5s;
background-image: url("action.png");
animation: actionv var(--animDuration) steps(var(--animFrames)) infinite, actionh calc(var(--animDuration) / var(--animFrames)) steps(var(--animFrames)) infinite;
}
#keyframes actionv {
0% {background-position-y: 0px;}
100% {background-position-y: -7168px;}
}
#keyframes actionh {
0% {background-position-x: 0px;}
100% {background-position-x: -7168px;}
}
When I change the class to another animation with the following code, I see a small frieze at the beginning of the animation:
$('.animation-container').removeClass('idle').addClass('action');
When changing to idle and again to action, it no longer observes a frieze. If I use 3 animations, for example, otherAction, and go along the path "idle -> action -> idle -> otherAction -> idle -> action" then in action I see the frieze again (by the way in "otherAction" too).
Perhaps this is due to the fact that my sprites are too large? I tried to preload them so that they didn't download when animation start, but that didn't help.
Any ideas how to fix this?
P.S. Sorry, but I can’t upload sprites for your tests, since I promised not to provide them to third parties :(

Moving element on screen and back with keyframes

Provided I have following code:
<div class="leftBox">
<div class="mainNode"></div>
</div>
<script type="text/javascript">
$('.mainNode').click(function() {
var element = $('.mainNode');
if (!element.hasClass('show')) {
element.removeClass('hide');
element.addClass('show');
} else {
element.removeClass('show');
element.addClass('hide');
}
})
</script>
and in CSS:
.mainNode {
width: 160px;
height: 160px;
border-radius: 50%;
background-color: red;
position :relative;
}
.show {
-webkit-animation: mymove 1s forwards; /* Safari 4.0 - 8.0 */
animation: mymove 1s forwards;
}
.hide {
-webkit-animation: mymove 1s reverse; /* Safari 4.0 - 8.0 */
animation: mymove 1s reverse;
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
/* Standard syntax */
#keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
What I'm looking for is that my circle moves to the bottom when I click it using the keyframes (I will have more of them in the future).
After the first click the circle should stay at the bottom, this is happening already with the code above.
However, when I reclick the circle, I want it to do the same animation in reverse and return to the original position. Also allowing me to reclick it after to move it back down using the same animation... This is currently not working. It moves down and the jumps to the top and the bottom without the animation.
Any help would be appreciated.
Here be my example
Please try this. I try my best. Animation work top to bottom and bottom to top every time.
$('.mainNode').click(function() {
var element = $('.mainNode');
if (!element.hasClass('show')) {
element.removeClass('hide');
element.addClass('show');
element.before( element.clone(true)).remove();
} else {
element.removeClass('show');
element.addClass('hide');
element.before( element.clone(true)).remove();
}
})
.mainNode {
width: 160px;
height: 160px;
border-radius: 50%;
background-color: red;
position :relative;
}
.show {
-webkit-animation: mymove 1s forwards; /* Safari 4.0 - 8.0 */
animation: mymove 1s forwards;
}
.hide {
-webkit-animation: mymove1 1s forwards; /* Safari 4.0 - 8.0 */
animation: mymove1 1s forwards;
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
/* Standard syntax */
#keyframes mymove {
from {top: 0px;}
to {top: 200px;}
}
/* Safari 4.0 - 8.0 */
#-webkit-keyframes mymove1 {
from {top: 200px;}
to {top: 0px;}
}
/* Standard syntax */
#keyframes mymove1 {
from {top: 200px;}
to {top: 0px;}
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="leftBox">
<div class="mainNode"></div>
</div>
Use backwords instead of reverse it will work for you.
.hide {
-webkit-animation: mymove 1s backwards; /* Safari 4.0 - 8.0 */
animation: mymove 1s backwards;
animation-delay: .2s;
}
You need to change two things to make this work:
.hide {
-webkit-animation: mymove 1s reverse forwards; /* Safari 4.0 - 8.0 */
animation: mymove 1s reverse forwards;
animation-delay: .2s;
}
Use animation-direction reverse, but animation-fill-mode forwards. This way, the animation will start from the end, and stay at the last keyframe (which is back at the top).
But there is an additional problem: As soon as the show class is removed, it jumps back to top, since the animation no longer applies. To prevent this, you can add animation-name: mymove to your .mainNode.
.mainNode {
animation-name: mymove;
// Other properties...
}
See it in action here: https://codepen.io/anon/pen/jLgrjW

CSS Keyframe animation along with screen height

I am trying to animate an object in second page from one position to another using the below code.
#myimg2{
position: absolute;
-webkit-animation: myfirst2 3s none; /* Chrome, Safari, Opera */
-webkit-animation-direction: top; /* Chrome, Safari, Opera */
animation: myfirst2 3s none;
}
#-webkit-keyframes myfirst2 {
0% { left: 10%; top: 1325px;}
100% { left: 10%; top: 1285px;}
}
Here, I have hardcoded top and it is working perfectly fine.
I can extract the height of the screen using
var hgt = $('#img1').height();
Can anyone suggest how i can set this var+40 as top for 100 percent animation and var for 0 percent animation rather than hardcoding with 1325 and 1285 respectively

How To Move/Animate A DIV Background Image Smoothly Vertical?

I have a DIV with some text in it. I added a background image on it. Now I want to keep scrolling my DIV background image from bottom to top smoothly. For this purpose, I searched for the code and I found some codes...
<style type="text/css">
#moving_bg {
background-image:url('http://i.imgur.com/zF1zrkC.jpg');
background-repeat:repeat-y;
color:#FFFFFF;
width:1000px;
height:300px;
text-align:center;
}
</style>
<div id="moving_bg">
<h2>This is my DIV text that I want do not want to move/animate.</h2>
</div>
CODE 1:) http://jsfiddle.net/ZTsG9/1/ This is a code that I found but this one have some problems with me. First of all its moving horizontally and second is that its making image width doubled to 200% that I dont want also.
CODE 2:) http://jsfiddle.net/hY5Dx/3/ This one is also moving horizontally and not making the image width doubled. But its JQuery that I dont want.
I want only CSS3 or JavaScript with HTML code to move my background image in DIV from bottom to top without doubling the image width. Is this possible in these two web languages...???
If you can get away with using 2 divs you can get it to work like this:
Working Example
html, body {
height: 100%;
margin: 0;
}
.outer {
height:100%;
overflow: hidden; /* hide the overflow so .inner looks like it fits in the window*/
}
.inner {
height:200%; /* the inner div will need to be twice as tall as the outer div */
width:100%;
-webkit-animation:mymove 5s linear infinite;
animation:mymove 5s linear infinite;
background-image: url('http://static1.360vrs.com/pano-content/judith-stone-at-sunset-east-farndon/640px-360-panorama.jpg');
background-size: 100% 50%; /* 50% height will be 100% of the window height*/
}
#-webkit-keyframes mymove {
from {
background-position: 0% 0%;
}
to {
background-position: 0% -100%;
}
}
#keyframes mymove {
from {
background-position: 0% 0%;
}
to {
background-position: 0% -100%;
}
}
As per Muhammad's request i'll add my fiddle as an answer.
VanillaJS using requestAnimationFrame for that butter smooth slide :)
http://jsfiddle.net/hY5Dx/103/
Code to please SO:
var y = 0;
requestAnimationFrame(move);
var body = document.body;
function move(){
y++;
body.style.backgroundPosition = '0 ' + y + 'px';
requestAnimationFrame(move);
}
As there is too much comments after #Skynet answer, here I add the one I wrote following his base structure.
So in CSS, you can make use of animation CSS property
This property still is vendor-prefixes dependant.
Basically for what you want to do, you have to animate the background-position property, only on y axis.
Here is the CSS code
/* Following defines how the animation 'mymove' will run */
#keyframes mymove {
/* 0% is the beginning of animation */
0% {
background-position: 0 0;
}
/* This is the end… where we set it to the size of the background image for y axis (0 being the x axis) */
100% {
background-position: 0 860px;
}
}
/* same for webkit browsers */
#-webkit-keyframes mymove {
0% {
background-position: 0 0;
}
100% {
background-position: 0 860px;
}
html, body {
height: 100%;
}
.view {
color:#FFFFFF;
height: 366px;
text-align:center;
/* Here we assign our 'mymove' animation to the class .view, we ask it to last 3 seconds, linearly (no ease at start or end), and repeating infinitely */
animation: mymove 5s linear infinite;
/* again webkit browsers */
-webkit-animation:mymove 5s linear infinite;
background: url('http://i.imgur.com/zF1zrkC.jpg');
}
And here we are.
The other answers are ok but as mentionned, using multiple divs isn't always possible and the use of requestAnimationFrame() is also browser specific (Paul Irish has good polyfill for this).
Furthermore, I'm not sure incrementing a var infinitely is a good solution : it will block near 6100000px, and its much more code to change the speed or to take control over the animation.
<div class="view" style="background-image: url('http://i.imgur.com/zF1zrkC.jpg')">According to a new report from AnandTech.</div>
html, body {
height: 100%;
}
.view {
color:#FFFFFF;
width:1000px;
height:300px;
text-align:center;
-webkit-animation:mymove 5s linear infinite;
/* Safari and Chrome */
animation:mymove 5s linear infinite;
background-size: 200% 100%;
background-repeat: repeat-y;
}
#keyframes mymove {
100% {
transform: translate3d(0px, -400px, 0px);
}
}
#-webkit-keyframes mymove
/* Safari and Chrome */
{
100% {
transform: translate3d(0px, -400px, 0px);
}
}
check jsfiddle

Categories