欢送关注我的公众号:前端侦探
明天来分享一个比拟有意思的图片 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反对。
最初,如果感觉还不错,对你有帮忙的话,欢送点赞、珍藏、转发❤❤❤
欢送关注我的公众号:前端侦探