css3中animation的steps分步动画

css的animation中,有一种描述动画变化速率的东西,例如常见的linear,ease-in,ease-out等,这些都是连续的变化,还有一种叫做steps的,它用来描述一种不连续的动画,也就是逐帧动画。

基本认识

steps的格式为:

 
  1. animation-timing-function : steps(number,[end | start])

steps的变化如下图:

这个图,我相信大家肯定都看过,但是这个图,很容易让人产生误解,steps中的number,指的是走了number步,但是实际上呢,却是将整个动画分成了number+1份。

例如number为3,它其实是将一个连续的动画,分成了4份:

它这种效果,其实有点像快照,在一个连续的动画上,截取均匀的4个位置快照。

它的第二个参数为start或者end,表示舍弃哪个截图:

如果为start,表示舍弃第一个截图:

那么只会播放第2,3,4个截图。

如果为end,表示舍弃最后一个截图:

那么只会播放第1,2,3个截图。

也就是说,动画被分成了n+1份,但是实际上,只走了n份,start代表去首,end代表去尾。

需要特别注意的是number为1的情况,它截取的是[0,1]位置的,我开始以为是截取的[0,1/2]位置,测试后发现并不是,切记,截取的是两头的快照:

steps-start等价于steps(1,start),只播放最后的快照;steps-end等价于steps(1,end),只播放开头的快照。

实例说明

为了说明这个问题,我做了个demo,让我们一起来仔细讨论下关于steps的问题,我们先看图:

steps动画(二维码)

上面是使用steps分布动画制作的效果,它的原图是这样的:

我们看到,图片上有6个小人,分别代表不同的动作,连在一起就是动图效果。

我们看上图,steps的number改设置为多少呢?上面说到,连续的动画实际被分成了number+1分,因此number应该为5,划分成6分:

css如下:

#rect{
    width:76px;
    height:125px;
    border:1px solid black;
    background:url('step.jpg') no-repeat left center;
    animation:move  infinite 2s steps(5,start) ;
}
@keyframes move{
    0%{
        background-position:0%;
    }
    100%{
        background-position:100%;
    }
}

一切看起来很正常,很完美,但是这样播放,我们会发现少了一帧,what?

虽然图片分成了6分,但是实际上只走了5步啊!!如果为start,那么走的就是2,3,4,5,6;如果为end,走的就是1,2,3,4,5。因此不管怎么走,其实都会少了一帧。

设置start

正确的做法是,将number设置为6,生成7个快照,如果设置为start,表示丢弃第一个快照:

#rect{
    width:76px;
    height:125px;
    border:1px solid black;
    background:url('step.jpg') no-repeat left center;
    animation:move  infinite 2s steps(6,start) ;
}
@keyframes move{
    0%{
        background-position:-22%;/*注意这里*/
    }
    100%{
        background-position:100%;
    }
}

这里需要注意,background-position需要向左移动,移动多少呢?background-position中的百分比为容器和背景图片差*percent,可以参考:css中background-position百分比原理

这里容器宽高为一个小人,因此容器和背景差为6个小人,因此背景需要向左扩充1/6=16.7%,这里设置-22%,因此背景人物分布不均匀,因此稍微一动了一些。

设置为start,表示丢弃第一个快照,因此只播放2,3,4,5,6,7快照,可以完整播放。

设置end

我们还可以在尾部添加一个空白人物:

#rect{
    width:76px;
    height:125px;
    border:1px solid black;
    background:url('step.jpg') no-repeat left center;
    animation:move  infinite 2s steps(6,end) ;
}
@keyframes move{
    0%{
        background-position:0%;
    }
    100%{
        background-position:122%;/*注意这里*/
    }
}

注意,这里的background-position需要向右扩充16.7%左右,增加一个空白人物。

设置为end,丢弃最后一个,只播放1,2,3,4,5,6,可以完整播放。

number为其他的情况

steps中number为1,快照截取的是两头的,不是从中间截取的:

#rect{
    width:76px;
    height:125px;
    border:1px solid black;
    background:url('step.jpg') no-repeat left center;
    animation:move  1 2s steps(1,start) ;
}
@keyframes move{
    0%{
        background-position:0%;
    }
    100%{
        background-position:100%;
    }
}

例如上面的代码,将会播放的是图6,因为截取的有两个快照,1和6,1被舍弃了,因此只会播放6。

如果设置end,那么只会播放图1。

steps中number为2:

#rect{
    width:76px;
    height:125px;
    border:1px solid black;
    background:url('step.jpg') no-repeat left center;
    animation:move  1 2s steps(2,end) ;
}
@keyframes move{
    0%{
        background-position:0%;
    }
    100%{
        background-position:122%;
    }
}

有3个快照,分别是1,4,7。

如果设置为end,只会播放1,4;如果设置为start,只会播放4,7。

animation-fill-mode:forwards

这里需要注意一个问题,就是当我们只播放一次,并且设置播放停在最后一帧的时候,如果我们设置steps为end,就会停在丢弃的那一帧上:

例如上图,我们设置css如下:

#rect{
    width:76px;
    height:125px;
    border:1px solid black;
    background:url('step.jpg') no-repeat left center;
    animation:move  1 2s steps(5,end) ;
}
@keyframes move{
    0%{
        background-position:0%;
    }
    100%{
        background-position:100%;
    }
}

如果正常播放,第6帧会被丢弃掉,播放完,停在第一帧,但是如果你设置了forwrads:

#rect{
    width:76px;
    height:125px;
    border:1px solid black;
    background:url('step.jpg') no-repeat left center;
    animation:move  1 2s steps(5,end) forwards;
}
@keyframes move{
    0%{
        background-position:0%;
    }
    100%{
        background-position:100%;
    }
}

那么将会停在丢弃的第6帧上,这个需要特别注意。

转载于:http://www.qiutianaimeili.com/html/page/2021/06/2028tl9nhl7wfij.html

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值