CSS3 Sprite Animation without tweening
Asked Answered
M

3

5

Read below for my final edit!

Is it possible to use CSS3 animations without having the animations tween between frames?

For example, I have an image that I have two character animation sprites on. They are spaced evenly 50px. When I use the following animation I still get a tween (although a very fast tween so it can look like a flicker).

#ball .animated{
        -webkit-animation-name: animate;
        -webkit-animation-duration: .5s;
        -webkit-animation-iteration-count: infinite;
        -webkit-animation-direction: alternate;
        -webkit-animation-timing-function: linear;}
@-webkit-keyframes animate{
        0%{-webkit-transform: translate3d(0,0,0);}
        49%{-webkit-transform: translate3d(0,0,0);}

        50%{-webkit-transform: translate3d(-50px,0,0);}
        100%{-webkit-transform: translate3d(-50px,0,0);}

So based on the above, the sprite-frame should be held on the first part of the image (x = 0px) for the first 0-49% of the duration and then jump to second part of the image (x = -50px) for 50-100%. However, the 1% difference is still enough to visually see a tween from 0 to -50px.

Thoughts?

Edit:

-webkit-animation-timing-function: cubic-bezier(1,0,1,0);

The above seemed to straighten it out a bit but after a while it goes back to flickering.

Edit: I hadn't realized that you could use decimals with the percentages. Closing the gap from 1% to 0.1% creates a much faster tween which is just about not visible (with a -webkit-animation-duration: < 1s;)

0%{-webkit-transform: translate3d(0,0,0);}
49.9%{-webkit-transform: translate3d(0,0,0);}

50%{-webkit-transform: translate3d(-50px,0,0);}
100%{-webkit-transform: translate3d(-50px,0,0);}

Final edit!: Ok, so from what I've found web-kit animations percentages will accept a decimal to the millionth place (i.e. 0.0001). Which on a relatively quick animation timer will result in an instantaneous translation. A little bit of a hack I suppose but it does the trick.

Example:

@-webkit-keyframes sprite {
 0% {
   -webkit-transform: translate3d(0,0,0);
 }
 50% {
   -webkit-transform: translate3d(0,0,0);
 }
 50.0001%{
   -webkit-transform: translate3d(-50px,0,0);
 }
 100%{
   -webkit-transform: translate3d(-50px,0,0);
 }
}

The above example is of an image of 100px (each sprite on the image is 50px wide) within a container div with the width: 50px and overflow:hidden to only show one sprite off the image at a time.

Note: I am using translate3d because it is hardware accelerated in mobile browsers where translateX,translateY,translateZ are not yet hardware accelerated.

Manure answered 21/12, 2010 at 19:36 Comment(3)
I am currently attempting to use a cubic-bezier that is a vertical line.Manure
Empereol: unfortunately css animations do not currently support non-tweening keyframes. Your solution might not look the same on a very fast computer (since you could still be able to catch a few frames between the two states). I'd suggest using sprite.js readwriteweb.com/hack/2010/12/… which does this great.Overcome
Data belongs in HTML, Styles belong in CSS, Interactions belong in JS. It sounds to me like you're trying to create an interaction with a styling language.Hollyanne
S
9

Here is another great example using steps().

It is a simple yet powerful way for animating sprites. Below there's an animation of old Duke waving.

@keyframes wink {
    from { background-position: 0px; }
    to { background-position: -500px; }
}

.hi {
    width: 50px;
    height: 72px;
    background-image: url("https://i.sstatic.net/1Ad8o.png");
    margin: 0 auto;      
    animation: wink .8s steps(10, end) infinite;
}
<img src="https://i.sstatic.net/1Ad8o.png">
<div class="hi"></div>

There's a demo you can play with on cssdeck.

Selfsustaining answered 18/7, 2012 at 6:37 Comment(0)
L
1

It's been awhile since this question was asked, but CSS3 now has a step timing function, so I've used that for sprite animations. From my codepen example at http://codepen.io/natedsaint/pen/2/7 :

/* Animation keyframes */
@keyframes walk {
  0% { background-position:0px 0px;}
  16.67% { background-position:-104px 0px;}
  33.33% { background-position:-208px 0px;}
  50% {background-position:-320px 0px;}
  66.66% { background-position:-416px 0px;}
  80.65% { background-position:-520px 0px;}
  100% { background-position:-624px 0px;}
}

#guyBrush {
  animation: walk infinite 1s steps(1,end);
  background-image:url('http://www.nathanstpierre.com/gb_walk.png');
  width:104px;
  height:152px;
  position:absolute;
  top:160px;
  left:360px;
} 

The benefit to this is that you can alter the speed by changing the duration of the animation to a lower number. I've implemented a slider to show this.

Leboff answered 22/6, 2012 at 22:54 Comment(0)
C
0

The general idea of CSS Animation is to, well, animate. If you want things to jump from position to position, then you might just consider setting position directly via JavaScript and doing your iterations with JavaScript.

However if you do want to use animations, you have a few options. One is setting the opacity to zero and back to one with two filler keyframes. Or alternatively changing z-index to hide your animating object behind a masking div while the translation happens. z-indexes don't tween.

UPDATE: Step function transitions have been added to the spec and are now implemented in Chrome, so now what you wanted to do is possible.

Confessedly answered 21/12, 2010 at 23:6 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.