Animate an SVG sprite with CSS - css

I’ve got some svg sprites and want to animate them on a website.
What is the recommended way to use these files?
First, this is my Hunter (raw covert) - I got it as eps and converted to svg via indesign.
My entry is to animate it via css by changing the current picture in a keyframes animation.
Ideas:
I found this wonderful blogpost where the current image is selected via anchor
Use background position
So I’ve identified the different images in my file, gave them an ID and hidden the others. You can interconnect with #a #b #c ....
Hunter Image #a
-> Problem: Position on the sprite is still different. I had to change the background position as well.
https://jsfiddle.net/roest/035r0ozq/
0% {
background-image: url(http://elefantenjagdverein.de/server/elephants/hunter/hunter.hidden.svg#a);
}
20% {
background-image: url(http://elefantenjagdverein.de/server/elephants/hunter/hunter.hidden.svg#b);
}
Entry 2 - use background-position like a normal sprite ...
But something still seems broken.
If you use getspritexy.com with a normal sprite you see within "Generated sprite image" the selection. with my svg you see multiple images ...
Same result in my testFiddle:
https://jsfiddle.net/roest/4bbnnm9t/
0% {
background: url('http://elefantenjagdverein.de/server/elephants/hunter/hunter.svg') no-repeat -83px -15px;
width: $width;
height: $height;
}
20% {
background: url('http://elefantenjagdverein.de/server/elephants/hunter/hunter.svg') no-repeat -131px -15px;
width: $width;
height: $height;
}
Which of my ideas is the best and how can i get my hunter to animate correctly?

To have your frames step from one position to anothe without sliding, you can use step-end for the timing function.
animation: hunter-animation 2.5s step-end both infinite;
See: https://jsfiddle.net/4bbnnm9t/3/
Now that it steps, you just have to adjust the positions so they are correct.

Related

How to show transitionDuration in css animation?

Fiddle A:
I have a gallery of images (there are 4 right now) as shown here in this JSFiddle (lets call as Fiddle A)
in which every single image fades out after 3s second and there is transition delay of 800ms.
I have used JS to make the animation work. In JS, I have used the following constants in my JS.
transitionDuration => is the delay (white flash which we see) which happens on moving from one image to another.
transitionDelay => is the presenation time of an image (meaning the time span for which the image stay at their place).
totalDelay => is only for one image.
Fiddle B:
I also have another gallery of images as shown in this JSFiddle (let's call as Fiddle B) in which a CSS animation is going on.
Presentation time of one image in the fiddle is 3 seconds, and then it moves to another images.
Problem Statement:
I am wondering what changes I need to make in Fiddle B so that it looks like Fiddle A. In Fiddle B there is no transitionDuration. Is there a way we can add a transitionDuration (white flash which we can
see on moving from one image to another)?
In Fiddle B, I have used the following CSS:
a:nth-of-type(4), .featured-block a:nth-of-type(5), .featured-block a:nth-of-type(6) {
position: absolute;
animation: 9s infinite ease-in-out cf4FadeInOut;
opacity: 0;
z-index:1;
}
Adjusting opacity in keyframes to achieve transition duration works, which you have implemented.
Remove opacity: 1 and opacity: 0 so that it becomes
.featured-block a { display: inline-block; }
a:nth-of-type(4), .featured-block a:nth-of-type(5), .featured-block a:nth-of-type(6) {
position: absolute;
animation: 3s infinite ease-in-out cf4FadeInOut;
z-index:1;
}

Can divs below a css transform move along with divs above?

I am using css transitions to lay out a bunch of divs on top of each other. At any point, one of the divs may collapse. And all of the divs below it are supposed to move up to fill its spot.
Here is a codepen that describes the situation.
The css I am using is the following:
div {
height: 100px;
width: 100px;
margin: 15px;
}
.top {
background-color: red;
transform-origin: top;
animation: move 2s infinite;
}
.bottom {
background-color: blue;
}
#keyframes move {
0% {
transform: rotateX(0deg);
}
50% {
transform: rotateX(90deg);
}
}
With this, the top div will expand and contract. I want the divs below it to move up as the top one collapses.
If I switch transform for height, like this:
#keyframes move {
0% {
height 0;
}
50% {
height: 100px;
}
}
The bottom divs do move, but this is not a good solution for me because in the actual application, each div has a dynamically calculated size.
How can the bottom divs move smoothly with the top div?
With transform you won't be able to do that, as when an element is transformed, the surrounding elements won't see any change in the DOM, as DOM-wise nothing have happened.
What you can do to optimize it all, is to prepare the browser that the height will change, with the property will-change: height
MDN: https://developer.mozilla.org/en-US/docs/Web/CSS/will-change
This new CSS property aim's to do what transform does, make smoother and more optimized animations.
Do note though:
will-change is intended to be used as a last resort, in
order to try to deal with existing performance problems. It should not
be used to anticipate performance problems.
Another possible solution (read hack), is to trick the browser to use GPU instead of CPU, shown in this answer (see its p.1):
CSS `will-change` - how to use it, how it works
Updated
In case of the height is auto, or similar, this will work with the max-height trick, and here is a couple of answers of mine, showing how-to:
CSS Animation on max-height change
Can't use the same animation in reverse for class toggle
CSS transition auto width
And the last resort, if none of the above is applicable, is to use a small script and either create a styles dynamically (links below), or set them inline.
Dynamically styling pseudo-elements using jQuery or Javascript
How to prevent css from getting converted to inline css

Add background image in between another class for aesthetic purposes only

So I have a specific code for a hover effect on buttons that lead to certain categories on a wiki I raised. You can see those buttons here. (You can click on 'edit' to see the HTML on that page.)
Here's the code I'm using for this
.helpmodule
img:hover {
-moz-opacity: .8;
-khtml-opacity: .8;
background-image: url(vignette3.wikia.nocookie.net/zombieescape/images/3/32/…);
background-position: center;
opacity: .8;
width: 200px;
height: 200px;
}
Basically, all the code works for everything I need except for one little thing: The background-image, which you can find here. This image needs to be put at the center of those 9 buttons. The problem is that the class I'm using, of course, puts all those functions to all images used.
I want to find a way to get that specific image at the center of the buttons, without it moving away the buttons etc... so like a background image (that potentially can get behind the buttons if necessary).
Ok, I managed to get the exact result I wanted. What you need to do is first create an ID that has the background image, in this case the code is:
#buttons-navigator-body {
background-image: url(insert your url here);
background-repeat: no-repeat, no-repeat;
background-position: center;
}
You now add a <div id="buttons-navigator-body"></div>
and then, you can create your entire setup of elements within this ID. It will now automatically center the image in the middle of the bounding box of all elements together. All these are driven by one class that hovers images as you go over them with the following code:
.buttons-navigator-hover img:hover {
-moz-opacity: .8;
-khtml-opacity: .8;
opacity: .8;
width: 200px;
height: 200px;
}
The result can be seen here: http://zombieescape.wikia.com/wiki/Zombie_Escape_Wiki
Note that this might seem very logical or already answered in thousand posts, but in my case it was the purpose to have a background image that center itself exactly at the middle of a specific setup of elements to work along with multiple functional hover buttons, as opposed to just have a tiling image.

Stop Keyframes animation from sliding CSS3

I am using this demo http://cssdeck.com/labs/css-image-sprite-animations-with-steps-function to create a CSS3 animation. However, my image is of a different size so I have:
<div id="boules"></div>
Then the CSS:
#keyframes boules{
from { background-position: 0px; }
to { background-position: -1067px; }
}
#boules {
background: url(../images/boules.png) 0 0 no-repeat;
width: 133px;
height: 108px;
animation: boules 2s steps(10, end) infinite;
}
I want to reproduce the same effect as the example link above but for some reason in my version the frames slide across instead of giving the animation effect of a still image which morphs into a different shape.
I have tried changing the steps, the seconds and positioning of the background but I still get this slide effect instead of an animation. Is this is calculation issue?
Thanks
Your numbers aren't correct
If you say that you have 10 steps...
animation: boules 2s steps(10, end) infinite;
then the offset ...
to { background-position: -1067px; }
must be a number divisible by 10. But 1067 / 10 = 106.7px means your sprites would be a fractional dimension, and this is not possible.
Review what your sprite dimensions are, and check your math.
Yes, it works Vals. Thanks for your help. As it turns out number of sprites is the same as the keyframe width but I get your point. Cheers!

How to find the proper offsets for CSS sprites?

I have a sprite image set as the background of an element on my page, but how do I find the proper offsets so I can actually see it on the screen?
When you build your sprite image in your graphics program you have to write down the offsets for each element and use those in your CSS.
You can use a tool like this and get background positions of the icons in the sprite.
You need to first upload your image, then select an icon from the sprite. CSS will be generated, just copy the generated CSS and use it in your class.
It will generate CSS styles like this, you need to include that in your CSS class
background-position: -213px -135px;
width: 97px;
height: 65px;
There are web tools that will create the sprite and give you CSS with positions for you. http://css-sprit.es/ is an example.
The online CSS Sprite Generator is worth looking into, it should take some of the tedium out of this approach.
The main thing to remember is that the offsets will be negative. If you have an image that's 100x500 with 100x100 sprites, then the offsets will be:
.img1 { background-position: 0 0; }
.img2 { background-position: 0 -100px; }
.img3 { background-position: 0 -200px; }
.img4 { background-position: 0 -300px; }
.img5 { background-position: 0 -400px; }
Since empty areas of a png file takes up very few bytes, just put all "images" at a regular interval, say every 50 or 100 pixels. That way you can simply find the first proper value and remove 50/100 pixels from that (50 ctrl-x in vim).

Resources