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 相关文章推荐
css3中背景尺寸background-size详解
Sep 02 HTML / CSS
css3动画效果小结(推荐)
Jul 25 HTML / CSS
浅谈pc和移动端的响应式的使用
Jan 03 HTML / CSS
HTML5样式控制示例代码
Nov 27 HTML / CSS
五个2015 年最佳HTML5 框架
Nov 11 HTML / CSS
Html5实现移动端、PC端 刮刮卡效果
Jun 30 HTML / CSS
canvas裁剪clip()函数的具体使用
Mar 01 HTML / CSS
详解webapp页面滚动卡顿的解决办法
Dec 26 HTML / CSS
html+css实现分层金字塔的实例
Jun 02 HTML / CSS
div与span之间的区别与使用介绍
Dec 06 HTML / CSS
css中有哪些方式可以隐藏页面元素及区别
Jun 16 HTML / CSS
CSS浮动引起的高度塌陷问题
Aug 05 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
绿山咖啡和蓝山咖啡
2021/03/04 新手入门
php字符串截取中文截取2,单字节截取模式
2007/12/10 PHP
PHP实现UTF-8文件BOM自动检测与移除实例
2014/11/05 PHP
PHP判断数据库中的记录是否存在的方法
2014/11/14 PHP
php+ajax实现异步上传文件或图片功能
2017/07/18 PHP
java解析json方法总结
2019/05/16 PHP
Expandable &quot;Detail&quot; Table Rows
2007/08/29 Javascript
鼠标经过的文本框textbox变色
2009/05/21 Javascript
JS获取dom 对象 ajax操作 读写cookie函数
2009/11/18 Javascript
json原理分析及实例介绍
2012/11/29 Javascript
JQuery的read函数与js的onload不同方式实现
2013/03/18 Javascript
JavaScript数组深拷贝和浅拷贝的两种方法
2014/04/16 Javascript
流量统计器如何鉴别C#:WebBrowser中伪造referer
2015/01/07 Javascript
Angular.js回顾ng-app和ng-model使用技巧
2016/04/26 Javascript
jQuery siblings()用法实例详解
2016/04/26 Javascript
jquery动态添加文本并获取值的方法
2016/10/12 Javascript
JS获得多个同name 的input输入框的值的实现方法
2017/01/09 Javascript
js常用DOM方法详解
2017/02/04 Javascript
JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法
2017/04/28 Javascript
Vue 2.0学习笔记之Vue中的computed属性
2017/10/16 Javascript
JavaScript之创意时钟项目(实例讲解)
2017/10/23 Javascript
解决Vue 通过下表修改数组,页面不渲染的问题
2018/03/08 Javascript
浅谈React 服务器端渲染的使用
2018/05/08 Javascript
[54:27]TNC vs Serenity 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
用python分割TXT文件成4K的TXT文件
2009/05/23 Python
python处理xml文件的方法小结
2017/05/02 Python
Django内容增加富文本功能的实例
2017/10/17 Python
Python设计模式之迭代器模式原理与用法实例分析
2019/01/10 Python
画pytorch模型图,以及参数计算的方法
2019/08/17 Python
使用python代码进行身份证号校验的实现示例
2019/11/21 Python
pytorch点乘与叉乘示例讲解
2019/12/27 Python
Python使用monkey.patch_all()解决协程阻塞问题
2020/04/15 Python
Dockers美国官方网站:卡其裤、男士服装、鞋及配件
2016/11/22 全球购物
Volcom法国官网:美国冲浪滑板品牌
2017/05/25 全球购物
班干部演讲稿
2014/04/24 职场文书
vue实力踩坑之push当前页无效
2022/04/10 Vue.js