跟随鼠标炫彩小球

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跟随鼠标 内容请搜索程序员的世界以前的文章或继续浏览下面的相关文章,希望大家以后多多支持程序员的世界!

Canvas跟随鼠标炫彩小球的实现的更多相关文章

  1. Jquery 格式化时间

    我们常常会通过datetime得到时间,但是网页前台往往会显示不同的时间如:2013-12-152013年12月23日2013 12 15等多种显示效果,这就需要我们把时间格式化一下。下面是通过Jquery格式化时间:$(function () { var time =......

  2. JavaScript实现页面动态验证码的实现示例

    引言:现在很多在用户登陆或注册的时候为了防止程序攻击,加入了动态验证的技术,一般是让用户输入随即生成的验证码来实现。我自己写了一个没有跟后台交互的,就在前端验证,发出来给大家看看。效果图: 实现思路:把数字和字母放到一个数组中,通过随机的方式取得数组下标,总共取4个组成验证码;把验证码渲染出来(......

  3. react实现Radio组件的示例代码

    本文旨在用最清楚的结构去实现一些组件的基本功能。希望和大家一起学习,共同进步效果展示:测试组件:class Test extends Component {constructor(props) {super(props)this.state = {active:1}}onGroupChange(va......

  4. js简单粗暴的发布订阅示例代码

    什么是发布/订阅?我打个比方,你去某个门店买衣服,你和门店店长相互并不认识,门店店长只管卖他的衣服,并不关心是谁来买,而你也只管买你想要的衣服,并不关心是哪个门店在卖,这时,门店和你就组成了一个发布/订阅的关系。当门店挂出衣服款式,你去找你想要的衣服,如果找到了,那就买下来,如果没找到,那就离开这家......

  5. JavaScript——深入了解this

    前言我曾以为func()其实就是window.func()function func(){console.log('this : ' + this);}func();//this : [object Window]window.func();//this : [object Window] 直到'u......

  6. JavaScript实现点击切换功能

    本文实例为大家分享了JavaScript实现点击切换功能的具体代码,供大家参考,具体内容如下在实际应用中,点击或者移入某一元素上,弹出下拉菜单或者页面,是网页设计的常见操作。下面我们实现一种点击菜单实现菜单切换,使用js提供三种方式实现该功能。1.使用html设计基本结构多Tab点击切换10元套餐3......

  7. JS数组去重的九种高阶方法(亲测有效)

    前言一般的方法此处也不列举了,还是有很多的,如双层循环判断是否相等,或新建数组比较再push等等,需要注意的是,使用splice方法移除元素时,有可能会导致数组塌陷问题,需要处理一下本文中介绍了多种数组去重的方法,使用了较多的高阶方法及API,并给出相应解释及语法,还有其他多种组合调用方式,原理逻辑......

  8. 原生JavaScript实现轮播图

    本文实例为大家分享了JavaScript实现轮播图的具体代码,供大家参考,具体内容如下效果:代码:* {margin: 0;padding: 0;}ul,li {list-style: none;}.banner {width: 1200px;height: 535px;border: 1px so......

  9. jquery表格插件Datatables使用、快速上手

    Datatables使用一、简介官网:https://datatables.net/ 中文官网:http://datatables.club/Datatables是一款jquery表格插件。它是一个高度灵活的工具,可以将任何HTML表格添加高级的交互功能。操作DOM的分页,即时搜索和排序,几乎支持任......

  10. jquery文本框内容改变事件

    /** * 内容改变时并不会触发事件,但是在失去焦点的时候会触发。*/$("#inputid").change(function(){ console.log($(this).val());});/** * 只要文本类容发生改变,就会触发该事件 */$("#inp......

随机推荐

  1. python 网页解析器掌握第三方 lxml 扩展库与 xpath 的使用方法

    今天说的则是使用另外一种扩展库 lxml 来对网页完成解析。同样的,lxml 库能完成对 html、xml 格式的文件解析,并且能够用来解析大型的文档、解析速度也是相对比较快的。要掌握 lxml 的使用,就需要掌握掌握 xpath 的使用方法,因为 lxml 扩展库就是基于 xpath 的,所以这一......

  2. 透过现象看本质:Java类动态加载和热替换

    摘要:本文主要介绍类加载器、自定义类加载器及类的加载和卸载等内容,并举例介绍了Java类的热替换。最近,遇到了两个和Java类的加载和卸载相关的问题:1) 是一道关于Java的判断题:一个类被首次加载后,会长期留驻JVM,直到JVM退出。这个说法,是不是正确的?2) 在开发的一个集成平台中,需要集成......

  3. 用Python发一封图文并茂的邮件

    最近使用了不少通讯工具的接口, 比如企业微信机器人,钉钉,微信公众号的接口(未认证的订阅公众号),相对于邮件来说,它们的表现形式太弱。比如没有更丰富的版本方式。当然了,并不是说表现形式越棒就是约好的通知手段,这个依个人情况而定,而我恰恰需要比较丰富的表现形式,最终还是回到了邮件,邮件真香!而个人微信......

  4. R语言变量的知识点总结

    变量为我们提供了我们的程序可以操作的命名存储。 R语言中的变量可以存储原子向量,原子向量组或许多Robject的组合。 有效的变量名称由字母,数字和点或下划线字符组成。 变量名以字母或不以数字后跟的点开头。变量名合法性原因var_name2.有效有字母,数字,点和下划线VAR_NAME%无效有字符'......

  5. 【应急响应】Windows应急响应入门手册

    0x01 应急响应概述首先我们来了解一下两个概念:应急响应和安全建设,这两者的区别就是应急响应是被动响应、安全建设是主动防御。所谓有因才有果,既然是被动的,那么我们在应急响应的时候就得先了解本次安全事件的起因,常见的有:安全设备告警、数据被勒索加密、数据泄露在网上贩卖、网页被篡改、服务器CPU爆满卡......

  6. vue backtop组件的实现完整代码

    效果:代码:<template><div class="back-top"><div ><img src="imgsrc" class="line" :class="isHide? 'is......

  7. python 使用OpenCV进行简单的人像分割与合成

    实现思路通过背景建模的方法,对源图像中的动态人物前景进行分割,再将目标图像作为背景,进行合成操作,获得一个可用的合成影像。实现步骤如下。使用BackgroundSubtractorMOG2进行背景分割BackgroundSubtractorMOG2是一个以高斯混合模型为基础的背景前景分割算法,混合高......

  8. MySQL全面瓦解17:触发器相关

    关于触发器现实开发中我们经常会遇到这种情况,比如添加、删除和修改信息的时候需要记录日志,我们就要在完成常规的数据库逻辑操作之后再去写入日志表,这样变成了两步操作,更复杂了。又比如删除一个人员信息的时候,需要将他的购物记录、收货地址、收藏夹等都删了,这个连续的操作容易出错,一致性和完整性不好保证。这时......

  9. 详解如何在ASP.NET Core Web API中以三种方式返回数据

    在 ASP.NET Core 中有三种返回 数据 和 HTTP状态码 的方式,最简单的就是直接返回指定的类型实例,如下代码所示:[ApiController][Route("[controller]")]public class WeatherForecastController......

  10. JavaScript canvas实现文字时钟

    本文实例为大家分享了canvas实现文字时钟的具体代码,供大家参考,具体内容如下 先看看效果图 代码 <!DOCTYPE html> <htmllang="en"> <head> <metacharset......