本文使用的api
已停用
,暂未找到可替代的api(2023-02-10)
最近做一个室外大屏项目,系统上的输入法使用不方便,客户要求做一个嵌入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 | - |
注:此接口通过其他大佬文章获知,原文在此,本人未能查到官方文档相关地址,如果有大佬知晓还请留言告知,感谢!
// 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;
}
}
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
}
}
// 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() // 识别文字
}
},
}
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)
})
},
}
// 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>