Canvas进阶-4、边界检测(流光,鼠标拖尾)

1. 什么是边界检测?

在之前的开发中,物体在运动过程中一旦超出画布,就会消失,今天学习如何去检测是否碰到了边界,碰到边界后又会有哪些处理的办法。

边界检测,就是物体运动的限制范围。边界检测的范围,既可以是画布的某个区域,也可以是整个画布。

下面是一个代码示例:


html 复制代码
 <canvas id="myCanvas"></canvas>
js 复制代码
 init() {
      //定义一个球
      class Ball {
        constructor(x, y) {
          this.x = x
          this.y = y
          this.radius = 10 //球的半径
          this.color = 'red' 
        }
        fill(context) {
          context.beginPath()
          context.arc(this.x, this.y, this.radius, 0, Math.PI * 2)
          context.fillStyle = this.color
          context.fill()
          context.closePath()
        }
      }
      const cnv = document.getElementById('myCanvas')
      const cxt = cnv.getContext('2d')
      // 初始化一个小球
      const ball = new Ball(0, cnv.height / 2)
      const vx = 2

      ;(function frame() {
        window.requestAnimationFrame(frame)
        //绘制前一定要重置
        cxt.clearRect(0, 0, cnv.width, cnv.height)
        ball.x += vx
       
        if (ball.x > cnv.width + ball.radius) {
          // 完全超出右边界
          ball.x = -ball.radius
        }
        ball.fill(cxt)
      })()
    },

看图理解边界限制,什么是边界?

js 复制代码
        if (ball.x < ball.radius) {
          //半径大于圆心绘制点
          console.log('小球碰到了左边界')
        } else if (ball.x > cnv.width - ball.raduis) {
          //圆心绘制点大于canvas-半径(球的圆边)
          console.log('小球碰到了右边界')
        }
        if (ball.y < ball.radius) {
          console.log('小球碰到了上边界')
        } else if (ball.y > cnv.height - ball.raduis) {
          console.log('小球碰到了下边界')
        }
        if (ball.x < -ball.radius) {
          console.log('完全超出左边界')
        } else if (ball.x > cnv.width + ball.radius) {
          console.log('完全超出右边界')
        }

        if (ball.y < -ball.radius) {
          console.log('完全超出上边界')
        } else if (ball.y > cnv.height + ball.radius) {
          console.log('完全超出下边界')
        }

2.如何利用边界?进阶应用

上图为超出边界线消失,下图只要我们稍稍调整,就成为一个简单的鼠标拖尾,就是如此简单

js 复制代码
 init1() {
      class Ball {
        constructor(x, y, color, radius) {
          this.x = x
          this.y = y
          this.radius = radius
          this.color = color
          this.vx = Math.random() * 3 - 1 // 添加随机速度
          this.vy = Math.random() * 3 - 1
          this.opacity = 1
          this.lifeTime = 400 // 添加生命周期属性(毫秒)
          this.birthTime = Date.now() // 记录小球创建的时间
        }
        fill(context) {
          context.save()
          context.globalAlpha = this.opacity
          context.beginPath()
          context.arc(this.x, this.y, this.radius, 0, Math.PI * 2)
          context.fillStyle = this.color
          context.fill()
          context.closePath()
          context.restore()
        }
      }

      function getMouse(element) {
        let mouse = { x: 0, y: 0 }
        element.addEventListener('mousemove', e => {
          mouse.x = e.clientX - element.getBoundingClientRect().left // 使用clientX和getBoundingClientRect计算鼠标位置
          mouse.y = e.clientY - element.getBoundingClientRect().top
        })
        return mouse
      }

      var cnv = document.getElementById('myCanvas1')
      var ctx = cnv.getContext('2d')
      var mouse = getMouse(cnv)

      const getRandomColor = () => {
        return '#' + Math.floor(Math.random() * 16777215).toString(16)
      }

      let balls = []

      cnv.addEventListener('mousemove', () => {
        // 生成新小球
        const ball = new Ball(mouse.x, mouse.y, getRandomColor(), 2)
        balls.push(ball)
      })

      function frame() {
        window.requestAnimationFrame(frame)
        ctx.clearRect(0, 0, cnv.width, cnv.height)
        balls.forEach((ball, index) => {
          const remainingLifeTime = ball.lifeTime - (Date.now() - ball.birthTime)
          if (remainingLifeTime <= 0) {
            balls.splice(index, 1)
          } else {
            // 否则,根据剩余生命周期计算透明度
            ball.opacity = remainingLifeTime / ball.lifeTime
            ball.fill(ctx)
            ball.x += ball.vx
            ball.y += ball.vy
          }
        })
      }

      frame()
    }

到此canvas进阶边界检测学习结束,道阻且长,行则将至。与诸君共勉。 ⭐️

相关推荐
徐子颐9 分钟前
从 Vibe Coding 到 Agent Coding:Cursor 2.0 开启下一代 AI 开发范式
前端
开心-开心急了12 分钟前
pyside6实现win10自动切换主题
开发语言·python·pyqt·pyside
小月鸭21 分钟前
如何理解HTML语义化
前端·html
沐知全栈开发36 分钟前
Foundation 模态框
开发语言
jump68044 分钟前
url输入到网页展示会发生什么?
前端
wjs20241 小时前
CSS 导航栏
开发语言
诸葛韩信1 小时前
我们需要了解的Web Workers
前端
brzhang1 小时前
我觉得可以试试 TOON —— 一个为 LLM 而生的极致压缩数据格式
前端·后端·架构
共享家95271 小时前
Qt窗口教程(上)
开发语言·qt
yivifu1 小时前
JavaScript Selection API详解
java·前端·javascript