乐趣区

关于前端:基于CSS-maskimage-实现炫酷图片过渡效果之星球大战

在给公司开发官网的过程中,会有波及到一些图片的鼠标悬停成果,鼠标悬停后会扭转原图,单纯的渐隐渐现,放大放大,左右平移曾经满足不了产品经理冀望了,总感觉不够惊艳,创意不够。其实作为一个开发者,也不会满足这一般日常的动画交互成果,在寻找新的 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-mode

mask-repeat

mask-position

mask-clip

mask-origin

mask-size

mask-type

mask-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…

退出移动版