一、知识点
(1)css变量
(2)linear-gradient
(3)background-blend-mode、mix-blend-mode 混合模式
二、知识内容普及
1、css变量
在css中,可以声明自定义属性(也叫css变量),格式为: 两个连字符 -- 加变量名,如下:
--w: 100px;
然后就可以用 var() 函数来使用这个css变量,这样做可以大大提高css的复用性。本文实现祥云背景时,将一些关键参数抽离成了css变量,方便调整细节。
div {
--w: 100px;
width: var(--w);
}
2、radial-gradient、linear-gradient 渐变背景
css中的 linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片,如下:
radial-gradient函数用径向渐变来创建 "图像"。径向渐变由中心点定义,为了创建径向渐变你必须设置两个终止色。如下:
3、background-blend-mode、mix-blend-mode 混合模式
css 的 blend-mode 混合模式的这两个属性是设置两个叠加的图层的混合效果的,不设置的情况下(即默认值),上层图像会完全覆盖下层图像,只能通过修改上层图像的透明度才能看到下层图像。
但是设置了不同的混合模式后,就可以让两张图有各种混合效果,如下图我设置了几种常用的混合模式:
三、实现过程
1、初步分析
经过我对以下祥云图的观察,得到以下结论:
(1)每个图元其实都是个环状波纹,环状波纹可以利用radial-gradient实现,只要以两个颜色,从 0% 到 100% 设置不同的渐变区间即可;
(2)然后将 background-size 设置为到一个图元的大小,我这里设置为宽100px,长50px。这样就可以让图元铺满整个div;
(3)因为每个波纹只显示了一部分,所以需要将径向渐变的中心设置到底边中点,这样只会显示半圆的波纹了;
(4)实现环状波纹我打算先用 repeating-radial-gradient 试一试,毕竟这样更简单,不需要设置每个区间的颜色变化,效果如下:
2、波纹改进
很明显,用 repeating-radial-gradient 实现的波纹不能满足我们的要求,因为:
(1)样图波纹线条宽度是越来越宽的,而用 repeating-radial-gradient 实现的波纹线条都是均匀等宽的;
(2)样图波纹靠近边缘的弧度是完整的,而用 repeating-radial-gradient 实现的波纹很明显边缘有被切割的效果;
所以,放弃repeating-radial-gradient实现波纹,改用 radial-gradient 单独设置每个渐变区间,如下:
:root{
--bg: radial-gradient( at center bottom
,var(--color2) 0%,var(--color1) 2%
,var(--color1) 2%,var(--color1) 6%
,var(--color2) 6%,var(--color2) 8%
,var(--color1) 8%,var(--color1) 12%
,var(--color2) 12%,var(--color2) 15%
,var(--color1) 15%,var(--color1) 19%
,var(--color2) 19%,var(--color2) 23%
,var(--color1) 23%,var(--color1) 28%
,var(--color2) 28%,var(--color2) 32%
,var(--color1) 32%,var(--color1) 37%
,var(--color2) 37%,var(--color2) 42%
,var(--color1) 42%,var(--color1) 48%
,var(--color2) 48%,var(--color2) 54%
,var(--color1) 54%,var(--color1) 61%
,var(--color2) 61%,var(--color2) 70%
,var(--color1) 70%,var(--color1) 100%);
}
body{
background: var(--bg);
background-size: 100px 50px;
}
3、扇形波纹
观察样图可以得知,每个波纹并不是半圆,而是一个钝角的扇形,那怎么实现一个扇形的径向渐变呢?要知道css的 radial-gradient是不支持设置角度的。
有了!底部两个各画个三角形遮盖住一部分波纹不就好了,因为要和背景融合,三角形背景色设置为波纹的缝隙颜色,即图里的浅蓝色。
三角形用 linear-gradien 线性渐变实现,注意设置background-image的顺序,三角形要写在前面,才能覆盖住波纹。(其实如果三角形写在最后,也可以通过设置混合模式呈现扇形波纹的效果,例如在我的例子中可以谁lighten变亮混合模式)
//写法一:推荐
:root{
--bg: linear-gradient(30deg,var(--color1) 0,var(--color1) 30%,transparent 30%)
,linear-gradient(-30deg,var(--color1) 0,var(--color1) 30%,transparent 30%)
,radial-gradient( at center bottom
,var(--color2) 0%,var(--color1) 2%
,var(--color1) 2%,var(--color1) 6%
,var(--color2) 6%,var(--color2) 8%
,var(--color1) 8%,var(--color1) 12%
,var(--color2) 12%,var(--color2) 15%
,var(--color1) 15%,var(--color1) 19%
,var(--color2) 19%,var(--color2) 23%
,var(--color1) 23%,var(--color1) 28%
,var(--color2) 28%,var(--color2) 32%
,var(--color1) 32%,var(--color1) 37%
,var(--color2) 37%,var(--color2) 42%
,var(--color1) 42%,var(--color1) 48%
,var(--color2) 48%,var(--color2) 54%
,var(--color1) 54%,var(--color1) 61%
,var(--color2) 61%,var(--color2) 70%
,var(--color1) 70%,var(--color1) 100%);
}
body{
background: var(--bg);
background-size: 100px 50px;
}
//写法二
:root{
--bg: radial-gradient( at center bottom
,var(--color2) 0%,var(--color1) 2%
,var(--color1) 2%,var(--color1) 6%
,var(--color2) 6%,var(--color2) 8%
,var(--color1) 8%,var(--color1) 12%
,var(--color2) 12%,var(--color2) 15%
,var(--color1) 15%,var(--color1) 19%
,var(--color2) 19%,var(--color2) 23%
,var(--color1) 23%,var(--color1) 28%
,var(--color2) 28%,var(--color2) 32%
,var(--color1) 32%,var(--color1) 37%
,var(--color2) 37%,var(--color2) 42%
,var(--color1) 42%,var(--color1) 48%
,var(--color2) 48%,var(--color2) 54%
,var(--color1) 54%,var(--color1) 61%
,var(--color2) 61%,var(--color2) 70%
,var(--color1) 70%,var(--color1) 100%)
,linear-gradient(30deg,var(--color1) 0,var(--color1) 30%,transparent 30%)
,linear-gradient(-30deg,var(--color1) 0,var(--color1) 30%,transparent 30%);
}
body{
background: var(--bg);
background-size: 100px 50px;
background-blend-mode: lighten;
}
4、构图分析
实现一组扇形波纹后,观察样图可以得知:只需要两组扇形波纹错误叠加,即可实现祥云纹理的效果。
用 :before 伪元素 给原来的图像上再覆盖一层相同的图案,并设置背景位置 background-position 为 “一个扇形波纹的宽/2,一个扇形波纹的高/2”,
我们把一些关键参数抽离成css变量,例如每个图元的宽高,波纹渐变的两个颜色,背景图层。
:root{
--w: 100px;
--h: 50px;
--color1: #707dda;
--color2: #09135e;
--bg: 同上;
}
body{
width: 100%;
height: 100vh;
overflow: hidden;
background: var(--bg);
background-size: var(--w) var(--h);
}
body::before{
content: '';
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100vh;
--color1: #707dda;
--color2: #09135e;
width: 100%;
height: 100vh;
background: var(--bg);
background-size: var(--w) var(--h);
background-position: calc(var(--w) / 2) calc(var(--h) / 2);
}
效果如下:
5、最终实现
在上一步用两组扇形波纹层叠后,你发现怎么没有效果,因为这时候图像的混合模式是默认的覆盖,伪元素的图层把body的背景给覆盖了,所以看不到下面的图层。
这时候最关键的一步来了,我们要利用混合模式将body的背景和伪元素的背景融合。那选用哪个混合模式呢?
思考一下即可得出答案:因为波纹的主体线条颜色是深蓝色,背景色是浅蓝色,混合后需要将下层图层(即body背景)中的波纹线条显示出来,所以要保留深色,答案就是可以选用darken变暗混合模式或者multiply正片叠底。
设置darken变暗混合模式的效果:
设置multiply正片叠底的效果:
三、总结
本文实现祥云纹理主要利用了渐变色函数以及图层混合模式,其中的要点在于处理好每个波纹图元的样式以及设置合理的混合模式。