在给公司开发官网的过程中,会有波及到一些图片的鼠标悬停成果,鼠标悬停后会扭转原图,单纯的渐隐渐现,放大放大,左右平移曾经满足不了产品经理冀望了,总感觉不够惊艳,创意不够。其实作为一个开发者,也不会满足这一般日常的动画交互成果,在寻找新的 idea 时发现基于 CSS mask-image 能够实现很多不错的成果,本文将基于此属性实现四种图片过渡动画成果。

前置知识点 mask-image

mask-image CSS 属性用于设置元素上遮罩层的图像。默认值是 none,也就是无遮罩图片。因而,和 border 属性中的 border-style 属性相似,是一个想要有成果就必须设定的属性值。留神因为此属性目前还不是齐全反对,局部浏览器还须要减少-webkit-前缀应用。

mask-image遮罩所反对的图片类型十分的宽泛,能够是 url()动态图片资源,格局包含 JPG,PNG 以及 SVG 等都是反对的;也能够是动静生成的图片,例如应用各种 CSS3 突变绘制的图片。语法上反对 CSS3 各类突变,以及 url()性能符,image()性能符,甚至 element()性能符。同时还反对多背景,因而实践上,应用 mask-image 咱们能够遮罩出任意咱们想要的图形,十分弱小。

语法如下:

/* <mask-source> value */mask-image: url(masks.svg#mask1);/* <image> values */mask-image: linear-gradient(rgba(0, 0, 0, 1.0), transparent);mask-image: image(url(mask.png), skyblue);/* Multiple values */mask-image: image(url(mask.png), skyblue), linear-gradient(rgba(0, 0, 0, 1.0), transparent);

示例演示,一个渐变色背景的纯文本元素减少 mask-image 属性后是什么成果呢。

.mask {  -webkit-mask-size: contain; -webkit-mask-image: url(https://p6-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/161ced10bf344eb085c34cefd8958dd1~tplv-k3u1fbpfcp-watermark.image?);}

两张图片以突变的形式合并成为一张图片。

.scene-2 {  background-image: url(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/fd9e83460a5645ccb78dc1c8efb86871~tplv-k3u1fbpfcp-watermark.image?);  -webkit-mask-image: linear-gradient(to right, transparent 8%, #fff 30%);}

如上图 1 所示,应用 mask-image 属性设置了一个 png 格局的客服图标,整个元素将只显示 png 图像的内容区域,其余区域都隐没不见了。如图 2 所示,应用 mask-image 属性设置突变色彩,使两种图片以突变叠加的形式交融在了一起。

想必大家能够看出 mask-image 的次要性能了吧,CSS mask 属性在应用的时候就是 mask: xxx,当初随着这个属性的规范化,mask 属性实际上曾经成为了诸多 mask-\*的缩写,除了 mask-image 还有以下属性,用法和 CSS background 用法是相仿的,具体属性值能够看 mask 遮罩层详解。

mask-modemask-repeatmask-positionmask-clipmask-originmask-sizemask-typemask-composite

介绍完次要的前置知识点,接下来就进入到具体的动画成果和实现过程。

成果一

两张图片切换的过渡成果,动画开始前两头定位了一个通明的图标,动画开始后图标一直放大,直到图标放大到全屏此时已过渡到第二张图片,整个过程相当炫酷。基于下面的前置知识点,很快可想到对应的实现形式,这里须要额定用到其余的几个属性,用法和 background 相似:

  • mask-size: 如动画所示,两头的 png 图标从小放大,则须要这个属性管制图标的大小变动
  • mask-position: 图标始终是放弃在程度垂直居中的地位放大,则须要这个属性图像的起始地位
  • mask-repeat:和 background 相似,不设置 no-repeat 图标会反复整个界面

动画成果示意图如下:

外围代码如下:

.scene-2 {  background-image: url(https://assets.codepen.io/77020/sw-shape-zoom-scene-2.jpg);  -webkit-mask-image: url(https://assets.codepen.io/77020/sw-jedi-crest.svg);  -webkit-mask-size: 10%;  -webkit-mask-position: center;  -webkit-mask-repeat: no-repeat;}.scenes:is(:hover, :focus) .scene-2 {  animation: scene-transition 4s cubic-bezier(1, 0, 1, 1) forwards;}@keyframes scene-transition {  100% {    -webkit-mask-size: 1800%;  }}

这时整体动画成果根本实现了,然而还有细节持续优化,动画开始前图标内的图片曾经看到,这样比照整个界面不够显明好看,所以须要默认设置第二张图片的亮度,当动画进行到肯定的阶段再彻底显示进去。

代码如下:

.scene-2 {  filter: brightness(0%);}@keyframes scene-transition {  25% {    filter: brightness(100%);  }  100% {    filter: brightness(100%);  }}

代码在线预览:
https://code.juejin.cn/pen/71...

成果二

如效果图所示,这里用到了锥形突变 conic-gradient,通过一个残缺的锥形突变过渡图片。和下面的示例二相似,只不过把 linear-gradient 线性突变扭转为 conic-gradient 锥形突变,通过管制锥形突变的角度实现图片的过渡成果,动画成果示例图如下:

外围代码如下:

@property --angle {  syntax: '<angle>';  inherits: true;  initial-value: -10deg;}.scene-2 {  background-image: url(https://assets.codepen.io/77020/sw-clock-wipe-scene-2.jpg);  z-index: -1;  -webkit-mask-image:    conic-gradient(      #fff 0deg,      #fff calc(var(--angle) - 10deg),      transparent calc(var(--angle) + 10deg),      transparent 360deg    ),    conic-gradient(      transparent 340deg,      #fff 360deg    );}.scenes:is(:hover, :focus) .scene-2 {  z-index: 1;  animation: scene-transition 2s linear forwards;}@keyframes scene-transition {  to { --angle: 370deg; }}

代码在线预览:
https://code.juejin.cn/pen/71...

成果三


此成果由成果二的锥形突变扭转为 radial-gradient 径向突变,管制突变的范畴从齐全不见到笼罩整个元素。动画成果示例图如下:

外围代码如下:

@property --radius {  syntax: '<percentage>';  inherits: true;  initial-value: -5%;}@keyframes scene-transition {  to { --radius: 105%; }}.scene-2 {  background-image: url(https://assets.codepen.io/77020/sw-iris-wipe-scene-2.jpg);  -webkit-mask-image: radial-gradient(    circle,    #fff calc(var(--radius) - 5%),    transparent calc(var(--radius) + 5%)  );}.scenes:is(:hover, :focus) .scene-2 {  animation: scene-transition 2s linear forwards;}

代码在线预览:
https://code.juejin.cn/pen/71...

成果四


此成果和示例二中的成果一样,应用 linear-gradient 线性突变过渡图片,这里将 mask-size 设置宽度的两倍,后面一半设置为通明色,则看到的还是第一张图片。触发动画的时候扭转 mask-positionleft 变更为 right,动画成果示例图如下:

外围代码如下:

.scene-2 {  background-image: url(https://assets.codepen.io/77020/sw-horizontal-wipe-scene-2.jpg);  -webkit-mask-image: linear-gradient(    to right,    transparent 47.5%,    #fff 52.5%  );  -webkit-mask-size: 210%;  -webkit-mask-position: left;}.scenes:is(:hover, :focus) .scene-2 {  -webkit-mask-position: right;  transition: -webkit-mask-position 2s linear;}

代码在线预览:
https://code.juejin.cn/pen/71...

最初

本文基于 CSS mask-image 实现了四种图片过渡成果,置信这几种成果可能让你的老板眼前一亮,让你的我的项目炫酷起来吧。看到最初如果感觉有用,记得点个赞珍藏起来,说不定哪天就用上啦。

专一前端开发,分享前端相干技术干货,公众号:南城大前端(ID: nanchengfe)

参考

mask-image:
https://developer.mozilla.org...

codepen:https://codepen.io/lonekorean...

mask 遮罩层详解:https://blog.csdn.net/qq_3268...

CSS的mask-image属性详解
:https://www.php.cn/css-tutori...