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 相关文章推荐
CSS实现的一闪而过的图片闪光效果
Apr 23 HTML / CSS
纯css3实现鼠标经过图片显示描述的动画效果
Sep 01 HTML / CSS
利用CSS3的border-radius绘制太极及爱心图案示例
May 17 HTML / CSS
使用CSS3 制作一个material-design 风格登录界面实例
Dec 12 HTML / CSS
利用CSS3动画实现圆圈由小变大向外扩散的效果实例
Sep 10 HTML / CSS
详解基于 Canvas 手撸一个六边形能力图
Sep 02 HTML / CSS
详解Html5中video标签那些属性和方法
Jul 01 HTML / CSS
HTML5 Canvas旋转动画的2个代码例子(一个旋转的太极图效果)
Apr 10 HTML / CSS
HTML5 Canvas中使用用路径描画圆弧
Jan 01 HTML / CSS
【HTML5】3D模型--百行代码实现旋转立体魔方实例
Dec 16 HTML / CSS
canvas实现圆形进度条动画的示例代码
Dec 26 HTML / CSS
小程序实现悬浮按钮的全过程记录
Oct 16 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
无线电广播的开始
2002/01/30 无线电
用Flash图形化数据(二)
2006/10/09 PHP
php合并js请求的例子
2013/11/01 PHP
浅析PHP中strlen和mb_strlen的区别
2014/08/31 PHP
PHP实现的简单三角形、矩形周长面积计算器分享
2014/11/18 PHP
PHP中实现Bloom Filter算法
2015/03/30 PHP
PHP操作mysql数据库分表的方法
2016/06/09 PHP
php简单计算年龄的方法(周岁与虚岁)
2016/12/06 PHP
PHP静态成员变量
2017/02/14 PHP
Yii2框架操作数据库的方法分析【以mysql为例】
2019/05/27 PHP
JS短路原理的应用示例 精简代码的途径
2013/12/13 Javascript
jQuery事件绑定和委托实例
2014/11/25 Javascript
Javascript发送AJAX请求实例代码
2016/08/21 Javascript
Vue axios 中提交表单数据(含上传文件)
2017/07/06 Javascript
深入理解Node.js中通用基础设计模式
2017/09/19 Javascript
vue.js项目中实用的小技巧汇总
2017/11/29 Javascript
利用js实现前后台传送Json的示例代码
2018/03/29 Javascript
微信小程序wx:for和wx:for-item的用法详解
2018/04/01 Javascript
原生js实现form表单序列化的方法
2018/08/02 Javascript
Easyui 去除jquery-easui tab页div自带滚动条的方法
2019/05/10 jQuery
微信小程序将页面按钮悬浮固定在底部的实现代码
2020/10/29 Javascript
[05:11]TI9战队采访——VIRTUSPRO
2019/08/22 DOTA
跟老齐学Python之list和str比较
2014/09/20 Python
简单介绍Python中用于求最小值的min()方法
2015/05/15 Python
python2.7实现FTP文件下载功能
2018/04/15 Python
Linux CentOS Python开发环境搭建教程
2018/11/28 Python
详解python statistics模块及函数用法
2019/10/27 Python
Python3爬虫发送请求的知识点实例
2020/07/30 Python
python 线程的五个状态
2020/09/22 Python
用纯CSS3实现网页中常见的小箭头
2017/10/16 HTML / CSS
39美元购买一副眼镜或太阳镜:39DollarGlasses.com
2018/06/17 全球购物
求职信模板标准格式范文
2014/02/23 职场文书
护士节慰问信
2015/02/15 职场文书
2015年数学教师工作总结
2015/05/20 职场文书
国王的演讲观后感
2015/06/03 职场文书
Python first-order-model实现让照片动起来
2022/06/25 Python