嘉兴绿城濮院
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

424 lines
10 KiB

<template>
<div class="keyborad-container">
<TypeBtnList class="btn-group" :list="list" @change-type="change" />
<transition
enter-active-class="animate__animated animate__zoomIn animate__faster"
leave-active-class="animate__animated animate__zoomOut animate__faster"
>
<ul v-if="mode === 'keyboard'" key="keyboard" class="keyboard">
<li v-for="(item, index) in letterNum" :key="index" class="item" :data-key="item" @click="handleKeyLetter(item)">
{{ item }}
</li>
<li class="empty item" @click="handleKeyLetter(' ')">空格</li>
<li class="keyboard-del item" @click="delLetter">
<img src="@/assets/images/search/key-del.svg" alt="" />
</li>
<!-- <li class="switch-mode item" @click="handleChangeKeyboardMode('hand')">
<img src="@/assets/images/search/icon_hand.svg" alt="" />
!-- <p class="switchhand-txt">{{ $t('search.switchHand') }}</p> --
</li> -->
</ul>
<div v-else class="hand">
<!-- <div class="change-keyboard" @click="handleChangeKeyboardMode('keyboard')">
<img src="@/assets/images/search/icon_key.svg" alt="" />
</div> -->
<li class="keyboard-del" @click="delLetter">
<img src="@/assets/images/search/key-del.svg" alt="" />
</li>
<scroll-view
ref="wordsScrollRef"
:class="{ active: wordsList && wordsList.length }"
class="words-scroll"
:scroll-x="true"
:refresh-delay="100"
:list="wordsList"
>
<ul class="words-list" :style="{ width: getWidth }">
<li
v-for="(item, index) of wordsList"
:key="item"
class="word"
:class="{ active: isPress === index }"
@mousedown="() => (isPress = index)"
@mouseup="() => (isPress = -1)"
@touchstart="() => (isPress = index)"
@touchend="() => (isPress = -1)"
@click="handleWord(item)"
>
{{ item }}
</li>
</ul>
</scroll-view>
<div class="hand-wrapper">
<handWriting
ref="handWritingRef"
lang="CN"
:style="styles"
fill-text="手写输入区域"
fill-font-size="50px"
background-color="#fff"
border-radius="12px"
stroke-style="#D8B78A"
fill-style="rgba(0, 0, 0, 0.03)"
:width="700"
:height="214"
@result="result"
/>
</div>
</div>
</transition>
</div>
</template>
<script setup lang="ts">
import scrollView from '@/base/ScrollView/ScrollView.vue'
import handWriting from '@/components/Written/Written.vue'
import { ref, reactive, watch, nextTick, computed } from 'vue'
import { storeToRefs } from 'pinia'
import { useRootStore } from '@/store/root'
import TypeBtnList from '@/components/TypeBtnList/TypeBtnList.vue'
const store = useRootStore()
const { device } = storeToRefs(store)
const emit = defineEmits(['letterKey', 'mode'])
const isPress = ref(-1)
const handWritingRef = ref()
const styles = reactive({
background: '#fff',
borderRadius: '0 0 12px 12px',
marginTop: '0px'
})
const letterNum = ref('1234567890QWERTYUIOPASDFGHJKLZXCVBNM')
const letters = ref('')
const mode = ref('keyboard')
const INPUT_MAX_LEN = computed(() => (mode.value === 'hand' ? 5 : 7))
const wordsList = ref([])
const wordsScrollRef = ref()
const list = [
{
title: '键盘输入',
titleEn: 'Keyboard'
},
{
title: '手写输入',
titleEn: 'Handwriting'
}
]
const getWidth = computed(() => wordsList.value?.length * (66 + 5) + 'px')
defineExpose({
handleChangeKeyboardMode,
clear
})
function clear() {
letters.value = ''
wordsList.value = []
}
function delLetter() {
letters.value = letters.value.substring(0, letters.value.length - 1)
if (letters.value.length === 0) {
wordsList.value = []
}
}
function result(words: []) {
console.log('words :>> ', words)
wordsList.value = words
}
function handleChangeKeyboardMode(val: 'keyboard' | 'hand') {
mode.value = val
}
function handleKeyLetter(letter: string) {
if (letters.value.length > INPUT_MAX_LEN.value) {
return
}
letters.value += letter
}
function handleWord(word: string) {
if (letters.value.length > INPUT_MAX_LEN.value) {
return
}
letters.value += word
}
function change(params: any) {
if (params.order === 0) {
handleChangeKeyboardMode('keyboard')
} else {
handleChangeKeyboardMode('hand')
}
}
watch(letters, newVal => {
emit('letterKey', newVal)
})
watch(mode, newVal => {
letters.value = ''
// this.$emit('letterKey', this.letters)
emit('mode', newVal)
if (newVal === 'hand') {
wordsList.value = []
setTimeout(() => {
handWritingRef.value.setCanvasSize()
handWritingRef.value.updateBound()
handWritingRef.value.reload()
}, 200)
}
})
watch(wordsList, () => {
nextTick(() => {
if (wordsScrollRef.value) {
wordsScrollRef.value?.refresh()
}
})
})
</script>
<style lang="scss" scoped>
.keyborad-container {
position: absolute;
top: 700px;
left: 0;
z-index: 1;
display: flex;
// justify-content: center;
align-items: center;
width: 1080px;
// padding: 48px 64px;
background: rgb(255 255 255 / 0%);
border-radius: 0;
.btn-group {
position: absolute;
top: 0;
right: 0;
left: 0;
width: 428px;
margin: 0 auto;
}
.keyboard {
position: absolute;
top: 145px;
left: 264px;
display: flex;
width: 552px;
height: 228px;
background: #fff0;
border-radius: 0;
opacity: 1;
// box-shadow: 0px 4px 20px 0px rgba(110,82,53,0.15);
animation-duration: 50ms;
// padding: 33px;
// justify-content: center;
flex-wrap: wrap;
.item {
width: 48px;
height: 48px;
margin-right: 8px;
margin-bottom: 12px;
font-size: 18px;
font-family: 'font_bold';
text-align: center;
color: rgb(0 0 0 / 90%);
background: #f4f4f4;
border-radius: 8px;
box-shadow: 0 4px 8px rgb(0 0 0 / 3%), inset 0 -1px 0 rgb(177 189 220 / 10%);
line-height: 48px;
&:active {
color: #fff;
background: linear-gradient(180deg, #d8b78a 0%, #e9dbc4 102.5%);
}
&[data-key='0'] {
margin-right: 0;
}
&[data-key='P'] {
margin-right: 0;
}
&[data-key='Q'] {
margin-left: 0;
}
&[data-key='A'] {
margin-left: 25px;
}
&[data-key='L'] {
margin-right: 30px;
}
}
.keyboard-del {
// position: absolute;
// right: 16px;
// top: 33px;
display: flex;
justify-content: center;
align-items: center;
width: 104px;
margin-right: 0;
img {
width: 21px;
object-fit: scale-down;
}
}
.empty {
width: 48px;
font-size: 14px;
font-family: 'font_bold';
}
.switch-mode {
position: absolute;
top: 374px;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 520px;
height: 111px;
font-size: 14px;
font-family: 'font_bold';
text-align: center;
color: rgb(0 0 0 / 60%);
background: rgb(36 36 36 / 5%);
border-radius: 16px;
flex-direction: column;
// .switchhand-txt {
// }
img {
width: 52px;
object-fit: scale-down;
}
&::before {
position: absolute;
left: -50px;
width: 0;
height: 164px;
// background: #f4f4f4;
background-repeat: 4px;
content: '';
}
}
}
.hand {
position: absolute;
top: 145px;
left: 190px;
width: 700px;
height: 270px;
padding-top: 0;
padding-left: 0;
background: #fff;
border-radius: 12px;
opacity: 1;
animation-duration: 50ms;
.keyboard-del {
position: absolute;
right: 8px;
bottom: 8px;
z-index: 10;
display: flex;
justify-content: center;
align-items: center;
width: 104px;
height: 48px;
padding: 8px;
font-size: 14px;
font-family: 'font_regular';
text-align: center;
color: #4d4846;
background: rgb(0 0 0 / 3%);
border-radius: 8px;
box-shadow: 0 4px 8px rgb(0 0 0 / 3%), inset 0 -1px 0 rgb(177 189 220 / 10%);
line-height: 48px;
&:active {
color: #fff;
background: linear-gradient(180deg, #d8b78a 0%, #e9dbc4 102.5%);
}
img {
flex-shrink: 0;
width: 25px;
// object-fit: scale-down;
}
}
.change-keyboard {
position: absolute;
bottom: 0;
left: 0;
display: flex;
justify-content: center;
align-items: center;
width: 520px;
height: 111px;
padding: 8px;
background: rgb(38 36 36 / 5%);
border-radius: 16px;
// box-shadow: 2px 4px 16px rgba(255, 171, 124, 0.4);
img {
// width: 24px;
object-fit: scale-down;
}
}
.words-scroll {
position: absolute;
top: 0;
right: 0;
left: 0;
overflow: hidden;
height: 56px;
padding-top: 0;
background: #f4f4f4;
box-shadow: 0 8px 16px rgb(0 0 0 / 4%);
border-top-left-radius: 12px;
border-top-right-radius: 12px;
&.active {
background: #fafafa;
&::after {
position: absolute;
top: 0;
right: 0;
width: 66px;
width: 3px;
height: 40px;
border-radius: 8px;
opacity: 0.37;
// background: #eb7736;
box-shadow: 2px 4px 16px rgb(255 171 124 / 40%);
content: '';
// filter: blur(4px);
border-top-left-radius: 16px;
}
}
.words-list {
display: flex;
align-items: center;
height: 56px;
.word {
display: inline-block;
width: 66px;
height: 56px;
margin-right: 5px;
font-size: 18px;
font-family: 'font_bold';
text-align: center;
color: rgb(0 0 0 / 80%);
border-radius: 12px;
opacity: 1;
// flex-shrink: 0;
line-height: 56px;
// background: #fff;
&.active {
color: #fff;
background: linear-gradient(180deg, #d8b78a 0%, #e9dbc4 102.5%);
}
}
}
}
.hand-wrapper {
width: 700px;
height: 270px;
}
}
}
</style>