Canvas跟随鼠标炫彩小球的实现


Posted in Javascript onApril 11, 2021

跟随鼠标炫彩小球

canvas没有让我失望,真的很有意思

实现效果

超级炫酷

Canvas跟随鼠标炫彩小球的实现

实现原理

  • 创建小球
  • 给小球添加随机颜色,随机半径
  • 鼠标移动通过实例化,新增小球
  • 通过调用给原型新增的方法,来实现小球的动画效果
  • 通过定时器不断地更新画布

实现过程

创建小球

通过创建函数收纳小球所有的样式,再通过实例化函数,将鼠标当前的位置传递给Ball函数,让通过实例化创建出来的小球,最后将创建出来的小球存入数组中,数组中以对象形式存放着每个小球的属性和属性值

function Ball(x, y, r) {
    this.x = x;
    this.y = y;
    this.r = r;
    this.color = getRandom();//随机生成颜色
    this.dx = parseInt(Math.random() * 10) - 5;//生成随机移动的位置
    this.dy = parseInt(Math.random() * 10) - 5;//`-5`是让小球能向四周随机移动
    ballArr.push(this);//添加小球
}
//监听鼠标移动事件
canvas.addEventListener('mousemove', function (e) {
    new Ball(e.offsetX, e.offsetY, parseInt(Math.random() * 20));
    /*实例化Ball为Ball对象通过__proto__来调用原型的方法*/
})

生成随机颜色

对于color这个属性,可以通过6位16进制的值来表示一种颜色

因此,可以通过随机产生一个6位的16进制数来做为随机颜色

0到f这16个数存入数组中,通过随机生成6个0到16的索引值,这样就能通过数组的索引号随机的获取6个到0到f中的数了

split的作用是:以括号内的参数为标志符来分割字符串,返回数组

//设置随机颜色
function getRandom() {
    var allType = '0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f';//16进制颜色
    var allTypeArr = allType.split(',');//通过','分割为数组
    var color = '#';
    for (var i = 0; i < 6; i++) {
        //随机生成一个0-16的数
        var random = parseInt(Math.random() * allTypeArr.length);
        color += allTypeArr[random];
    }
    return color;//返回随机生成的颜色
}

渲染小球

给函数的原型链中添加render方法,让每一个通过Ball函数实例化出来的对象,带有这些方法

这个函数的作用是,通过Ball的参数生成一个圆形,在实例化的时候,会生成一个对象,这个对象里就存放的x,y,r这些值

Ball.prototype.render = function () {
    ctx.beginPath();//路径开始
    ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);//画圆,位置,半径
    ctx.fillStyle = this.color;//颜色
    ctx.fill();//填充
}

更新小球信息

因为生成的小球x,y,r是固定的,所以小球的位置也是固定的,不会改变

因此需要通过改变每个小球的位置和半径让小球动起来,当小球的半径小于0时,调用remove方法将小球从数组中删除

/* 更新小球位置和半径 小于0时清除 */
Ball.prototype.update = function () {
    this.x += this.dx;//x改变
    this.y += this.dy;//y改变
    this.r -= 0.1;//半径减小
    if (this.r < 0) {
        this.remove();//调用添加的remove方法
    }
}

删除小球

这是上面调用的remove方法,当this也就是当前小球半径小于0时i,遍历整个数组,找到这个this,也就是”这个小球“,通过调用数组中的方法,删除掉数组的这个元素

splice(index,num) 方法可删除从 index 处开始删除num个元素

Ball.prototype.remove = function () {
    for (var i = 0; i < ballArr.length; i++) {
        if (ballArr[i] == this) {
            ballArr.splice(i, 1);//找到这个小于0 的元素,删除
        }
    }
}

渲染画布

通过定时器,不断的更新画布,主要是这几个步骤

  • 清除画布
  • 遍历数组,获取到所有小球的信息,渲染到画布上
  • 不断的重复调用,更新小球信息
setInterval(function () {
    ctx.clearRect(0, 0, canvas.width, canvas.height);//清屏
    for (var i = 0; i < ballArr.length; i++) {
        ballArr[i].update();//更新小球
        if (ballArr[i]) {
            ballArr[i].render();//渲染小球
        }
    }
}, 20);

完整代码

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

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            background: black;
        }
        canvas {
            display: block;
            border: 1px solid black;
            margin: 0 auto;
        }
    </style>
</head>

<body>
    <canvas width="1000px" height="1000px" id="myCanvas">
        当前浏览器版本不支持,请升级浏览器
    </canvas>
    <script>
        var canvas = document.getElementById('myCanvas');
        var ctx = canvas.getContext('2d');
        //定义球的位置和半径
        function Ball(x, y, r) {
            this.x = x;
            this.y = y;
            this.r = r;
            this.color = getRandom();//随机生成颜色
            this.dx = parseInt(Math.random() * 10) - 5;//生成随机移动的位置
            this.dy = parseInt(Math.random() * 10) - 5;
            ballArr.push(this);//添加小球
        }
        /* 更新小球位置和半径 小于0时清除 */
        Ball.prototype.update = function () {
            this.x += this.dx;
            this.y += this.dy;
            this.r -= 0.1;
            if (this.r < 0) {
                this.remove();//调用添加的remove方法
            }
        }
        Ball.prototype.remove = function () {
            for (var i = 0; i < ballArr.length; i++) {
                if (ballArr[i] == this) {
                    ballArr.splice(i, 1);//找到这个小于0 的元素,删除
                }
            }
        }
        //渲染小球 画小球
        //在原型中添加方法
        Ball.prototype.render = function () {
            ctx.beginPath();//路径开始
            ctx.arc(this.x, this.y, this.r, 0, Math.PI * 2, false);//画圆,位置,半径
            ctx.fillStyle = this.color;//颜色
            ctx.fill();
        }
        //监听鼠标移动事件
        canvas.addEventListener('mousemove', function (e) {
            new Ball(e.offsetX, e.offsetY, parseInt(Math.random() * 20));
            //实例化Ball为Ball对象通过__proto__来调用原型的方法
            console.log(ballArr);
        })
        var ballArr = [];
        setInterval(function () {
            ctx.clearRect(0, 0, canvas.width, canvas.height);//清屏
            for (var i = 0; i < ballArr.length; i++) {
                ballArr[i].update();//更新小球
                if (ballArr[i]) {
                    ballArr[i].render();//渲染小球
                }
            }
        }, 20);
        //设置随机颜色
        function getRandom() {
            var allType = '0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f';//16进制颜色
            var allTypeArr = allType.split(',');//通过','分割为数组
            var color = '#';
            for (var i = 0; i < 6; i++) {
                var random = parseInt(Math.random() * allTypeArr.length);
                //随机生成一个0-16的数
                color += allTypeArr[random];
            }
            return color;//返回随机生成的颜色
        }
    </script>
</body>

</html>

到此这篇关于Canvas跟随鼠标炫彩小球的实现的文章就介绍到这了,更多相关Canvas跟随鼠标 内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章,希望大家以后多多支持三水点靠木!

 
Javascript 相关文章推荐
jQuery入门知识简介
Mar 04 Javascript
ASP.NET jQuery 实例9  通过控件hyperlink实现返回顶部效果
Feb 03 Javascript
javascript随机将第一个dom中的图片添加到第二个div中示例
Oct 08 Javascript
关于jquery的多个选择器的使用示例
Oct 18 Javascript
javascript实现左右控制无缝滚动
Dec 31 Javascript
JS实现的论坛Ajax打分效果完整实例
Oct 31 Javascript
vue-resource 拦截器使用详解
Feb 21 Javascript
jQuery.Sumoselect插件实现下拉复选框效果
Nov 09 jQuery
p5.js入门教程之键盘交互
Mar 19 Javascript
vue配置接口域名方法总结
May 12 Javascript
vue中 数字相加为字串转化为数值的例子
Nov 07 Javascript
Javascript数组及类数组相关原理详解
Oct 29 Javascript
uniapp开发小程序的经验总结
JS新手入门数组处理的实用方法汇总
Apr 07 #Javascript
vue backtop组件的实现完整代码
一文帮你理解PReact10.5.13源码
JS一分钟在github+Jekyll的博客中添加访问量功能的实现
给原生html中添加水印遮罩层的实现示例
html实现随机点名器的示例代码
You might like
上传多个文件的PHP脚本
2006/11/26 PHP
php写的简易聊天室代码
2011/06/04 PHP
利用PHP函数计算中英文字符串长度的方法
2014/11/11 PHP
PHP中的常见魔术方法功能作用及用法实例
2015/07/01 PHP
php利用smtp类实现电子邮件发送
2015/10/30 PHP
浅谈PHP中其他类型转化为Bool类型
2016/03/28 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
Prototype 1.5.0_rc1 及 Prototype 1.5.0 Pre0小抄本
2006/09/22 Javascript
基于jquery的tab切换 js原理
2010/04/01 Javascript
基于jquery实现图片广告轮换效果代码
2011/07/07 Javascript
Javascript设置对象的ReadOnly属性(示例代码)
2013/12/25 Javascript
jQuery之ajax删除详解
2014/02/27 Javascript
Bootstrap开发实战之响应式轮播图
2016/06/02 Javascript
jQuery实现的手风琴侧边菜单效果
2017/03/29 jQuery
20行js代码实现的贪吃蛇小游戏
2017/06/20 Javascript
gulp安装以及打包合并的方法教程
2017/11/19 Javascript
JavaScript canvas基于数组生成柱状图代码实例
2020/03/06 Javascript
vue 通过 Prop 向子组件传递数据的实现方法
2020/10/30 Javascript
Python字典操作简明总结
2015/04/13 Python
Python备份目录及目录下的全部内容的实现方法
2016/06/12 Python
python下如何查询CS反恐精英的服务器信息
2017/01/17 Python
老生常谈进程线程协程那些事儿
2017/07/24 Python
python用户评论标签匹配的解决方法
2018/05/31 Python
python logging重复记录日志问题的解决方法
2018/07/12 Python
python字典的遍历3种方法详解
2019/08/10 Python
执行Python程序时模块报错问题
2020/03/26 Python
Pytest框架之fixture的详细使用教程
2020/04/07 Python
亚马逊新加坡官方网站:Amazon.sg
2020/03/25 全球购物
大型活动策划方案
2014/01/12 职场文书
《跨越海峡的生命桥》教学反思
2014/02/24 职场文书
中层干部培训方案
2014/06/16 职场文书
大学运动会加油稿200字(5篇)
2014/09/27 职场文书
高三英语教学反思
2016/03/03 职场文书
Go 在 MongoDB 中常用查询与修改的操作
2021/05/07 Golang
Redis如何实现分布式锁
2021/08/23 Redis
css清除浮动clearfix:after的用法详解(附完整代码)
2023/05/21 HTML / CSS