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 相关文章推荐
Javascript 类与静态类的实现
Apr 01 Javascript
javascript实现json页面分页实例代码
Feb 20 Javascript
jquery.validate.js插件使用经验记录
Jul 02 Javascript
js中不同的height, top的区别对比
Sep 24 Javascript
javascript Promise简单学习使用方法小结
May 17 Javascript
JS图片放大效果简单实现代码
Sep 08 Javascript
JQuery实现table中tr上移下移的示例(超简单)
Jan 08 jQuery
关于echarts在节点显示动态数据及添加提示文本所遇到的问题
Apr 20 Javascript
vue 解决addRoutes多次添加路由重复的操作
Aug 04 Javascript
React实现阿里云OSS上传文件的示例
Aug 10 Javascript
js定时器出现第一次延迟的原因及解决方法
Jan 04 Javascript
vue中控制mock在开发环境使用,在生产环境禁用方式
Apr 06 Vue.js
uniapp开发小程序的经验总结
JS新手入门数组处理的实用方法汇总
Apr 07 #Javascript
vue backtop组件的实现完整代码
一文帮你理解PReact10.5.13源码
JS一分钟在github+Jekyll的博客中添加访问量功能的实现
给原生html中添加水印遮罩层的实现示例
html实现随机点名器的示例代码
You might like
使用php 获取时间今天明天昨天时间戳的详解
2013/06/20 PHP
关于js和php对url编码的处理方法
2014/03/04 PHP
PHP下的Oracle客户端扩展(OCI8)安装教程
2014/09/10 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
JavaScript 函数调用规则
2009/09/14 Javascript
js使用ajax读博客rss示例
2014/05/06 Javascript
jQuery中[attribute*=value]选择器用法实例
2014/12/31 Javascript
jQuery中DOM树操作之使用反向插入方法实例分析
2015/01/23 Javascript
详解AngularJS中$http缓存以及处理多个$http请求的方法
2016/02/06 Javascript
JQuery日期插件datepicker的使用方法
2016/03/03 Javascript
jQuery实现滚动条滚动到子元素位置(方便定位)
2017/01/08 Javascript
AngularJs中 ng-repeat指令中实现含有自定义指令的动态html的方法
2017/01/19 Javascript
jQuery中的on与bind绑定事件区别实例详解
2017/02/28 Javascript
JavaScript Canvas绘制圆形时钟效果
2020/08/20 Javascript
Vue.js 2.0学习教程之从基础到组件详解
2017/04/24 Javascript
windows系统下更新nodejs版本的方案
2017/11/24 NodeJs
JavaScript数据结构之单链表和循环链表
2017/11/28 Javascript
基于vue-cli vue-router搭建底部导航栏移动前端项目
2018/02/28 Javascript
vue elementui 实现搜索栏公共组件封装的实例代码
2020/01/20 Javascript
Vue双向数据绑定(MVVM)的原理
2020/10/03 Javascript
跟老齐学Python之坑爹的字符编码
2014/09/28 Python
python文件读写操作与linux shell变量命令交互执行的方法
2015/01/14 Python
python实现根据窗口标题调用窗口的方法
2015/03/13 Python
python之pymysql模块简单应用示例代码
2019/12/16 Python
python学生信息管理系统实现代码
2019/12/17 Python
Django 5种类型Session使用方法解析
2020/04/29 Python
使用darknet框架的imagenet数据分类预训练操作
2020/07/07 Python
15款Python编辑器的优缺点,别再问我“选什么编辑器”啦
2020/10/19 Python
Python中openpyxl实现vlookup函数的实例
2020/10/28 Python
浅析移动设备HTML5页面布局
2015/12/01 HTML / CSS
台湾最大银发乐活百货:乐龄网
2018/05/21 全球购物
日本卡普空电视游戏软件公司官方购物网站:e-CAPCOM
2018/07/17 全球购物
加大码胸罩、内裤和服装:Just My Size
2019/03/21 全球购物
Brasty波兰:香水、化妆品、手表网上商店
2019/04/15 全球购物
365 Tickets英国:全球景点门票
2019/07/06 全球购物
Java 获取Word中所有的插入和删除修订的方法
2022/04/06 Java/Android