feat(docs): add welcome screen with animated logo
Introduce a new welcome screen that automatically redirects first-time visitors from the homepage. The screen features an animated "Easy Vibe" logo with three color themes (ocean, rainbow, sunset) that cycle through a drawing animation. Users can click anywhere to enter the main site. The welcome screen includes: - A JSON file containing SVG path data for the animated logo - A Vue component with gradient backgrounds and smooth animations - Logic to detect first-time visitors using localStorage - Integration into the existing VitePress theme structure - Updated navigation to exclude the welcome page from sidebar controls - Modified homepage logic to redirect to welcome screen on first visit
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
<script setup>
|
||||
import DefaultTheme from 'vitepress/theme'
|
||||
import { useData } from 'vitepress'
|
||||
import { useData, useRoute } from 'vitepress'
|
||||
import TextType from './components/TextType.vue'
|
||||
import GitHubStars from './components/GitHubStars.vue'
|
||||
import { onMounted, ref, watch, computed } from 'vue'
|
||||
@@ -8,6 +8,7 @@ import ReadingProgress from './components/ReadingProgress.vue'
|
||||
import { Setting } from '@element-plus/icons-vue'
|
||||
|
||||
const { frontmatter } = useData()
|
||||
const route = useRoute()
|
||||
|
||||
const homeTaglineTyping = {
|
||||
typingSpeed: 45,
|
||||
@@ -86,6 +87,11 @@ const toggleSidebar = () => {
|
||||
}
|
||||
|
||||
const isHomePage = computed(() => frontmatter.value.layout === 'home')
|
||||
const isWelcomePage = computed(() =>
|
||||
route.path === '/welcome/' ||
|
||||
route.path.endsWith('/welcome/') ||
|
||||
route.path.endsWith('/welcome.html')
|
||||
)
|
||||
|
||||
onMounted(() => {
|
||||
const saved = clampFontSize(localStorage.getItem(FONT_SIZE_STORAGE_KEY))
|
||||
@@ -292,7 +298,7 @@ watch(sidebarCollapsed, (collapsed) => {
|
||||
|
||||
<template>
|
||||
<DefaultTheme.Layout>
|
||||
<template v-if="!isHomePage" #nav-bar-title-before>
|
||||
<template v-if="!isHomePage && !isWelcomePage" #nav-bar-title-before>
|
||||
<button
|
||||
class="ev-sidebar-nav-btn"
|
||||
type="button"
|
||||
@@ -430,7 +436,7 @@ watch(sidebarCollapsed, (collapsed) => {
|
||||
</DefaultTheme.Layout>
|
||||
<ClientOnly>
|
||||
<div
|
||||
v-if="!isHomePage"
|
||||
v-if="!isHomePage && !isWelcomePage"
|
||||
class="ev-sidebar-hover-area"
|
||||
:class="{ collapsed: sidebarCollapsed }"
|
||||
>
|
||||
|
||||
@@ -8,6 +8,7 @@ const { site, page, lang } = useData()
|
||||
const activeTab = ref('home')
|
||||
const showLangMenu = ref(false)
|
||||
const topPromoProgress = ref(1)
|
||||
const WELCOME_SEEN_KEY = 'easy-vibe-welcome-seen'
|
||||
|
||||
// Appendix Scroll Logic
|
||||
const appendixWrapper = ref(null)
|
||||
@@ -1629,7 +1630,45 @@ const topPromoStyle = computed(() => {
|
||||
}
|
||||
})
|
||||
|
||||
const replayIntro = () => {
|
||||
const currentPath = window.location.pathname
|
||||
router.go(withBase(`/welcome/?next=${encodeURIComponent(currentPath)}`))
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
const currentPath = window.location.pathname
|
||||
const basePath = site.value.base || '/'
|
||||
const normalizedBase = basePath.endsWith('/') ? basePath : `${basePath}/`
|
||||
const normalizedPath = currentPath.endsWith('/')
|
||||
? currentPath
|
||||
: `${currentPath}/`
|
||||
const localeHomeSuffixes = [
|
||||
'/zh-cn/',
|
||||
'/en/',
|
||||
'/zh-tw/',
|
||||
'/ja-jp/',
|
||||
'/ko-kr/',
|
||||
'/es-es/',
|
||||
'/fr-fr/',
|
||||
'/de-de/',
|
||||
'/ar-sa/',
|
||||
'/vi-vn/'
|
||||
]
|
||||
const isLocaleHome = localeHomeSuffixes.some(
|
||||
(suffix) =>
|
||||
currentPath.endsWith(suffix) ||
|
||||
currentPath.endsWith(`${suffix}index.html`)
|
||||
)
|
||||
const isRootHome =
|
||||
normalizedPath === normalizedBase ||
|
||||
currentPath === `${normalizedBase}index.html`
|
||||
if (isRootHome && !isLocaleHome) {
|
||||
const hasSeenWelcome = window.localStorage.getItem(WELCOME_SEEN_KEY) === '1'
|
||||
if (!hasSeenWelcome) {
|
||||
router.go(withBase(`/welcome/?next=${encodeURIComponent(currentPath)}`))
|
||||
return
|
||||
}
|
||||
}
|
||||
document.addEventListener('click', closeLangMenu)
|
||||
if (appendixWrapper.value) {
|
||||
appendixWrapper.value.addEventListener('scroll', onAppendixScroll)
|
||||
@@ -1822,7 +1861,13 @@ const appendixCards = [
|
||||
<nav class="sticky-nav glass">
|
||||
<div class="nav-content">
|
||||
<div class="nav-cluster">
|
||||
<span class="nav-title">{{ t.nav.title }}</span>
|
||||
<button
|
||||
class="nav-title"
|
||||
type="button"
|
||||
@click="replayIntro"
|
||||
>
|
||||
{{ t.nav.title }}
|
||||
</button>
|
||||
<div class="nav-links">
|
||||
<button
|
||||
:class="{ active: activeTab === 'home' }"
|
||||
@@ -2247,6 +2292,11 @@ a {
|
||||
color: var(--vp-c-text-1) !important;
|
||||
flex-shrink: 0;
|
||||
letter-spacing: -0.008em;
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.nav-links {
|
||||
|
||||
@@ -0,0 +1,319 @@
|
||||
<script setup>
|
||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||
import { useRouter, withBase } from 'vitepress'
|
||||
import easyVibePaths from '../data/easyVibePaths.json'
|
||||
|
||||
const router = useRouter()
|
||||
const WELCOME_SEEN_KEY = 'easy-vibe-welcome-seen'
|
||||
const phase = ref('reset')
|
||||
const theme = ref('ocean')
|
||||
const themes = ['ocean', 'rainbow', 'sunset']
|
||||
let timers = []
|
||||
|
||||
const themeColor = computed(() => `url(#welcome-${theme.value})`)
|
||||
const themeClass = computed(() => `welcome-theme-${theme.value}`)
|
||||
|
||||
const clearTimers = () => {
|
||||
timers.forEach((timer) => clearTimeout(timer))
|
||||
timers = []
|
||||
}
|
||||
|
||||
const runLoop = () => {
|
||||
clearTimers()
|
||||
const run = () => {
|
||||
phase.value = 'draw'
|
||||
timers.push(
|
||||
setTimeout(() => {
|
||||
phase.value = 'fade'
|
||||
}, 6200)
|
||||
)
|
||||
timers.push(
|
||||
setTimeout(() => {
|
||||
phase.value = 'reset'
|
||||
}, 7600)
|
||||
)
|
||||
timers.push(
|
||||
setTimeout(() => {
|
||||
const currentIndex = themes.indexOf(theme.value)
|
||||
theme.value = themes[(currentIndex + 1) % themes.length]
|
||||
run()
|
||||
}, 7800)
|
||||
)
|
||||
}
|
||||
timers.push(setTimeout(run, 80))
|
||||
}
|
||||
|
||||
const enterHome = () => {
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
const nextPath = params.get('next')
|
||||
window.localStorage.setItem(WELCOME_SEEN_KEY, '1')
|
||||
if (nextPath) {
|
||||
router.go(nextPath)
|
||||
return
|
||||
}
|
||||
router.go(withBase('/'))
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
runLoop()
|
||||
})
|
||||
|
||||
onUnmounted(() => {
|
||||
clearTimers()
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="welcome-overlay"
|
||||
:class="themeClass"
|
||||
@click="enterHome"
|
||||
>
|
||||
<div class="welcome-content">
|
||||
<div
|
||||
class="welcome-logo"
|
||||
:style="{ '--welcome-theme-color': themeColor }"
|
||||
:class="{
|
||||
'welcome-fin': phase === 'draw' || phase === 'fade',
|
||||
'welcome-fade': phase === 'fade',
|
||||
'welcome-reset': phase === 'reset'
|
||||
}"
|
||||
>
|
||||
<svg
|
||||
viewBox="0 0 460 220"
|
||||
class="welcome-svg"
|
||||
>
|
||||
<defs>
|
||||
<linearGradient
|
||||
id="welcome-rainbow"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="460"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0%" stop-color="#00a6ff" />
|
||||
<stop offset="18%" stop-color="#00c6a2" />
|
||||
<stop offset="36%" stop-color="#53d93e" />
|
||||
<stop offset="54%" stop-color="#f4c732" />
|
||||
<stop offset="72%" stop-color="#ff7a1a" />
|
||||
<stop offset="86%" stop-color="#ff3c81" />
|
||||
<stop offset="100%" stop-color="#9d4edd" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="welcome-ocean"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="460"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0%" stop-color="#06b6d4" />
|
||||
<stop offset="50%" stop-color="#0ea5e9" />
|
||||
<stop offset="100%" stop-color="#3b82f6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="welcome-sunset"
|
||||
x1="0"
|
||||
y1="0"
|
||||
x2="460"
|
||||
y2="0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
>
|
||||
<stop offset="0%" stop-color="#f43f5e" />
|
||||
<stop offset="50%" stop-color="#f97316" />
|
||||
<stop offset="100%" stop-color="#f59e0b" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path
|
||||
v-for="(path, index) in easyVibePaths"
|
||||
:key="index"
|
||||
:d="path"
|
||||
class="welcome-path"
|
||||
:class="`welcome-path-${index}`"
|
||||
/>
|
||||
</svg>
|
||||
</div>
|
||||
<p class="welcome-tip">
|
||||
Click anywhere to enter home
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.welcome-overlay {
|
||||
position: fixed;
|
||||
inset: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
overflow: hidden;
|
||||
isolation: isolate;
|
||||
background:
|
||||
radial-gradient(120% 90% at 50% -20%, rgba(255, 255, 255, 0.86), rgba(255, 255, 255, 0)),
|
||||
linear-gradient(135deg, #e8f8ff 0%, #e9edff 36%, #efe7ff 68%, #ffeef4 100%);
|
||||
background-size: 130% 130%;
|
||||
background-position: 0% 0%;
|
||||
cursor: pointer;
|
||||
animation: welcome-bg-base-flow 42s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
.welcome-overlay::before,
|
||||
.welcome-overlay::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
inset: -18%;
|
||||
pointer-events: none;
|
||||
will-change: transform, opacity;
|
||||
}
|
||||
|
||||
.welcome-overlay::before {
|
||||
background:
|
||||
radial-gradient(60% 58% at 18% 45%, rgba(182, 225, 255, 0.32), rgba(182, 225, 255, 0)),
|
||||
radial-gradient(48% 52% at 82% 62%, rgba(223, 199, 255, 0.28), rgba(223, 199, 255, 0));
|
||||
animation: welcome-bg-wave-a 26s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
.welcome-overlay::after {
|
||||
background:
|
||||
radial-gradient(54% 52% at 68% 26%, rgba(186, 245, 228, 0.24), rgba(186, 245, 228, 0)),
|
||||
radial-gradient(56% 48% at 30% 82%, rgba(255, 219, 189, 0.22), rgba(255, 219, 189, 0));
|
||||
animation: welcome-bg-wave-b 34s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
.welcome-theme-ocean {
|
||||
background:
|
||||
radial-gradient(120% 90% at 50% -20%, rgba(255, 255, 255, 0.88), rgba(255, 255, 255, 0)),
|
||||
linear-gradient(135deg, #e0f7fa 0%, #e7f0ff 45%, #eef3ff 100%);
|
||||
}
|
||||
|
||||
.welcome-theme-rainbow {
|
||||
background:
|
||||
radial-gradient(120% 90% at 50% -20%, rgba(255, 255, 255, 0.9), rgba(255, 255, 255, 0)),
|
||||
linear-gradient(135deg, #e8f8ff 0%, #e9edff 36%, #efe7ff 68%, #ffeef4 100%);
|
||||
}
|
||||
|
||||
.welcome-theme-sunset {
|
||||
background:
|
||||
radial-gradient(120% 90% at 50% -20%, rgba(255, 255, 255, 0.86), rgba(255, 255, 255, 0)),
|
||||
linear-gradient(135deg, #fff0e8 0%, #ffe9dc 45%, #ffe1f0 100%);
|
||||
}
|
||||
|
||||
.welcome-content {
|
||||
width: min(88vw, 700px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 24px;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.welcome-logo {
|
||||
width: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.welcome-svg {
|
||||
width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.welcome-path {
|
||||
fill: var(--welcome-theme-color);
|
||||
fill-opacity: 0;
|
||||
stroke: var(--welcome-theme-color);
|
||||
stroke-width: 2;
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-dasharray: 1000;
|
||||
stroke-dashoffset: 1000;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.welcome-fin .welcome-path {
|
||||
stroke-dashoffset: 0;
|
||||
fill-opacity: 1;
|
||||
}
|
||||
|
||||
.welcome-fin .welcome-path-0 { transition: stroke-dashoffset 0.62s ease-in-out 0s, fill-opacity 0.45s ease-in 2.75s; }
|
||||
.welcome-fin .welcome-path-1 { transition: stroke-dashoffset 0.62s ease-in-out 0.28s, fill-opacity 0.45s ease-in 2.75s; }
|
||||
.welcome-fin .welcome-path-2 { transition: stroke-dashoffset 0.62s ease-in-out 0.56s, fill-opacity 0.45s ease-in 2.75s; }
|
||||
.welcome-fin .welcome-path-3 { transition: stroke-dashoffset 0.62s ease-in-out 0.84s, fill-opacity 0.45s ease-in 2.75s; }
|
||||
.welcome-fin .welcome-path-4 { transition: stroke-dashoffset 0.62s ease-in-out 1.12s, fill-opacity 0.45s ease-in 2.75s; }
|
||||
.welcome-fin .welcome-path-5 { transition: stroke-dashoffset 0.62s ease-in-out 1.4s, fill-opacity 0.45s ease-in 2.75s; }
|
||||
.welcome-fin .welcome-path-6 { transition: stroke-dashoffset 0.62s ease-in-out 1.68s, fill-opacity 0.45s ease-in 2.75s; }
|
||||
.welcome-fin .welcome-path-7 { transition: stroke-dashoffset 0.62s ease-in-out 1.96s, fill-opacity 0.45s ease-in 2.75s; }
|
||||
.welcome-fin .welcome-path-8 { transition: stroke-dashoffset 0.62s ease-in-out 2.24s, fill-opacity 0.45s ease-in 2.75s; }
|
||||
|
||||
.welcome-fade {
|
||||
opacity: 0;
|
||||
transition: opacity 0.85s ease-out;
|
||||
}
|
||||
|
||||
.welcome-reset {
|
||||
opacity: 0;
|
||||
transition: none;
|
||||
}
|
||||
|
||||
.welcome-tip {
|
||||
margin: 24px 0 0;
|
||||
font-size: 11px;
|
||||
letter-spacing: 0.08em;
|
||||
color: rgba(34, 34, 34, 0.38);
|
||||
text-transform: uppercase;
|
||||
animation: welcome-tip-breathe 7s ease-in-out infinite;
|
||||
}
|
||||
|
||||
@keyframes welcome-tip-breathe {
|
||||
0% {
|
||||
opacity: 0.24;
|
||||
}
|
||||
50% {
|
||||
opacity: 0.72;
|
||||
}
|
||||
100% {
|
||||
opacity: 0.24;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes welcome-bg-base-flow {
|
||||
0% {
|
||||
background-position: 0% 0%;
|
||||
}
|
||||
100% {
|
||||
background-position: 100% 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes welcome-bg-wave-a {
|
||||
0% {
|
||||
transform: translate3d(-2.5%, 1.8%, 0) scale(1.02);
|
||||
opacity: 0.72;
|
||||
}
|
||||
50% {
|
||||
transform: translate3d(2%, -1.6%, 0) scale(1.06);
|
||||
opacity: 0.9;
|
||||
}
|
||||
100% {
|
||||
transform: translate3d(4%, -2.4%, 0) scale(1.08);
|
||||
opacity: 0.72;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes welcome-bg-wave-b {
|
||||
0% {
|
||||
transform: translate3d(2.2%, -1.4%, 0) scale(1.01);
|
||||
opacity: 0.6;
|
||||
}
|
||||
50% {
|
||||
transform: translate3d(-2.6%, 1.6%, 0) scale(1.05);
|
||||
opacity: 0.86;
|
||||
}
|
||||
100% {
|
||||
transform: translate3d(-4.4%, 2.4%, 0) scale(1.07);
|
||||
opacity: 0.6;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,10 @@
|
||||
[
|
||||
"M59.28 123.24Q60.84 123.24 61.74 124.68Q62.64 126.12 62.64 128.64L62.64 128.64Q62.64 133.44 60.36 136.08L60.36 136.08Q55.92 141.48 47.82 146.04Q39.72 150.60 30.48 150.60L30.48 150.60Q17.88 150.60 10.92 143.76Q3.96 136.92 3.96 125.04L3.96 125.04Q3.96 116.76 7.44 109.62Q10.92 102.48 17.10 98.28Q23.28 94.08 31.08 94.08L31.08 94.08Q38.04 94.08 42.24 98.22Q46.44 102.36 46.44 109.44L46.44 109.44Q46.44 117.72 40.50 123.66Q34.56 129.60 20.40 133.08L20.40 133.08Q23.40 138.60 31.80 138.60L31.80 138.60Q37.20 138.60 44.10 134.82Q51 131.04 56.04 124.92L56.04 124.92Q57.48 123.24 59.28 123.24L59.28 123.24ZM29.04 105.84Q24.60 105.84 21.54 111Q18.48 116.16 18.48 123.48L18.48 123.48L18.48 123.72Q25.56 122.04 29.64 118.68Q33.72 115.32 33.72 110.88L33.72 110.88Q33.72 108.60 32.46 107.22Q31.20 105.84 29.04 105.84L29.04 105.84Z",
|
||||
"M67.68 150.60Q60.24 150.60 55.80 145.20Q51.36 139.80 51.36 131.04L51.36 131.04Q51.36 121.44 55.80 112.86Q60.24 104.28 67.62 99.06Q75 93.84 83.28 93.84L83.28 93.84Q85.92 93.84 86.82 94.86Q87.72 95.88 88.32 98.52L88.32 98.52Q90.84 98.04 93.60 98.04L93.60 98.04Q99.48 98.04 99.48 102.24L99.48 102.24Q99.48 104.76 97.68 114.24L97.68 114.24Q94.92 128.04 94.92 133.44L94.92 133.44Q94.92 135.24 95.82 136.32Q96.72 137.40 98.16 137.40L98.16 137.40Q100.44 137.40 103.68 134.46Q106.92 131.52 112.44 124.92L112.44 124.92Q113.88 123.24 115.68 123.24L115.68 123.24Q117.24 123.24 118.14 124.68Q119.04 126.12 119.04 128.64L119.04 128.64Q119.04 133.44 116.76 136.08L116.76 136.08Q111.84 142.20 106.32 146.40Q100.80 150.60 95.64 150.60L95.64 150.60Q91.68 150.60 88.38 147.90Q85.08 145.20 83.40 140.52L83.40 140.52Q77.16 150.60 67.68 150.60L67.68 150.60ZM72 138.48Q74.64 138.48 77.04 135.36Q79.44 132.24 80.52 127.08L80.52 127.08L84.96 105Q79.92 105.12 75.66 108.78Q71.40 112.44 68.88 118.44Q66.36 124.44 66.36 131.16L66.36 131.16Q66.36 134.88 67.86 136.68Q69.36 138.48 72 138.48L72 138.48Z",
|
||||
"M131.64 153.24Q125.40 153.24 122.10 150.36Q118.80 147.48 118.80 143.88L118.80 143.88Q118.80 140.76 121.08 138.48Q123.36 136.20 127.80 136.20L127.80 136.20Q129.36 136.20 131.46 136.50Q133.56 136.80 134.64 136.92L134.64 136.92Q134.52 133.80 133.26 131.04Q132 128.28 130.08 125.70Q128.16 123.12 126.48 121.20L126.48 121.20Q122.76 128.28 119.10 132.96Q115.44 137.64 111.12 141.84L111.12 141.84Q108.96 144 106.56 144L106.56 144Q104.64 144 103.44 142.62Q102.24 141.24 102.24 139.20L102.24 139.20Q102.24 136.80 103.92 134.76L103.92 134.76L105.48 132.84Q112.08 124.68 115.44 119.40L115.44 119.40Q117.48 115.92 120.24 110.10Q123 104.28 125.64 98.04L125.64 98.04Q127.92 92.76 135.12 92.76L135.12 92.76Q138.48 92.76 139.80 93.36Q141.12 93.96 141.12 95.28L141.12 95.28Q141.12 96 140.64 97.56Q140.16 99.12 139.32 100.68L139.32 100.68Q137.16 105 137.16 108L137.16 108Q137.16 109.80 138.42 111.96Q139.68 114.12 142.32 117.36L142.32 117.36Q146.16 122.40 148.14 125.94Q150.12 129.48 150.12 133.68L150.12 133.68Q150.12 134.88 149.88 137.04L149.88 137.04Q155.76 134.76 163.68 124.92L163.68 124.92Q165.12 123.24 166.92 123.24L166.92 123.24Q168.48 123.24 169.38 124.68Q170.28 126.12 170.28 128.64L170.28 128.64Q170.28 133.20 168 136.08L168 136.08Q162 143.52 156.54 146.22Q151.08 148.92 143.04 149.16L143.04 149.16Q138.24 153.24 131.64 153.24L131.64 153.24Z",
|
||||
"M222 123.48Q223.56 123.48 224.46 124.98Q225.36 126.48 225.36 128.76L225.36 128.76Q225.36 131.52 224.52 133.08Q223.68 134.64 221.88 135.84L221.88 135.84L198.84 151.32Q194.28 176.16 186.90 190.38Q179.52 204.60 168.12 204.60L168.12 204.60Q162 204.60 158.16 200.82Q154.32 197.04 154.32 190.92L154.32 190.92Q154.32 185.28 156.90 179.40Q159.48 173.52 166.50 165.90Q173.52 158.28 186.36 148.44L186.36 148.44L186.72 145.68Q187.56 141.24 188.64 132.96L188.64 132.96Q186.24 141.60 181.92 146.10Q177.60 150.60 172.80 150.60L172.80 150.60Q167.40 150.60 163.98 145.62Q160.56 140.64 160.56 133.20L160.56 133.20Q160.56 124.20 161.76 116.70Q162.96 109.20 165.72 100.80L165.72 100.80Q166.92 97.20 169.08 95.64Q171.24 94.08 175.92 94.08L175.92 94.08Q178.56 94.08 179.58 94.92Q180.60 95.76 180.60 97.44L180.60 97.44Q180.60 98.40 179.28 103.92L179.28 103.92Q178.08 108.36 177.36 111.96L177.36 111.96Q176.40 116.88 175.68 121.38Q174.96 125.88 174.96 128.76L174.96 128.76Q174.96 133.32 177.48 133.32L177.48 133.32Q179.28 133.32 181.98 129.72Q184.68 126.12 187.74 118.80Q190.80 111.48 193.68 100.80L193.68 100.80Q194.64 97.20 196.62 95.64Q198.60 94.08 202.56 94.08L202.56 94.08Q205.32 94.08 206.40 94.80Q207.48 95.52 207.48 97.20L207.48 97.20Q207.48 100.20 204.36 117.84L204.36 117.84L201.24 137.16Q210.48 130.20 219.24 124.44L219.24 124.44Q220.80 123.48 222 123.48L222 123.48ZM169.44 192.96Q172.44 192.96 176.16 186Q179.88 179.04 183.60 162.84L183.60 162.84Q174.36 170.64 170.22 177.06Q166.08 183.48 166.08 188.28L166.08 188.28Q166.08 190.32 166.86 191.64Q167.64 192.96 169.44 192.96L169.44 192.96Z",
|
||||
"M309.24 113.52Q309.60 113.40 310.44 113.40L310.44 113.40Q312.24 113.40 313.20 114.60Q314.16 115.80 314.16 117.84L314.16 117.84Q314.16 121.56 312.72 123.66Q311.28 125.76 308.40 126.72L308.40 126.72Q302.88 128.52 296.64 128.52L296.64 128.52Q291.36 128.52 286.68 127.08L286.68 127.08Q283.20 132.72 279 138.72L279 138.72Q274.20 145.56 270.72 148.08Q267.24 150.60 262.80 150.60L262.80 150.60Q257.88 150.60 255.06 146.76Q252.24 142.92 251.52 134.64L251.52 134.64Q250.08 117.84 250.08 105.24L250.08 105.24L250.08 101.04Q250.20 97.08 252.24 95.52Q254.28 93.96 258.36 93.96L258.36 93.96Q261.48 93.96 262.98 95.34Q264.48 96.72 264.48 99.96L264.48 99.96Q264.48 113.76 266.16 135.84L266.16 135.84Q273.36 125.16 276.96 118.80L276.96 118.80Q275.16 115.32 275.16 110.52L275.16 110.52Q275.16 106.44 276.96 102.60Q278.76 98.76 281.88 96.36Q285 93.96 288.96 93.96L288.96 93.96Q292.44 93.96 294.60 96.42Q296.76 98.88 296.76 103.56L296.76 103.56Q296.76 108.96 293.88 115.92L293.88 115.92Q298.44 115.68 306 114.12L306 114.12L309.24 113.52Z",
|
||||
"M319.44 86.16Q314.40 86.16 311.88 83.82Q309.36 81.48 309.36 77.28L309.36 77.28Q309.36 73.08 312.66 70.26Q315.96 67.44 320.88 67.44L320.88 67.44Q325.32 67.44 328.08 69.60Q330.84 71.76 330.84 75.72L330.84 75.72Q330.84 80.52 327.72 83.34Q324.60 86.16 319.44 86.16L319.44 86.16ZM318.48 150.60Q310.68 150.60 307.14 145.08Q303.60 139.56 303.60 130.44L303.60 130.44Q303.60 125.04 304.98 116.58Q306.36 108.12 308.52 100.80L308.52 100.80Q309.60 96.96 311.40 95.52Q313.20 94.08 317.16 94.08L317.16 94.08Q323.28 94.08 323.28 98.16L323.28 98.16Q323.28 101.16 321 112.08L321 112.08Q318.12 125.28 318.12 129.96L318.12 129.96Q318.12 133.56 319.08 135.48Q320.04 137.40 322.32 137.40L322.32 137.40Q324.48 137.40 327.72 134.40Q330.96 131.40 336.36 124.92L336.36 124.92Q337.80 123.24 339.60 123.24L339.60 123.24Q341.16 123.24 342.06 124.68Q342.96 126.12 342.96 128.64L342.96 128.64Q342.96 133.44 340.68 136.08L340.68 136.08Q328.80 150.60 318.48 150.60L318.48 150.60Z",
|
||||
"M397.08 113.16Q398.64 113.16 399.48 114.72Q400.32 116.28 400.32 118.68L400.32 118.68Q400.32 121.68 399.48 123.30Q398.64 124.92 396.84 125.52L396.84 125.52Q389.64 128.04 381.00 128.40L381.00 128.40Q378.60 138.36 371.94 144.48Q365.28 150.60 357.24 150.60L357.24 150.60Q345.12 150.60 339.60 141.36Q334.08 132.12 334.08 114.60L334.08 114.60Q334.08 99.12 337.92 80.94Q341.76 62.76 349.14 49.98Q356.52 37.20 366.72 37.20L366.72 37.20Q372.24 37.20 375.60 41.94Q378.96 46.68 378.96 54.24L378.96 54.24Q378.96 64.08 375.24 73.80Q371.52 83.52 362.88 94.20L362.88 94.20Q370.92 94.80 375.96 100.86Q381.00 106.92 381.96 115.80L381.96 115.80Q387.60 115.44 395.40 113.40L395.40 113.40Q396.12 113.16 397.08 113.16L397.08 113.16ZM363.96 49.08Q361.56 49.08 358.74 56.22Q355.92 63.36 353.52 75.60Q351.12 87.84 349.92 102.36L349.92 102.36Q357.84 87.84 362.58 76.74Q367.32 65.64 367.32 57L367.32 57Q367.32 53.16 366.42 51.12Q365.52 49.08 363.96 49.08L363.96 49.08ZM357.72 137.88Q361.44 137.88 364.32 134.76Q367.20 131.64 368.16 125.76L368.16 125.76Q364.44 123.24 362.46 119.16Q360.48 115.08 360.48 110.52L360.48 110.52Q360.48 108.84 360.96 105.96L360.96 105.96L360.60 105.96Q355.68 105.96 352.38 110.82Q349.08 115.68 349.08 123.84L349.08 123.84Q349.08 130.68 351.66 134.28Q354.24 137.88 357.72 137.88L357.72 137.88Z",
|
||||
"M443.52 123.24Q445.08 123.24 445.98 124.68Q446.88 126.12 446.88 128.64L446.88 128.64Q446.88 133.44 444.60 136.08L444.60 136.08Q440.16 141.48 432.06 146.04Q423.96 150.60 414.72 150.60L414.72 150.60Q402.12 150.60 395.16 143.76Q388.20 136.92 388.20 125.04L388.20 125.04Q388.20 116.76 391.68 109.62Q395.16 102.48 401.34 98.28Q407.52 94.08 415.32 94.08L415.32 94.08Q422.28 94.08 426.48 98.22Q430.68 102.36 430.68 109.44L430.68 109.44Q430.68 117.72 424.74 123.66Q418.80 129.60 404.64 133.08L404.64 133.08Q407.64 138.60 416.04 138.60L416.04 138.60Q421.44 138.60 428.34 134.82Q435.24 131.04 440.28 124.92L440.28 124.92Q441.72 123.24 443.52 123.24L443.52 123.24ZM413.28 105.84Q408.84 105.84 405.78 111Q402.72 116.16 402.72 123.48L402.72 123.48L402.72 123.72Q409.80 122.04 413.88 118.68Q417.96 115.32 417.96 110.88L417.96 110.88Q417.96 108.60 416.70 107.22Q415.44 105.84 413.28 105.84L413.28 105.84Z"
|
||||
]
|
||||
@@ -9,6 +9,7 @@ import { useRoute, useData } from 'vitepress'
|
||||
import './style.css'
|
||||
import Layout from './Layout.vue'
|
||||
import HomeFeatures from './components/HomeFeatures.vue'
|
||||
import WelcomeScreen from './components/WelcomeScreen.vue'
|
||||
import NavGrid from './components/NavGrid.vue'
|
||||
import NavCard from './components/NavCard.vue'
|
||||
import CategoryIndex from './components/CategoryIndex.vue'
|
||||
@@ -846,6 +847,7 @@ export default {
|
||||
enhanceApp({ app }) {
|
||||
app.use(ElementPlus)
|
||||
app.component('HomeFeatures', HomeFeatures)
|
||||
app.component('WelcomeScreen', WelcomeScreen)
|
||||
app.component('NavGrid', NavGrid)
|
||||
app.component('NavCard', NavCard)
|
||||
app.component('CategoryIndex', CategoryIndex)
|
||||
|
||||
@@ -772,7 +772,7 @@
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://datawhalechina.github.io/easy-vibe/zh-cn/stage-0/0.1-learning-map/</loc>
|
||||
<lastmod>2026-02-26T04:35:28+08:00</lastmod>
|
||||
<lastmod>2026-03-16T12:42:29+08:00</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://datawhalechina.github.io/easy-vibe/zh-cn/stage-0/0.1-learning-map/"/>
|
||||
@@ -780,7 +780,7 @@
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://datawhalechina.github.io/easy-vibe/zh-cn/stage-0/0.2-ai-capabilities-through-games/</loc>
|
||||
<lastmod>2026-02-26T04:35:28+08:00</lastmod>
|
||||
<lastmod>2026-03-16T12:42:29+08:00</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://datawhalechina.github.io/easy-vibe/zh-cn/stage-0/0.2-ai-capabilities-through-games/"/>
|
||||
@@ -812,7 +812,7 @@
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://datawhalechina.github.io/easy-vibe/zh-cn/stage-1/1.1-introduction-to-ai-ide/</loc>
|
||||
<lastmod>2026-03-06T17:59:01+08:00</lastmod>
|
||||
<lastmod>2026-03-16T12:42:29+08:00</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://datawhalechina.github.io/easy-vibe/zh-cn/stage-1/1.1-introduction-to-ai-ide/"/>
|
||||
@@ -820,7 +820,7 @@
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://datawhalechina.github.io/easy-vibe/zh-cn/stage-1/1.2-building-prototype/</loc>
|
||||
<lastmod>2026-03-06T17:59:01+08:00</lastmod>
|
||||
<lastmod>2026-03-16T12:42:29+08:00</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://datawhalechina.github.io/easy-vibe/zh-cn/stage-1/1.2-building-prototype/"/>
|
||||
@@ -828,7 +828,7 @@
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://datawhalechina.github.io/easy-vibe/zh-cn/stage-1/1.3-integrating-ai-capabilities/</loc>
|
||||
<lastmod>2026-03-12T13:45:38+08:00</lastmod>
|
||||
<lastmod>2026-03-16T12:42:29+08:00</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://datawhalechina.github.io/easy-vibe/zh-cn/stage-1/1.3-integrating-ai-capabilities/"/>
|
||||
@@ -836,7 +836,7 @@
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://datawhalechina.github.io/easy-vibe/zh-cn/stage-1/1.4-complete-project-practice/</loc>
|
||||
<lastmod>2026-02-26T05:34:19+08:00</lastmod>
|
||||
<lastmod>2026-03-16T12:42:29+08:00</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.9</priority>
|
||||
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://datawhalechina.github.io/easy-vibe/zh-cn/stage-1/1.4-complete-project-practice/"/>
|
||||
@@ -963,14 +963,14 @@
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/2.0-lovart-assets/</loc>
|
||||
<lastmod>2026-03-05T22:32:03+08:00</lastmod>
|
||||
<lastmod>2026-03-16T12:42:29+08:00</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/2.0-lovart-assets/"/>
|
||||
</url>
|
||||
<url>
|
||||
<loc>https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/2.1-figma-mastergo/</loc>
|
||||
<lastmod>2026-02-27T18:46:11+08:00</lastmod>
|
||||
<lastmod>2026-03-16T12:42:29+08:00</lastmod>
|
||||
<changefreq>weekly</changefreq>
|
||||
<priority>0.8</priority>
|
||||
<xhtml:link rel="alternate" hreflang="zh-CN" href="https://datawhalechina.github.io/easy-vibe/zh-cn/stage-2/frontend/2.1-figma-mastergo/"/>
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
layout: false
|
||||
---
|
||||
|
||||
<WelcomeScreen />
|
||||
Reference in New Issue
Block a user