有关SVG中遮罩动画跳帧的问题分析

0 结论

图片动画的 begin 参数值应设置 大于 0 的值,如 1s
具体可参考SVG SMIL动画的begin,end属性详解

1 问题代码分析

1.1 实现代码

首先看一个由SVG遮罩动画实现的骰子滚动动画,代码如下:

<svg viewBox="0 0 99 114">
    <!--轮播动画-->
    <g>
        <!--第1组图片-->
        <foreignObject x="0" y="0" height="100%" width="100%">
            <svg style="margin: 0px;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/qicPQRG4YVIE4ib3icibS1JL2kPoCHWphEShk5pI15RXtIDe5h1jYUDIqHuqwqQYtpY6GujicWRGicjwsw1ibqy9XZhEw/0?wx_fmt=png&quot;);background-size: 100%;" viewBox="0 0 99 114"></svg>
        </foreignObject>
        <!--第2组图片-->
        <foreignObject x="100" y="0" height="100%" width="100%">
            <svg style="margin: 0px;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/qicPQRG4YVIE4ib3icibS1JL2kPoCHWphEShBbto0SE9libibDa8yOCTBQsBH6Vc9EtAEBzjWnGpM5lOdCwtqJRTFEew/0?wx_fmt=png&quot;);background-size: 100%;" viewBox="0 0 99 114"></svg>
        </foreignObject>
        <!--第3组图片-->
        <foreignObject x="200" y="0" height="100%" width="100%">
            <svg style="margin: 0px;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/qicPQRG4YVIE4ib3icibS1JL2kPoCHWphEShlmDc5uofMjodb18DonTNtHF7hWKCXFFK3oABWcibd8icYguaICPkIiaEw/0?wx_fmt=png&quot;);background-size: 100%;" viewBox="0 0 99 114"></svg>
        </foreignObject>
        <!--第4组图片-->
        <foreignObject x="300" y="0" height="100%" width="100%">
            <svg style="margin: 0px;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/qicPQRG4YVIE4ib3icibS1JL2kPoCHWphESh9d0iauOwlJlMdCVLbnGwLP5ZE3CsL91CeLuJ3K4N4ZDpKNGBQKruIuw/0?wx_fmt=png&quot;);background-size: 100%;" viewBox="0 0 99 114"></svg>
        </foreignObject>
        <!--第5组图片-->
        <foreignObject x="400" y="0" height="100%" width="100%">
            <svg style="margin: 0px;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/qicPQRG4YVIE4ib3icibS1JL2kPoCHWphEShWonkbHPTE1Kpl2AbvxIO9xmzBGib2JMktSyN3vKUeSKKhFjlOQfGQEQ/0?wx_fmt=png&quot;);background-size: 100%;" viewBox="0 0 99 114"></svg>
        </foreignObject>
        <!--第6组图片-->
        <foreignObject x="500" y="0" height="100%" width="100%">
            <svg style="margin: 0px;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/qicPQRG4YVIE4ib3icibS1JL2kPoCHWphEShokNjcvBpyMLorrTR8sp376M49fmicnfqTOMqY6fibeODUqgxNmgZdusw/0?wx_fmt=png&quot;);background-size: 100%;" viewBox="0 0 99 114"></svg>
        </foreignObject>
        <!--动画设置-->
        <animateTransform attributeName="transform" type="translate" values="0 0;-200 0;-500 0;-300 0;-100 0;-400 0;" repeatCount="indefinite" fill="freeze" begin="0s" end="touchend" dur="3s" calcMode="discrete"></animateTransform>
    </g>
    <!--遮罩层-->
    <g>
        <foreignObject y="0" x="0" height="100%" width="100%">
            <svg style="margin: 0px;background-image: url(&quot;https://mmbiz.qpic.cn/mmbiz_png/qicPQRG4YVIE4ib3icibS1JL2kPoCHWphEShk5pI15RXtIDe5h1jYUDIqHuqwqQYtpY6GujicWRGicjwsw1ibqy9XZhEw/0?wx_fmt=png&quot;);background-size: 100%;" viewBox="0 0 99 114"></svg></foreignObject>
        <animateTransform attributeName="transform" type="translate" values="0 0;-100 0;" fill="freeze" begin="touchstart" dur="0.0001s" calcMode="discrete" restart="never"></animateTransform>
    </g>
</svg>

1.2 原理阐释

既然定位为遮罩动画,那该动画必然由图片层遮罩层组成,上述代码中的3-27行,链接了6张骰子的图片,由其左上角坐标值的变化

x="0"   y="0";
x="100" y="0";
x="200" y="0";
x="300" y="0";
x="400" y="0";
x="500" y="0";

不难看出,底层图片排列方式为横向依此排列的,示意图如下

排列好图片后,需要设置图片动画,此处设置为 translate 即平移动画,按上述图片坐标依此设置平移终点。

<!--动画设置-->
        <animateTransform attributeName="transform" type="translate" values="0 0;-200 0;-500 0;-300 0;-100 0;-400 0;" 
        repeatCount="indefinite" fill="freeze" begin="0s" end="touchend" dur="3s" calcMode="discrete"></animateTransform>

最后设置遮罩

 <animateTransform attributeName="transform" type="translate" values="0 0;-100 0;" fill="freeze" begin="touchstart" dur="0.0001s" calcMode="discrete" restart="never"></animateTransform>

其中 values 参数指定了可显示的区域,即一个骰子面图片的范围,其余部分被遮挡不予显示
由以上几部分组成了一个完整的SVG遮罩动画。

2 问题分析

在手机端运行上述代码可知,不管用户在哪一刻点击骰子,都会定格在5点,原因是:
begin值为 0,没有偏移量,用户点击后,动画执行完毕,定格在最后一帧图片上,由上述代码可知,平移坐标内设置的最后一帧,正是5点对应的图片坐标。

begin 值设置设置为大于0的数之后,有了偏移量,故动画不会在结束后退回最后一帧,而是保留在了用户点击对应的图片处。
具体可参考SVG SMIL动画的begin,end属性详解
所以最后将上述代码更改为

 <animateTransform attributeName="transform" type="translate" values="0 0;-200 0;-500 0;-300 0;-500 0;-300 0;-500 0;-300 0;-100 0;-400 0;-500 0;-100 0;-400 0;-300 0;" 
 repeatCount="indefinite" fill="freeze"
 begin="1s" dur="3s" calcMode="discrete" end="click">
 </animateTransform>

完美解决跳帧问题

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值