跟随鼠标炫彩小球

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

实现效果

超级炫酷

实现原理

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

实现过程

创建小球

通过创建函数收纳小球所有的样式,再通过实例化函数,将鼠标当前的位置传递给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 的元素,删除
}
}
}

渲染画布

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

  1. 清除画布
  2. 遍历数组,获取到所有小球的信息,渲染到画布上
  3. 不断的重复调用,更新小球信息
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>

更多阅读

充电水波摇晃效果
旋转水滴加载效果
抖音超火的罗盘时钟效果
圆盘时钟效果
文字抖动效果
旋转魔方效果
文字闪烁效果
加载动画效果
炫彩流光按钮
原生js轮播图效果
文字折叠效果

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

  1. [js高手之路]html5 canvas动画教程 - 跟着鼠标移动消失的一堆炫彩小球

    综合利用前面所学,实现一个绚丽的小球动画,这个实例用到的知识点,在我的博客全部都有,可以去这里查看所有的canvas教程 <head> <meta charset='utf-8' / ...

  2. 超多经典 canvas 实例,动态离子背景、移动炫彩小球、贪吃蛇、坦克大战、是男人就下100层、心形文字等等等

    超多经典 canvas 实例 普及:<canvas> 元素用于在网页上绘制图形.这是一个图形容器,您可以控制其每一像素,必须使用脚本来绘制图形. 注意:IE 8 以及更早的版本不支持 &l ...

  3. html5跟随鼠标炫酷网站引导页动画特效

    html5跟随鼠标炫酷网站引导页动画特效一款非常不错的引导页,文字效果渐变,鼠标跟随出绚丽的条纹.html5炫酷网站引导页,鼠标跟随出特效. 体验效果:http://hovertree.com/tex ...

  4. HTML5 canvas画布写炫彩动态的倒计时效果

    html代码如下,插入了2个js代码. <!DOCTYPE html> <html> <head> <title>canvas</title> ...

  5. 面向对象原生JavaScript案例炫彩小球

    面向对象其实对于初学者来说还是比较难以理解的,以前看到一个面试题目 面向对象是什么? 面向对象是一种思想,千万别入坑了: 这次给大家带来的是一个鼠标移动产生小球的案例,不是我不想给大家分享如何去认识面 ...

  6. java-js知识库之二——canvas绘制炫彩气泡

    现在使用canvas绘制气泡,虽说很多人都已经实现过了,可能方法都大同小异,但自己写和看别人写完全是两码事,自己会写的才是自己的,话不多说,直接上代码. 先来一张效果图: 现在上代码,代码有详细的注释 ...

  7. JS打造的跟随鼠标移动的酷炫拓扑图案

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  8. HTML5自学笔记[ 19 ]canvas绘图实例之炫彩时钟

    <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...

  9. canvas实现跟随鼠标旋转的箭头

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta ht ...

随机推荐

  1. commons-pool2 池化技术探究

    一.前言 我们经常会接触各种池化的技术或者概念,包括对象池.连接池.线程池等,池化技术最大的好处就是实现对象的重复利用,尤其是创建和使用大对象或者宝贵资源(HTTP连接对象,MySQL连接对象)等方面 ...

  2. python 迭代器,生成器,表达式

    1.迭代器 (1)什么是迭代器: #迭代器即迭代的工具,那什么是迭代呢?#迭代是一个重复的过程,每次重复即一次迭代,并且每次迭代的结果都是下一次迭代的初始值 while True: #只是单纯地重复, ...

  3. (数据科学学习手札119)Python+Dash快速web应用开发——多页面应用

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 这是我的系列教程Python+Dash快速web ...

  4. NumPy之:结构化数组详解

    目录 简介 结构化数组中的字段field 结构化数据类型 创建结构化数据类型 从元组创建 从逗号分割的dtype创建 从字典创建 操作结构化数据类型 Offsets 和Alignment Field ...

  5. hdu4496并查集的删边操作

    题意:       给你一个图,问你删除一些边后还有几个连通快.. 思路:       典型的并查集删边操作,并查集的删边就是先把不删除的边并查集一边(本题没有不删除的边),然后逆序吧所有要删除的边以 ...

  6. Win64 驱动内核编程-2.基本框架(安装.通讯.HelloWorld)

    驱动安装,通讯,Hello World 开发驱动的简单流程是这样,开发驱动安装程序,开发驱动程序,然后安装程序(或者其他程序)通过通讯给驱动传命令,驱动接到之后进行解析并且执行,然后把执行结果返回. ...

  7. MS06-040漏洞研究(中)【转载】

    课程简介 经过上次的分析,我们已经知道了MS06-040漏洞的本质,那么这次我们就通过编程实现漏洞的利用. 课程介绍 实验环境: 操作机: Windows XP 实验工具: Tools Path ID ...

  8. <JVM中篇:字节码与类的加载篇>01-Class字节码文件结构

    笔记来源:尚硅谷JVM全套教程,百万播放,全网巅峰(宋红康详解java虚拟机) 同步更新:https://gitee.com/vectorx/NOTE_JVM https://codechina.cs ...

  9. Openstack 虚拟机宽带限速

    修改Neutron配置文件,使其支持Qos 修改Neutron.conf service_plugins = neutron.services.qos.qos_plugin.QoSPlugin 修改p ...

  10. MySQL模糊查询,查询语句是对的。但是就是没有查询结果

    问题 解决 当我用其他非中文的值去查询,发现可以查询到结果 所以问题就出现在数据库的配置中 spring.datasource.url=jdbc:mysql://localhost:3306/data ...