蒙版对于UI设计师来讲,太熟悉不过了,固然了,可能PS里面用的多一些,AI里面用的少一些,SVG一样支持蒙版,并且借助蒙版,能完成不少神奇的效果。我喜欢称蒙版动画为一种魔术,这是真正的“障眼法”,它只让你看到想要看到的部分。
前面SVG的动画效果里,有两次用过了蒙版,一个是在路径动画中(juejin.im/post/590941… 这篇文章的结尾),利用蒙版的路径描边动画,逐渐画出白色的螺旋线,从而动态显示底部的小豆豆组成的路径,达到飞机撒播小豆的效果。
还有一次是在路径变形动画中(juejin.im/post/59195c… 第9部分的内容),利用蒙版的路径变形动画来实现镂空图形的变形动画。这还只是蒙版动画的冰山一角,下面会介绍几个有表明性的应用,掌握了蒙版动画以后,嗯,你会打开一扇全新的门。浏览器
先简单说一下SVG蒙版的基本语法,给没有SVG基础的UI设计师入入门。bash
<mask id="shade"><circle cx="50" cy="50" r="30" /></mask>
<rect mask="url(#shade)"/>复制代码
表示我定义了一个半径30的圆形蒙版shade,矩形使用这个shade蒙版。蒙版若是里面不定义任何形状,则默认为全黑蒙版,也就是说,使用蒙版的形状彻底被遮罩了,蒙版里定义的任何形状都是在这个黑色画布上进行绘制的。至于使用过程当中,那天然是各类变化多多,下面由浅入深,慢慢来说。svg
这个严格来讲不是蒙版动画,而是蒙版下的动画,还记得冯老板的新电影《我不是潘金莲》里面独特的表现手法吧,全部画面集中于一个圆形的视窗里,那用蒙版来实现的话,就是黑色底上放一个白色的圆形。下面就来模拟一下这种效果。这是我作的一个水波纹的动态效果
(实现方法能够参考之前发过的路径变形动画)。
工具
<svg>
<style>
@keyframes deform1{0% {d:path('');} 100%{d:path('');}}/*第一个路径变形动画*/
@keyframes deform1{0% {d:path('');} 100%{d:path('');}}/*第二个路径变形动画*/
#animate1 {animation: deform1 2s alternate infinite ;fill:#71CFD1;opacity:0.5}/*设定透明度*/
#animate2 {animation: deform2 2s alternate infinite;fill:#71CFD1;opacity:0.3}
</style>
<mask id="shade"><circle fill="#ffffff" cx=" " cy=" " r="200"/></mask><!--定义蒙版-->
<g mask="url(#shade)"><!--把变形动画放到一个组里,再调用蒙版-->
<path id="animate1" />
<path id="animate2"/>
</g>复制代码
看一下效果:post
<path id="animate1" />
<path id="animate2"/>
<path d=""/> <!--黑色镂空矩形对应的路径-->复制代码
注意一下路径叠加的顺序,从上到下对应AI里的图层顺序从下到上。也就是浏览器先渲染排序在前的路径图形,而后层层叠加。
效果棒棒哒字体
固然了,蒙版的方法仍是要掌握的,由于这是惟一一个特例嘛。并且缺点显而易见,你的矩形不能任意控制大小,只能大于被遮住的动画的区域。
若是说这种简单的圆形没法体现蒙版的优点,那下面这种会展示的更为充分。动画
来看代码部分:url
<mask id="shade"><path fill="#FFFFFF" d=" "/></mask>
<g mask="url(#shade)">
<path id="animate1"/>
<path id="animate2"/>
</g>
<g>
…此处省略若干杯子形状的代码…
</g>复制代码
其实大多数工做AI会帮咱们很好的完成,咱们要作的不过是定义动画和摆好各个图形的关系而已。这种给容器里加水的动效,若是不借助,那么作变形动画的时候还要精确计算边缘,而利用蒙版,不但动态底图绘制时无所畏忌,还能够实现多个不一样容器同时加水的动画,只要蒙版上多绘制几个白色的容器形状就能够了。来点小小的改动,发挥一下SVG的优点,来个大杂烩,咖啡,红酒,橙汁,咱们只要改变定义的变形动画的填充色,嗯,就这么简单。spa
蒙版的强大,不只仅在于支持图形,一样还支持文字,经过文字蒙版,还能够轻松实现填充变换的文字。好比我作了一个渐变的动态背景,这个用CSS3实现比用SVG更容易,不过我懒,就直接用SVG实现了,并且用的是最不靠谱的方法,动态背景实现方法不少,我是让一个很大的渐变背景位移实现的,没用过SVG渐变填充的能够看一下,就是下面这种方法:设计
<svg width="800" height="600" >
<style>
@keyframes animate{
0% {transform: translateX(0px) translateY(0px)}
100% {transform: translateX(-3000px) translateY(-2000px)}}
rect{animation:animate 4s alternate infinite}
</style>
<defs>
<linearGradient id="dream" x1="0%" y1="0%" x2="100%" y2="100%" spreadMethod="pad">
<stop offset="0%" stop-color="#345ca5" />
<stop offset="20%" stop-color="#6134a5" />
<stop offset="40%" stop-color="#3479a5"/>
<stop offset="60%" stop-color="#2b008b"/>
<stop offset="80%" stop-color="#3DC4D0"/>
<stop offset="100%" stop-color="#5c2392"/>
</linearGradient>
</defs>
<rect x="0" y="0" width="3800" height="3600" fill="url(#dream)" />
</svg>复制代码
先定义一个倾斜线性渐变dream,一共6个停靠点,而后画一个超大的矩形来使用这个渐变,并作位移动效,但因为尺寸是写死的,因此你只能看到800*600的区域,从而实现了动态渐变效果。
那这个动态渐变如何赋给文本呢?简单,我只须要像以下定义一下文字蒙版就能够了
<mask id="shade"><text>生如夏花</text></mask><!--文本的位置大小字体填充色单独定义-->
<g mask="url(#shade)">
<rect x="0" y="0" width="3800" height="3600" fill="url(#dream)"/>
</g>复制代码
我这里并无让动态渐变的矩形去直接调用文字蒙版,而是外面单独又套了一个<g>
标签,是由于我动态渐变的实现方式很差嘛,是移动实现的,若是蒙版直接给这个矩形,意味着蒙版就跟着一块儿跑啦。
见识过文字蒙版以后,说一下带透明度的蒙版,SVG的蒙版真真是和做图工具中的蒙版如出一辙,依然支持透明度,渐变,怎么都行,由于我没想到太好的案例,因此仍是拿咱们上面的案例下刀吧。
我给文字蒙版的上面再加一个蒙版,蒙版添加方式以下:
<mask id="shade"> <text x="" y="" >生如夏花</text></mask>
<mask id="shade2"><!--由灰色矩形和白色矩形组成的蒙版-->
<rect fill="#969696" x="0" y="0" width="800" height="150"></rect>
<rect fill="#ffffff" x="0" y="150" width="800" height="300"></rect>
</mask>
<g mask="url(#shade2)"> <!--新加蒙版-->
<g mask="url(#shade)">
<rect x="0" y="0" width="3800" height="3600" fill="url(#dream)" id="aaa"/><!--因为新加蒙版使用了矩形,因此这里要给矩形背景一个id,并修改CSS样式。-->
</g>
</g> 复制代码
那效果是怎样呢?
以上都是静态蒙版的应用,其做用就是从新生成一个视窗。下面,要开始动态蒙版的介绍了,等真正会用动态蒙版以后,SVG动画简直能够发挥想象不到的强大。动态蒙版说白了和普通形状的动效是同样的,无非以蒙版效果展示而已,依旧从最简单的入手,来一个日食的效果。
动画思路理一下
<svg width="800" height="600" >
<style>
@keyframes animate{
0% {transform: translateX(0)}
100% {transform: translateX(390px)}
}
#dog{animation:animate 4s ease 2s}
</style>
<mask id="shade"> <rect x="0" y="0" width="800" height="600" fill="#FFFFFF"/><circle cx="205" cy="200" r="95" fill="#000000" id="dog"/></mask>
<circle cx="400" cy="200" r="100" fill="#ff7f00" mask="url(#shade)" />
</svg>复制代码
产生的动画效果是下面这种
<svg width="800" height="600" >
<style>
@keyframes animate1{ /*定义变化的背景色*/
0% {fill:#c0f1ff;}
50% {fill:#1d3074;}
100% {fill:#c0f1ff;}
}
rect{animation:animate1 4s;fill:#c0f1ff;}
@keyframes animate2{
0% {transform: translateX(0)}
100% {transform: translateX(390px)}
}
#dog{animation:animate2 4s}
</style>
<rect width="800" height="600" /> <!--先绘制最下层的天空-->
<circle cx="400" cy="200" r="100" fill="#ff7f00" /><!--其次是完整的太阳-->
<mask id="shade"><circle cx="400" cy="200" r="100" fill="#FFFFFF" /></mask>
<g mask="url(#shade)">
<circle cx="205" cy="200" r="95" fill="#000000" fill-opacity="0.7" id="dog" />
</g>
</svg>复制代码
效果以下:
写到这里,感受又啰里啰嗦说了太多,因此还有一部分仍是放到下篇吧。