vue使用canvas手寫輸入識別中文
效果圖:

前言:
最近做一個室外大屏項目,系統(tǒng)上的輸入法使用不方便,客戶要求做一個嵌入web網(wǎng)頁的手寫輸入法。
核心:
后端接口api:使用 QQ輸入法手寫接口
https://handwriting.shuru.qq.com/cloud/cgi-bin/cloud_hw_pub.wsgi
| 參數(shù) | 說明 | 類型 | 默認值 |
|---|---|---|---|
| track_str | 筆畫字符串,單筆畫以'x1,y1,x2,y2,…‘格式拼接,多筆畫在單筆畫的基礎(chǔ)上以eb拼接,例如'x1,y1,x2,y2,eb,x3,y3,x4,y4' | string | - |
| cmd | 未知,目前傳0 | number | - |
注:此接口通過其他大佬文章獲知,原文在此,本人未能查到官方文檔相關(guān)地址,如果有大佬知曉還請留言告知,感謝!
思路:
(1)創(chuàng)建一個canvas繪圖區(qū)域
// 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回調(diào)函數(shù),跨域請求使用了 vue-jsonp ,具體用法可參vue中jsonp的使用方法
// script
data() {
return {
// ...
write_result: [], // 返回相近字
}
},
mounted() {
// ...
let _this = this
// 添加jsonp回調(diào)函數(shù), 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回調(diào)函數(shù), 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>
到此這篇關(guān)于vue使用canvas手寫輸入識別中文的文章就介紹到這了,更多相關(guān)vue使用canvas手寫輸入識別中文內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于vue-lunar-full-calendar的使用說明
這篇文章主要介紹了關(guān)于vue-lunar-full-calendar的使用說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-07-07
關(guān)于nuxt?store中保存localstorage的問題
這篇文章主要介紹了關(guān)于nuxt?store中保存localstorage的問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-10-10

