详解CSS故障艺术(2)

clip-path CSS 属性可以创建一个只有元素的部分区域可以显示的剪切区域。区域内的部分显示,区域外的隐藏。剪切区域是被引用内嵌的URL定义的路径或者外部 SVG 的路径。

也就是说,使用clip-path可以将一个容器切成我们想要的样子。

例如这样:

<div>TXET</div>

div { margin: auto; padding: 10px; line-height: 1.2; font-size: 60px; background: #ddd; }

正常是这样的:

详解CSS故障艺术

使用clip-path剪裁为一个平行四边形:

div { margin: auto; padding: 10px; line-height: 1.2; font-size: 60px; background: #ddd; + clip-path: polygon(35% 0, 85% 0, 75% 100%, 25% 100%); }

结果如下:

详解CSS故障艺术

那么,思路就有了,我们可以将一个文字复制几个副本,重叠在一起,再分别裁剪这几个副本进行位移动画即可。

使用 clip-path 实现文字断裂动画

我们还是使用元素的::before、::after两个伪元素复制两份副本,再分别使用clip-path进行剪裁,再使用 transform 进行控制。

核心代码:

<div data-text="Text Crack"> <span>Text Crack</span> </div>

div { position: relative; animation: shake 2.5s linear forwards; } div span { clip-path: polygon(10% 0%, 44% 0%, 70% 100%, 55% 100%); } div::before, div::after { content: attr(data-text); position: absolute; top: 0; left: 0; } div::before { animation: crack1 2.5s linear forwards; clip-path: polygon(0% 0%, 10% 0%, 55% 100%, 0% 100%); } div::after { animation: crack2 2.5s linear forwards; clip-path: polygon(44% 0%, 100% 0%, 100% 100%, 70% 100%); } // 元素晃动,断裂前摇 @keyframes shake { ... } @keyframes crack1 { 0%, 95% { transform: translate(-50%, -50%); } 100% { transform: translate(-55%, -45%); } } @keyframes crack2 { 0%, 95% { transform: translate(-50%, -50%); } 100% { transform: translate(-45%, -55%); } }

可以得到这样的效果:

详解CSS故障艺术

clip-path 的 Glitch Art

OK,继续,有了上面的铺垫之后,接下来,我们把这个效果作用于图片之上,并且再添加上动画。

随便选一张图片:

详解CSS故障艺术

哇哦,非常的赛博朋克。

实现动画的关键在于:

使用元素的两个伪元素,生成图片的两个副本

使用clip-path对两个副本图片元素进行裁剪,然后进行位移、transform变换、添加滤镜等一系列操作。

简单贴一下伪代码:

$img: "https://mzz-files.oss-cn-shenzhen.aliyuncs.com///uploads/U1002433/0cb5e044a1f0f7fc15f61264ee97ac1f.png"; div { position: relative; width: 658px; height: 370px; background: url($img) no-repeat; animation: main-img-hide 16s infinite step-end; } div::before, div::after { position: absolute; width: 658px; height: 370px; top: 0; left: 0; background: inherit; } div::after { content: ""; animation: glitch-one 16s infinite step-end; } div::before { content: ""; animation: glitch-two 16s infinite 1s step-end; } @keyframes glitch-one { @for $i from 20 to 30 { #{$i / 2}% { left: #{randomNum(200, -100)}px; clip-path: inset(#{randomNum(150, 30)}px 0 #{randomNum(150, 30)}px); } } 15.5% { clip-path: inset(10px 0 320px); left: -20px; } 16% { clip-path: inset(10px 0 320px); left: -10px; opacity: 0; } .... } @keyframes glitch-two { @for $i from 40 to 50 { #{$i / 2}% { left: #{randomNum(200, -100)}px; clip-path: inset(#{randomNum(180)}px 0 #{randomNum(180)}px); } } 25.5% { clip-path: inset(10px 0 320px); left: -20px; } 26% { clip-path: inset(10px 0 320px); left: -10px; opacity: 0; } ... } @keyframes main-img-hide { 5% { filter: invert(1); } ... }

由于动画部分代码量太多,所以使用了 SASS 循环函数随机生成了部分。如果手动控制,效果其实还会更好,当然,调试动画消耗的时间会更多。

看看效果,虽然 CSS 能力有限,但实际的效果也不是说那么的差:

详解CSS故障艺术

总结

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyfjyd.html