CSS sprite animation with a large sprite freezes at the start - javascript

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 :(

Related

Creating a FadeIn/FadeOut Animation with a set delay in HTML/CSS/JS (StreamLabs)

Streamlabs has a feature which lets you delay the fadeIn animation of a text after a certain time (without any extra code).
This feature is pretty much not usable though. There is also no option to control the fadeOut animation.
If you define the fadeIn delay to be ~4s: It jumps (after 4s) straight from 0% opacity to 50% opacity and after another second it jumps to 100% opacity. There is no fluid animation. However, this does not happen if you have the "text delay" on 0s. Everything looks fine if you keep it at 0s.
So I was wondering how to implement my own version of a fadeInFadeOut animation with either HTML, CSS or JS.
My goal is to have a text appear after 4 seconds with a fadeIn animation (duration 1 second), then it should stay visible for 3 seconds. Eventually the text should disappear with a fadeOut animation (duration 1 second) after 8 seconds.
Is this effect achievable with such a structure?
animation: fadeOut x y forwards;
Appreciate all the help! Thanks!
EDIT Here's the updated code from Streamlabs with the CSS FadeIn/Out animation.
```HTML
<div id="alert-image-wrap"
<div id="alert-image">{img}</div>
</div>
<div id="alert-text-wrap">
<div id="alert-text">
<div id="alert-message">{messageTemplate}</div>
<div id="alert-user-message">{userMessage}</div>
</div>
</div>
```
``` CSS (most important parts)
#alert-text {
z-index: 6;
position: relative;
top: -920px;
}
#alert-text-wrap {
z-index: 6;
position: relative;
opacity:1;
animation: fadein-fadeout 9s forwards;
}
*//credits #Cedric Cholley*
#keyframes fadein-fadeout {
...
100% {opacity: 0} /* (8 + 1) 9s / 9s = 100% */
It is achievable with CSS animation indeed. You only need to make some computations (see my comments on the CSS code.
.fadein-fadeout {
animation: fadein-fadeout 9s forwards;
}
#keyframes fadein-fadeout {
0% {opacity: 0}
44.4% {opacity: 0} /* 4s / 9s ~ 44.4…% */
55.6% {opacity: 1} /* (4 + 1) 5s / 9s ~ 55.6…% */
88.9% {opacity: 1} /* (5 + 3) 8s / 9s ~ 88.9…% */
100% {opacity: 0} /* (8 + 1) 9s / 9s = 100% */
<h1 class="fadein-fadeout">A random text</h1>

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

Change start of a CSS3 animation

I wanted to create a table with color-changing rows (for example: from complete green background to complete red in half an hour starting from 12o'clock). I managed to do this but now i thought about a case where the site is being called when the time's row is already 10 min up (so not half an hour of gradient progress but only 20 minutes and the row wouldn't start completely green).
so i wondered if it is possible to set the start time of a CSS animation.
Maybe over a keyframe? i have literally no idea cause i didn't work much with css3 the past time and i would be thankful for any information :)
[my animation css]
.timing {
background: linear-gradient(88deg, #05a400, #ff0000);
background-size: 400% 400%;
-webkit-animation: Gradient 180s linear infinite;
-moz-animation: Gradient 180s linear infinite;
animation: Gradient 180s linear infinite;
}
#-webkit-keyframes Gradient {
0%{background-position:0% 53%}
50%{background-position:100% 48%}
100%{background-position:0% 53%}
}
#-moz-keyframes Gradient {
0%{background-position:0% 53%}
50%{background-position:100% 48%}
100%{background-position:0% 53%}
}
#keyframes Gradient {
0%{background-position:0% 53%}
50%{background-position:100% 48%}
100%{background-position:0% 53%}
}
and sorry if the header isn't clearly stating my question, i didn't find the proper words...
You can use CSS variable to adjust the starting time of an animation then you can simply modify it using JS:
document.querySelectorAll('.timing')[1].style.setProperty('--t','5s');
.timing {
background: linear-gradient(88deg, #05a400, #ff0000);
background-size: 400% 400%;
animation: Gradient 2s linear infinite var(--t,0s);
height:80px;
color:#fff;
font-size:30px;
}
#keyframes Gradient {
0% {
background-position: 0% 53%
}
50% {
background-position: 100% 48%
}
100% {
background-position: 0% 53%
}
}
<div class="timing">
This one will start immediately
</div>
<div class="timing">
This one will start after 5s
</div>

CSS animations don't play properly

I have an introductory portion of a site where 4 letters (SVGS) pop onto the screen. Most of the time, it plays just fine. On occasion however, sometimes one or two or all the images won't animate in at all. I'm not sure what could be causing this (it's not the cache), and a page refresh usually fixes it. Am I missing something? Should I wait for the images to load AND for the entire DOM to be ready?
Here is the relevant CSS (Sass).
Animation:
#keyframes bobble {
0% {
transform: translateY(124px) scale(0.8, 1.6);
}
25% {
transform: translateY(-64px) scale(1.6, 0.8);
}
55% {
transform: translateY(16px) scale(0.9, 1.1);
}
100% {
transform: translateY(0) scale(1);
opacity: 1;
}
}
Styling
.hello-header-img {
height: 100%;
width: 100%;
opacity: 0;
animation: bobble $animation-duration cubic-bezier(0.64, 0.57, 0.67, 1.53);
animation-fill-mode: forwards;
animation-play-state: paused;
will-change: transform, opacity;
// Plays animations when images have loaded (JS)
.is-ready & {
animation-play-state: running;
}
}
Each letter also has an animation delay which starts at 0.4s and increases by 0.3s for each letter (so letter 1 = 0.4s delay, letter 2 = 0.7s delay, letter 3 = 1s delay, etc).
Javascript
const imgs = document.querySelectorAll('.hello-header img');
let counter = 0;
let hasScrolled = false;
// Animate after hello section images have loaded
[].forEach.call( imgs, function( img ) {
img.addEventListener( 'load', ()=> {
counter++;
if ( counter === imgs.length ) {
document.querySelectorAll('.js-hello-header')[0].classList.add('is-ready');
}
}, false );
});
Try replacing translate and scale with translate3d and scale3d (with the appropriate parameters).
translate and scale in general are very CPU expensive while their 3d counterparts utilize hardware acceleration from the graphics card and therefore play animations much smoother.

CSS3 animation change background-image without sliding

This is the current code I have
.jack_hitting{
-moz-animation: jackhitting 0.5s infinite;
}
#-moz-keyframes jackhitting {
0% {
background-position: -8px -108px;
}
20% {
background-position: -41px -108px;
}
40% {
background-position: -73px -108px;
}
60% {
background-position: -105px -108px;
}
80% {
background-position: -137px -108px;
}
100% {
background-position: -8px -108px;
}
}
and this cycles through the background image sliding to the next one, but i would rather have it not slide, so that it basically works like the following js code:
document.getElementById('id').style.backgroundPosition='-8px -108px';
Is there an effect that can do what I would like?
Thanks in advance :)
I think I found it: step-start (I think it's one of multiple that could do this in the animation-timing-function category)
animation: jackhitting 10s step-start infinite;
Long-form would be
animation-name: jackhitting;
animation-duration: 10s;
animation-timing-function: step-start;
animation-iteration-count: infinite;
Unfortunately, you'll have to prefix this for each browser for now.
Here's a fiddle to test it out:
http://jsfiddle.net/Ym6b5/4/
(The div is much too big. I wanted you to see the background image move and see if it's what you were after)
The animation-duration is the total amount of time it'll take to go through your keyframes. The animation-delay that I thought was the delay between steps is the delay before the animation should start.
http://dev.w3.org/csswg/css3-animations
Hope it's what you were looking for.
Cheers,
iso

Categories