美文网首页
vue 移动端 canvas 触摸板

vue 移动端 canvas 触摸板

作者: 村南一枝花 | 来源:发表于2019-08-21 14:11 被阅读0次

    需求

    通过canvas来实现触摸板来写下一些题目的解题步骤,然后使用设备是手机跟pad

    代码

    vue

    <template>
      <canvas id="canvas" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove"></canvas>
    </template>
    

    js

    export default {
      data() {
        return {
          ctx: '',
          point: {
            x: 0,
            y: 0
          }
        }
      },
      mounted() {
        this.init()
      },
      methods: {
        /**
         * @description: canvas 初始化
         * @param {type}
         * @return:
         */
        init() {
          const canvas = document.getElementById('canvas')
          this.ctx = canvas.getContext('2d')
          this.ctx.strokeStyle = '#474E60'
          this.ctx.lineWidth = 1
        },
        /**
         * @description: 获取相对坐标
         * @param {type}
         * @return:
         */
        absolutePoint(event) {
          const touch = event.targetTouches[0]
          const canvas = document.getElementById('canvas')
          const react = canvas.getBoundingClientRect()
          this.point = { x: touch.pageX - react.left, y: touch.pageY - react.top }
        },
        /**
         * @description: 绘制
         * @param {type}
         * @return:
         */
        draw(event) {
          this.ctx.lineTo(this.point.x, this.point.y)
          this.ctx.stroke()
        },
        /**
         * @description: 开始触摸
         * @param {type}
         * @return:
         */
        touchstart(event) {
          this.absolutePoint(event)
          this.ctx.moveTo(this.point.x, this.point.y)
        },
        /**
         * @description: 触摸结束
         * @param {type}
         * @return:
         */
        touchend(event) {},
        /**
         * @description: 触摸移动
         * @param {type}
         * @return:
         */
        touchmove(event) {
          this.absolutePoint(event)
          this.draw(event)
        }
      }
    }
    

    效果图

    old.gif

    问题

    触摸坐标跟画图坐标不符,然后线条模糊

    解决方案

    在init方法里边重置canvas的高宽

        /**
         * @description: canvas 初始化
         * @param {type}
         * @return:
         */
        init() {
          const canvas = document.getElementById('canvas')
          const width = canvas.offsetWidth // ++
          const height = canvas.offsetHeight // ++
          this.ctx = canvas.getContext('2d')
          canvas.width = width // ++
          canvas.height = height // ++
          this.ctx.strokeStyle = '#474E60'
          this.ctx.lineWidth = 1
        },
    

    问题原因

    canvas 的宽高属性是必须通过属性设置的,因为需求原因,我的canvas通过父元素进行100%设置,通过重置canvas高宽可以解决问题。

    完整实例

    new.gif

    完整代码

    <template>
      <canvas id="canvas" @touchstart="touchstart" @touchend="touchend" @touchmove="touchmove"></canvas>
    </template>
    
    <script>
    export default {
      data() {
        return {
          ctx: '',
          point: {
            x: 0,
            y: 0
          }
        }
      },
      mounted() {
        this.init()
      },
      methods: {
        /**
         * @description: canvas 初始化
         * @param {type}
         * @return:
         */
        init() {
          const canvas = document.getElementById('canvas')
          const width = canvas.offsetWidth
          const height = canvas.offsetHeight
          this.ctx = canvas.getContext('2d')
          canvas.width = width
          canvas.height = height
          this.ctx.strokeStyle = '#474E60'
          this.ctx.lineWidth = 1
        },
        /**
         * @description: 获取相对坐标
         * @param {type}
         * @return:
         */
        absolutePoint(event) {
          const touch = event.targetTouches[0]
          const canvas = document.getElementById('canvas')
          const react = canvas.getBoundingClientRect()
          this.point = { x: touch.pageX - react.left, y: touch.pageY - react.top }
        },
        /**
         * @description: 绘制
         * @param {type}
         * @return:
         */
        draw(event) {
          this.ctx.lineTo(this.point.x, this.point.y)
          this.ctx.stroke()
        },
        /**
         * @description: 开始触摸
         * @param {type}
         * @return:
         */
        touchstart(event) {
          this.absolutePoint(event)
          this.ctx.moveTo(this.point.x, this.point.y)
        },
        /**
         * @description: 触摸结束
         * @param {type}
         * @return:
         */
        touchend(event) {},
        /**
         * @description: 触摸移动
         * @param {type}
         * @return:
         */
        touchmove(event) {
          this.absolutePoint(event)
          this.draw(event)
        }
      }
    }
    </script>
    

    ps: 实例是以组件形式存在

    相关文章

      网友评论

          本文标题:vue 移动端 canvas 触摸板

          本文链接:https://www.haomeiwen.com/subject/wwvbsctx.html