SVG中利用事件双重触发制作开关动画
最近有学员问我苹果公众号中的伸长返回功能的实现方法,苹果的案例里用到了我称之为事件双重触发的技巧,这个技巧最早是在@科蝌的公众号中提出的,他巧妙地利用事件穿透原理实现了动画的双重触发,从而实现了以往要用ID或者JS才能实现的开关动画效果,今天行哥就来刨析一下这个技巧的实现原理。
事件穿透原理
要理解事件双重触发先要明白什么是事件穿透,所谓事件穿透就是利用click事件在移动设备上触发有300ms左右延迟的特性,我们可以在touchstart事件中快速移除当前层元素,让事件短时间内穿透到下层从而触发下层的click动画,请参考下图示意。
<!-- 事件穿透 -->
<svg style="height:0;">
<rect>
<animate
attributeName="opacity"
to="0"
begin="click"
dur="1s">
</animate>
</rect>
</svg>
<svg>
<rect>
<animate
attributeName="visibility"
to="hidden"
begin="touchstart"
dur="0.001ms">
</animate>
</rect>
</svg>
事件的双重触发
事件双重触发就是将开和关2个状态动画写在一起,系统会根据事件选择执行其中之一,拿苹果的图文伸缩动画为例。
<svg>
<!-- 伸长动画 -->
<animate
attributeName="width"
values="100%;100%;200%"
begin="touchstart"
fill="freeze"
dur="0.75s"
></animate>
<!-- 返回动画 -->
<animate
attributeName="width"
values="200%;100%;100%"
begin="click"
fill="freeze"
dur="0.75s"
></animate>
</svg>
当我们将这2段开关动画写在一起时,我们会发现系统只选择touchstart事件动画执行而选择性忽略了click事件动画,这是因为touchstart没有click事件的延迟,这就好比2个人前后脚到蛋糕店买蛋糕,而这时蛋糕店只剩下一块蛋糕,老板自然是会给先到店的那个人。
在执行了伸长动画后,我们怎么让返回动画执行呢?这就要利用上面介绍过的事件穿透模型,我们要在当前层之上制造一个挡板层,让系统选择click事件动画执行而忽略touchstart动画。
还是拿刚才蛋糕店的例子,现在我们通过”事件穿透”这层朋友关系让老板把蛋糕给晚进店的那个人。
总结
通过事件双重触发可以实现一些状态切换的开关效果,如图文的伸长和返回,弹窗的弹出和关闭等,还是许愿哦要配合一些防误触和遮挡的技巧,篇幅所限大家可以直接查看本文的源码来学习。