开发者

CSS3 Sprite Animation without tweening

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-animat开发者_如何学运维ion-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.


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("http://i.stack.imgur.com/1Ad8o.png");
    margin: 0 auto;      
    animation: wink .8s steps(10, end) infinite;
}
<img src="http://i.stack.imgur.com/1Ad8o.png">
<div class="hi"></div>

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


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.


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜