Canvas如何做个雪花屏版404的实现

本文主要介绍了Canvas如何做个雪花屏版404的实现,文中通过示例代码介绍的非常详细

Posted in HTML / CSS onSeptember 25, 2021

介绍

过往,电视用天线接收信号,没信号出雪花屏,刺啦刺啦作响,然后赶紧扶正想办法让他找到信号。当时电脑还经常连上小霸王打游戏,魂斗罗,超级玛丽,坦克大战。。。时间如白驹过隙,科技进步的飞快,现在都用网络电视了再也不会出现那种情况了,但那真是段令人怀念的时光。

我们今天的主题就是做一个雪花屏版的404页面,我们404找不到页面不就是当年没信号让你去扶正找信号一样的活么,这次我们还是用canvas技术去实现他,还会用到微量的css,效果下图:

Canvas如何做个雪花屏版404的实现

本期我们会从基础结构,绘制雪花屏,css3渐变,绘制文字,绘制波段几个方面去讲述这个项目。

出发

1.基础结构

我们先写好html,在里面我们用module模式,方面后面的模块加载。

<div class="content">
    <canvas id="canvas"></canvas>
</div>
​
<script type="module" src="./app.js"></script>

再写好css的基本样式,这里我们让里面的元素都是全屏显示的。

* {
    padding: 0;
    margin: 0;
}
html,
body {
    width: 100%;
    height: 100vh;
    overflow: hidden;
    position: relative;
    font-size: 12px;
}
#canvas {
    width: 100%;
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 1;
}
.content {
    z-index: 9;
    width: 100%;
    height: 100%;
    display: flex;
    align-items: center;
    justify-content: center;
    background-color: transparent;
}

接下来,我将要写主逻辑了:

/*app.js*/
class Application {
  constructor() {
    this.canvas = null;             // 画布
    this.ctx = null;                // 环境
    this.w = 0;                     // 画布宽 
    this.h = 0;                     // 画布高
    this.offset = 0;                // 波段偏移位置
    this.imgData = null;            // 画布图信息
    this.text = "404";              // 绘制文字
    this.alpha = 0;                 // 透明度
    this.alphaNum = 0.005;          // 透明度衰减值
    this.alphaMax = 0.35;           // 透明度极值
    this.init();
  }
  init() {
    // 初始化
    this.canvas = document.getElementById("canvas");
    this.ctx = this.canvas.getContext("2d");
    window.addEventListener("resize", this.reset.bind(this));
    this.reset();
    this.render();
  }
  reset() {
    // 屏幕改变调用
    this.w = this.canvas.width = this.ctx.width = window.innerWidth;
    this.h = this.canvas.height = this.ctx.height = window.innerHeight;
  }
  render() {
    // 主渲染
    this.step();
  }
  drawBackground() {
    // 绘制雪花屏
  }
  drawFrame(delta) {
    // 绘制波段
  }
  drawText() {
    // 绘制文字
  }
  step(delta) {
    // 重绘
    const {w, h, ctx} = this;
    requestAnimationFrame(this.step.bind(this));
    ctx.clearRect(0, 0, w, h);
    this.drawBackground();
    this.drawText();
    this.drawFrame(delta);
  }
}​
window.onload = new Application();

绘制方面的内容我们随后会开展,目前做的事就是拿到画布给其赋予宽高让其铺满每次监听都可以改变其宽高,此外,其实也不断在重绘执行中,尽管他里面没有东西空白一片。

2.绘制雪花屏

我们想让画布里面有点东西,先绘制雪花背景吧,所以我们先要分析雪花屏是如何产生的。
其实也不难,就是我们先要拿到当前画布内所有点的色值信息,对其修改成随机灰度值,当不断绘制的时候,便呈现出雪花不断闪动。

/*app.js*/
reset() {
    this.w = this.canvas.width = this.ctx.width = window.innerWidth;
    this.h = this.canvas.height = this.ctx.height = window.innerHeight;
    this.changeImgData()
}
changeImgData() {
    const {w, h, ctx} = this;
    ctx.fillStyle = 'white';
    ctx.fillRect(0, 0, w, h);
    ctx.fill();
    return this.imgData = ctx.getImageData(0, 0, w, h);
}

这一步我们就是期望再每次屏幕改变的时候都能拿到他的画布图片数据。imgData里面有个data信息,里面存储了一个Uint8ClampedArray,他里面对应的是点的色值信息,每隔从0到3分别代表红,绿,蓝,透明度的信息。
接下来,我们将利用这些信息搞点事情出来:

/*app.js*/
drawBackground() {
    const {ctx, imgData} = this;
    for (let i = 0, data = imgData.data; i < data.length; i += 4) {
        let color = Math.floor(Math.random() * 255) + 50;
        data[i] = color;
        data[i + 1] = color;
        data[i + 2] = color;
    }
    ctx.putImageData(imgData, 0, 0);
}

我们拿到了信息中的data让每一个色值都改变成一个随机具有灰度的值。再利用putImageData再次对当前矩形也就是整个画布进行绘制,这样雪花屏就出现了~~

Canvas如何做个雪花屏版404的实现

3.圆形渐变

但是,看着花屏太白了,没那种电视框起来那种味道,所以我们用css3在容器写一个渐变背景的伪类覆盖上。中间稍留一点白,为了让后面的主题文字更加让人一目了然。当然,你也可以在画布上绘制一个渐变上去,同样可以实现效果。

.content::after {
    content: "";
    display: block;
    position: absolute;
    top: 0;
    bottom: 0;
    left: 0;
    right: 0;
    z-index: 99;
    background: radial-gradient(
        ellipse at center,
        rgba(0, 0, 0, 0) 0%,
        rgba(0, 0, 0, 0.6) 100%
    );
}

Canvas如何做个雪花屏版404的实现

是不是瞬间感觉好多了~

4.绘制文字

drawText() {
    this.alpha += this.alphaNum;
    if (this.alpha >= this.alphaMax) {
        this.alpha = this.alphaMax;
        this.alphaNum *= -1;
    } else if (this.alpha < 0) {
        this.alpha = 0;
        this.alphaNum *= -1;
    }
    const {ctx, text, w, h} = this;
    let fontSize = w * 0.36;
    ctx.save();
    ctx.fillStyle = `rgba(0,0,0,${this.alpha})`
    ctx.font = `bold ${fontSize}px fantasy, monospace`;
    ctx.textAlign = "center";
    ctx.textBaseline = 'middle';
    ctx.shadowColor = "black";
    ctx.shadowBlur = 20;
    ctx.fillText(text, w / 2, h / 2);
    ctx.restore();
}

这里在绘制前先要改变他的透明度,让他有规律的一闪一闪,就是他让从0不断累加其透明度到达临界值时其再取反,反之亦然。后面的绘制也很简单,让他居中显示在屏幕中间加点投影罢了,这里不做过多赘述。

Canvas如何做个雪花屏版404的实现

现在我们的已经可以看到字体动画了,别着急,为了更加的逼真,我们隔一段时间再生成一个波段矩形,让人感觉到信号不稳定,跟字体闪动的动画相辅相成。

5.绘制波段

drawFrame(delta) {
    this.offset = delta / 10;
    const {w, h, ctx} = this;
    for (let y = -h / 5, v = h / 5; y < h; y += v) {
      ctx.fillStyle = `rgba(0,0,0,${(this.alphaMax - this.alpha) / 8 + 0.02})`;
      ctx.shadowColor = "black";
      ctx.shadowBlur = 20;
      ctx.fillRect(0, y + this.offset % v, w, v / 2);
    }
  }

这里我们设置每隔一个阶段自动绘制一个矩形,他的透明周期和文字的成负相关,文字透明度越高他的就会月低,使其主题文字更加明显。
里面的offset变量是为了波段经历的偏移位置,使其不间断的往下移动。后面就是正常的绘制矩形再略微加些投影,更加逼真。

讲到这里我们就做完了,还挺简单的吧,一下子就回到童年了,在线演示

拓展与延伸

本期,其本质上还是通过getImageData与putImageData一次结合使用,当然我们也不仅限于此,可以联想到各种各样的效果。还有,其实我们还可以把字体做高斯模糊算法去处理等这类操作,更加有特点。

注意:雪花屏会让用户的眼睛很快疲劳,影响健康,所以目的是让用户赶紧想办法换了,找到正确页面。开发者做的时候千万,别长期盯着看,不然会有不适,呃~

到此这篇关于Canvas如何做个雪花屏版404的实现的文章就介绍到这了,更多相关Canvas雪花屏版404内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木! 

 
HTML / CSS 相关文章推荐
HTML5 CSS3给网站设计带来出色效果
Jul 16 HTML / CSS
image-set实现Retina屏幕下图片显示详细介绍
Dec 24 HTML / CSS
Css3新特性应用之视觉效果实例
Dec 12 HTML / CSS
详解CSS 3 中的 calc() 方法
Jan 12 HTML / CSS
HTML5 video视频字幕的使用和制作方法
May 03 HTML / CSS
Html5实现iPhone开机界面示例代码
Jun 30 HTML / CSS
HTML5 Canvas如何实现纹理填充与描边(Fill And Stroke)
Jul 15 HTML / CSS
html5的canvas实现3d雪花飘舞效果
Dec 27 HTML / CSS
canvas实现二维码和图片合成的示例代码
Aug 01 HTML / CSS
html+css实现滚动到元素位置显示加载动画效果
Aug 02 HTML / CSS
css3 文字断裂效果
Apr 22 HTML / CSS
通过feDisplacementMap和feImage实现水波特效
Apr 24 HTML / CSS
使用canvas对video视频某一刻截图功能
Sep 25 #HTML / CSS
使用CSS实现一个搜索引擎的原理解析
sass 常用备忘案例详解
Sep 15 #HTML / CSS
关于HTML编码导致的乱码问题
Sep 04 #HTML / CSS
使用CSS3实现按钮悬停闪烁动态特效代码
Aug 30 #HTML / CSS
深入理解CSS 中 transform matrix矩阵变换问题
Aug 30 #HTML / CSS
CSS+HTML 实现顶部导航栏功能
Aug 30 #HTML / CSS
You might like
javascript,php获取函数参数对象的代码
2011/02/03 PHP
php简单创建zip压缩文件的方法
2016/04/30 PHP
Yii列表定义与使用分页方法小结(3种方法)
2016/07/15 PHP
Yii2针对指定url的生成及图片等的引入方法小结
2016/07/18 PHP
PHP获取客户端及服务器端IP的封装类
2016/07/21 PHP
php实现微信企业号支付个人的方法详解
2017/07/26 PHP
Laravel实现短信注册的示例代码
2018/05/29 PHP
PHP强制转化的形式整理
2020/05/22 PHP
如何让您的中波更粗更长 - 中波框形天线制作
2021/03/10 无线电
用js+xml自动生成表格的东西
2006/12/21 Javascript
JavaScript replace(rgExp,fn)正则替换的用法
2010/03/04 Javascript
jquery中的过滤操作详细解析
2013/12/02 Javascript
javascript中offset、client、scroll的属性总结
2015/08/13 Javascript
基于JavaScript实现通用tab选项卡(通用性强)
2016/01/07 Javascript
基于JQuery打造无缝滚动新闻步骤详解
2016/03/31 Javascript
jquery mobile 实现自定义confirm确认框效果的简单实例
2016/06/17 Javascript
详解NodeJS Https HSM双向认证实现
2019/03/12 NodeJs
[02:36]DOTA2英雄基础教程 一击致命幻影刺客
2013/12/06 DOTA
使用FastCGI部署Python的Django应用的教程
2015/07/22 Python
Python unittest单元测试框架总结
2018/09/08 Python
解决.ui文件生成的.py文件运行不出现界面的方法
2019/06/19 Python
Python3实现汉语转换为汉语拼音
2019/07/08 Python
HTML5手指下滑弹出负一屏阻止移动端浏览器内置下拉刷新功能的实现代码
2020/04/10 HTML / CSS
医疗保健专业人士购物网站:Scrubs & Beyond
2017/02/08 全球购物
英国领先的互联网葡萄酒礼品商:Vintage Wine & Port
2019/05/24 全球购物
教育实习生的自我评价分享
2013/11/21 职场文书
大一期末自我鉴定
2013/12/13 职场文书
《故乡》教学反思
2014/04/10 职场文书
助理政工师申报材料
2014/06/03 职场文书
小区门卫岗位职责范本
2014/08/24 职场文书
公司门卫岗位职责
2015/04/13 职场文书
《植树问题》教学反思
2016/03/03 职场文书
管理者们如何制定2019年的工作计划?
2019/07/01 职场文书
微信小程序APP的事件绑定以及传递参数时的冒泡和捕获
2022/04/19 Javascript
Python实现简单得递归下降Parser
2022/05/02 Python
JS前端可视化canvas动画原理及其推导实现
2022/08/05 Javascript