欢送关注我的公众号:前端侦探

明天来分享一个比拟有意思的图片 hover 成果,如下

案例来源于https://codepen.io/t_afif/details/abRWELR,略有批改

仔细观察,这个成果次要有两个要点

  1. 图片被切割成多个矩形
  2. 每个矩形会旋转 90 度

那么,这个是如何实现的呢?花几分钟工夫一起看看吧

一、宰割的矩形

假如HTML是这样的,很简略,就一个图片

<img src="xxx.jpg" alt="xxx">

而后,咱们须要一个变量,来管制宰割的数量,比方2示意2*2,这里能够用 CSS 变量

img{  --n: 4; /*横纵宰割的数量*/}

那么,如何来切割呢?

提到切割,能够想到镂空,进而能够想到遮罩(CSS Mask)。对于遮罩,这个技巧十分实用,之前在多篇文章中都有用到

  • CSS 如何实现羽化成果?
  • 别用图片了,CSS 遮罩合成实现带圆角的环形 loading 动画
  • CSS mask 实现鼠标追随镂空成果
  • CSS 实现Chrome标签栏的技巧
  • CSS 实现优惠券的技巧

原理很简略,最终成果只显示不通明的局部,通明局部将不可见,半透明类推,例如

在这里,咱们能够通过相似背景平铺的形式,来将一个残缺的图片切割成n*n个矩形,如下

img{  --n: 4;  -webkit-mask: radial-gradient(black, transparent);  -webkit-mask-size: calc(100% / var(--n)) calc(100% / var(--n));}

这里用了一个径向突变做了遮罩图片,遮罩尺寸是100% / var(--n),刚好将残缺的图片分成了n*n份,成果如下,别离是2*24*4的成果

这就是宰割的原理了

二、旋转的矩形

那么,问题来了,这里是背景层,并没有rotate这样的属性,如何让一个矩形旋转呢?或者说,如何绘制一个歪斜的矩形呢?

上面就来一步一步实现。

因为遮罩和背景的语法基本一致,为了不便调试,能够先用背景代替

大家都晓得,线性突变是能够设置角度的,为了计算不便,咱们能够用 CSS 变量来示意

div{  --r: 45deg;  background: linear-gradient(var(--r), red, orange)}

这样能够失去一个45deg的突变

而后,咱们能够将这个突变改成通明→纯色→通明的突变

div{  --r: 45deg;  background: linear-gradient(var(--r), transparent 5%, orange 0 95%, transparent 0)}

成果如下

为了计算不便,能够将通明的比例用 CSS 变量来示意

div{  --r: 45deg;  --d: 30%;  background: linear-gradient(var(--r), transparent var(--d), orange 0 calc(100% - var(--d)), transparent 0)}

上面是30%的成果

接下来,用同样的形式绘制和这个垂直的图形,也就是角度相差90deg

div{  --r: 45deg;  --d: 30%;  background: linear-gradient(var(--r), transparent var(--d), orange 0 calc(100% - var(--d)), transparent 0),    linear-gradient(calc(var(--r) + 90deg), transparent var(--d), red 0 calc(100% - var(--d)), transparent 0),}

成果如下

留神察看,两个重叠的局部不就是一个旋转45deg的矩形吗?如下

能够任意扭转角度

div{  --deg: 15deg}

上面扭转背景尺寸,变成4*4的成果

div{  background-size: 50% 50%}

是不是和咱们想要的成果有点类似呢?上面将背景用做遮罩

img{  --r: 30deg;  --d: 30%;  -webkit-mask:    linear-gradient(var(--r), transparent var(--d),red 0 calc(100% - var(--d)), transparent 0),    linear-gradient(calc(var(--r) + 90deg), transparent var(--d), red 0 calc(100% - var(--d)), transparent 0);  -webkit-mask-size: calc(100%/var(--n)) calc(100%/var(--n));}

变成了这样

是不是很凌乱?这是因为当初的遮罩还是间接叠加的,并不是只显示重叠局部,能够设置遮罩合成mask-composite,也就是将图形进行布尔运算,得出咱们想要的图形,这里简略介绍一下

mask-composite - CSS: Cascading Style Sheets | MDN (mozilla.org)
/* Keyword values */mask-composite: add; /* 叠加(默认) */mask-composite: subtract; /* 减去,排除掉下层的区域 */mask-composite: intersect; /* 相交,只显示重合的中央 */mask-composite: exclude; /* 排除,只显示不重合的中央 */

置信在很多图形设计软件中都见到相似的操作(上面是 photoshop)

这些是规范属性,Chrome 还不反对,能够用带前缀的属性-webkit-mask-composite ,然而值和下面这些不同,十分多,次要有这些

-webkit-mask-composite: clear; /*革除,不显示任何遮罩*/-webkit-mask-composite: copy; /*只显示上方遮罩,不显示下方遮罩*/-webkit-mask-composite: source-over; /*叠加,两者都显示*/-webkit-mask-composite: source-in; /*只显示重合的中央*/-webkit-mask-composite: source-out; /*只显示上方遮罩,重合的中央不显示*/-webkit-mask-composite: source-atop;-webkit-mask-composite: destination-over; /*叠加,两者都显示*/-webkit-mask-composite: destination-in; /*只显示重合的中央*/-webkit-mask-composite: destination-out;/*只显示下方遮罩,重合的中央不显示*/-webkit-mask-composite: destination-atop;-webkit-mask-composite: xor; /*只显示不重合的中央*/

回到这里,咱们想要失去两者重叠的局部,所以能够

-webkit-mask-composite: source-in;

成果如下

三、动画

最初就是动画了。

咱们须要在hover的时候,将矩形旋转90deg,能够间接扭转--r这个变量

img{  --r: 0deg;}img:hover{  --r: 90deg;  transition: 0.5s;}

然而,仅仅这样是没有动画的,因为--r并不是一个非法的、能够过渡的属性

这时能够用到 CSS @property。能够让任意变量像色彩一样进行反对过渡和动画

@property --r {   syntax: "<angle>";   initial-value: 0deg;   inherits: false;}

当初就有过渡成果了

当初还有一个问题,空隙太大了,还须要扭转--d的大小,起始点应该是0%,在两头45deg时最大,也就是0%→20%→0%,能够用animation实现

@keyframes d {  0%,100%{    --d: 0%  }  50%{    --d: 20%  }}img:hover{  --r: 90deg;  transition: 0.5s;  animation: d .5s;}

成果如下

当然还能够将这个过渡和动画写在一个动画里

@keyframes r {  0%{    --d: 0%  }  100%{    --d: 0%;    --r: 90deg  }  50%{    --d: 20%  }}img:hover{  animation: r .5s;}

这样也能实现雷同的成果,上面别离是2*24*46*6的成果

<img src="xxx.jpg" alt="xxx" style="--n:2"><img src="xxx.jpg" alt="xxx" style="--n:4"><img src="xxx.jpg" alt="xxx" style="--n:6">

残缺代码能够查看以下任意链接:

  • CSS img hover (codepen.io)
  • CSS img hover (runjs.work)

四、总结和阐明

以上就是实现的全副过程了,代码其实不多,其实次要难点在于旋转矩形的绘制,整体实现其实并不艰难,难点其实是创意,惋惜的是平时接触的还是太少。上面总结一下实现要点:

  1. 提到切割,能够想到镂空,进而能够想到遮罩
  2. 宰割成n*n块,其实就是遮罩背景的平铺
  3. 旋转的矩形其实就是两个相互垂直的线性突变重叠而成
  4. CSS 变量的过渡动画须要用到CSS @property 个性

兼容性其实就取决于CSS @property了,这是CSS Houdini的一部分,目前只有 Chrome 和 Safari反对。

最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤

欢送关注我的公众号:前端侦探