欢送关注我的公众号:前端侦探
明天来分享一个比拟有意思的图片 hover 成果,如下
案例来源于 https://codepen.io/t_afif/details/abRWELR,略有批改
仔细观察,这个成果次要有两个要点
- 图片被切割成多个矩形
- 每个矩形会旋转 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*2
和4*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*2
、4*4
、6*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)
四、总结和阐明
以上就是实现的全副过程了,代码其实不多,其实次要难点在于旋转矩形的绘制,整体实现其实并不艰难,难点其实是创意,惋惜的是平时接触的还是太少😥。上面总结一下实现要点:
- 提到 切割 ,能够想到 镂空 ,进而能够想到 遮罩
- 宰割成
n*n
块,其实就是遮罩背景的平铺 - 旋转的矩形其实就是两个相互垂直的线性突变重叠而成
- CSS 变量的过渡动画须要用到
CSS @property
个性
兼容性其实就取决于 CSS @property
了,这是 CSS Houdini
的一部分,目前只有 Chrome 和 Safari 反对。
最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤
欢送关注我的公众号:前端侦探