修改手写识别

This commit is contained in:
zyronon
2023-08-23 18:58:20 +08:00
parent ee343330e9
commit 0236463aeb
4 changed files with 97 additions and 37 deletions

View File

@@ -1,7 +1,9 @@
<script setup lang="js">
import {onMounted} from "vue"
import {createWorker} from "tesseract.js";
import useMobile from "@/hooks/useMobile.ts";
const isMobile = useMobile()
onMounted(async () => {
Array.prototype.clone = function () {
@@ -33,6 +35,16 @@ onMounted(async () => {
constructor(canvas) {
this.canvas = canvas;
this.ctx = canvas.getContext("2d")
let canvasRect = canvas.getBoundingClientRect()
let {width, height} = canvasRect
let dpr = window.devicePixelRatio
if (dpr) {
canvas.style.width = width + "px"
canvas.style.height = height + "px"
canvas.height = height * dpr
canvas.width = width * dpr
this.ctx.scale(dpr, dpr)
}
// this.points = new Array();
this.line = new Line();
this.pointLines = new Array();//Line数组
@@ -46,6 +58,7 @@ onMounted(async () => {
}
down(x, y) {
// console.log("down:", x, y)
this.isDown = true;
this.line = new Line();
this.line.lineWidth = this.lineWidth;
@@ -56,7 +69,7 @@ onMounted(async () => {
}
move(x, y) {
// console.log("move:",x,y)
// console.log("move:",x,y,this.isDown)
if (this.isDown) {
let currentPoint = new Point(x, y, Date.now())
this.addPoint(currentPoint);
@@ -83,7 +96,6 @@ onMounted(async () => {
this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);
this.ctx.strokeStyle = "rgba(255,20,87,1)";
//绘制不包含this.line的线条
this.pointLines.forEach((line, index) => {
let points = line.points;
@@ -178,6 +190,8 @@ onMounted(async () => {
this.ctx.ellipse(points[0].x - 1.5, points[0].y, 6, 3, Math.PI / 4, 0, Math.PI * 2);
this.ctx.fill();
// console.log('points', points)
this.ctx.beginPath();
this.ctx.moveTo(points[0].x, points[0].y);
let lastW = this.line.lineWidth;
@@ -228,7 +242,7 @@ onMounted(async () => {
}
}
if (this.line.points.length == 0) {
if (this.line.points.length === 0) {
this.begin = p;
p.isControl = true;
this.pushPoint(p);
@@ -245,8 +259,10 @@ onMounted(async () => {
pushPoint(p) {
//排除重复点
if (this.line.points.length >= 1 && this.line.points[this.line.points.length - 1].x == p.x && this.line.points[this.line.points.length - 1].y == p.y)
return;
if (this.line.points.length >= 1) {
let last = this.line.points[this.line.points.length - 1]
if (last.x === p.x && last.y === p.y) return;
}
this.line.points.push(p);
}
@@ -328,7 +344,6 @@ onMounted(async () => {
}
}
const worker = await createWorker({
// logger: m => console.log(m)
});
@@ -337,43 +352,60 @@ onMounted(async () => {
await worker.setParameters({
tessedit_char_whitelist: 'qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM'
});
// alert('好了')
let lastTime = Date.now()
let timer = -1
let checkTime = 400
//以下代码为鼠标移动事件部分
let eventMap = {
down: '',
move: '',
up: '',
}
if (isMobile) {
eventMap = {
down: 'touchstart',
move: 'touchmove',
up: 'touchend',
}
} else {
eventMap = {
down: 'mousedown',
move: 'mousemove',
up: 'mouseup',
}
}
let handwriting = new HandwritingSelf(document.getElementById("canvasId"))
// document.ontouchstart = document.onmousedown
document.onpointerdown = function (e) {
window.addEventListener(eventMap.down, (e) => {
if (Date.now() - lastTime > checkTime) {
handwriting.clear()
} else {
clearTimeout(timer)
}
if (e.type == "touchstart")
if (e.type === "touchstart")
handwriting.down(e.touches[0].pageX, e.touches[0].pageY);
else
handwriting.down(e.x, e.y);
}
// document.ontouchmove = document.onmousemove
document.onpointermove = function (e) {
if (e.type == "touchmove")
})
window.addEventListener(eventMap.move, (e) => {
if (e.type === "touchmove")
handwriting.move(e.touches[0].pageX, e.touches[0].pageY);
else
handwriting.move(e.x, e.y);
}
})
// document.ontouchend = document.onmouseup
document.onpointerup = function (e) {
if (e.type == "touchend")
window.addEventListener(eventMap.up, (e) => {
if (e.type === "touchend")
handwriting.up(e.touches[0].pageX, e.touches[0].pageY);
else
handwriting.up(e.x, e.y);
clearTimeout(timer)
timer = setTimeout(() => {
console.log('识别');
// console.log('识别');
// handwriting.canvas.toDataURL()
// var MIME_TYPE = "image/png";
@@ -390,30 +422,40 @@ onMounted(async () => {
(async () => {
const {data: {text}} = await worker.recognize(handwriting.canvas);
console.log(text);
if (isMobile){
alert(text)
}
})();
}, checkTime)
lastTime = Date.now()
}
})
})
</script>
<template>
<div class="mobile">
<canvas id="canvasId" width="800" height="720"></canvas>
<canvas id="canvasId"></canvas>
</div>
</template>
<style>
html, body {
overflow: hidden;
}
</style>
<style scoped lang="scss">
@import "assets/css/colors";
.mobile {
width: 100vw;
height: 100vh;
background: $dark-main-bg;
overflow: hidden;
canvas {
//width: 100%;
//height: 100%;
border: 1px solid gray;
width: 100%;
height: 100%;
//border: 1px solid gray;
}
}

View File

@@ -12,7 +12,6 @@ import {
VolumeNotice,
Bug
} from "@icon-park/vue-next"
import IconRepeat from '~icons/tabler/repeat'
import useThemeColor from "@/hooks/useThemeColor.ts"
import {useBaseStore} from "@/stores/base.ts"
import SettingModal from "@/components/Toolbar/SettingModal.vue"
@@ -23,6 +22,13 @@ import IconCog6Tooth from '~icons/heroicons/cog-6-tooth-solid'
import IconLanguage from '~icons/tabler/language'
import IconLanguageOff from '~icons/tabler/language-off'
import IconEye from '~icons/heroicons/eye-solid'
import IconCheck from '~icons/tabler/check'
import IconEyeSlash from '~icons/heroicons/eye-slash-solid'
import IconRepeat from '~icons/tabler/repeat'
import IconRepeatOff from '~icons/tabler/repeat-off'
const {appearance, toggle} = useThemeColor()
const store = useBaseStore()
const showFeedbackModal = $ref(false)
@@ -36,9 +42,11 @@ const showSettingModal = $ref(false)
</div>
<div class="options">
<Tooltip title="切换主题">
<moon v-if="appearance === 'dark'" theme="filled" size="20" fill="#0C8CE9" :strokeWidth="2"
@click="toggle"/>
<sun-one v-else theme="filled" size="20" fill="#0C8CE9" :strokeWidth="2" @click="toggle"/>
<IconWrapper>
<moon v-if="appearance === 'dark'"
@click="toggle"/>
<sun-one v-else @click="toggle"/>
</IconWrapper>
</Tooltip>
<Tooltip title="音效设置">
@@ -46,17 +54,21 @@ const showSettingModal = $ref(false)
<volume-notice/>
</IconWrapper>
</Tooltip>
<IconRepeat></IconRepeat>
<Tooltip title="单词本">
<Tooltip title="设置单词循环">
<IconWrapper>
<IconLanguage></IconLanguage>
<!-- <IconLanguageOff></IconLanguageOff>-->
<IconRepeat></IconRepeat>
</IconWrapper>
</Tooltip>
<Tooltip title="开关默写模式">
<IconWrapper>
<IconEye></IconEye>
<IconEyeSlash></IconEyeSlash>
</IconWrapper>
</Tooltip>
<Tooltip title="开关释义显示">
<IconWrapper>
<IconLanguage></IconLanguage>
<!-- <IconLanguageOff></IconLanguageOff>-->
<!-- <IconLanguageOff></IconLanguageOff>-->
</IconWrapper>
</Tooltip>

View File

@@ -8,5 +8,5 @@ export function useEsc(can: boolean) {
}
})
})
return [useEsc()]
return []
}

6
src/hooks/useMobile.ts Normal file
View File

@@ -0,0 +1,6 @@
export default function useMobile() {
if (/Mobi|Android|iPhone/i.test(navigator.userAgent)) {
return true
}
return false
}