实现
这个效果想利用 CSS 完全复制是比较困难的。CSS 模拟出来的光效阴影相对会 Low 一点,只能说是尽量还原。
其实每组光都基本是一样的,所以我们只需要实现其中一组,就几乎能实现了整个效果。
观察这个效果:
它的核心其实就是角向渐变 — conic-gradient(),利用角向渐变,我们可以大致实现这样一个效果:
1 | < div ></ div > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | div { width : 1000px ; height : 600px ; background : conic-gradient( from -45 deg at 400px 300px , hsla( 170 deg, 100% , 70% , . 7 ), transparent 50% , transparent ), linear-gradient ( -45 deg, #060d5e , #002268 ); } |
看看效果:
有点那意思了。当然,仔细观察,渐变的颜色并非是由一种颜色到透明就结束了,而是颜色 A — 透明 — 颜色 B,这样,光源的另一半并非就不会那么生硬,改造后的 CSS 代码:
1 2 3 4 5 6 7 8 9 10 11 | div { width : 1000px ; height : 600px ; background : conic-gradient( from -45 deg at 400px 300px , hsla( 170 deg, 100% , 70% , . 7 ), transparent 50% , hsla( 219 deg, 90% , 80% , . 5 ) 100% ), linear-gradient ( -45 deg, #060d5e , #002268 ); } |
我们在角向渐变的最后多加了一种颜色,得到观感更好的一种效果:
emm,到这里,我们会发现,仅仅是角向渐变 conic-gradient() 是不够的,它无法模拟出光源阴影的效果,所以必须再借助其他属性实现光源阴影的效果。
这里,我们会很自然的想到 box-shadow。这里有个技巧,利用多重 box-shadow, 实现 Neon 灯的效果。
我们再加个 div,通过它实现光源阴影:
1 | < div class = "shadow" ></ div > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | .shadow { width : 200px ; height : 200px ; background : #fff ; box-shadow : 0px 0 . 5px hsla( 170 deg, 95% , 80% , 1 ), 0px 0 1px hsla( 170 deg, 91% , 80% , . 95 ), 0px 0 2px hsla( 171 deg, 91% , 80% , . 95 ), 0px 0 3px hsla( 171 deg, 91% , 80% , . 95 ), 0px 0 4px hsla( 171 deg, 91% , 82% , . 9 ), 0px 0 5px hsla( 172 deg, 91% , 82% , . 9 ), 0px 0 10px hsla( 173 deg, 91% , 84% , . 9 ), 0px 0 20px hsla( 174 deg, 91% , 86% , . 85 ), 0px 0 40px hsla( 175 deg, 91% , 86% , . 85 ), 0px 0 60px hsla( 175 deg, 91% , 86% , . 85 ); } |
OK,光是有了,但问题是我们只需要一侧的光,怎么办呢?裁剪的方式很多,这里,我介绍一种利用 clip-path 进行对元素任意空间进行裁切的方法:
1 2 3 4 5 6 7 | .shadow { width : 200px ; height : 200px ; background : #fff ; box-shadow : .....; clip-path : polygon( -100% 100% , 200% 100% , 200% 500% , -100% 500% ); } |
原理是这样的:
这样,我们就得到了一侧的光:
这里,其实 CSS 也是有办法实现单侧阴影的,但是实际效果并不好,最终采取了上述的方案。
接下来,就是利用定位、旋转等方式,将上述单侧光和角向渐变重叠起来,我们就可以得到这样的效果:
这会,已经挺像了。接下来要做的就是让整个图案,动起来。这里技巧也挺多的,核心还是利用了 CSS @Property,实现了角向渐变的动画,并且让光动画和角向渐变重叠起来。
我们需要利用 CSS @Property 对代码渐变进行改造,核心代码如下:
1 2 3 | < div class = "wrap" > < div class = "shadow" ></ div > </ div > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | @property --xPoint { syntax: '' ; inherits: false; initial-value: 400px ; } @property --yPoint { syntax: '' ; inherits: false; initial-value: 300px ; } . wrap { position : relative ; margin : auto ; width : 1000px ; height : 600px ; background : conic-gradient( from -45 deg at var(--xPoint) var(--yPoint), hsla( 170 deg, 100% , 70% , . 7 ), transparent 50% , hsla( 219 deg, 90% , 80% , . 5 ) 100% ), linear-gradient ( -45 deg, #060d5e , #002268 ); animation : pointMove 2.5 s infinite alternate linear ; } .shadow { position : absolute ; top : -300px ; left : -330px ; width : 430px ; height : 300px ; background : #fff ; transform-origin : 100% 100% ; transform : rotate ( 225 deg); clip-path : polygon( -100% 100% , 200% 100% , 200% 500% , -100% 500% ); box-shadow : ... 此处省略大量阴影代码; animation : scale 2.5 s infinite alternate linear ; } @keyframes scale { 50% , 100% { transform : rotate ( 225 deg) scale ( 0 ); } } @keyframes pointMove { 100% { --xPoint: 100px ; --yPoint: 0 ; } } |
这样,我们就实现了完整的一处光的动画:
我们重新梳理一下,实现这样一个动画的步骤:
- 利用角向渐变 conic-gradient 搭出基本框架,并且,这里也利用了多重渐变,角向渐变的背后是深色背景色;
- 利用多重 box-shadow 实现光及阴影的效果(又称为 Neon 效果)
- 利用 clip-path 对元素进行任意区域的裁剪
- 利用 CSS @Property 实现渐变的动画效果
剩下的工作,就是重复上述的步骤,补充其他渐变和光源,调试动画,最终,我们就可以得到这样一个简单的模拟效果:
由于原效果是 .mp4,无法拿到其中的准确颜色,无法拿到阴影的参数,其中颜色是直接用的色板取色,阴影则比较随意的模拟了下,如果有源文件,准确参数,可以模拟的更逼真。
完整的代码你可以戳这里:CodePen — iPhone 13 Pro Gradient
最后
本文更多的是图一乐呵,实际中制作上述效果肯定是有更为优雅的解法,并且利用 CSS 模拟的话,也应该有更好的方法,这里我仅仅是抛砖引玉,过程中的 1、2、3、4 技巧本身有一些还是值得借鉴学习的。
以上就是CSS巧用渐变实现高级感背景光动画 的详细内容,更多关于CSS渐变背景动画的资料请关注IT俱乐部其它相关文章!