Canvas进阶-1、事件操作及动画

在Canvas开发中,常见的事件有三种:鼠标事件、键盘事件、循环事件,有了这些事件,我们便可以开发出交互性更强的动画.

1. 鼠标事件

鼠标事件分为3种:鼠标按下 mousedown、鼠标松开 mouseup、鼠标移动 mousemove

获取鼠标指针位置

我们可以通过 pageX与pageY这两个属性来确定鼠标指针当前位置,然后再结合画布相对于文档的偏移距离,我们就可以确定鼠标在画布中的相对坐标

请添加图片描述

<canvas id="myCanvas" width="500" height="200"></canvas>
<div id="text"></div>
<div id="text1"></div>
<div id="text2"></div>
//获取鼠标指针位置
getMouse(element) {
      let mouse = { x: 0, y: 0 } // 存储鼠标位置信息
      element.addEventListener('mousemove', e => {
        let x = e.pageX
        let y = e.pageY
        // 计算鼠标在canvas画布中的相对位置
        mouse.x = x - element.offsetLeft
        mouse.y = y - element.offsetTop
      })
      return mouse
    },
//绘制
init() {
      var canvas = document.getElementById('myCanvas')
      var ctx = canvas.getContext('2d')

      var isDragging = false
      var startX, startY, offsetX, offsetY
      var rect = { x: 50, y: 50, width: 100, height: 100 }

      function draw() {
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        ctx.fillRect(rect.x, rect.y, rect.width, rect.height)
      }
      // 鼠标移动 mousemove
      var mouse = this.getMouse(canvas)
      canvas.addEventListener('mousemove', event => {
        document.getElementById('text').innerHTML = `鼠标坐标为:${mouse.x}, ${mouse.y}`
        if (isDragging) {
          var x = event.offsetX
          var y = event.offsetY
          rect.x = x + offsetX
          rect.y = y + offsetY
          draw()
        }
      })
      // 鼠标按下 mousedown
      canvas.addEventListener('mousedown', event => {
        document.getElementById('text1').innerHTML = `鼠标坐标为:${mouse.x}, ${mouse.y}`
        var x = event.offsetX
        var y = event.offsetY
        if (x >= rect.x && x <= rect.x + rect.width && y >= rect.y && y <= rect.y + rect.height) {
          isDragging = true
          startX = x
          startY = y
          offsetX = rect.x - startX
          offsetY = rect.y - startY
        }
      })
      // 鼠标松开 mouseup
      canvas.addEventListener('mouseup', () => {
        document.getElementById('text2').innerHTML = `鼠标坐标为:${mouse.x}, ${mouse.y}`
        isDragging = false
      })
    },

2. 键盘事件

在Canvas开发中,常用的键盘事件有两个:

  1. 键盘按下 keydown
  2. 键盘松开 keyup

因为Canvas本身无法绑定键盘事件,所以实际开发中我们是监听window键盘事件来实现的。

//type为字符串类型,指的是事件类型。
window.addEventListener(type, fn, false)

请添加图片描述

在javaScript中,我们使用keyCode来判断用户按下了哪个键,在这里我们只列出Canvas开发中常用的几个keyCode。

按键keyCode
W8738
S8340
A6537
D6839
// 键盘事件
    getKey() {
      //封装键盘事件方法
      // window.addEventListener(type, fn, false)
      let key = {}
      window.addEventListener(
        'keydown',
        e => {
          if (e.keyCode === 38 || e.keyCode === 87) {
            key['direction'] = 'up'
          } else if (e.keyCode === 39 || e.keyCode === 68) {
            key['direction'] = 'right'
          } else if (e.keyCode === 40 || e.keyCode === 83) {
            key['direction'] = 'down'
          } else if (e.keyCode === 37 || e.keyCode === 65) {
            key['direction'] = 'left'
          } else {
            key['direction'] = null
          }
        },
        false
      )
      return key
    },
    // 键盘按下 keydown   // 键盘松开 keyup
   init1() {
      var canvas = document.getElementById('myCanvas1')
      var ctx = canvas.getContext('2d')
      // 绘制小球
      const drawBall = (x, y, ctx) => {
        ctx.beginPath()
        ctx.arc(x, y, 20, 0, (360 * Math.PI) / 180, true)
        ctx.closePath()
        ctx.fillStyle = 'blue'
        ctx.fill()
      }
      // 初始化小球
      let x = 20
      let y = 20
      drawBall(x, y, ctx)
      // 获取按键方向
      const key = this.getKey()
      window.addEventListener(
        'keydown',
        e => {
          // 每次绘制前清空画布
          ctx.clearRect(0, 0, canvas.width, canvas.height)
          // 根据事件重绘小球
          switch (key['direction']) {
            case 'up':
              y -= 2
              break
            case 'down':
              y += 2

              break
            case 'left':
              x -= 2
              break
            case 'right':
              x += 2
              break
            default:
              break
          }
          drawBall(x, y, ctx)
        },
        false
      )
    },

3. 循环事件

在Canvas中,我们使用 requestAnimationFrame()来实现循环, 确保绘制帧率。

盯着看一会,会出现一个正五边形哦

请添加图片描述

 // 循环事件
    init2() {
      var canvas = document.getElementById('myCanvas2')
      var ctx = canvas.getContext('2d')

      let angle = 0
      const amplitude = 50 // 振幅,控制曲线的弯曲程度
      const frequency = 0.02 // 频率,控制曲线的周期
      const speed = 10 // 速度,控制矩形移动的快慢

      ;(function frame() {
        window.requestAnimationFrame(frame)
        // 清除整个画布
        ctx.clearRect(0, 0, canvas.width, canvas.height)
        // 计算新位置
        const x = canvas.width / 2 + Math.sin(angle) * amplitude
        const y = canvas.height / 2 + Math.cos(angle) * amplitude
        // 绘制矩形
        ctx.beginPath()
        ctx.arc(x - 25, y, 25, 25, (360 * Math.PI) / 180, true)
        ctx.fill()
        // 更新角度以改变矩形的位置
        angle += speed
        // 当矩形到达边界时,改变方向
        if (x <= 0 || x >= canvas.width) {
          speed = -speed
        }
      })()
    }

到此canvas进阶事件及动画学习结束,道阻且长,行则将至。与诸君共勉。 ⭐️

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值