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进阶边界检测学习结束,道阻且长,行则将至。与诸君共勉。 ⭐️

相关推荐
2501_9159184110 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
程序员的世界你不懂10 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
索迪迈科技10 小时前
网络请求库——Axios库深度解析
前端·网络·vue.js·北京百思可瑞教育·百思可瑞教育
gnip10 小时前
JavaScript二叉树相关概念
前端
lingchen190611 小时前
MATLAB的数值计算(三)曲线拟合与插值
开发语言·matlab
gb421528711 小时前
java中将租户ID包装为JSQLParser的StringValue表达式对象,JSQLParser指的是?
java·开发语言·python
一朵梨花压海棠go11 小时前
html+js实现表格本地筛选
开发语言·javascript·html·ecmascript
蒋星熠11 小时前
Flutter跨平台工程实践与原理透视:从渲染引擎到高质产物
开发语言·python·算法·flutter·设计模式·性能优化·硬件工程
attitude.x11 小时前
PyTorch 动态图的灵活性与实用技巧
前端·人工智能·深度学习
β添砖java11 小时前
CSS3核心技术
前端·css·css3