feat:save
This commit is contained in:
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -38,6 +38,9 @@ importers:
|
||||
git-last-commit:
|
||||
specifier: ^1.0.1
|
||||
version: 1.0.1
|
||||
gsap:
|
||||
specifier: ^3.13.0
|
||||
version: 3.13.0
|
||||
hover.css:
|
||||
specifier: ^2.3.2
|
||||
version: 2.3.2
|
||||
@@ -2208,6 +2211,9 @@ packages:
|
||||
resolution: {integrity: sha512-rXunEHF9M9EkMydTBux7+IryYXEZinRk6g8OBOGDBzo/qWJjhTxy86i5q7lQYpCLHN8Sqv1XX3OIOc7ka2gtvQ==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
|
||||
gsap@3.13.0:
|
||||
resolution: {integrity: sha512-QL7MJ2WMjm1PHWsoFrAQH/J8wUeqZvMtHO58qdekHpCfhvhSL4gSiz6vJf5EeMP0LOn3ZCprL2ki/gjED8ghVw==}
|
||||
|
||||
gulp-cli@2.3.0:
|
||||
resolution: {integrity: sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==}
|
||||
engines: {node: '>= 0.10'}
|
||||
@@ -6167,6 +6173,8 @@ snapshots:
|
||||
|
||||
grad-school@0.0.5: {}
|
||||
|
||||
gsap@3.13.0: {}
|
||||
|
||||
gulp-cli@2.3.0:
|
||||
dependencies:
|
||||
ansi-colors: 1.1.0
|
||||
|
||||
12
src/App.vue
12
src/App.vue
@@ -3,7 +3,6 @@ import {onMounted, watch} from "vue";
|
||||
import {BaseState, useBaseStore} from "@/stores/base.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import Backgorund from "@/pages/pc/components/Backgorund.vue";
|
||||
import useTheme from "@/hooks/theme.ts";
|
||||
import * as localforage from "localforage";
|
||||
import SettingDialog from "@/pages/pc/components/dialog/SettingDialog.vue";
|
||||
@@ -69,7 +68,6 @@ watch(() => route.path, (to, from) => {
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<Backgorund/>
|
||||
<router-view v-slot="{ Component }">
|
||||
<transition :name="transitionName">
|
||||
<keep-alive :exclude="runtimeStore.excludeRoutes">
|
||||
@@ -83,14 +81,4 @@ watch(() => route.path, (to, from) => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.main-page {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: hidden;
|
||||
font-size: 14rem;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
</style>
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB |
@@ -5,9 +5,12 @@ import "vue-activity-calendar/style.css";
|
||||
import {useRouter} from "vue-router";
|
||||
import {enArticle} from "@/assets/dictionary.ts";
|
||||
import BasePage from "@/pages/pc/components/BasePage.vue";
|
||||
import {useNav} from "@/utils";
|
||||
|
||||
const {nav} = useNav()
|
||||
const base = useBaseStore()
|
||||
const router = useRouter()
|
||||
const store = useBaseStore()
|
||||
|
||||
function clickEvent(e) {
|
||||
console.log('e', e)
|
||||
@@ -52,6 +55,23 @@ function clickEvent(e) {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="card flex flex-col">
|
||||
<div class="title">
|
||||
我的词典
|
||||
</div>
|
||||
<div class="grid grid-cols-6 gap-4 mt-4">
|
||||
<div class="my-dict" @click="nav('edit-word-dict',{type:0})">
|
||||
<span>收藏</span>
|
||||
<div class="absolute bottom-4 right-4">{{ store.collectWord.words.length }}个词</div>
|
||||
</div>
|
||||
<div class="my-dict" @click="nav('edit-word-dict',{type:1})">
|
||||
<span>错词本</span>
|
||||
<div class="absolute bottom-4 right-4">{{ store.wrong.words.length }}个词</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-4">
|
||||
<div class="title">文章</div>
|
||||
<div class="mt-4 flex gap-4">
|
||||
@@ -82,4 +102,7 @@ function clickEvent(e) {
|
||||
.title {
|
||||
@apply text-lg font-medium;
|
||||
}
|
||||
.my-dict {
|
||||
@apply p-4 rounded-md bg-slate-200 relative cursor-pointer h-40;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,110 +0,0 @@
|
||||
<template>
|
||||
<div id="background" class="anim">
|
||||
<img src="../../../assets/img/moon.png" alt="" id="moon" style="display:none">
|
||||
<Transition name="fade">
|
||||
<canvas ref="canvas" v-show="settingStore.theme === 'dark'"/>
|
||||
</Transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
import {onMounted} from "vue"
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
|
||||
const canvas = $ref<HTMLCanvasElement>()
|
||||
const settingStore = useSettingStore()
|
||||
|
||||
onMounted(() => {
|
||||
// console.log('canvas;', canvas)
|
||||
let ctx = canvas.getContext("2d");
|
||||
canvas.width = window.innerWidth;
|
||||
canvas.height = window.innerHeight;
|
||||
let maxRadius = 1,
|
||||
stars = [];
|
||||
|
||||
|
||||
let Star = function (x: number, y: number, r: number) {
|
||||
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: HTMLImageElement = 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">
|
||||
|
||||
#background {
|
||||
position: fixed;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
left: 0;
|
||||
top: 0;
|
||||
background-color: var(--color-main-bg);
|
||||
|
||||
canvas {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
</style>
|
||||
@@ -3,8 +3,6 @@
|
||||
import {ShortcutKey} from "@/types.ts";
|
||||
import Logo from "@/pages/pc/components/Logo.vue";
|
||||
import {Icon} from "@iconify/vue";
|
||||
import {usePracticeStore} from "@/stores/practice.ts";
|
||||
import {useBaseStore} from "@/stores/base.ts";
|
||||
import {useSettingStore} from "@/stores/setting.ts";
|
||||
import {useRuntimeStore} from "@/stores/runtime.ts";
|
||||
import {useRouter} from "vue-router";
|
||||
@@ -13,50 +11,50 @@ import Tooltip from "@/pages/pc/components/Tooltip.vue";
|
||||
import useTheme from "@/hooks/theme.ts";
|
||||
import BaseIcon from "@/components/BaseIcon.vue";
|
||||
|
||||
const statisticsStore = usePracticeStore()
|
||||
const store = useBaseStore()
|
||||
|
||||
const settingStore = useSettingStore()
|
||||
const runtimeStore = useRuntimeStore()
|
||||
const router = useRouter()
|
||||
const {toggleTheme} = useTheme()
|
||||
|
||||
let show = $ref(false)
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="layout">
|
||||
<div class="aside" :class="{'hide':settingStore.showSide}">
|
||||
<div class="aside" :class="{'expand':settingStore.sideExpand}">
|
||||
<div class="top">
|
||||
<Logo/>
|
||||
<Logo v-if="settingStore.sideExpand"/>
|
||||
<div class="row" @click="router.push('/home')">
|
||||
<Icon icon="iconoir:home"/>
|
||||
<span>主页</span>
|
||||
<span v-if="settingStore.sideExpand">主页</span>
|
||||
</div>
|
||||
<div class="row" @click="router.push('/word')">
|
||||
<Icon icon="material-symbols-light:dictionary-outline-sharp"/>
|
||||
<!-- <Icon icon="streamline:dictionary-language-book"/>-->
|
||||
<span>单词</span>
|
||||
<span v-if="settingStore.sideExpand">单词</span>
|
||||
</div>
|
||||
<div class="row" @click="router.push('/article')">
|
||||
<Icon icon="ph:article-ny-times"/>
|
||||
<span>文章</span>
|
||||
<span v-if="settingStore.sideExpand">文章</span>
|
||||
</div>
|
||||
<div class="row" @click="router.push('/article2')">
|
||||
<Icon icon="healthicons:i-exam-multiple-choice-outline"/>
|
||||
<span>试卷</span>
|
||||
<span v-if="settingStore.sideExpand">试卷</span>
|
||||
</div>
|
||||
<div class="row">
|
||||
<Icon icon="mdi-light:forum"/>
|
||||
<span>社区</span>
|
||||
<span v-if="settingStore.sideExpand">社区</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bottom flex justify-evenly ">
|
||||
<BaseIcon
|
||||
:title="`收起(${settingStore.shortcutKeyMap[ShortcutKey.OpenSetting]})`"
|
||||
@click="settingStore.showSide = !settingStore.showSide"
|
||||
icon="formkit:left"/>
|
||||
@click="settingStore.sideExpand = !settingStore.sideExpand"
|
||||
:icon="settingStore.sideExpand?'formkit:left':'formkit:right'"/>
|
||||
<Tooltip
|
||||
:title="`切换主题(${settingStore.shortcutKeyMap[ShortcutKey.ToggleTheme]})`"
|
||||
v-if="settingStore.sideExpand"
|
||||
>
|
||||
<IconWrapper>
|
||||
<Icon icon="ep:moon" v-if="settingStore.theme === 'dark'"
|
||||
@@ -65,48 +63,12 @@ let show = $ref(false)
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
<BaseIcon
|
||||
v-if="settingStore.sideExpand"
|
||||
:title="`设置(${settingStore.shortcutKeyMap[ShortcutKey.OpenSetting]})`"
|
||||
@click="runtimeStore.showSettingModal = true"
|
||||
icon="uil:setting"/>
|
||||
</div>
|
||||
</div>
|
||||
<div class="fixed top-8 left-8 z-9">
|
||||
<BaseIcon
|
||||
title="菜单"
|
||||
@click="show = !show"
|
||||
icon="hugeicons:menu-square"/>
|
||||
<div class="menus flex flex-col" v-if="show">
|
||||
<BaseIcon
|
||||
title="单词"
|
||||
@click="router.push('/word')"
|
||||
icon="material-symbols-light:dictionary-outline-sharp"/>
|
||||
<BaseIcon
|
||||
title="文章"
|
||||
@click="router.push('/article')"
|
||||
icon="ph:article-ny-times"/>
|
||||
<BaseIcon
|
||||
title="试卷"
|
||||
icon="healthicons:i-exam-multiple-choice-outline"/>
|
||||
<BaseIcon
|
||||
title="展开"
|
||||
@click="settingStore.showSide = !settingStore.showSide"
|
||||
icon="formkit:right"/>
|
||||
<Tooltip
|
||||
:title="`切换主题(${settingStore.shortcutKeyMap[ShortcutKey.ToggleTheme]})`"
|
||||
>
|
||||
<IconWrapper>
|
||||
<Icon icon="ep:moon" v-if="settingStore.theme === 'dark'"
|
||||
@click="toggleTheme"/>
|
||||
<Icon icon="tabler:sun" v-else @click="toggleTheme"/>
|
||||
</IconWrapper>
|
||||
</Tooltip>
|
||||
<BaseIcon
|
||||
:title="`设置(${settingStore.shortcutKeyMap[ShortcutKey.OpenSetting]})`"
|
||||
@click="runtimeStore.showSettingModal = true"
|
||||
icon="uil:setting"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-1 z-1">
|
||||
<router-view></router-view>
|
||||
</div>
|
||||
@@ -118,44 +80,43 @@ let show = $ref(false)
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: flex;
|
||||
background: var(--color-background);
|
||||
}
|
||||
|
||||
.aside {
|
||||
background: var(--color-second-bg);
|
||||
position: fixed;
|
||||
z-index: 999;
|
||||
top: 0;
|
||||
left: 0;
|
||||
height: 100vh;
|
||||
width: var(--aside-width);
|
||||
padding: 1rem 1rem;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
box-shadow: rgb(0 0 0 / 3%) 0px 0px 12px 0px;
|
||||
transition: all .3s;
|
||||
width: 4.5rem;
|
||||
transition: all 0.3s;
|
||||
z-index: 2;
|
||||
|
||||
.row {
|
||||
@apply cursor-pointer rounded-md text p-2 my-2 flex items-center gap-2;
|
||||
transition: all .5s;
|
||||
flex-shrink: 0;
|
||||
|
||||
&:hover {
|
||||
background: var(--color-primary);
|
||||
color: white;
|
||||
}
|
||||
span{
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
svg {
|
||||
font-size: 1.5rem;
|
||||
flex-shrink: 0;
|
||||
font-size: 1.5rem!important;
|
||||
}
|
||||
}
|
||||
|
||||
&.hide {
|
||||
transform: translateX(-12rem);
|
||||
&.expand {
|
||||
width: var(--aside-width);
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
flex: 1;
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -262,4 +262,4 @@ function changePerDayStudyNumber() {
|
||||
color: var(--color-font-1);
|
||||
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
@@ -36,7 +36,7 @@ export interface SettingState {
|
||||
wordTranslateFontSize: number,
|
||||
},
|
||||
showPanel: boolean,
|
||||
showSide: boolean,
|
||||
sideExpand: boolean,
|
||||
theme: string,
|
||||
collapse: boolean,
|
||||
chapterWordNumber: number,
|
||||
@@ -49,7 +49,7 @@ export const DefaultSettingState = (): SettingState => ({
|
||||
showToolbar: true,
|
||||
show: false,
|
||||
showPanel: true,
|
||||
showSide: true,
|
||||
sideExpand: true,
|
||||
|
||||
allSound: true,
|
||||
wordSound: true,
|
||||
@@ -109,4 +109,4 @@ export const useSettingStore = defineStore('setting', {
|
||||
})
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user