JavaScript Canvas实现噪点滤镜回忆童年电视雪花屏

目录
  • 引言
  • 正文
    • 初始化渲染
    • 雪花屏动画
    • 帧动画播放

引言

相信很多人80,90后的同学对童年里电视机的突然出现刺啦刺啦的雪花屏记忆犹新,本期将用 pixi.js 来完成一个电视机播放动漫然后突然出现雪花屏的动画,里面主要讲解了如何使用pixi.js播放帧动画和如何用噪点滤镜制造雪花屏。

正文

初始化渲染

import * as PIXI from "pixi.js"
const GAME_WIDTH = 800;
const GAME_HEIGHT = 600;
export default class Game {
    constructor(el) {
        this.isOpen = false;
        return this.init(el)
    }
    init(el) {
        this.app = new PIXI.Application({
            width: GAME_WIDTH,
            height: GAME_HEIGHT,
            backgroundColor: 0x000000,
            antialias: true,
            clearBeforeRender: true,
            antialias: true,
            autoDensity: true,
            resolution: window.devicePixelRatio || 1,
        });
        el.appendChild(this.app.view);
        this.loader = new PIXI.Loader();
        this.loader
            .add("tv", "./assets/SnowflakeScreen/TV.png")
            .load(this.render.bind(this))
        return this;
    }
    render(loader, resources) {
        // 渲染
        this.resources = resources;
        // 创建容器
        this.container = new PIXI.Container();
        this.container.interactive = true;
        this.container.buttonMode = true;
        this.app.stage.addChild(this.container);
        this.tv = this.drawTV();
        this.container.addChild(this.tv);
    }
    drawTV() {
        // 绘制电视机
        let tv = PIXI.Sprite.from(this.resources.tv.texture);
        tv.anchor.set(0.5);
        tv.position.set(GAME_WIDTH / 2, GAME_HEIGHT / 2)
        tv.scale.set(.7, .7)
        tv.zIndex = 9;
        return tv;
    }
}

初始化就是创建 pixi.js 应用,然后把生成后的视图追加到要传入的 el 元素节点上。这里我们还要先加载一张电视机png格式的图片。加载完这张图后,我们才会执行 render 方法进行渲染。先创建主容器 container 并添加到场景舞台中,同时开启 interactive 为了可以给他下面的元素设置 zIndex 来改变图层优先级。 然后就用刚加载的电视机图片的纹理图变成图片精灵添加到主容器中,就这样电视机就绘制到屏幕中央了。

雪花屏动画

实现雪花屏动画之前先来绘制一个电视屏幕:

export default class Game {
	render(loader, resources) {
        // 渲染
        // ...
        this.noise = this.drawNoise()
        this.noise.visible = true
        this.container.addChild(this.noise);
    }
    drawNoise() {
        let noise = new PIXI.Graphics()
        noise.beginFill(0xffffff, .55)
        noise.drawRect(105, 100, 450, 360)
        noise.zIndex = 1
        return noise;
    }
}

其实就是一个简单的白色透明矩形矩形放置在电视机之下。

然后,接下来就是在这个半透明矩形上用噪点滤镜,就可以出现雪花效果:

this.noise.filters = [new PIXI.filters.NoiseFilter(.6, Math.random())]

里面可以传两个值,第一个值代表了噪声强度应为范围[0,1],第二个值则是用于噪声生成的随机量,感兴趣的可以看它具体的 shader 实现

当然,现在画面虽然是雪花,但是它还不会动,非常简单,我们只要在每次渲染时改变它就好了。

export default class Game {
	render(loader, resources) {
        // 渲染
        // ...
        this.noise.filters = []
        this.app.ticker.add(this.step.bind(this));
    }
    step() {
        this.noise.filters = [new PIXI.filters.NoiseFilter(.6, Math.random())]
    }
}

帧动画播放

先要准备好播放的帧动画图片:

export default class Game {
	render(loader, resources) {
        // 渲染
        // ...
       	this.video = this.drawVideo()
        this.container.addChild(this.video);
    }
	drawVideo() {
        let textureList = []
        for (let i = 1; i <= 28; i++) {
            let texture = PIXI.Texture.from(`assets/SnowflakeScreen/video/ezgif-frame-${(i + "").padStart(3, 0)}.jpg`);
            textureList.push(texture);
        };
        const video = new PIXI.AnimatedSprite(textureList);
        video.anchor.set(.5, .5)
        video.position.set(GAME_WIDTH / 2, GAME_HEIGHT / 2 - 10)
        video.scale.set(.48, .48)
        video.loop = false;
        video.animationSpeed = .16
        return video;
    }
}

我们把这28张图片先生成纹理图,按照顺序保存到一个数组里面,然后可以把这个数组传入一个实例化的 AnimatedSprite 类中,里面可以控制它的大小位置是否循环或者播放速度等信息,添加到容器里就可以自动播放啦。

export default class Game {
	render(loader, resources) {
        // 渲染
        // ...
        this.video.visible = false;
        this.video.onComplete = () => {
            this.video.visible = false;
            this.noise.visible = true
        }
        this.container.on('pointerdown', (e) => {
            if(!this.isOpen){
                this.isOpen = true;
                this.video.visible = true;
                this.noise.visible = false
                this.video.gotoAndPlay(0)
            }
            else{
                this.isOpen = false;
                this.noise.filters.length = 0
                this.video.visible = false;
                this.noise.visible = true;
            }
        })
    }
    step() {
        if(!this.isOpen) return;
        this.noise.filters = [new PIXI.filters.NoiseFilter(.6, Math.random())]
    }
}

最后加入一些逻辑比如播放完开启雪花屏,容器点击后播放动画等,非常快速的就可以实现这个电视机播放动漫然后突然出现雪花屏的动画效果了。

以上就是JavaScript Canvas实现噪点滤镜回忆童年电视雪花屏的详细内容,更多关于JavaScript Canvas 噪点滤镜的资料请关注我们其它相关文章!

时间: 2022-09-18

JS前端可视化canvas动画原理及其推导实现

目录 前言 动画的本质 动画的实现 动画的推导 小结 前言 到目前为止我们的 fabric.js 雏形已经有了,麻雀虽小五脏俱全,我们不仅能够在画布上自由的添加物体,同时还实现了点选和框选,并且能够对它们做一些变换,不过只有变换这个操作还不够灵活,要是能够让物体动起来就好了,于是就引入了这个章节的主题:动画,以及动画最核心的一个问题,如何保证在不同的电脑上达到同样的动画效果?然后说干就干,立马开撸. 虽然我写的是系列文章,但每个章节单独食用是木问题的,所以,请放心大胆的看

JS前端以轻量fabric.js实现示例理解canvas

目录 缘起 fabric.js 初体验 fabric.js 的大体结构 canvas 能干嘛? 小结 缘起 最近想系统看下 canvas 这个东西,所以找了一个库看看,本来打算写一两篇文章沉淀一下,发现东西有点多

JS前端使用canvas实现物体的点选示例

目录 前言 hover 的实现 click 的实现 矩形的坐标哪来的 点在多边形内的其他判断方法 穿透 本章小结 前言 上个章节中我们已经给物体加上了被选中的效果,现在可以上点交互了,这个章节主要实现的就是物体的 hover 和 click 事件,当鼠标 hover 到物体上时,我们会改变鼠标的样式使其变成移动的样子: 当 hover 到控制点时则会变成对应的操作样式: 当 click 物体时,会将物体变成激活态,也就是展示边框和控制点.话不多说,直接开撸 hover 的实现 首先我们来处理鼠标

JS前端使用canvas实现扩展物体类和事件派发

目录 前言 FabricImage 图片类 事件派发 小结 前言 虽然我们讲了这么多个章节,但其实目前为止就只有一个 Rect 类能用,略显单调.于是乎,为了让整个画布稍微生动一些,这个章节我们来尝试增加一个图片类,如果你以后需要扩展一个物体类,也是用同样的方法. 另外有时候我们还希望在物体属性改变时或者画布创建后做一些额外的事情,这个时候事件系统就派上用场啦,也就是我们常说的发布订阅,我觉的这是前端应用最广的设计模式没有之一了

JS前端canvas交互实现拖拽旋转及缩放示例

目录 正文 拖拽 旋转 缩放 小结 正文 到目前为止,我们已经能够对物体进行点选和框选的操作了,但是这还不够,因为并没有什么实际性的改变,并且画布看起来也有点呆板,所以这个章节的主要目的就是让画布中的物体活起来,其实就是增加一些常见的交互而已啦,比如拖拽.旋转和缩放.这是这个系列最重要的章节之一,希望能够对你有所帮助. 拖拽 先来说说拖拽平移的实现吧,因为它最为简单

JS前端使用canvas搞一个手势识别

目录 前言 具体步骤 第一步:手势绘制 第二步:重新取样 第二步:平移 第三步:旋转 第四步:缩放 第五步:手势录入 第六步:比较(重点) 注意事项 比较的基本套路(可跳过) 关于多笔画(可跳过) 小结 前言 最近在看一些关于图形学的东西,写了个一笔画手势识别的小 demo,效果大概是下面这个样子: 如果你是初次看过肯定会觉得很有意思

JS前端使用canvas编写一个签名板

目录 需求 方案分析canvas 涉及知识点 代码 以上代码,未开发的点 需求 需求是做不完了,福利也被砍了,旅游也泡汤了,手上有2个需求,还没做完,PM就来新需求了. 开发一个签名板:要求PC端/移动端都能用.扫码签名.实时同步.可以改变笔画粗细.笔画颜色.可以生成base64图片. 方案分析canvas 1.获取页面[canvas]元素,设置宽高(800*200) 2.通过**HTMLCanvasElement.getContext()**  方法返回[canvas] 的上下文ctx 3.初

JS前端使用Canvas快速实现手势解锁特效

目录 前言 Demo 需要实现的功能 初始化数据和页面渲染 touchstart 手指开始触摸事件 touchmove 监听手指滑动事件 touchend 监听手指触摸结束事件 页面滚动处理 连接的两颗星星之间有其他星星时 前言 之前在公司开发活动项目的时候,遇到一个项目需求要让用户使用手势画星位图来解锁星座运势,一看设计稿,这不就是我们平时的手机屏幕解锁吗?于是上网搜了一些关于手势解锁的文章,没找到可以直接复用的,于是只能自己打开canvas教程,边学习边设计实现了这个功能,同时兼容了移动端和

JS前端使用canvas动态绘制函数曲线示例详解

目录 前言 第一步:绘制坐标系 1.如何确定 x 轴和 y 轴的边界值 2.不是传入多少网格数就是多少网格 3.如何让坐标原点位于画布中心 4.刻度总是会有浮点数 第二步:画函数曲线 第三步:绘制辅助线和交点坐标 第四步:平移 第五步:缩放 第六步:动态绘制曲线 第七步:模糊到高清 前言 不说废话,我们直入主题.先来看看读了这篇文章你将得到什么,就是下面这个东西啦(是不是很清晰很顺滑): 那具体要做什么呢,我们来简单拆解一下步骤: 绘制坐标系 绘制多条函数曲线 绘制辅助线和坐标点 支持平移.缩放

JS前端基于canvas给图片添加水印

前两天给个人网站添加了一个小功能,就是在文章编辑上传图片的时候自动给图片加上水印.给网页图片添加水印是个常见的功能,也是互联网内容作者保护自己版权的方法之一.本文简单记录一下借助canvas在前端实现图片添加水印的实现方法. canvas元素其实就是一个画布,我们可以很方便地绘制一些文字.线条.图形等,它也可以将一个img标签里渲染的图片画在画布上. 在上传文件到后端的时候,使用input标签读取用户本地文件后得到的其实是一个Blob对象(更精确的说是File对象,特殊的Blob对象):而在页面

JS前端绘图canvas模糊问题示例高清图解

目录 缘起 模糊的原因 1.canvas 的大小和 css 的大小不一致 2.当绘制的东西不足 1px,会自动补足 1px 3.受到高清屏的影响 结语 缘起 模糊在 canvas 中应该算是个经典问题了,相信大家也曾经看过很多相关文章,但总是记不住,因为概念很多,描述的也不够明确,所以我就自己总结了一篇,刨去了复杂概念,顺带画了几张高清图,以此加深理解(我觉得画的贼好,记不住就来打我). 模糊的原因 总的来说模糊的原因大致可分为以下三点: 1.canvas 的大小和 css 的大小不一致 首先让

原生js基于canvas实现一个简单的前端截图工具代码实例

这篇文章主要介绍了原生js基于canvas实现一个简单的前端截图工具代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 先看效果 代码如下 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title></title> <style type="text/css"> *{