本文将使用纯 CSS,带大家一步一步实现一个这样的科幻字符跳动背景动画。类似于这样的字符雨动画:

Digital Char Rain Animation

或者是类似于这样的:

CodePen Home Matrix digital rain (animated version) By yuanchuan

运用在一些类似科技主题的背景之上,非常的添彩。

文字的竖排

首先第一步,就是需要实现文字的竖向排列:

这一步非常的简单,可能方法也很多,这里我简单罗列一下:

  1. 使用控制文本排列的属性 writing-mode 进行控制,可以通过 writing-mode: vertical-lr 等将文字进行竖向排列,但是对于数字和英文,将会旋转 90° 展示:

<p>1234567890ABC</p>
<p>中文或其他字符ォヶ</p>
p {writing-mode: vertical-lr;
}

当然这种情况下,英文字符的展示不太满足我们的需求。

  1. 控制容器的宽度,控制每行只能展示 1 个中文字符。

这个方法算是最简单便捷的方法了,但是由于英文的特殊性,要让连续的长字符串自然的换行,我们还需要配合 word-break: break-all

p {width: 12px;font-size: 10px;word-break: break-all;
}

效果如下,满足需求:

使用 CSS 实现随机字符串的选取

为了让我们的效果更加自然。每一列的字符的选取最好是随机的。

但是要让 CSS 实现随机生成每一列的字符可太难了。所以这里我们请出 CSS 预处理器 SASS/LESS 。

而且由于不太可能利用 CSS 给单个标签内,譬如 <p> 标签插入字符,所以我们把标签内的字符展示,放在每个 <p> 元素的伪元素 ::beforecontent 当中。

我们可以提前设置好一组字符串,然后利用 SASS function 随机生成每一次元素内的 content,伪代码如下:

<div><p></p><p></p><p></p>
</div>
$str: 'ぁぃぅぇぉかきくけこんさしすせそた◁▣▤▥▦▧♂♀♥☻►◄▧▨♦ちつってとゐなにぬねのはひふへほゑまみむめもゃゅょゎをァィゥヴェォカヵキクケヶコサシスセソタチツッテトヰンナニヌネノハヒフヘホヱマミムメモャュョヮヲㄅㄉㄓㄚㄞㄢㄦㄆㄊㄍㄐㄔㄗㄧㄛㄟㄣㄇㄋㄎㄑㄕㄘㄨㄜㄠㄤㄈㄏㄒㄖㄙㄩㄝㄡㄥabcdefghigklmnopqrstuvwxyz123456789%@#$<>^&*_+';
$length: str-length($str);@function randomChar() {$r: random($length);@return str-slice($str, $r, $r);
}@function randomChars($number) {$value: '';@if $number > 0 {@for $i from 1 through $number {$value: $value + randomChar();}}@return $value;
}p:nth-child(1)::before {content: randomChars(25);
}
p:nth-child(2)::before {content: randomChars(25);
}
p:nth-child(3)::before {content: randomChars(25);
}

简单解释下上面的代码:

  1. $str 定义了一串随机字符串,$length 表示字符串的长度

  2. randomChar() 中利用了 SASS 的 random() 方法,每次随机选取一个 0 - $length 的整形数,记为 $r,再利用 SASS 的 str-slice 方法,每次从 $str 中选取一个下标为 $r 的随机字符

  3. randomChars() 就是循环调用 randomChar() 方法,从 $str 中随机生成一串字符串,长度为传进去的参数 $number

这样,每一列的字符,每次都是不一样的:

当然,上述的方法我认为不是最好的,CSS 的伪元素的 content 是支持字符编码的,譬如 content: '\3066'; 会被渲染成字符 ,这样,通过设定字符区间,配合 SASS function 可以更好的生成随机字符,但是我尝试了非常久,SASS function 生成的最终产物会在 \3066 这样的数字间添加上空格,无法最终通过字符编码转换成字符,最终放弃...

使用 CSS 实现打字效果

OK,继续,接下来我们要使用 CSS 实现打字效果,就是让字符一个一个的出现,像是这样:

纯 CSS 实现文字输入效果

这里借助了 animation 的 steps 的特性实现,也就是逐帧动画。

从左向右和从上向下原理是一样的,以从左向右为例,假设我们有 26 个英文字符,我们已知 26 个英文字符组成的字符串的长度,那么我们只需要设定一个动画,让它的宽度变化从 0 - 100% 经历 26 帧即可,配合 overflow: hidden,steps 的每一帧即可展出一个字符。

当然,这里需要利用一些小技巧,我们如何通过字符的数量知道字符串的长度呢?

划重点:通过等宽字体的特性,配合 CSS 中的 ch 单位

如果不了解什么是等宽字体族,可以看看我的这篇文章 -- 《你该知道的字体 font-family》[1]

CSS 中,ch 单位表示数字 “0” 的宽度。如果字体恰巧又是等宽字体,即每个字符的宽度是一样的,此时 ch 就能变成每个英文字符的宽度,那么 26ch 其实也就是整个字符串的长度。

利用这个特性,配合 animation 的 steps,我们可以轻松的利用 CSS 实现打字动画效果:

<h1>Pure CSS Typing animation.</h1>
h1 {font-family: monospace;width: 26ch;white-space: nowrap;overflow: hidden;animation: typing 3s steps(26, end);
}@keyframes typing {0{width: 0;}100% {width: 26ch;}
}

就可以得到如下结果啦:

纯 CSS 实现文字输入效果

完整的代码你可以戳这里:

CodePen Demo -- 纯 CSS 实现文字输入效果[2]

改造成竖向打字效果

接下来,我们就运用上述技巧,改造一下。将一个横向的打字效果改造成竖向的打字效果。

核心的伪代码如下:

<div><p></p><p></p><p></p>
</div>
$str: 'ぁぃぅぇぉかきくけこんさしすせそた◁▣▤▥▦▧♂♀♥☻►◄▧▨♦ちつってとゐなにぬねのはひふへほゑまみむめもゃゅょゎをァィゥヴェォカヵキクケヶコサシスセソタチツッテトヰンナニヌネノハヒフヘホヱマミムメモャュョヮヲㄅㄉㄓㄚㄞㄢㄦㄆㄊㄍㄐㄔㄗㄧㄛㄟㄣㄇㄋㄎㄑㄕㄘㄨㄜㄠㄤㄈㄏㄒㄖㄙㄩㄝㄡㄥabcdefghigklmnopqrstuvwxyz123456789%@#$<>^&*_+';
$length: str-length($str);@function randomChar() {$r: random($length);@return str-slice($str, $r, $r);
}@function randomChars($number) {$value: '';@if $number > 0 {@for $i from 1 through $number {$value: $value + randomChar();}}@return $value;
}p {width: 12px;font-size: 10px;word-break: break-all;
}p::before {content: randomChars(20);color: #fff;animation: typing 4s steps(20, end) infinite;
}@keyframes typing {0% {height: 0;}25% {height: 100%;}100% {height: 100%;}
}

这样,我们就实现了竖向的打字效果:

当然,这样看上去比较整齐划一,缺少了一定的随机,也就缺少了一定的美感。

基于此,我们进行 2 点改造:

  1. 基于动画的时长 animation-time、和动画的延迟 animation-delay,增加一定幅度内的随机

  2. 在每次动画的末尾或者过程中,重新替换伪元素的 content,也就是重新生成一份 content

可以借助 SASS 非常轻松的实现这一点,核心的 SASS 代码如下:

$n: 3;
$animationTime: 3;
$perColumnNums: 20;@for $i from 0 through $n {$content: randomChars($perColumnNums);$contentNext: randomChars($perColumnNums);$delay: random($n);$randomAnimationTine: #{$animationTime + random(20) / 10 - 1}s;p:nth-child(#{$i})::before {content: $content;color: #fff;animation: typing-#{$i} $randomAnimationTine steps(20, end) #{$delay * 0.1s * -1} infinite;}@keyframes typing-#{$i} {0% {height: 0;}25% {height: 100%;}100% {height: 100%;content: $contentNext;}}
}

看看效果,已经有不错的改观:

当然,上述由横向打字转变为竖向打字效果其实是有一些不一样的。在现有的竖向排列规则下,无法通过 ch 配合字符数拿到实际的竖向高度。所以这里有一定的取舍,实际放慢动画来看,没个字的现出不一定是完整的。

当然,在快速的动画效果下几乎是察觉不到的。

增加光影与透明度变化

最后一步,就是增加光影及透明度的变化。

最佳的效果是要让每个新出现的字符保持亮度最大,同时已经出现过的字符亮度慢慢减弱。

但是由于这里我们无法精细操控每一个字符,只能操控每一行字符,所以在实现方式上必须另辟蹊径。

最终的方式是借用了另外一个伪元素进行同步的遮罩以实现最终的效果。下面我们就来一步一步看看过程。

给文字增添亮色及高光

第一步就是给文字增添亮色及高光,这点非常容易,就是选取一个黑色底色下的亮色,并且借助 text-shadow 让文字发光。

p::before {color: rgb(179, 255, 199);text-shadow: 0 0 1px #fff, 0 0 2px #fff, 0 0 5px currentColor, 0 0 10px currentColor;
}

看看效果,左边是白色字符,中间是改变字符颜色,右边是改变了字体颜色并且添加了字体阴影的效果:

给文字添加同步遮罩

接下来,就是在文字动画的行进过程中,同步添加一个黑色到透明的遮罩,尽量还原让每个新出现的字符保持亮度最大,同时已经出现过的字符亮度慢慢减弱。

这个效果的示意图大概是这样的,这里我将文字层和遮罩层分开,并且底色从黑色改为白色,方便理解:

蒙层遮罩原理图

大概的遮罩的层的伪代码如下,用到了元素的另外一个伪元素:

p::after {content: '';background: linear-gradient(rgba(0, 0, 0, .9), transparent 75%, transparent);background-size: 100% 220%;background-repeat: no-repeat;animation: mask 4s infinite linear;
}@keyframes mask {0% {background-position: 0 220%;} 30% {background-position: 0 0%;}100% {background-position: 0 0%;}
}

好,合在一起的最终效果大概就是这样:

通过调整 @keyframes mask 的一些参数,可以得到不一样的字符渐隐效果,需要一定的调试。

完整代码及效果

OK,拆解了一下主要的步骤,最后上一下完整代码,应用了 Pug 模板引擎和 SASS 语法。

完整代码加起来不过 100 行。

.g-container-for(var i=0; i<50; i++)p
@import url('https://fonts.googleapis.com/css2?family=Inconsolata:wght@200&display=swap');$str: 'ぁぃぅぇぉかきくけこんさしすせそた◁▣▤▥▦▧♂♀♥☻►◄▧▨♦ちつってとゐなにぬねのはひふへほゑまみむめもゃゅょゎをァィゥヴェォカヵキクケヶコサシスセソタチツッテトヰンナニヌネノハヒフヘホヱマミムメモャュョヮヲㄅㄉㄓㄚㄞㄢㄦㄆㄊㄍㄐㄔㄗㄧㄛㄟㄣㄇㄋㄎㄑㄕㄘㄨㄜㄠㄤㄈㄏㄒㄖㄙㄩㄝㄡㄥabcdefghigklmnopqrstuvwxyz123456789%@#$<>^&*_+';
$length: str-length($str);
$n: 50;
$animationTime: 4;
$perColumnNums: 25;@function randomChar() {$r: random($length);@return str-slice($str, $r, $r);
}@function randomChars($number) {$value: '';@if $number > 0 {@for $i from 1 through $number {$value: $value + randomChar();}}@return $value;
}body, html {width: 100%;height: 100%;background: #000;display: flex;overflow: hidden;
}.g-container {width: 100vw;display: flex;justify-content: space-between;flex-wrap: nowrap;flex-direction: row;font-family: 'Inconsolata', monospace, sans-serif;
}p {position: relative;width: 5vh;height: 100vh;text-align: center;font-size: 5vh;word-break: break-all;white-space: pre-wrap;&::before,&::after {position: absolute;top: 0;left: 0;right: 0;height: 100%;overflow: hidden;}
}@for $i from 0 through $n {$content: randomChars($perColumnNums);$contentNext: randomChars($perColumnNums);$delay: random($n);$randomAnimationTine: #{$animationTime + random(20) / 10 - 1}s;p:nth-child(#{$i})::before {content: $content;color: rgb(179, 255, 199);text-shadow: 0 0 1px #fff, 0 0 2px #fff, 0 0 5px currentColor, 0 0 10px currentColor;animation: typing-#{$i} $randomAnimationTine steps(20, end) #{$delay * 0.1s * -1} infinite;z-index: 1;}p:nth-child(#{$i})::after {$alpha: random(40) / 100 + 0.6;content: '';background: linear-gradient(rgba(0, 0, 0, $alpha), rgba(0, 0, 0, $alpha), rgba(0, 0, 0, $alpha), transparent 75%, transparent);background-size: 100% 220%;background-repeat: no-repeat;animation: mask $randomAnimationTine infinite #{($delay - 2) * 0.1s * -1} linear;z-index: 2;}@keyframes typing-#{$i} {0% {height: 0;}25% {height: 100%;}100% {height: 100%;content: $contentNext;}}
}@keyframes mask{0% {background-position: 0 220%;} 30% {background-position: 0 0%;}100% {background-position: 0 0%;}
}

最终效果也就是题图所示:

Digital Char Rain Animation

完整的代码及演示效果你可以戳这里:

CodePen Demo -- Digital Char Rain Animation[3]

如果觉得这篇文章还不错,来个【转发、收藏、在看】三连吧,让更多的人也看到~

纯 CSS 实现科技感十足的暗黑字符雨动画相关推荐

  1. 【Web动画】科技感十足的暗黑字符雨动画

    大家好,我是前端点线面,毕业于华中科技大学,非科班出身的一枚新时代农民工,现在是百度前端研发工程师,著有<前端百题斩>.数十篇学习思维导图(go.React.Redux.Vue.Vuex. ...

  2. 纯css实现科技感十足的方格闪烁背景

    依然是Vue项目中的效果,GIF图看起来有点卡顿 ,但实际效果很流畅.代码如下: <div class="main-body"><span :class=&quo ...

  3. 联想电脑锁屏界面设置被组织隐藏_Word Clock数字时钟动态屏保,让你的电脑锁屏瞬间科技感十足!...

    今天我们为大家分享一下最近某音非常火的电子时钟屏保,让你的电脑屏保动起来,而且随着时间流逝而变化(作为一个时间观念强的人,一定会看着屏保更加惜时如金),让你的电脑锁屏与众不同,瞬间黑科技感十足!今天的 ...

  4. 科技感十足五款APP软件,让你的手机不再低调!

    手机买的越贵就是越好,这种理念在人们心中一直存在,毕竟一份价钱一份货嘛!但是同款的手机如何才能体现出你的与众不同,是手机壳?不!是手机上的APP软件,科技感十足的APP能使你的手机与众不同! 接下来小 ...

  5. 科技感十足的数码首图海报

    科技感十足的数码首图海报 下载地址: 百度网盘:http://pan.baidu.com/s/1c1oEloO 解压密码:scienfun 查看原文:http://www.c2biot.com/783 ...

  6. 手机3D碎屏动态壁纸,随着手机晃动变幻的3D特效!科技感十足!

    上次我们分享了视频桌面壁纸.今天,给大家带来更加炫酷的壁纸--3D碎屏动态壁纸,随重力变化呈现3D特效,科技感十足! 适用系统:安卓 演示机型:魅族MX6 一.3D碎屏动态壁纸 第一步当然是下载安装软 ...

  7. 广财华商学院计算机房,广东财经大学华商学院现超豪华教室,科技感十足!

    原标题:广东财经大学华商学院现超豪华教室,科技感十足! 广东财经大学华商学院占地近千亩,坐落于风景秀丽的广州市增城区,交通便利.校园规划井然有序,绿树成荫,建筑面积达50多万平方米,教学设施和生活配套 ...

  8. 如何做出科技感十足的宣传片?

    科技感十足的宣传是如何制作的呢?视频工厂为大家分享制作流程. 一.画面效果 无论是哪种类型的宣传视频,画面都是不可忽视的构成素材.如果我们想要制作出极富科技感的宣传视频,那么在画面拍摄的时候,也要注意 ...

  9. 【JAVAFX-HUD2未来世界科技感十足UI】

    [JAVAFX-HUD2未来世界科技感十足UI] 简介 HUD界面本来科技感就非常好,可惜网上的资料太少,psd素材,heml模板设计都没有太理想的.至于效果非常好的只是网络图片而已,尤其是psd的也 ...

最新文章

  1. 采集练习(一) php 获得全国的小学(数据来自腾讯朋友网)
  2. “最少惊讶”和可变默认参数
  3. android中的常用方法,android开发中常用方法总结
  4. 如何使用SAP Cloud for Customer里的ABSL代码调用Web service
  5. python聚类分析结果很差_python中的聚类分析:value错误:x和y的大小必须相同
  6. SSM(Spring+Spring MVC+Mybatis)整合 1:整体概述、目录内容及实验环境介绍
  7. git和python交互_使用Python连接和执行GIT命令
  8. 《系统工程理论与实践》Latex 模板使用教程
  9. Graph Convolutional Networks Meet Markov Random Fields: Semi-Supervised Community Detection in Attri
  10. 计算机网络运输层的简单总结与思考
  11. angular.js:13920 Error: [$injector:unpr] Unknown provider: $scopeProvider - $scope - testServe
  12. 主数据与数据中台有什么区别?
  13. cf12月9日服务器维护时间,《CF》12月9日更新后进不去大厅怎么回事 新版大厅无法进入解决攻略...
  14. 2011 年互联网十大浏览器
  15. python中文正则表达式匹配
  16. TortoiseGit 的使用
  17. leetcode 2413:最小偶数倍
  18. 【日期、时区、时间】本地时间转UTC时间详解
  19. 新长城 Html标签
  20. uni-app 原生标题栏搜索输入框事件合集

热门文章

  1. [多屏互动] 实现双屏异显一:安卓Presentation
  2. 【图像处理】python skimage 图像处理
  3. 计算机科学与技术能自考吗,自考有计算机科学与技术这个专业吗?
  4. [win10+Ubuntu18.04双系统安装] UEFI启动 Dell-G3-3579
  5. 斩获三大电商平台销量与销售额双冠军:iQOO Z5首销火爆
  6. 新标日初级上册单词5----8
  7. 一般实验室、专用实验室及研究工作室的设计
  8. Matlab生成RGB彩色渐变光栅图,RGB渐变色
  9. NFT数字藏品系统全面解析!
  10. 7135制作自动量程电压切换_基于STM32和ICL7135的数字电压表设计