乐趣区

关于前端:一个有意思的CSS图片hover效果

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

明天来分享一个比拟有意思的图片 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 反对。

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

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

退出移动版