效果图

前言

最近做一个室外大屏项目,系统上的输入法使用不方便,客户要求做一个嵌入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;}
}
  1. 获取初始横纵坐标
data() {return {initX: 0, // 初始横坐标initY: 0, // 初始纵坐标}
},
mounted() {this.initBound()
},
methods: {// 初始化canvas位置initBound() {let bound = this.$refs.canvas.getBoundingClientRect()this.initX = bound.xthis.initY = bound.y}
}
  1. 添加鼠标点击事件、移动事件、松开事件
// 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.initXlet cy = e.clientY - this.initYthis.lastX = cxthis.lastY = cythis.pointsXY.push(cx)this.pointsXY.push(cy)this.isHandWrite = true},onMouseMove(e) {if (this.isHandWrite) {let cx = e.clientX - this.initXlet cy = e.clientY - this.initYthis.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 = 8ctx.lineCap = 'round'ctx.moveTo(this.lastX, this.lastY)ctx.lineTo(cx, cy)ctx.stroke()this.lastX = cxthis.lastY = cy}},onMouseUp(e) {if (this.isHandWrite) {this.isHandWrite = falsethis.allPointsXY.push(this.pointsXY.join(','))this.queryText() // 识别文字}},
}
  1. 添加识别文字接口以及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)})},
}
  1. 最后再加个清除画布的重写按钮
// template
<div><button @click="onReload">重写</button>
</div>// script
onReload() {if (!this.$refs.canvas) returnthis.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.xthis.initY = bound.y},onMouseDown(e) {console.log('onDown', e)this.pointsXY = []let cx = e.clientX - this.initXlet cy = e.clientY - this.initYthis.lastX = cxthis.lastY = cythis.pointsXY.push(cx)this.pointsXY.push(cy)this.isHandWrite = true},onMouseMove(e) {if (this.isHandWrite) {let cx = e.clientX - this.initXlet cy = e.clientY - this.initYthis.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 = 8ctx.lineCap = 'round'ctx.moveTo(this.lastX, this.lastY)ctx.lineTo(cx, cy)ctx.stroke()this.lastX = cxthis.lastY = cy}},onMouseUp(e) {if (this.isHandWrite) {this.isHandWrite = falsethis.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) returnthis.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手写输入识别中文相关推荐

  1. vue 中利用canvas 给pdf文件加水印---详细教程(附上完整代码)

    需求:在h5网页中打开pdf文件,要求给文件添加水印 实现技术及插件:vue,vue-pdf,canvas 插件安装: npm i vue-pdf --save npm i pdf-lib --sav ...

  2. 在vue中使用canvas实现简单特效(下雨天)

    效果展示 还不了解canvas的同学可以先看一下官方的api https://www.canvasapi.cn 话不多说直接上代码 在页面中添加canvas标签 <template>< ...

  3. vue中使用canvas实现移动端手写板、电子签名功能

    直接上Demo <template><div class="hello"><button type v-on:click="clear&qu ...

  4. html中哪些字体不识别中文字体,div字体_正确设置div兼容的汉字中文字体

    这里可以学习DIV字体设置方法,同时如果设置常见中文汉字字体,就需要将汉字进行转化或使用英文对应汉字字体来兼容各大浏览器,这样CSS设置的字体才能兼容各地浏览器. 一.全网页DIV默认字体设置 div ...

  5. 记录下vue中使用canvas:给漂浮的圆球加阴影(发光边)

    漂的气泡不同的外阴影(发光边)就这样 场景:随机生成几个透明的发光的圆,滚来滚去,里面显示文字,每个圆可点击,携带参数跳转不同路由. 1.原想用strokeStyle画,但是出来后特别浅淡,基本看不见 ...

  6. vue中实现canvas画布基本操作

    <template><div class="practice-html5"><div><p>canvas1</p>< ...

  7. Vue中利用canvas添加炫动背景

    1.展示页面 <template><div id="main"><canvas id="myCanvas" style=" ...

  8. vue项目中使用trackingjs人脸识别

    vue项目中使用trackingjs人脸识别 前言 一.下载trackingjs库 二.trackingjs引用 三.检测过程 1.初始化设置.创建实例 2.检测视频中人脸 3.判断上传 4.上传人脸 ...

  9. java图片片识别中文_Java中使用tess4J进行图片文字识别(支持中文)

    Java 版本:建议JDK1.8 使用的软件是tesseractocr3.02,3以后的版本才支持中文, 这个软件需要安装在本地电脑中,安装的过程中全部都按照默认进行安装(以便于Java直接调用) 代 ...

最新文章

  1. 【UVA】11992 - Fast Matrix Operations(段树模板)
  2. 人群密度估计--Fully Convolutional Crowd Counting On Highly Congested Scenes
  3. 北师大计算机网络原理和应用作业,北师大网络作业计算机组成原理 作业一(可编辑)...
  4. Java那些事之多线程
  5. python 冷门_csvkit---python一个牛逼到不行的csv处理库
  6. github不用输入用户密码即可登录
  7. java服务器http post_使用Java程序通过http post访问ABAP Netweaver服务器
  8. VTK:可视化算法之ColorIsosurface
  9. c语言随机生成int64_t类型的数据_手把手教你代码生成(上):MATLAB代码生成
  10. TurboLinux11system»adjtimex简介
  11. Python 数据类型 list(1)
  12. DeOccNet:国防科大提出阵列相机去除前景遮挡成像新方法
  13. VMWare 复制虚拟机系统后,模块“Disk”启动失败
  14. day 22 封装 + property + classmethod + staticmethod
  15. SDUT OJ 3403 数据结构实验之排序六:希尔排序
  16. System Repair Engineer (SREng) 2.6 正式发布
  17. 简单易懂Kafka搭建
  18. vb.net 教程 3-4 窗体编程 公共控件7 DateTimePicker MonthCalendar
  19. Luat Inside | 致敬经典,使用Air724UG制作简易贪吃蛇
  20. 为什么python文件会闪退_困扰已久的问题--python文件打开方式?为什么打开py文件会闪退!...

热门文章

  1. GTD任务管理软件:Chaos Control for Mac
  2. ChinaSoft 论坛巡礼 | 泛在操作系统理论、技术与开源生态构建
  3. 全民热衷“合成大西瓜”,游戏外挂上热搜,不愧是程序员!
  4. 自制p站小姐姐图片返回api.
  5. 热带地区数据中心需要太阳能发电,而不是自然冷却
  6. JS数组Arry 操作方法速记
  7. adblockplus简单介绍
  8. vue、Cascader 级联选择、Cascader 属性事件方法、vue Cascader 所有级联选择样式、vue Cascader 级联选择全部属性事件方法
  9. uniapp项目打包与部署云服务器
  10. 阿里大数据之路:数据管理篇大总结