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 渐变(Gradients)之CSS3 线性渐变
Jul 08 HTML / CSS
css3制作彩色边线3d立体按钮的示例(css3按钮)
May 06 HTML / CSS
css3类选择器之结合元素选择器和多类选择器用法
Mar 09 HTML / CSS
html5 touch事件实现触屏页面上下滑动(二)
Mar 10 HTML / CSS
HTML5的文档结构和新增标签完全解析
Apr 21 HTML / CSS
HTML5在IE10、火狐下中文乱码问题的解决方法
Nov 18 HTML / CSS
Html5无刷新修改browser Url的方法
Jan 15 HTML / CSS
使用iframe+postMessage实现页面跨域通信的示例代码
Jan 14 HTML / CSS
详解HTML5常用的语义化标签
Sep 27 HTML / CSS
详解如何解决H5开发使用wx.hideMenuItems无效果不生效
Jan 20 HTML / CSS
Canvas在超级玛丽游戏中的应用详解
Feb 06 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创建、获取cookie及基础要点分析
2015/01/26 PHP
Expandable &quot;Detail&quot; Table Rows
2007/08/29 Javascript
Tips 带三角可关闭的文字提示
2010/10/06 Javascript
JQuery之拖拽插件实现代码
2011/04/14 Javascript
JavaScript的Module模式编程深入分析
2013/08/13 Javascript
jquery如何实现锚点链接之间的平滑滚动
2013/12/02 Javascript
JavaScript实现生成GUID(全局统一标识符)
2014/09/05 Javascript
node.js中的querystring.unescape方法使用说明
2014/12/10 Javascript
JavaScript判断一个字符串是否包含指定子字符串的方法
2015/03/18 Javascript
javascript中$(function() {});写与不写有哪些区别
2015/08/10 Javascript
jquery实现的判断倒计时是否结束代码
2016/02/05 Javascript
Node.js连接postgreSQL并进行数据操作
2016/12/18 Javascript
js点击任意区域弹出层消失实现代码
2016/12/27 Javascript
详细分析JS函数去抖和节流
2017/12/05 Javascript
Vue 页面切换效果之 BubbleTransition(推荐)
2018/04/08 Javascript
mpvue跳转页面及注意事项
2018/08/03 Javascript
Element Table的row-class-name无效与动态高亮显示选中行背景色
2018/11/30 Javascript
React Native中Mobx的使用方法详解
2018/12/04 Javascript
vuex vue简单使用知识点总结
2019/08/29 Javascript
构建Vue大型应用的10个最佳实践(小结)
2019/11/07 Javascript
Vue路由守卫及页面登录权限控制的设置方法(两种)
2020/03/31 Javascript
antd form表单数据回显操作
2020/11/02 Javascript
Python3实现发送QQ邮件功能(文本)
2017/12/15 Python
Keras-多输入多输出实例(多任务)
2020/06/22 Python
银行门卫岗位职责
2013/12/29 职场文书
迟到检讨书400字
2014/01/13 职场文书
迟到检讨书1000字
2014/01/15 职场文书
新学期开学演讲稿
2014/05/24 职场文书
绿色环保标语
2014/06/12 职场文书
党员公开承诺书2015
2015/01/21 职场文书
六一领导慰问欢迎词
2015/01/26 职场文书
食品安全责任书范本
2015/05/09 职场文书
微信小程序实现聊天室功能
2021/06/14 Javascript
基于Redis zSet实现滑动窗口对短信进行防刷限流的问题
2022/02/12 Redis
《艾尔登法环》1.03.3补丁上线 碎星伤害调整
2022/04/06 其他游戏
Go web入门Go pongo2模板引擎
2022/05/20 Golang