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的CSS 多栏(Multi-column)实现瀑布流源码分享
Jun 11 HTML / CSS
Css3圆角边框制作代码
Nov 18 HTML / CSS
css3实现蒙版弹幕功能
Jun 18 HTML / CSS
CSS3 实现发光边框特效
Nov 11 HTML / CSS
html5+CSS3+JS实现七夕言情功能代码
Aug 28 HTML / CSS
HTML5 Canvas实现平移/放缩/旋转deom示例(附截图)
Jul 04 HTML / CSS
使用jquery实现HTML5响应式导航菜单教程
Apr 02 HTML / CSS
html5 datalist标签使用示例(自动完成组件)
May 04 HTML / CSS
关于HTML5语义标签的实践(blog页面)
Jul 12 HTML / CSS
HTML5新特性之type=file文件上传功能
Feb 02 HTML / CSS
HTML5 新增内容和 API详解
Nov 17 HTML / CSS
el-form每行显示两列底部按钮居中效果的实现
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
php+mysql 实现身份验证代码
2010/03/24 PHP
PHP实现的博客欢迎提示功能(很特别哦)
2014/06/05 PHP
ThinkPHP快速入门实例教程之数据分页
2014/07/01 PHP
46 个非常有用的 PHP 代码片段
2016/02/16 PHP
PHP策略模式定义与用法示例
2017/07/27 PHP
PHP通过curl获取接口URL的数据方法
2018/05/31 PHP
Avengerls vs Newbee BO3 第一场2.18
2021/03/10 DOTA
经常用到的JavasScript事件的翻译
2007/04/09 Javascript
jquery下实现overlay遮罩层代码
2010/08/25 Javascript
博客侧边栏模块跟随滚动条滑动固定效果的实现方法(js+jquery等)
2013/03/24 Javascript
jQuery中fadeIn、fadeOut、fadeTo的使用方法(图片显示与隐藏)
2013/05/08 Javascript
JavaScript实现检查页面上的广告是否被AdBlock屏蔽了的方法
2014/11/03 Javascript
纯CSS3代码实现滑动开关效果
2015/08/19 Javascript
jQuery弹出窗口打开链接的实现代码
2016/12/24 Javascript
如何将百度地图包装成Vue的组件的方法步骤
2019/02/12 Javascript
jquery实现有过渡效果的tab切换
2020/07/17 jQuery
[03:04]DOTA2英雄基础教程 影魔
2013/12/11 DOTA
Python抓取Discuz!用户名脚本代码
2013/12/30 Python
python中的多重继承实例讲解
2014/09/28 Python
Python实现桶排序与快速排序算法结合应用示例
2017/11/22 Python
基于numpy.random.randn()与rand()的区别详解
2018/04/17 Python
python挖矿算力测试程序详解
2019/07/03 Python
Python3+Appium实现多台移动设备操作的方法
2019/07/05 Python
Python 实现遥感影像波段组合的示例代码
2019/08/04 Python
浅谈PyQt5中异步刷新UI和Python多线程总结
2019/12/13 Python
Python Tornado实现WEB服务器Socket服务器共存并实现交互的方法
2020/05/26 Python
纯CSS改变webkit内核浏览器的滚动条样式
2014/04/17 HTML / CSS
html5中去掉input type date默认样式的方法
2018/09/06 HTML / CSS
Html5移动端网页端适配(js+rem)
2021/02/03 HTML / CSS
Chemist Warehouse官方海外旗舰店:澳洲第一连锁大药房
2017/08/25 全球购物
开工仪式主持词
2014/03/20 职场文书
2015年科室工作总结
2015/04/10 职场文书
2019年警察入党转正申请书最新范文
2019/09/03 职场文书
2019个人工作自我评价范文(3篇)
2019/09/19 职场文书
Keras多线程机制与flask多线程冲突的解决方案
2021/05/28 Python
Tomcat安装使用及部署Web项目的3种方法汇总
2022/08/14 Servers