添加canvas背景
This commit is contained in:
37
src/App.vue
37
src/App.vue
@@ -18,6 +18,7 @@ import WordList from "./components/WordList.vue";
|
||||
import Side from "@/components/Side.vue"
|
||||
import {usePlayWordAudio} from "@/hooks/usePlayWordAudio.ts"
|
||||
import DictModal from "@/components/DictModal.vue"
|
||||
import Backgorund from "@/components/Backgorund.vue"
|
||||
|
||||
let input = $ref('')
|
||||
let wrong = $ref('')
|
||||
@@ -47,14 +48,6 @@ onMounted(() => {
|
||||
store.init()
|
||||
window.addEventListener('keydown', onKeyDown)
|
||||
window.addEventListener('keyup', onKeyUp)
|
||||
|
||||
Tesseract.recognize(
|
||||
'https://tesseract.projectnaptha.com/img/eng_bw.png',
|
||||
'eng',
|
||||
{ logger: m => console.log(m) }
|
||||
).then(({ data: { text } }) => {
|
||||
console.log(text);
|
||||
})
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
@@ -79,7 +72,16 @@ function next() {
|
||||
}
|
||||
} else {
|
||||
store.currentDict.wordIndex++
|
||||
// console.log('这个词完了')
|
||||
|
||||
// var msg = new SpeechSynthesisUtterance();
|
||||
// // msg.text = store.word.name
|
||||
// msg.text = 'Hawaii wildfires burn historic town of Lahaina to the ground'
|
||||
// msg.rate = 0.8;
|
||||
// msg.pitch = 1;
|
||||
// msg.lang = 'en-US';
|
||||
// window.speechSynthesis.speak(msg);
|
||||
|
||||
console.log('这个词完了')
|
||||
}
|
||||
if ([DictType.custom, DictType.inner].includes(store.currentDictType.name) && store.skipWordNames.includes(store.word.name)) {
|
||||
next()
|
||||
@@ -92,9 +94,10 @@ function onKeyUp(e: KeyboardEvent) {
|
||||
}
|
||||
|
||||
async function onKeyDown(e: KeyboardEvent) {
|
||||
//TODO 还有横杠
|
||||
if (e.keyCode >= 65 && e.keyCode <= 90 || e.code === 'Space') {
|
||||
let letter = e.key.toLowerCase()
|
||||
if (input + letter === store.word.name.slice(0, input.length + 1)) {
|
||||
let letter = e.key
|
||||
if ((input + letter).toLowerCase() === store.word.name.toLowerCase().slice(0, input.length + 1)) {
|
||||
input += letter
|
||||
wrong = ''
|
||||
playKeySound()
|
||||
@@ -107,9 +110,9 @@ async function onKeyDown(e: KeyboardEvent) {
|
||||
// wrong = input = ''
|
||||
}, 500)
|
||||
}
|
||||
if (input === store.word.name) {
|
||||
if (input.toLowerCase() === store.word.name.toLowerCase()) {
|
||||
playCorrect()
|
||||
setTimeout(next, 200)
|
||||
setTimeout(next, 300)
|
||||
}
|
||||
} else {
|
||||
// console.log('e', e)
|
||||
@@ -149,10 +152,14 @@ async function onKeyDown(e: KeyboardEvent) {
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Backgorund/>
|
||||
<div class="main-page">
|
||||
<button @click="store.dictModalIsOpen = true">ok</button>
|
||||
<div class="content">
|
||||
@@ -188,7 +195,9 @@ async function onKeyDown(e: KeyboardEvent) {
|
||||
@import "@/assets/css/colors";
|
||||
|
||||
.main-page {
|
||||
background: $dark-main-bg;
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
//background: $dark-main-bg;
|
||||
width: 100vw;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
$dark-main-bg: rgb(46, 46, 46);
|
||||
//$dark-main-bg: rgb(46, 46, 46);
|
||||
$dark-main-bg: rgba(0, 5, 24, 1);
|
||||
$dark-second-bg: rgb(60, 63, 65);
|
||||
|
||||
$font-color: rgb(187, 187, 187);
|
||||
|
||||
BIN
src/assets/img/moon.png
Normal file
BIN
src/assets/img/moon.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 36 KiB |
110
src/components/Backgorund.vue
Normal file
110
src/components/Backgorund.vue
Normal file
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<div id="background">
|
||||
<img src="@/assets/img/moon.png" alt="" id="moon" style="display:none">
|
||||
<canvas ref="canvas"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {onMounted} from "vue"
|
||||
|
||||
const canvas = $ref()
|
||||
let ctx = null
|
||||
|
||||
onMounted(() => {
|
||||
console.log('canvas;', canvas)
|
||||
// ctx = canvas.getContext('2d')
|
||||
let ocas = document.createElement("canvas");
|
||||
let octx = ocas.getContext("2d");
|
||||
let ctx = canvas.getContext("2d");
|
||||
ocas.width = canvas.width = window.innerWidth;
|
||||
ocas.height = canvas.height = window.innerHeight;
|
||||
let maxRadius = 1,
|
||||
stars = [];
|
||||
|
||||
|
||||
let Star = function (x, y, r) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.r = r;
|
||||
};
|
||||
Star.prototype = {
|
||||
paint: function () {
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.arc(this.x, this.y, this.r, 0, 2 * Math.PI);
|
||||
ctx.fillStyle = "rgba(255,255,255," + this.r + ")";
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
},
|
||||
};
|
||||
|
||||
function drawBg() {
|
||||
for (let i = 0; i < 1000; i++) {
|
||||
let r = Math.random() * maxRadius;
|
||||
let x = Math.random() * canvas.width;
|
||||
let y = Math.random() * 2 * canvas.height - canvas.height;
|
||||
let star = new Star(x, y, r);
|
||||
stars.push(star);
|
||||
star.paint();
|
||||
}
|
||||
}
|
||||
|
||||
drawBg()
|
||||
|
||||
function drawMoon() {
|
||||
let moon = document.getElementById("moon");
|
||||
let centerX = canvas.width - 200,
|
||||
centerY = 100,
|
||||
width = 80;
|
||||
|
||||
let index = 0;
|
||||
for (let i = 0; i < 10; i++) {
|
||||
ctx.save();
|
||||
ctx.beginPath();
|
||||
ctx.arc(
|
||||
centerX + width / 2,
|
||||
centerY + width / 2,
|
||||
width / 2 + index,
|
||||
0,
|
||||
2 * Math.PI
|
||||
);
|
||||
ctx.fillStyle = "rgba(240,219,120,0.05)";
|
||||
index += 2;
|
||||
ctx.fill();
|
||||
ctx.restore();
|
||||
}
|
||||
if (moon.complete) {
|
||||
ctx.drawImage(moon, centerX, centerY, width, width);
|
||||
} else {
|
||||
moon.onload = function () {
|
||||
ctx.drawImage(moon, centerX, centerY, width, width);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
drawMoon()
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import "@/assets/css/colors";
|
||||
|
||||
#background {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background: $dark-main-bg;
|
||||
|
||||
canvas {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -1,11 +1,12 @@
|
||||
import {createApp} from 'vue'
|
||||
import './assets/css/style.scss'
|
||||
import App from './App.vue'
|
||||
import Mobile from './Mobile.vue'
|
||||
// import Mobile from './Mobile.vue'
|
||||
import {createPinia} from "pinia"
|
||||
|
||||
const pinia = createPinia()
|
||||
const app = createApp(Mobile)
|
||||
// const app = createApp(Mobile)
|
||||
const app = createApp(App)
|
||||
|
||||
app.use(pinia)
|
||||
app.mount('#app')
|
||||
@@ -3,127 +3,127 @@ import {Config, Dict, DictType, SaveKey, State, Word} from "../types.ts"
|
||||
import {chunk, cloneDeep} from "lodash";
|
||||
|
||||
export const useBaseStore = defineStore('base', {
|
||||
state: (): State => {
|
||||
return {
|
||||
newWordDict: {
|
||||
type: DictType.newWordDict,
|
||||
wordList: [],
|
||||
chapterList: [],
|
||||
chapterIndex: -1,
|
||||
wordIndex: -1,
|
||||
},
|
||||
skipWordDict: {
|
||||
type: DictType.skipWordDict,
|
||||
wordList: [],
|
||||
chapterList: [],
|
||||
chapterIndex: -1,
|
||||
wordIndex: -1,
|
||||
},
|
||||
dict: {
|
||||
type: DictType.inner,
|
||||
name: '新概念英语-2',
|
||||
description: '新概念英语第二册',
|
||||
category: '青少年英语',
|
||||
tags: ['新概念英语'],
|
||||
url: '/dicts/NCE_2.json',
|
||||
length: 858,
|
||||
language: 'en',
|
||||
languageCategory: 'en',
|
||||
wordList: [],
|
||||
chapterList: [],
|
||||
chapterIndex: 0,
|
||||
wordIndex: 0,
|
||||
},
|
||||
currentDictType: {
|
||||
name: DictType.inner,
|
||||
dictUrl: '/dicts/NCE_2.json'
|
||||
},
|
||||
sideIsOpen: false,
|
||||
dictModalIsOpen: false,
|
||||
state: (): State => {
|
||||
return {
|
||||
newWordDict: {
|
||||
type: DictType.newWordDict,
|
||||
wordList: [],
|
||||
chapterList: [],
|
||||
chapterIndex: -1,
|
||||
wordIndex: -1,
|
||||
},
|
||||
skipWordDict: {
|
||||
type: DictType.skipWordDict,
|
||||
wordList: [],
|
||||
chapterList: [],
|
||||
chapterIndex: -1,
|
||||
wordIndex: -1,
|
||||
},
|
||||
dict: {
|
||||
type: DictType.inner,
|
||||
name: '新概念英语-2',
|
||||
description: '新概念英语第二册',
|
||||
category: '青少年英语',
|
||||
tags: ['新概念英语'],
|
||||
url: '/dicts/NCE_2.json',
|
||||
length: 858,
|
||||
language: 'en',
|
||||
languageCategory: 'en',
|
||||
wordList: [],
|
||||
chapterList: [],
|
||||
chapterIndex: 0,
|
||||
wordIndex: 0,
|
||||
},
|
||||
currentDictType: {
|
||||
name: DictType.inner,
|
||||
dictUrl: '/dicts/NCE_2.json'
|
||||
},
|
||||
sideIsOpen: false,
|
||||
dictModalIsOpen: false,
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
skipWordNames: (state: State) => {
|
||||
return state.skipWordDict.wordList.map(v => v.name)
|
||||
},
|
||||
currentDict(state: State): Dict {
|
||||
switch (state.currentDictType.name) {
|
||||
case DictType.newWordDict:
|
||||
return state.newWordDict
|
||||
case DictType.skipWordDict:
|
||||
return state.skipWordDict
|
||||
case DictType.inner:
|
||||
case DictType.custom:
|
||||
return state.dict
|
||||
}
|
||||
},
|
||||
chapter(): Word[] {
|
||||
return this.currentDict.chapterList[this.currentDict.chapterIndex] ?? []
|
||||
},
|
||||
word(): Word {
|
||||
return this.chapter[this.currentDict.wordIndex] ?? {
|
||||
trans: [],
|
||||
name: ''
|
||||
}
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
this[key] = value
|
||||
}
|
||||
console.log('this/', this)
|
||||
},
|
||||
async init() {
|
||||
let configStr = localStorage.getItem(SaveKey)
|
||||
if (configStr) {
|
||||
let obj: Config = JSON.parse(configStr)
|
||||
this.setState(obj)
|
||||
}
|
||||
if (this.currentDictType.name === DictType.inner) {
|
||||
let r = await fetch(`/public/${this.currentDictType.dictUrl}`)
|
||||
r.json().then(v => {
|
||||
this.dict.wordList = v
|
||||
this.dict.chapterList = chunk(this.dict.wordList, 15)
|
||||
})
|
||||
}
|
||||
if (this.currentDictType.name === DictType.custom) {
|
||||
let r = await fetch(`/public/${this.currentDictType.dictUrl}`)
|
||||
r.json().then(v => {
|
||||
this.dict.wordList = v
|
||||
this.dict.chapterList = chunk(this.dict.wordList, 15)
|
||||
})
|
||||
}
|
||||
},
|
||||
async changeDict(dict: Dict, chapterIndex: number = -1, wordIndex: number = -1) {
|
||||
console.log('changeDict')
|
||||
if ([DictType.newWordDict, DictType.skipWordDict].includes(dict.type)) {
|
||||
this.currentDictType.name = dict.type
|
||||
this.currentDictType.dictUrl = ''
|
||||
this[dict.type].chapterList = [this[dict.type].wordList]
|
||||
this[dict.type].chapterIndex = chapterIndex === -1 ? 0 : chapterIndex
|
||||
this[dict.type].wordIndex = wordIndex === -1 ? 0 : wordIndex
|
||||
} else {
|
||||
if (dict.name === this.dict.name) {
|
||||
this.currentDictType.name = dict.type
|
||||
this.currentDictType.dictUrl = dict.url
|
||||
if (wordIndex !== -1) this.dict.wordIndex = wordIndex
|
||||
if (chapterIndex !== -1) this.dict.chapterIndex = chapterIndex
|
||||
} else {
|
||||
// let r = await fetch(`/public/${dict.url}`)
|
||||
// r.json().then(v => {
|
||||
// this.currentDictType.name === dict.type
|
||||
// this.currentDictType.dictUrl = dict.url
|
||||
//
|
||||
// })
|
||||
this.dict = cloneDeep(dict)
|
||||
this.dict.chapterList = chunk(this.dict.wordList, 15)
|
||||
this.dict.chapterIndex = chapterIndex === -1 ? 0 : chapterIndex
|
||||
this.dict.wordIndex = wordIndex === -1 ? 0 : wordIndex
|
||||
}
|
||||
},
|
||||
getters: {
|
||||
skipWordNames: (state: State) => {
|
||||
return state.skipWordDict.wordList.map(v => v.name)
|
||||
},
|
||||
currentDict(state: State): Dict {
|
||||
switch (state.currentDictType.name) {
|
||||
case DictType.newWordDict:
|
||||
return state.newWordDict
|
||||
case DictType.skipWordDict:
|
||||
return state.skipWordDict
|
||||
case DictType.inner:
|
||||
case DictType.custom:
|
||||
return state.dict
|
||||
}
|
||||
},
|
||||
chapter(): Word[] {
|
||||
return this.currentDict.chapterList[this.currentDict.chapterIndex] ?? []
|
||||
},
|
||||
word(): Word {
|
||||
return this.chapter[this.currentDict.wordIndex] ?? {
|
||||
trans: [],
|
||||
name: ''
|
||||
}
|
||||
},
|
||||
},
|
||||
actions: {
|
||||
setState(obj: any) {
|
||||
for (const [key, value] of Object.entries(obj)) {
|
||||
this[key] = value
|
||||
}
|
||||
console.log('this/', this)
|
||||
},
|
||||
async init() {
|
||||
let configStr = localStorage.getItem(SaveKey)
|
||||
if (configStr) {
|
||||
let obj: Config = JSON.parse(configStr)
|
||||
this.setState(obj)
|
||||
}
|
||||
if (this.currentDictType.name === DictType.inner) {
|
||||
let r = await fetch(`/public/${this.currentDictType.dictUrl}`)
|
||||
r.json().then(v => {
|
||||
this.dict.wordList = v
|
||||
this.dict.chapterList = chunk(this.dict.wordList, 15)
|
||||
})
|
||||
}
|
||||
if (this.currentDictType.name === DictType.custom) {
|
||||
let r = await fetch(`/public/${this.currentDictType.dictUrl}`)
|
||||
r.json().then(v => {
|
||||
this.dict.wordList = v
|
||||
this.dict.chapterList = chunk(this.dict.wordList, 15)
|
||||
})
|
||||
}
|
||||
},
|
||||
async changeDict(dict: Dict, chapterIndex: number = -1, wordIndex: number = -1) {
|
||||
console.log('changeDict')
|
||||
if ([DictType.newWordDict, DictType.skipWordDict].includes(dict.type)) {
|
||||
this.currentDictType.name = dict.type
|
||||
this.currentDictType.dictUrl = ''
|
||||
this[dict.type].chapterList = [this[dict.type].wordList]
|
||||
this[dict.type].chapterIndex = chapterIndex === -1 ? 0 : chapterIndex
|
||||
this[dict.type].wordIndex = wordIndex === -1 ? 0 : wordIndex
|
||||
} else {
|
||||
if (dict.name === this.dict.name) {
|
||||
this.currentDictType.name = dict.type
|
||||
this.currentDictType.dictUrl = dict.url
|
||||
if (wordIndex !== -1) this.dict.wordIndex = wordIndex
|
||||
if (chapterIndex !== -1) this.dict.chapterIndex = chapterIndex
|
||||
} else {
|
||||
// let r = await fetch(`/public/${dict.url}`)
|
||||
// r.json().then(v => {
|
||||
// this.currentDictType.name === dict.type
|
||||
// this.currentDictType.dictUrl = dict.url
|
||||
//
|
||||
// })
|
||||
this.dict = cloneDeep(dict)
|
||||
this.dict.chapterList = chunk(this.dict.wordList, 15)
|
||||
this.dict.chapterIndex = chapterIndex === -1 ? 0 : chapterIndex
|
||||
this.dict.wordIndex = wordIndex === -1 ? 0 : wordIndex
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
}
|
||||
},
|
||||
})
|
||||
@@ -2,6 +2,7 @@
|
||||
"compilerOptions": {
|
||||
"target": "ES2020",
|
||||
"useDefineForClassFields": true,
|
||||
"allowJs": true,
|
||||
"module": "ESNext",
|
||||
"lib": [
|
||||
"ES2020",
|
||||
|
||||
Reference in New Issue
Block a user