导语:直播过程中,往往会有各种动画特效增强直播效果,近期需求中,设计要求在企鹅电竞PC官网上实现一种卡牌效果,在不规则图片上叠加倒计时效果。前端项目中,往往使用css来完成动画,像倒计时效果也可以使用css完成,但是相对来说css实现方案比较复杂,层次嵌套较多。倒计时动效要求覆盖图片的倒计时阴影为非规则且半透明的。在日常的圆环动画中,也会有类似的倒计时效果,只不过圆环是规则的,实现起来比较简单。但是基于圆环效果,再加上svg的mask特性,就可以实现此类特殊效果。

[ 实现动态图]

css的mask属性可以切割图形,实现不规则图形,但是css mask属性兼容性比较差。canvas基于像素绘制,上下文占用内存大,多次切换上下文会造成内存释放慢,影响到页面的流畅度。而svg的兼容性好,基于XML,比较轻量,而且当前特效的XML结构比较简单,不会影响页面性能,鉴于当前页面已经有多处特效使用canvas绘制,基于性能考虑,本次方案不采用canvas实现。综合对比后决定用svg来实现这个效果。

实现方式

兼容性

性能(小规模)

css(mask)

一般

canvas

一般

svg

效果分为两部分,下层部分是一张静态图,上层部分是倒计时效果。实现难点在倒计时效果上,而倒计时效果又可以分为几部分:

1、实现半透明倒计时图层,且时间可随意设置;

2、实现切割半透明倒计时蒙版;

3、把蒙版作用在倒计时图层,并覆盖在静态图上;

4、组件化,可实现各种不规则图形的效果;

SVG半透明倒计时图层

1. 圆环效果

在一些页面中,经常可以看到一些圆环进度条,因为svg实现简单,所以这些基本上都是用svg的实现,svg circle是svg绘制圆形矢量图的属性,它支持设置以下属性:

  • cx,cy:坐标位置

  • r:半径

  • stroke-width:填充宽度

  • fill:填充内容

  • stroke-dasharray:虚线宽度

  • transform:变换

下面用几行代码演示svg圆环图:

<svg xmlns:xlink="http://www.w3.org/1999/xlink"  xmlns="http://www.w3.org/2000/svg"   width="200" height="200">  <circle cx="50%" cy="50%" r="40%" stroke-width="20%" stroke="#D1D3D7" fill="none"></circle>   <circle class="transformNe90" cx="50%" cy="50%" r="40%" stroke-width="20%" stroke="#00A5E0" fill="none" stroke-dasharray="100 502.7"></circle>
</svg>

[ svg圆环图 ]

2. 虚线效果

实现这个效果的重点在circle的stroke-dasharray属性,stroke-dasharray在SVG中表示的是描边虚线。需要传入两个值,第一个是虚线的宽度,第二个是虚线之间的间距stroke-dashoffset,下面看一下用stroke-dasharray实现的虚线效果:

<svg width="200" height="200" viewPort="0 0 200 200" version="1.1" xmlns="http://www.w3.org/2000/svg">    <line stroke-width="2" stroke-dasharray="5, 5" stroke="black" x1="10" y1="10" x2="190" y2="10"></line> <line stroke-width="2" stroke-dasharray="5, 10" stroke="black" x1="10" y1="30" x2="190" y2="30"></line>    <line stroke-width="2" stroke-dasharray="10, 5" stroke="black" x1="10" y1="50" x2="190" y2="50"></line>    <line stroke-width="2" stroke-dasharray="5, 1" stroke="black" x1="10" y1="70" x2="190" y2="70"></line> <line stroke-width="2" stroke-dasharray="1, 5" stroke="black" x1="10" y1="90" x2="190" y2="90"></line> <line stroke-width="2" stroke-dasharray="0.9" x1="10" y1="110" x2="190" y2="110"></line>  <line stroke-width="2" stroke-dasharray="15, 10, 5" stroke="black" x1="10" y1="130" x2="190" y2="130"></line>  <line stroke-width="2" stroke-dasharray="15, 10, 5, 10" stroke="black" x1="10" y1="150" x2="190" y2="150"></line>  <line stroke-width="2" stroke-dasharray="15, 10, 5, 10, 15" stroke="black" x1="10" y1="170" x2="190"   y2="170"></line>    <line stroke-width="2" stroke-dasharray="5, 5, 1, 5" stroke="black" x1="10" y1="190" x2="190" y2="190"></line>
</svg>

[ svg虚线图 ]

3. 实现圆环

从上面的虚线图可以看出,stroke-width表示虚线的“高度”,虚线的宽度是stroke-dasharray的第一个参数值,虚线间隔是stroke-dasharray的第二个参数值。

在实现圆环效果时,也是这个原理,stroke-width表示圆环的边框宽度,stroke-dasharray的第一个参数为圆环边框的可见长度,stroke-dasharray的第二个参数为圆环边框的非可见长度。

如果把stroke-dasharray设置为"0 a",其中a大于等于圆环的周长时。此时整个圆环的可见长度为0,非可见长度为a,整个圆环不可见,表现为圆环进度条为0,若增大可见长度,便可以看到圆环进度条增长了。

[ 可见长度为0 ]

[ 可见长度为10% ]

[ 可见长度为100% ]

4. 圆环动画

svg的animate属性可以实现svg动画,它支持设置以下属性:

  • attributeName:要变化的元素属性名称

  • attributeType:CSS | XML | auto

  • begin,end:开始结束时间,可以是单时间或分号隔开的时间列表,常见单位有 “h”|”min”|”s”|”ms”

  • from, to, by, values 开始结束点

  • fill:表示动画间隙的填充方式。支持参数有:freeze | remove. 其中remove是默认值,表示动画结束直接回到开始的地方。freeze“冻结”表示动画结束后像是被冻住了,元素保持了动画结束之后的状态。

  • repeatCount:动画执行次数

  • repeatDur:定义重复动画的总时间

当stroke-dasharray的可见长度等于圆环的周长,此时可见长度刚好覆盖了整个圆环,基于以上的实现,再加上动画,就可以实现圆环动画了

<svg xmlns:xlink="http://www.w3.org/1999/xlink"   xmlns="http://www.w3.org/2000/svg"   width="200" height="200">  <circle cx="50%" cy="50%" r="40%" stroke-width="30" stroke="#D1D3D7" fill="none"></circle>    <circle cx="50%" cy="50%" r="40%" stroke-width="30" stroke="#00A5E0" fill="none" transform="matrix(0,-1,1,0,0,200)" stroke-dasharray="0 502.7">   <animate attributeType="XML" attributeName="stroke-dasharray" from="0" to="502.7" dur="10s" fill="freeze" repeatCount="10"></animate>  </circle>
</svg>

[ 动态圆环 ]

5. 实心环形动画

接下来就是要把圆环动画扩宽到实心环形动画。那么若增大storke-width,会发现圆宽度会向内外扩展

[ stroke-width等于半径 ]

继续增大stroke-width,使得stoken-width等于圆的直径,因为设置r=”40%”,所以stroke-width=”80%”。此时填充的位置刚好覆盖到圆的中心

这里需要注意的是stroke-dasharray的起始位置在右侧,而不是上方,因此,需要使用transform逆时针旋转90°,所以通过添加class="transformNe90"旋转整个circle动画

<svg xmlns:xlink="http://www.w3.org/1999/xlink"   xmlns="http://www.w3.org/2000/svg"   width="200" height="200">  <circle cx="50%" cy="50%" r="40%" stroke-width="80%" stroke="#D1D3D7" fill="none"></circle>   <circle class="transformNe90" cx="50%" cy="50%" r="40%" stroke-width="80%" stroke="#00A5E0" fill="none" stroke-dasharray="0 502.7">   <animate attributeType="XML" attributeName="stroke-dasharray" from="0" to="502.7" dur="10s" fill="freeze" repeatCount="10"></animate>  </circle>
</svg>
<style>
.transformNe90 {    transform: rotate(-90deg);  transform-origin: center center;
}
</style>

[ stroke-width等于直径 ]

此时倒计时效果刚好覆盖了整个圆,填充的倒计时效果完成。

实现切割半透明倒计时蒙版

1. css遮罩层

了解svg蒙版,先了解一下css的遮罩mask属性,css mask遮罩属性是一个很古老的属性,它的原理是黑透白不透,它是基于图像的alpha计算遮罩程度的,颜色越深透过遮罩层的可见视图就越多,如果是全黑就会全透,同理全白就会透不过,看起来就像把白色区域的图形给切掉了。它支持在样式中设置以下几种属性:

  • mask-image

  • mask-mode

  • mask-repeat

  • mask-position

  • mask-clip

  • mask-origin

  • mask-size

  • mask-type

  • mask-composite

mask-image指遮罩使用的图片资源,所支持的图片类型非常的广泛,可以是url()静态图片资源,格式包括JPG,PNG以及SVG,使用mask-image我们可以遮罩出任意我们想要的图形,非常强大。下面看一个用css mask实现的遮罩效果:

<style>
.mask-image {   width: 200px; height: 200px;    -webkit-mask-image: url(http://imgcache.gtimg.cn/club/pgg/ams/img/pkcard_placeholder.png);  mask-image: url(http://imgcache.gtimg.cn/club/pgg/ams/img/pkcard_placeholder.png);
}
</style>
<div style="width: 200px;height: 200px; background: #00A5E0" class="mask-image"></div>

[ css mask]

2. svg蒙版

从上面这个的例子,我们可以看出,所谓遮罩,就是原始图片只显示遮罩图片非透明的部分。同比,我们在svg中也使用svg的蒙版属性mask来实现遮罩。

<svg xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg"   width="200" height="200">  <mask id="maskId" patternUnits="userSpaceOnUse" >   <image x="0" y="0" xlink:href="http://imgcache.gtimg.cn/club/pgg/ams/img/pkcard_placeholder.png" width="100%" height="100%" /> </mask>   <rect    x="0"    y="0"    width="100%" height="100%"    fill="#00A5E0"   mask="url(#maskId)"  />
</svg>

[ svg mask ]

3. svg的蒙版mask-type

可以看到,基于svg 的mask属性,可以生成一块用于切割倒计时动画的遮罩层。但是有些地方是半透明的是怎么回事,实际上svg的mask属性,其遮罩类型是luminance,也就是基于亮度来进行遮罩的。因此只需要把mask的mask-type设置为基于透明度就可以了mask-type='alpha':

<mask id="maskId" patternUnits="userSpaceOnUse" mask-type="alpha">   <image x="0" y="0" xlink:href="http://imgcache.gtimg.cn/club/pgg/ams/img/pkcard_placeholder.png" width="100%" height="100%" />
</mask>

[ mask-type='alpha' ]

被遮罩的倒计时效果

基于以上的倒计时效果和蒙版遮罩层,再设置circle上面的stroke属性的颜色值为rgba(0,0,0,.5),就可以实现半透明的遮罩层。综合上面的倒计时效果,就可以实现想要的半透明不规则倒计时效果。


由于为了把circle的倒计时起点设置为顶部,加了类transformNe90旋转了90度,因此在图形遮罩层上,需要设置类transform90实现反方向90度的旋转:

<svg xmlns:xlink="http://www.w3.org/1999/xlink"   xmlns="http://www.w3.org/2000/svg"   width="200" height="200">  <mask id="maskId" patternUnits="userSpaceOnUse" mask-type="alpha">   <image x="0" y="0" xlink:href="http://imgcache.gtimg.cn/club/pgg/ams/img/fushenka2.png" width="100%" height="100%" class="transform90"/>    </mask>   <image x="0" y="0" xlink:href="http://imgcache.gtimg.cn/club/pgg/ams/img/fushenka2.png" width="100%" height="100%"/>   <circle class="transformNe90" cx="50%" cy="50%" r="50%" stroke-width="100%" stroke="rgba(0,0,0,.5)" fill="none" stroke-dasharray="628.32 628.32" mask="url(#maskId)">  <animate attributeType="XML" attributeName="stroke-dasharray" from="0" to="628.3" dur="10s" fill="freeze" repeatCount="10"></animate>  </circle>
</svg>
<style>
.transform90 {  transform: rotate(90deg);   transform-origin: center center;
}
.transformNe90 {    transform: rotate(-90deg);  transform-origin: center center;
}
</style>

[ 不规则倒计时动效 ]

组件化,实现各种不规则图形的倒计时效果

基于以上的实现,已经实现了一个固定长宽,固定图,固定透明度的不规则倒计时效果,但是在实际的应用中,我们需要兼容各种不同尺寸的图形,因此需要把它抽象成组件,支持设置image的src、height、width以及circle的dur、from等属性

<svg xmlns:xlink="http://www.w3.org/1999/xlink"   xmlns="http://www.w3.org/2000/svg"   :width="width"   :height="height" :viewbox="'0 0 ' + width + ' ' + height"  class="pk-countdown" >    <defs>    <mask :id="maskId" patternUnits="userSpaceOnUse">   <image x="0" y="0" width="100%" height="100%" class="transform90" :xlink:href="src" />  </mask>   </defs>   <image x="0" y="0" :xlink:href="src" width="100%" height="100%" /> <circle  cx="50%" cy="50%" r="50%"  stroke-width="100%"  :stroke="'rgba(0,0,0,' + opacity + ')'"    fill="none"  :stroke-dasharray="'0 ' + circle" :mask="'url(#'+maskId+')'" class="transformNe90"    >    <animate attributeType="XML"  attributeName="stroke-dasharray" :from="circleStart"  :to="circle" :dur="duration + 's'" fill="freeze"    :repeatCount="repeatCount"   />   </circle> </svg>    ...
circleStart() { return (this.process / this.duration) * this.circle
},
circle() {  return (Math.PI * 2 * Math.max(this.width, this.height)) / 2
}

这样就可以通过父组件传递属性,控制倒计时效果的各种属性,实现通用的不规则倒计时效果。

总结

svg是一个很强大的矢量图绘制工具,可以直接内嵌到网页的dom中,并且可以通过css设置svg的各种属性,相对于canvas,它的操作更加灵活,实现更加简单。结合svg的mask和filter等属性,可以实现很多酷炫的效果。而且它的兼容性好,基本主流的浏览器都支持,还兼容到IE9,对于需要用css实现的复杂效果,都可以考虑用svg实现。

附图:

[ svg兼容性 ]

卡牌特效: svg不规则倒计时动效相关推荐

  1. 【OpenGL】Shader实例分析(六)- 卡牌特效

    转发请保持地址:http://blog.csdn.net/stalendp/article/details/30989295 本文将介绍怎么通过alpha通道来隐藏信息.并实现卡牌特效. 执行效果例如 ...

  2. 仪表特效——AE在UI动效设计中的应用

    动效设计是UI设计中不可或缺的一环.随着硬件性能的发展和动效输出方式的优化,大家对动效的认知也从最初的认为动效只是为了美观酷炫,到逐渐认识到动效对于提升用户体验和产品需求的重要作用. 最近几年,除了老 ...

  3. 盛大搅局手游市场:引入日系卡牌游戏_0

    腾讯科技讯(娄池)7月18日消息,盛大游戏宣布热门手游<百万亚瑟王>于今日开启国服公测,这款由日本知名游戏公司Square Enix(SE)研发,盛大游戏韩国子公司Actoz Soft负责 ...

  4. 如何让动效又快又好落地?我分析了这5种格式的优缺点

    动效设计,可以提升界面的趣味性和引导性,让用户浏览过程中不会太枯燥,获得更好的体验. 最近做的金山知了(后面改名为金山知识库)官网,头图元素加入了缓动效果,第一眼挺新颖的.金山协作新年许愿活动,许愿按 ...

  5. js svg语音波动动画_让动效更酷炫!4 个常见且常用的 SVG 交互动画方法

    本文介绍了 4 种常见的 SVG 交互动画方法,帮你了解 SVG 交互动画的原理和简单方法. 优秀的人机交互和舒适合理的动画,一直是 UX 设计师孜孜不倦追求的目标.但 UX 设计师每天都遇到能做出效 ...

  6. 怎么用class引入svg_让动效更酷炫!4 个常见且常用的 SVG 交互动画方法

    本文介绍了 4 种常见的 SVG 交互动画方法,帮你了解 SVG 交互动画的原理和简单方法. 优秀的人机交互和舒适合理的动画,一直是 UX 设计师孜孜不倦追求的目标.但 UX 设计师每天都遇到能做出效 ...

  7. 暗夜发光,独自闪耀,盘点网页暗黑模式(DarkMode)下的特效和动效,CSS3实现

    众所周知,网页的暗黑模式可以减少屏幕反射和蓝光辐射,减少眼睛的疲劳感,特别是在夜间使用时更为明显.其实暗黑模式也给霓虹灯效应(Neon Effect)提供了发挥的环境. 霓虹灯效应是一种视觉效果,其特 ...

  8. 三看 SVG Web 动效

    CSS3 动效玩腻了吗?没关系的,我们还有 SVG. Welikesmall 是一个互联网品牌宣传代理,这是我见过的最喜欢使用 SVG 做动效的网页设计团队.事实上,越来越多的网页动效达人选择在 SV ...

  9. Android使用SVG矢量图打造酷炫动效!

    一个真正酷炫的动效往往让人虎躯一震,话不多说,咱们先瞅瞅效果: 如果你想看 GAStudio Github主页,请戳这里: 如果你想看 GAStudio更多技术文章,请戳这里: QQ技术交流群:277 ...

最新文章

  1. LLVM语法语义指令特性
  2. 李沐亲授加州大学伯克利分校深度学习课程移师中国,现场资料新鲜出炉
  3. 2021.5.13指导论文
  4. 英特尔宣布全新自动驾驶平台整合处理器和视觉芯片
  5. 《C和C++程序员面试秘笈》——1.9 如何理解C++是面向对象化的,而C是面向过程化的...
  6. 【Android NDK 开发】JNI 引用 ( 局部引用 | 局部引用作用域 | 局部引用产生 | 局部引用释放 | 代码示例)
  7. java---面试题 丑数
  8. 前端 javascript 数据类型 字典
  9. python参数顺序 元组 字典_python学习之元组列表字典操作
  10. ASP.NET MVC的ContentResult
  11. Linux--date命令 date命令
  12. navicate使用小技巧
  13. Vue-router学习(一)- 路由匹配
  14. Android开发——搭建最新版本的Android开发环境
  15. CoAP协议学习笔记 3.2 CoAP协议翻译 DTLS加密
  16. 2022云栖大会开幕 阿里张勇:以更先进技术承担更大责任
  17. [机器视觉]摄像机标定(2) 张正友标定最详细推导
  18. TCP-IP学习笔记11--无线通信- 无线通信的种类 点对点通信协议
  19. Android 更换App图标
  20. 移动硬盘在mac电脑上不能用的原因和解决方法

热门文章

  1. 每天一个linux命令(56):netstat命令
  2. Docker 容器中“TERM environment variable not set.”问题解决
  3. OAF_OAF增删改-新增的实现(案例)
  4. 游戏的乐趣和任务设计
  5. HDU多校4 - 6808 Go Running(最小点覆盖+网络流优化)
  6. java中日期计算2月份_计算两日期间2月29日总数的Java程序
  7. linux wine运行效率,Wine 3.0让Windows应用在Linux上流畅运行!
  8. [luogu4027] [NOI2007]货币兑换
  9. PE文件结构详解(二)可执行文件头
  10. 简单的IDT HOOK介绍