添加canvas背景

This commit is contained in:
zyronon
2023-08-10 18:50:49 +08:00
parent a2274790dc
commit 097b2614eb
7 changed files with 259 additions and 137 deletions

View File

@@ -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;

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

View 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>

View File

@@ -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')

View File

@@ -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
}
}
}
}
},
}
},
})

View File

@@ -2,6 +2,7 @@
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"allowJs": true,
"module": "ESNext",
"lib": [
"ES2020",