文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

vue使用canvas手写输入识别中文

2024-04-02 19:55

关注

效果图:

前言:

最近做一个室外大屏项目,系统上的输入法使用不方便,客户要求做一个嵌入web网页的手写输入法。

核心:

后端接口api:使用 QQ输入法手写接口

https://handwriting.shuru.qq.com/cloud/cgi-bin/cloud_hw_pub.wsgi

参数 说明 类型 默认值
track_str 笔画字符串,单笔画以'x1,y1,x2,y2,…‘格式拼接,多笔画在单笔画的基础上以eb拼接,例如'x1,y1,x2,y2,eb,x3,y3,x4,y4' string -
cmd 未知,目前传0 number -

注:此接口通过其他大佬文章获知,原文在此,本人未能查到官方文档相关地址,如果有大佬知晓还请留言告知,感谢!

思路:

(1)创建一个canvas绘图区域


// template
<div class="canvas-container">
 <canvas ref="canvas" width="300" height="200">你的浏览器不支持 canvas,请升级你的浏览器。</canvas>
</div>

// scss
.canvas-container {
 background: #fafafa;

 canvas {
 background: #fff;
  border: 1px solid #000;
 }
}


(2)获取初始横纵坐标


data() {
  return {
    initX: 0, // 初始横坐标
    initY: 0, // 初始纵坐标
  }
},
mounted() {
  this.initBound()
},
methods: {
  // 初始化canvas位置
  initBound() {
    let bound = this.$refs.canvas.getBoundingClientRect()
    this.initX = bound.x
    this.initY = bound.y
  }
}

(3)添加鼠标点击事件、移动事件、松开事件


// template
<div class="canvas-container">
 <canvas ref="canvas" width="300" height="200" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseup="onMouseUp">你的浏览器不支持 canvas,请升级你的浏览器。</canvas>
</div>
// script
data() {
  return {
    // ...
    
    lastX: 0, // 上一个横坐标
    lastY: 0, // 上一个纵坐标
    isHandWrite: false, // 是否开始手写
    pointsXY: [], // 单笔画
    allPointsXY: [], // 全部笔画
  }
},
methods: {
  onMouseDown(e) {
    this.pointsXY = []
    let cx = e.clientX - this.initX
    let cy = e.clientY - this.initY
    this.lastX = cx
    this.lastY = cy
    this.pointsXY.push(cx)
    this.pointsXY.push(cy)
    this.isHandWrite = true
  },
  onMouseMove(e) {
    if (this.isHandWrite) {
      let cx = e.clientX - this.initX
      let cy = e.clientY - this.initY
      this.pointsXY.push(cx - this.lastX)
      this.pointsXY.push(cy - this.lastY)
      // 获取2d上下文对象
      let ctx = this.$refs.canvas.getContext('2d')
      // 新建一条路径
      ctx.beginPath()
      ctx.strokeStyle = '#000'
      ctx.fillStyle = '#000'
      ctx.lineWidth = 8
      ctx.lineCap = 'round'
      ctx.moveTo(this.lastX, this.lastY)
      ctx.lineTo(cx, cy)
      ctx.stroke()
      this.lastX = cx
      this.lastY = cy
    }
  },
  onMouseUp(e) {
    if (this.isHandWrite) {
      this.isHandWrite = false
      this.allPointsXY.push(this.pointsXY.join(','))
      this.queryText() // 识别文字
    }
  },
}


(4)添加识别文字接口以及jsonp回调函数,跨域请求使用了 vue-jsonp ,具体用法可参vue中jsonp的使用方法


// script
data() {
  return {
    // ...
    
    write_result: [], // 返回相近字
  }
},
mounted() {
  // ...

  let _this = this
  // 添加jsonp回调函数, qq输入法特定
  window['QQShuru'] = {
    HWPanel: {
      ajax_callback: function (res) {
        _this.write_result = res.cand
      },
    },
  }
},
methods: {
  queryText() {
    let track_str = this.allPointsXY.join(',eb,')
    this.$jsonp(
      `https://handwriting.shuru.qq.com/cloud/cgi-bin/cloud_hw_pub.wsgi?track_str=${track_str}&cmd=0`
    ).catch(err => {
      console.log(err)
    })
  },
}


(5)最后再加个清除画布的重写按钮


// template
<div>
  <button @click="onReload">重写</button>
</div>

// script
onReload() {
  if (!this.$refs.canvas) return
  this.pointsXY = []
  this.allPointsXY = []
  let ctx = this.$refs.canvas.getContext('2d')
  ctx.clearRect(0, 0, 300, 200)
}

全部代码如下:


<template>
  <div id="app">
    <div class="canvas-container">
      <canvas ref="canvas" width="300" height="200" @mousedown="onMouseDown" @mousemove="onMouseMove" @mouseup="onMouseUp">你的浏览器不支持 canvas,请升级你的浏览器。</canvas>
    </div>
    <div>[{{ lastX + ', ' + lastY }}]</div>
    <div>
      <button @click="onReload">重写</button>
    </div>
    <div>返回相近字:{{ write_result }}</div>
  </div>
</template>

<script>
export default {
  name: 'App',
  data() {
    return {
      initX: 0, // 初始横坐标
      initY: 0, // 初始纵坐标
      lastX: 0, // 上一个横坐标
      lastY: 0, // 上一个纵坐标
      isHandWrite: false, // 是否开始手写
      pointsXY: [], // 单笔画
      allPointsXY: [], // 全部笔画
      write_result: [], // 返回相近字
    }
  },
  mounted() {
    this.initBound()

    let _this = this
    // 添加jsonp回调函数, qq输入法特定
    window['QQShuru'] = {
      HWPanel: {
        ajax_callback: function (res) {
          _this.write_result = res.cand
        },
      },
    }
  },
  methods: {
    // 初始化canvas位置
    initBound() {
      let bound = this.$refs.canvas.getBoundingClientRect()
      this.initX = bound.x
      this.initY = bound.y
    },
    onMouseDown(e) {
      console.log('onDown', e)
      this.pointsXY = []
      let cx = e.clientX - this.initX
      let cy = e.clientY - this.initY
      this.lastX = cx
      this.lastY = cy
      this.pointsXY.push(cx)
      this.pointsXY.push(cy)
      this.isHandWrite = true
    },
    onMouseMove(e) {
      if (this.isHandWrite) {
        let cx = e.clientX - this.initX
        let cy = e.clientY - this.initY
        this.pointsXY.push(cx - this.lastX)
        this.pointsXY.push(cy - this.lastY)
        // 获取2d上下文对象
        let ctx = this.$refs.canvas.getContext('2d')
        // 新建一条路径
        ctx.beginPath()
        ctx.strokeStyle = '#000'
        ctx.fillStyle = '#000'
        ctx.lineWidth = 8
        ctx.lineCap = 'round'
        ctx.moveTo(this.lastX, this.lastY)
        ctx.lineTo(cx, cy)
        ctx.stroke()
        this.lastX = cx
        this.lastY = cy
      }
    },
    onMouseUp(e) {
      if (this.isHandWrite) {
        this.isHandWrite = false
        this.allPointsXY.push(this.pointsXY.join(','))
        this.queryText()
      }
    },
    // 识别文字
    queryText() {
      let track_str = this.allPointsXY.join(',eb,')
      this.$jsonp(
        `https://handwriting.shuru.qq.com/cloud/cgi-bin/cloud_hw_pub.wsgi?track_str=${track_str}&cmd=0`
      ).catch(err => {
        console.log(err)
      })
    },
    onReload() {
      if (!this.$refs.canvas) return
      this.pointsXY = []
      this.allPointsXY = []
      let ctx = this.$refs.canvas.getContext('2d')
      ctx.clearRect(0, 0, 300, 200)
    },
  },
}
</script>

<style lang="scss">
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;

  .canvas-container {
    background: #fafafa;

    canvas {
      background: #fff;
      border: 1px solid #000;
    }
  }
}
</style>

到此这篇关于vue使用canvas手写输入识别中文的文章就介绍到这了,更多相关vue使用canvas手写输入识别中文内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-前端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯