- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>canvas 版炫彩小球 </title>
- <!--
- -->
- <style>
- #canvas {
- border: 1px solid #000;
- /*background-color: #000;*/
- }
- </style>
- </head>
- <body>
- <canvas id="canvas" width="800" height="600"></canvas>
- <script>
- var canvas = document.getElementById('canvas')
- var ctx = canvas.getContext('2d')
- var ballList = []
- function Ball(x, y) {
- this.x = x
- this.y = y
- // 20 - 50
- this.r = Math.random() * 30 + 20
- this.color = 'rgb(' + Math.floor(Math.random() * 256) + ',' + Math.floor(Math.random() * 256) + ',' + Math.floor(Math.random() * 256) + ')'
- this.directionX = Math.random() * 10 - 5
- this.directionY = Math.random() * 10 - 5
- }
- Ball.prototype.update = function () {
- this.x += this.directionX
- this.y += this.directionY
- // 31 2
- this.r -= 2
- // console.log(this.r)
- // if (this.r <= 0) {
- //// 如果衰减的半径小球等于 0 了, 则把这个小球从数组中删除
- // var index = ballList.findIndex(function (item) {
- // return item === this
- // }.bind(this))
- // console.log(index)
- // ballList.splice(index, 1)
- // }
- }
- Ball.prototype.render = function () {
- ctx.beginPath()
- ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI)
- ctx.fillStyle = this.color
- ctx.fill()
- }
- // 鼠标在画布上移动的时候, 不断地产生小球
- canvas.onmousemove = function (e) {
- // 获取鼠标移动的坐标就是圆心的坐标
- ballList.push(new Ball(e.clientX, e.clientY))
- }
- // 动画主循环定时器
- // 1. 清除整个画布
- // 2. 更新每个小球的状态
- // x y r 运动衰减
- // 当半径衰减的 小于等于 0 的时候, 把小球从数组中删除
- // 3. 把更新过后的小球重新绘制到画布中
- window.setInterval(function () {
- // 注意: 动画原理: 一定要在重新绘制直线先清除整个画布
- ctx.clearRect(0, 0, canvas.width, canvas.height)
- // ballList.forEach(function (item) {
- //// 小球先 update 自己
- //// update 的过程可能会把自己删除, 一旦删除数组索引就错乱了
- //// 当数组索引错乱之后, 你再继续遍历就可能会把误删
- // item.update() // 小球自己更新自己
- // if (item) {
- // item.render() // 小球自己渲染自己
- // }
- // })
- // 如果在遍历数组的过程中删除元素, 不要使用 forEach 循环
- // 因为如果你在遍历的过程中删除了数组元素, 会导致索引错乱
- // 所以解决方法就是使用 for 循环, 在循环中当满足删除条件的时候, 把该元素从数组中删除, 同时记得维护循环变量 i 让它倒退一次
- // 这样做的话才能保证你的删除不会影响别的, 这才是最正确的删除的做法
- for (var i = 0; i <ballList.length; i++) {
- ballList[i].update()
- if (ballList[i].r <= 0) {
- ballList.splice(i, 1)
- i--
- // 结束该元素的循环处理, 处理下一个元素
- continue
- }
- ballList[i].render()
- }
- }, 1000 / 50)
- </script>
- </body>
- </html>
来源: http://www.qdfuns.com/article/50506/9d2435a39a6d3d5656894db092fb7d02.html