5分钟实现Canvas鼠标跟随动画背景


Posted in HTML / CSS onNovember 18, 2019

关于Canvas制作炫酷背景,我会在git上不定时去更新,并会附上详细的解析,如果有喜欢的话,可以到git上瞧瞧

gitHub传送门

前言

相信很多前端小白都看过这样的背景动画,也好奇如何去实现这种效果!将这种效果应用到自己的个人网站上,会让整个网站变得与众不同!

5分钟实现Canvas鼠标跟随动画背景 

下面我会直击重点,用最短的时间,使用 Canvas 制作 鼠标跟随动画

 如何制作动画

常用的绘图动画的方式有以下几种:

  • CSS3
  • SVG
  • Canvas
  • WebGL

让我们先分析分析这些方法的优劣性

  • CSS3 通过css3的关键帧等方式实现动画效果,看起来好像挺实用,但这样增加了一个没有意义的DOM节点,不符合语义化编程规范
  • SVG、Canvas 都可以使用脚本语言来实现动画
    • SVG 本质上是使用XML描述2D图形的语言(矢量图),SVG创建的每一个元素都是一个独立的DOM元素,既然是独立的DOM元素,那表示我们可以通过CSS和JS来控制DOM,也可以对每一个DOM元素进行监听,但由于都是DOM元素,所以如果我们修改了SVG中的DOM元素,浏览器就会自动进行DOM重绘
    • Canvas通过Javascript来绘制2D图形(位图),而Canvas只是一个HTML元素,其中的图形不会单独创建DOM元素,所以我们无法通过Js来操作Canvas内的图形,也无法监听具体图形
  • WebGL 用于3D展示、动画、游戏,说白了就是基于Canvas的3D框架

 Canvas、SVG适用场景

  • Canvas 适用于位图,高数据量绘制频率的场景,小游戏,小特效,绘制图表、活动页面、炫酷背景
  • SVG 适用于矢量图,低数据量绘制频率的场景,如图形图表

直击重点,制作鼠标跟随动画

最终效果

5分钟实现Canvas鼠标跟随动画背景

需求分析:鼠标移动,经过的地方创建一个圆,圆的半径大小由小变大,达到某个固定大小时该圆消失,圆的颜色随机变化

创建全屏Canvas元素

var canvas = document.getElementById('canvas'),
    ctx = canvas.getContext('2d'),
    WIDTH = canvas.width = document.documentElement.clientWidth,
    HEIGHT = canvas.height = document.documentElement.clientHeight,
    para = {
        num: 100,
        color: false,    //  颜色  如果是false 则是随机渐变颜色
        radius: 0.9,          //   圆每次增加的半径 
        o: 0.09,         //      判断圆消失的条件,数值越大,消失的越快
    },
    color,
    circleColor,
    round_arr = [];     // 存放圆的数组

监听鼠标 onmousemove 事件

需求:在鼠标移动的过程中,不断在鼠标滑过的位置产生一个逐渐变大的圆

Canvas中创建动画的方式就是不断的清除屏幕然后重绘

由于移动的轨迹是由一个个圆构成,那我们就应该使用数组存储圆的信息(xy坐标,半径),然后在鼠标移动的时候将鼠标的位置信息存放在数组中

所以监听onmousemove事件就是为了拿到鼠标的信息

window.onmousemove = function(event) {
    X = event.clientX  // 当前在屏幕的x位置
    Y = event.clientY  // 当前在屏幕的y位置

    // 将信息存入圆数组
    round_arr.push({
        X:X,
        Y:Y,
        radius:para.radius
        o:1
    })
}

设置 color

在onmousemove中,我们已经将坐标信息和半径存入round_arr圆数组中,接下来就设置颜色了

在para对象里,默认的color是false,说明圆的颜色是随机的,如果color不为false,则圆的颜色就为color的颜色

if(para.color){
    circleColor = para.color
}else{
    color = Math.random() * 360
}

若想要设置颜色渐变
if (!para.color) {
    color += .1;
    circleColor = 'hsl(' + color + ',100%,80%)';
}

如果要让颜色变化,则需要将颜色变化的代码放在一个会一直执行的函数

定义 animation() 函数 !important

function animate() {

    if (!para.color) {         # 设置颜色
        color += .1
        color2 = 'hsl(' + color + ',100%,80%)'
    }

    ctx.clearRect(0, 0, WIDTH, HEIGHT)      # 清除屏幕

    for (var i = 0; i < round_arr.length; i++) {

        ctx.fillStyle = circleColor 
        ctx.beginPath()
        ctx.arc( round_arr[i].X ,round_arr[i].Y,round_arr[i].radius,0, Math.PI * 2)     # 画圆
        ctx.closePath()
        ctx.fill()
        round_arr[i].radius += para.radius    # 增大半径
        round_arr[i].o -= para.o    # 消失快慢

        if( round_arr[i].o <= 0){       # 移除圆
            round_arr.splice(i,1)
            i--
        }
    }

    window.requestAnimationFrame(animate)   # 使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用
}

requestAnimationFrame()会告诉浏览器,你需要执行动画,并请求浏览器调用指定的函数在下一次重绘之前更新动画。requestAnimationFrame()使用一个回调函数作为参数,这个回调函数会在浏览器重绘之前调用

完整代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>鼠标屏幕互动动画</title>
    <style>
        * {
            padding: 0;
            margin: 0;
        }
        
        #canvas {
            background: #000;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
    <script>
        var canvas = document.getElementById('canvas'),
            ctx = canvas.getContext('2d'),
            WIDTH = canvas.width = document.documentElement.clientWidth,
            HEIGHT = canvas.height = document.documentElement.clientHeight,
            para = {
                num: 100,
                color: false, //  颜色  如果是false 则是随机渐变颜色
                radius: 0.9,
                o: 0.09, //  判断圆消失的条件,数值越大,消失的越快
            },
            color,
            circleColor,
            round_arr = [];

        window.onmousemove = function(event) {
            X = event.clientX
            Y = event.clientY

            round_arr.push({
                X: X,
                Y: Y,
                radius: para.radius,
                o: 1
            })
        }

        // 判断参数中是否设置color,设置则使用该color,否则为随机
        if (para.color) {
            circleColor = para.color
        } else {
            color = Math.random() * 360
        }

        function animate() {
            if (!para.color) {
                color += .1
                circleColor = 'hsl(' + color + ',100%,80%)'
            }

            ctx.clearRect(0, 0, WIDTH, HEIGHT) // 清除屏幕

            for (var i = 0; i < round_arr.length; i++) {
                ctx.fillStyle = circleColor
                ctx.beginPath() // 开始路径
                ctx.arc(round_arr[i].X, round_arr[i].Y, round_arr[i].radius, 0, Math.PI * 2) // 画圆
                ctx.closePath() // 结束路径
                ctx.fill()
                round_arr[i].radius += para.radius // 增大圆
                round_arr[i].o -= para.o //  消失时间变快

                if (round_arr[i].o <= 0) {
                    round_arr.splice(i, 1);
                    i--;
                }
            }

            window.requestAnimationFrame(animate)
        }

        animate()
    </script>
</body>

</html>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

HTML / CSS 相关文章推荐
Web前端绘制0.5像素的几种方法
Aug 11 HTML / CSS
CSS3控制HTML元素动画效果
Feb 08 HTML / CSS
纯CSS和jQuery实现的在页面顶部显示的进度条效果2例(仿手机浏览器进度条效果)
Apr 16 HTML / CSS
CSS3实现圆角、阴影、透明效果并兼容各大浏览器
Aug 08 HTML / CSS
简单总结CSS3中视窗单位Viewport的常见用法
Feb 04 HTML / CSS
CSS3实现大小不一的粒子旋转加载动画
Apr 21 HTML / CSS
实例讲解CSS3中Transform的perspective属性的用法
Apr 22 HTML / CSS
CSS3弹性盒模型flex box快速入门心得(必看篇)
May 24 HTML / CSS
CSS3 animation ? steps 函数详解
Aug 30 HTML / CSS
Canvas引入跨域的图片导致toDataURL()报错的问题的解决
Sep 19 HTML / CSS
浅谈css清除浮动(clearfix和clear)的用法
May 21 HTML / CSS
HTML5实现无刷新修改URL的方法
Nov 14 #HTML / CSS
iframe跨域的几种常用方法
Nov 11 #HTML / CSS
Canvas环形饼图与手势控制的实现代码
Nov 08 #HTML / CSS
Html5监听手机摇一摇事件的实现
Nov 07 #HTML / CSS
解决HTML5中的audio在手机端和微信端的不能自动播放问题
Nov 04 #HTML / CSS
详解使用postMessage解决iframe跨域通信问题
Nov 01 #HTML / CSS
跨域修改iframe页面内容详解
Oct 31 #HTML / CSS
You might like
PHP常用代码
2006/11/23 PHP
PHP中的函数-- foreach()的用法详解
2013/06/24 PHP
WordPress中用于更新伪静态规则的PHP代码实例讲解
2015/12/18 PHP
PHP实现的浏览器检查类
2016/04/11 PHP
PHP中ajax无刷新上传图片与图片下载功能
2017/02/21 PHP
WordPress伪静态规则设置代码实例
2020/12/10 PHP
js版本A*寻路算法
2006/12/22 Javascript
JS实现清除指定cookies的方法
2014/09/20 Javascript
JavaScript中实现异步编程模式的4种方法
2014/09/24 Javascript
JavaScript实现表格点击排序的方法
2015/05/11 Javascript
jQuery使用serialize()表单序列化时出现中文乱码问题的解决办法
2016/07/27 Javascript
React学习笔记之条件渲染(一)
2017/07/02 Javascript
使用MUI框架模拟手机端的下拉刷新和上拉加载功能
2017/09/04 Javascript
javascript变量提升和闭包理解
2018/03/12 Javascript
基于vue实现可搜索下拉框定制组件
2020/03/26 Javascript
浅谈HTTP 缓存的那些事儿
2018/10/17 Javascript
js实现星星打分效果
2020/07/05 Javascript
vue-router 按需加载 component: () =&gt; import() 报错的解决
2020/09/22 Javascript
Python continue语句用法实例
2014/03/11 Python
python实现的阳历转阴历(农历)算法
2014/04/25 Python
浅析python 中__name__ = '__main__' 的作用
2014/07/05 Python
完美解决python中ndarray 默认用科学计数法显示的问题
2018/07/14 Python
对numpy中数组转置的求解以及向量内积计算方法
2018/10/31 Python
Python-numpy实现灰度图像的分块和合并方式
2020/01/09 Python
python利用JMeter测试Tornado的多线程
2020/01/12 Python
英国高街品牌:Miss Selfridge(塞尔弗里奇小姐)
2016/09/21 全球购物
教育科研先进个人材料
2014/01/26 职场文书
《最可爱的人》教学反思
2014/02/14 职场文书
培训主管的职业生涯规划
2014/03/06 职场文书
社区维稳工作方案
2014/06/06 职场文书
2014年信用社工作总结
2014/11/25 职场文书
元旦主持词开场白
2015/05/29 职场文书
离职信范文
2015/06/23 职场文书
2015年基层党建工作汇报材料
2015/06/25 职场文书
导游词之南京莫愁湖公园
2019/11/13 职场文书
Windows Server 2012 R2服务器安装与配置的完整步骤
2022/07/15 Servers