CSS 实现祥云纹理背景

2023-09-18 16:07:07

🪴 背景

最近掘金出来一个中秋创意活动,我准备参加一下。作品方向选择用纯css做一个中秋贺卡,其中有一些中秋的元素和一些简单的动画,而贺卡背景的实现就是本文要讲的内容

中秋贺卡成果图(生成gif有点失真😵‍💫)如下:有兴趣的可以看我的另一篇文章:中秋贺卡传送门

tutieshi_640x277_5s.gif

贺卡背景是我用css,仿照从网上搜到的祥云纹理背景图实现的,搜到的图如下:

Alt

那么本文我就来讲讲如何用 css 实现这个祥云纹理背景~

🗝 核心知识点

  • css变量
  • linear-gradient
  • background-blend-mode、mix-blend-mode 混合模式

浏览本文之前,我默认你已经掌握了css的基本知识,这里只对这三个知识点做个大概的解释:

css变量

在css中,可以声明自定义属性(也叫css变量),格式为: 两个连字符 – 加变量名,如下:

 --w: 100px;

然后就可以用 var() 函数来使用这个css变量,这样做可以大大提高css的复用性。本文实现祥云背景时,将一些关键参数抽离成了css变量,方便调整细节。

 div {
   --w: 100px;
   width: var(--w);
 }

radial-gradient、linear-gradient 渐变背景

css中的 linear-gradient() 函数用于创建一个表示两种或多种颜色线性渐变的图片,如下:

Alt

radial-gradient函数用径向渐变来创建 “图像”。径向渐变由中心点定义,为了创建径向渐变你必须设置两个终止色。如下:

Alt

background-blend-mode、mix-blend-mode 混合模式

css 的 blend-mode 混合模式的这两个属性是设置两个叠加的图层的混合效果的,不设置的情况下(即默认值),上层图像会完全覆盖下层图像,只能通过修改上层图像的透明度才能看到下层图像。

但是设置了不同的混合模式后,就可以让两张图有各种混合效果,如下图我设置了几种常用的混合模式:

Alt

🥷 实现过程

初步分析

经过我对以下祥云图的观察,得到以下结论:

Alt

Alt

  1. 每个图元其实都是个环状波纹,环状波纹可以利用radial-gradient实现,只要以两个颜色,从 0% 到 100% 设置不同的渐变区间即可;
  2. 然后将 background-size 设置为到一个图元的大小,我这里设置为宽100px,长50px。这样就可以让图元铺满整个div;
  3. 因为每个波纹只显示了一部分,所以需要将径向渐变的中心设置到底边中点,这样只会显示半圆的波纹了;
  4. 实现环状波纹我打算先用 repeating-radial-gradient 试一试,毕竟这样更简单,不需要设置每个区间的颜色变化,效果如下:

Alt

波纹改进

很明显,用 repeating-radial-gradient 实现的波纹不能满足我们的要求,因为:

  • 样图波纹线条宽度是越来越宽的,而用 repeating-radial-gradient 实现的波纹线条都是均匀等宽的;
  • 样图波纹靠近边缘的弧度是完整的,而用 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;
}

image.png

扇形波纹

观察样图可以得知,每个波纹并不是半圆,而是一个钝角的扇形,那怎么实现一个扇形的径向渐变呢?要知道css的 radial-gradient是不支持设置角度的。

有了!底部两个各画个三角形遮盖住一部分波纹不就好了,因为要和背景融合,三角形背景色设置为波纹的缝隙颜色,即图里的浅蓝色。

Alt

三角形用 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;
}

Alt

构图分析

实现一组扇形波纹后,观察样图可以得知:

只需要两组扇形波纹错误叠加,即可实现祥云纹理的效果

image.png

: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);
}

效果如下:

Alt

最终实现

在上一步用两组扇形波纹层叠后,你发现怎么没有效果,因为这时候图像的混合模式是默认的覆盖,伪元素的图层把body的背景给覆盖了,所以看不到下面的图层。

这时候最关键的一步来了,我们要利用混合模式将body的背景和伪元素的背景融合。那选用哪个混合模式呢?

思考一下即可得出答案:因为波纹的主体线条颜色是深蓝色,背景色是浅蓝色,混合后需要将下层图层(即body背景)中的波纹线条显示出来,所以要保留深色,答案就是可以选用darken变暗混合模式或者multiply正片叠底

设置darken变暗混合模式的效果:

image.png

设置multiply正片叠底的效果:

image.png

🎁 说在最后

本文实现祥云纹理主要利用了渐变色函数以及图层混合模式,其中的要点在于处理好每个波纹图元的样式以及设置合理的混合模式。

在上一章节实现过程中,实际开发顺序其实是以下顺序,只是为了行文流畅,调换了下顺序:

初步分析 -〉构图分析 -> 扇形波纹 -> 波纹改进 ->最终实现

我是喜欢归纳总结前端相关知识的前端阿彬,尽力持续输出原创优质文章,欢迎点赞关注😘

Alt

往期文章
# 🥳🥳🥳 “钉钉官网首页的炫酷动效” 被我用css新特性轻松破解啦~
# 🐿 CSS魔术师Houdini,用浏览器引擎实现高级CSS效果
# ⛳前端进阶:SEO 全方位解决方案
# 我给自己搭建的前端导航网站,你们都别用🤪
# 2023 最新最细 vite+vue3+ts 多页面项目架构,建议收藏备用!
# 2023 前端性能优化清单

更多推荐

模拟实现C语言--memcpy函数和memmove函数

模拟实现C语言–memcpy函数和memmove函数文章目录模拟实现C语言--memcpy函数和memmove函数一、memcpy函数和memmove函数1.1memcpy函数是什么1.1memmove函数是什么二、使用示例2.1从起始位置复制2.2从任意位置复制三、模拟实现3.1模拟实现1--memcpy函数3.2针

MySQL数据库——索引(2)-B+Tree、Hash结构,索引分类(聚集索引、二级索引)

目录索引结构(2)B+TreeHash思考索引分类索引分类聚集索引&二级索引查找过程思考索引结构(2)B+TreeB+Tree是B-Tree的变种,我们以一颗最大度数为4的b+树为例,来看一下其结构示意图:我们可以看到两部分:绿色虚线圈起来的部分,是所引部分,仅仅起到索引数据的作用,不存储数据。红色虚线圈起来的部分,是

什么是HTML?

互联网上的应用程序被称为Web应用程序,Web应用程序使用Web文档(网页)来表现用户界面,而Web文档都遵循标准HTML格式。HTML5是最新的HTML标准。之前的版本HTML4.01于1999年发布。20多年过去了,互联网已经发生了翻天覆地的变化,原有的标准已经不能满足各种Web应用程序的需求。本篇带大家一起了解H

CSP-J 2023 入门级 第一轮 阅读程序(3)

【题目】CSP-J2023入门级第一轮阅读程序(3)#include<iostream>#include<cmath>usingnamespacestd;intsolve1(intn){returnn*n;}intsolve2(intn){intsum=0;for(inti=1;i<=sqrt(n);i++){if(n

Flutter插件开发流程

本文主要给大家介绍如何开发FlutterPlugin中Android的部分。有关Flutter以及FlutterPlugin的概念,感兴趣的可以从官网查看相关资料。一、简介笔者的环境是Mac下AndroidStudio进行的开发,AS也是谷歌官推的,安装flutter插件后,开发起来相对于其他IDE来说,方便很多,自带

使用Feign实现远程调用

目录概述1、引入依赖2、启用Feign3、创建Feign接口4、使用Feign客户端5、配置Feign客户端5.1、全局配置文件5.2、Feign客户端接口5.3、自定义配置类5.4、自定义属性文件总结概述Feign是一个基于注解的HTTP客户端库,它允许您将HTTP请求转换为声明式的Java接口。您可以使用类似于Sp

qt day2

完善登录框点击登录按钮后,判断账号(admin)和密码(123456)是否一致,如果匹配失败,则弹出错误对话框,文本内容“账号密码不匹配,是否重新登录”,给定两个按钮ok和cancel,点击ok后,会清除密码框中的内容,继续进行登录;如果点击cancel按钮,则关闭界面。如果账号和密码匹配,则弹出信息对话框,给出提示信

Docker容器网络安全性最佳实践:防止容器间攻击

Docker容器在现代应用开发和部署中扮演着重要的角色,但由于容器共享宿主机网络环境,容器网络的安全性变得尤为重要。为了防止容器间的攻击,并保护容器网络的安全,有一些最佳实践可以采用。下面将介绍一些重要的Docker容器网络安全性最佳实践。首先,一个基本的安全原则是使用可靠和受信任的容器镜像。确保从受信任的仓库中拉取和

Unity中Shader的模板测试

文章目录前言什么是模板测试1、模板缓冲区2、模板缓冲区中存储的值3、模板测试是什么(看完以下流程就能知道模板测试是什么)模板测试就是在渲染,后渲染的物体前,与渲染前的模板缓冲区的值进行比较,选出符合条件的部分,对后渲染的物体进行渲染前言Unity中Shader的模板测试什么是模板测试1、模板缓冲区2、模板缓冲区中存储的

C++ 指针

C++指针学习C++的指针既简单又有趣。通过指针,可以简化一些C++编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。所以,想要成为一名优秀的C++程序员,学习指针是很有必要的。正如您所知道的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个

网络安全(黑客)自学

前言我是去年8月22日才正式学习网络安全的,因为在国营单位工作了4年,在广东一个月工资只有5000块,而且看不到任何晋升的希望,如果想要往上走,那背后就一定要有关系才行。而且国营单位的气氛是你干的多了,领导觉得你有野心,你干的不多,领导却觉得你这个人不错。我才24周岁,实在的受不了这种工作氛围,情绪已经压制了很多久,一

热文推荐