基于 canvas 一款非常酷炫的动态气泡背景实现方法

发布于 2020-05-22

基于 canvas 一款非常酷炫的动态气泡背景实现方法

canvas 是 HTML5 新增的标签,利用它我们可以轻松实现图形的绘制。canvas 元素本身并没有绘制能力,它只是一个图形的容器,必须使用脚本(通常是 JavaScript)配合来完成绘图任务。今天为大家分享一下基于 canvas 动态气泡背景的实现方法。

 实现方式

将下面的内容保存为 .js 文件,然后在网页中引入即可。

document.writeln("<div id=\'bubble\' style=\'width:100%;height:100%;position:fixed;top:0;left:0;z-index:-1;\'></div>");

class BGBubble {
    constructor(opts) {
        this.defaultOpts = {
            id: '',                 // 容器ID
            num: 100,               // 个数
            start_probability: 0.1, // 如果数量小于num,有这些几率添加一个新的
            radius_min: 1,          // 初始半径最小值
            radius_max: 2,          // 初始半径最大值
            radius_add_min: .3,     // 半径增加最小值
            radius_add_max: .5,     // 半径增加最大值
            opacity_min: 0.3,       // 初始透明度最小值
            opacity_max: 0.5,       // 初始透明度最大值
            opacity_prev_min: .003, // 透明度递减值最小值
            opacity_prev_max: .005, // 透明度递减值最大值
            light_min: 40,          // 颜色亮度最小值
            light_max: 70,          // 颜色亮度最大值
            is_same_color: false,   // 泡泡颜色是否相同
            background: "#f1f3f4"
        }
        if (Object.prototype.toString.call(opts) == "[object Object]") {
            this.userOpts = {...this.defaultOpts, ...opts}
        } else {
            this.userOpts = {...this.defaultOpts, id: opts}
        }
        this.color = this.random(0, 360)
        this.bubbleNum = []
        this.requestAnimationFrame = window.requestAnimationFrame || window.mozRequestAnimationFrame || window.webkitRequestAnimationFrame || window.msRequestAnimationFrame
        this.cancelAnimationFrame = window.cancelAnimationFrame || window.mozCancelAnimationFrame
    }

    random(a, b) {
        return Math.random() * (b - a) + a //取a-b之间的随机值
    }

    initBubble(color, isSameColor) {
        const width = window.innerWidth
        const height = window.innerHeight
        const userOpts = this.userOpts
        const light = this.random(userOpts.light_min, userOpts.light_max)
        this.bubble = {
            x: this.random(0, width),
            y: this.random(0, height),
            radius: this.random(userOpts.radius_min, userOpts.radius_max),
            radiusChange: this.random(userOpts.radius_add_min, userOpts.radius_add_max),
            opacity: this.random(userOpts.opacity_min, userOpts.opacity_max),
            opacityChange: this.random(userOpts.opacity_prev_min, userOpts.opacity_prev_max),
            light,
            color: `hsl(${isSameColor ? color : this.random(0, 360)},100%,${light}%)`,
        }
    }

    bubbling(ctx, color, isSameColor) {
        !this.bubble && this.initBubble(color, isSameColor)
        const bubble = this.bubble
        ctx.fillStyle = bubble.color;
        ctx.globalAlpha = bubble.opacity;
        ctx.beginPath();
        ctx.arc(bubble.x, bubble.y, bubble.radius, 0, 2 * Math.PI, true);
        ctx.closePath();
        ctx.fill();
        ctx.globalAlpha = 1;
        bubble.opacity -= bubble.opacityChange;
        bubble.radius += bubble.radiusChange;
        if (bubble.opacity <= 0) {
            this.initBubble(color, isSameColor)
            return
        }
    }

    createCanvas() {
        this.canvas = document.createElement('canvas')
        this.ctx = this.canvas.getContext('2d')
        this.canvas.id = "bg_canvas";
        this.canvas.style.display = 'block' //防止全屏的canvas出现滚动条
        this.canvas.width = window.innerWidth
        this.canvas.height = window.innerHeight
        this.canvas.style.position = 'fixed'
        this.canvas.style.top = '0'
        this.canvas.style.left = '0'
        this.canvas.style.zIndex = '-1'
        document.getElementById(this.userOpts.id).appendChild(this.canvas)
        window.onresize = () => {
            this.canvas.width = window.innerWidth
            this.canvas.height = window.innerHeight
        }
    }

    start() {
        const width = window.innerWidth
        const height = window.innerHeight
        this.color += 0.1
        this.ctx.fillStyle = this.defaultOpts.background; //这里修改颜色hsl(${this.color},100%,97%)//rgba(255, 255, 255, 0)
        this.ctx.fillRect(0, 0, width, height);
        if (this.bubbleNum.length < this.userOpts.num && Math.random() < this.userOpts.start_probability) {
            this.bubbleNum.push(new BGBubble())
        }
        this.bubbleNum.forEach(bubble => bubble.bubbling(this.ctx, this.color, this.userOpts.is_same_color))
        const requestAnimationFrame = this.requestAnimationFrame
        this.myReq = requestAnimationFrame(() => this.start())
    }

    destory() {
        const cancelAnimationFrame = this.cancelAnimationFrame
        cancelAnimationFrame(this.myReq)
        window.onresize = null
    }
}

const bubbleDemo = new BGBubble('bubble')
bubbleDemo.createCanvas()
bubbleDemo.start()

效果预览

参数可以自行修改,完成后的预览效果如下:

结束语

利用 canvas 通过脚本我们可以绘制出各式各样的图形,本文简单分享了一下一款基于 canvas 标签非常酷炫的动态气泡背景的实现方法,如果大家喜欢的话可以添加到自己的网站上。如果有任何问题或建议,欢迎在下方评论处留言。

喜欢 1
奋楫笃行,臻于至善!

相关文章

基于 sketch.js 实现非常酷炫的鼠标点击特效

JavaScript 是浏览器端脚本语言,有许多非常实用的第三方 JS 类库,我们可以借助它来实现各种各样的特效,今天为大家分享一下基于 sketch.js 实现鼠标点击特效的方法。 实现方法 实现的...
阅读全文

网站夜间模式的实现思路与详细教程分享

网站夜间模式是怎样实现的? 整体思路 夜间模式开关按钮:用来手动切换夜间模式的,会存储cookie。 自动夜间模式:当cookie为空时,浏览器时间大于22点小于6点时会自动进入夜间模式,并存储coo...
阅读全文

pace.js 网页自动加载进度条 JavaScript 插件

我们在浏览网页的时候,经常会看到网站顶部有一个好看的加载进度条,我们可能会好奇它是怎样实现的。页面的加载进度百分比,有时候获取是比较麻烦的,当然也可以利用一些优秀的JavaScript插件来实现,今天...
阅读全文

Vue.js 开发环境搭建及实例运行简明教程

Vue和jQuery一样,是一个前端框架,如果你要问在过去的一年里,前端技术框架什么最火,那无疑就是前端三巨头:React、Angular和Vue。今天,我们就一起来简单了解一下什么是Vue,以及它的...
阅读全文

nofollow、noopener 和 noreferrer 的区别与联系

大家应该都知道rel='nofllow'的作用,它是告诉搜索引擎,不要将该链接计入权重。因此多数情况下,我们可以将一些不想传递权重的链接进行nofllow处理,例如一些非本站的链接,不想传递权重,但是...
阅读全文

使用 Prism.js 实现代码语法高亮

之前给大家推荐过两款代码高亮库,分别是 code-prettify 和 Crayon Syntax Highlighter,今天给大家推荐的是另一个代码高亮库Prism.js。 一、介绍 Prism...
阅读全文

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注