Amazing!!CSS 也能实现极光?
在上次写完这篇文章 -- 巧用渐变实现高级感拉满的背景光动画 之后,文章下面的评论有同学留言,使用 CSS 可以实现极光吗?
像是这样:
emmm,这有点难为人了。不过,最近我也尝试着去试了下,虽然不可能模拟出那么真实的效果,但是使用 CSS 还是可以作出类似的一些特效的,今天我们就一起来尝试下。
观察了一些极光的图片之后,我发现了极光动画中一些比较重要的元素:
- 基于深色背景的明亮渐变色彩
- 类似于水波流动的动画效果
明亮渐变色彩我们可以尽量使用 渐变 模拟。而水波流动的动画效果,在 SVG 滤镜中 feturbulence 就是专门干这个的,这个滤镜的使用在我过去的多篇文章中也有反复的提及过。
而除了渐变、SVG 的 <feturbulence> 滤镜之外,我们可能还会用到混合模式(mix-blend-mode)、CSS 滤镜等提升效果。
OK,有了大概的思路后,剩下的就是不断的尝试。
Step 1. 绘制深色背景
首先,我们可能需要一个深色的背景,用于表示我们的夜空。同时点缀一些星星,星星可以使用 box-shadow 模拟,这样,一副夜空背景我们可以在 1 个 div 内完成:
<div class="g-wrap">
</div>
@function randomNum($max, $min: 0, $u: 1) {
@return ($min + random($max)) * $u;
}
@function shadowSet($n, $size) {
$shadow : 0 0 0 0 #fff;
@for $i from 0 through $n {
$x: randomNum(350);
$y: randomNum(500);
$scale: randomNum($size) / 10;
$shadow: $shadow, #{$x}px #{$y}px 0 #{$scale}px rgba(255, 255, 255, .8);
}
@return $shadow;
}
.g-wrap {
position: relative;
width: 350px;
height: 500px;
background: #0b1a3a;
overflow: hidden;
&::before {
content: "";
position: absolute;
width: 1px;
height: 1px;
border-radius: 50%;
box-shadow: shadowSet(100, 6);
}
这一步比较简单,借助了 SASS 之后,我们能够得到这样一幅夜空背景图:
Step 2. 使用渐变画出极光的轮廓
接下来,就是利用渐变,画出极光的一个轮廓效果。
其实就是一个径向渐变:
<div class="g-wrap">
<div class="g-aurora"></div>
</div>
.g-aurora {
width: 400px;
height: 300px;
background: radial-gradient(
circle at 100% 100%,
transparent 45%,
#bd63c1 55%,
#53e5a6 65%,
transparent 85%
);
}
Step 3. 旋转拉伸
目前看来,是有一点点轮廓了。下一步,我们把得到的这个渐变效果通过旋转拉伸变换一下。
.g-aurora {
...
transform: rotate(45deg) scaleX(1.4);
}
我们大概就能得到这样一个效果:
Step 4. 神奇的混合模式变换!
到这里,其实雏形已经出来了。但是颜色看着不太像,为了和深色的背景融合在一起,这里我们运用上混合模式 mix-blend-mode。
.g-aurora {
...
transform: rotate(45deg) scaleX(1.4);
mix-blend-mode: color-dodge;
}
神奇的事情发生了,看看效果:
整体的颜色看上去更加像极光的颜色。
Step 5. 叠加 SVG feturbulence 滤镜
接下来,我们要产生水纹波动的效果,需要借助 SVG 的 <feturbulence> 滤镜,对这个滤镜还不太了解的,可以看看我的这几篇文章:
回归正题。我们添加一个 SVG 的 <feturbulence> 滤镜,利用 CSS filter 进行引用
<div class="g-wrap">
<div class="g-aurora"></div>
</div>
<svg id='blob' version='1.1' xmlns='http://www.w3.org/2000/svg'>
<defs>
<filter id='wave'>
<feturbulence basefrequency='0.003 0.003 id='turbulence' numoctaves='3' result='noise' seed='10' />
<fedisplacementmap id='displacement' in2='noise' in='SourceGraphic' scale='96' />
</filter>
</defs>
</svg>
.g-aurora {
...
transform: rotate(45deg) scaleX(1.4);
mix-blend-mode: color-dodge;
filter: url(#wave);
}
我们即可得到这样一种效果:
Wow,是不是已经很有那种感觉了。通过 feturbulence 的特性,我们近乎模拟出了极光的效果!
Step 6. 让极光动起来
最后一步,我们就需要让我们的极光动起来。由于 SVG 动画本身不支持类似 animation-fill-mode: alternate 这种特性。我们还是需要写一点 JavaScript 代码,控制动画的整体循环。
大概的代码是这样:
var filter = document.querySelector("#turbulence");
var frames = 0;
var rad = Math.PI / 180;
function freqAnimation() {
bfx = 0.005;
bfy = 0.005;
frames += .5
bfx += 0.0025 * Math.cos(frames * rad);
bfy += 0.0025 * Math.sin(frames * rad);
bf = bfx.toString() + ' ' + bfy.toString();
filter.setAttributeNS(null, 'baseFrequency', bf);
window.requestAnimationFrame(freqAnimation);
}
window.requestAnimationFrame(freqAnimation);
至此,我们就得到了一幅完整的,会动的极光动画:
一些技巧及其他事项
- 渐变元素的周围会存在明显的边界毛刺效果,可以使用黑色内阴影
box-shadow: inset ...去除; - 实际行文过程中的各个属性的实际参数看似简单,过程中其实经过了不断的调试才得到;
- 混合模式及 SVG 的 feturbulence 滤镜比较难掌握,需要不断的练习,不断的调试;本文极光的颜色选取没有经过太多反复调试,愿意花时间,可以调试出效果更好的颜色。
最终的效果,不太完美,但也算一副不错的 CSS + SVG 作品。完整的代码,你可以看这里:
最后
好了,本文到此结束,希望本文对你有所帮助
更多精彩 CSS 技术文章汇总在我的 Github -- iCSS ,持续更新,欢迎点个 star 订阅收藏。
如果还有什么疑问或者建议,可以多多交流,原创文章,文笔有限,才疏学浅,文中若有不正之处,万望告知。
Amazing!!CSS 也能实现极光?的更多相关文章
- Amazing!!CSS 也能实现烟雾效果?
最近利用 CSS 实现了一些看似超出 CSS 能力的效果: 巧用渐变实现高级感拉满的背景光动画 Amazing!!CSS 也能实现极光? 本文继续此系列,本文主要想探讨一下,使用 CSS 能否比较好的 ...
- LPL Ban/Pick 选人阶段的遮罩效果是如何实现的?
最近 S11 LPL 春季赛开赛,在看比赛的过程中,我发现新赛季的 Ban/Pick 选人阶段,出现了一种新的,有意思的遮罩效果,如下图所示: 当然,它是一个动态的效果,当选人的过程中,会有一种呼吸的 ...
- Django 新人开发的十个注意点
总结一下 Django开发中,注意的事项,特别是新人,由于水平有限,也只能到这个层次,更多模式思想性的东西,还得在开发中慢慢体会. 1.各个APP独立,做到项目的模块分明.说的有点大,列几个列子优先 ...
- 开始了大概三四天的Rails学习之路
最近因为一位极光推送朋友,我开始了大概三四天的Rails学习之路,最终达到的水平是可以比较轻松地做出大部分功能,然后自我感觉可以自如地按照Rails的设计思想去思考.由于编程的日益流行,我结识了越来越 ...
- Django问题2
接触django是从上个月开始,学习python时间也不长,但我经常在社区看看别人发表的文章,早上看到一篇不错的博客,却一直不能访 问,最终从bing的缓存里找到,因为害怕丢失和忘掉,所以顺便翻译过来 ...
- Django新手十个开发指导
下面是关于Django新手开发中的一些建议,大家可以参考一下~~ 1,不要将项目名称包含在引用代码里 比如你创建了一个名为"project"的项目,包含一个名为"app& ...
- Matplotlib数据可视化(3):文本与轴
在一幅图表中,文本.坐标轴和图像的是信息传递的核心,对着三者的设置是作图这最为关心的内容,在上一篇博客中虽然列举了一些设置方法,但没有进行深入介绍,本文以围绕如何对文本和坐标轴进行设置展开(对图像 ...
- Amazing!巧用 CSS 视差实现酷炫交互动效
本文将介绍利用 CSS 实现滚动视差效果的一个小技巧,并且,利用这个技巧来制作一些有意思的交互特效. 关于使用 CSS 实现滚动视差效果,在之前有一篇文章详细描述过具体方案 - CSS 实现视差效果, ...
- Head First Html and CSS学习笔记之CSS
第七章 CSS入门 元素的许多属性都可以设置样式,太多了,记不住,可以参考<CSS Pocket Reference>. 外部样式表,<link type = "text/ ...
随机推荐
- 《HelloGitHub》第 68 期
兴趣是最好的老师,HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣.入门级的开源项目. https://github.com/521xueweiha ...
- js--迭代器总结
前言 我们已经熟练使用set.map.array几种集合类型了,掌握了map(),for..of..,filter()等迭代集合的方法,你是否思考过,js引擎是怎么迭代的,怎么判断迭代是否结束,本文来 ...
- 5.基于二进制部署kubernetes(k8s)集群
1 kubernetes组件 1.1 Kubernetes 集群图 官网集群架构图 1.2 组件及功能 1.2.1 控制组件(Control Plane Components) 控制组件对集群做出全局 ...
- mount 挂载详解
挂接命令(mount) 首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的. 命令格式:mount [-t vfstype] [-o option ...
- Macbookpro vim操作键说明
i → Insert 模式,按 ESC 回到 Normal 模式. x → 删当前光标所在的一个字符.:wq → 存盘 + 退出 (:w 存盘, :q 退出) (陈皓注::w 后可以跟文件名)dd → ...
- ZAQI
mysql> CREATE TABLE emploee ( -> name CHAR(64) NOT NULL, -> email CHAR(64), -> password ...
- Python基础之格式化输出的三种方式
目录 1. 格式化输出的三种方式 1.1 占位符 1.2 format格式化 1.3 f-string格式化 1. 格式化输出的三种方式 在程序中,需要将输出信息打印成固定的格式,这时候就需要格式化输 ...
- JavaScript获取html表单值验证后跳转网页中的关键点
关键代码: 1.表单部分 <form action="Depart.jsp" name="myform" method="post" ...
- 内存管理——new delete expression
C++申请释放内存的方法与详情表 调用情况 1.new expression new表达式在申请内存过程中都发生了什么? 编译器将new这个分解为下面的主要3步代码,①首先调用operator new ...
- vue SCSS
C:\eclipse\wks\vue\esql-ui>node -v v12.18.1 C:\eclipse\wks\vue\esql-ui>npm -v 6.14.5 直接修改p ...