Skip to content

Commit ab3a111

Browse files
committed
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
1 parent 67daaff commit ab3a111

7 files changed

Lines changed: 404 additions & 12 deletions

File tree

docs/.vitepress/theme/Layout.vue

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
<script setup>
22
import DefaultTheme from 'vitepress/theme'
3-
import { useData } from 'vitepress'
3+
import { useData, useRoute } from 'vitepress'
44
import TextType from './components/TextType.vue'
55
import GitHubStars from './components/GitHubStars.vue'
66
import { onMounted, ref, watch, computed } from 'vue'
77
import ReadingProgress from './components/ReadingProgress.vue'
88
import { Setting } from '@element-plus/icons-vue'
99
1010
const { frontmatter } = useData()
11+
const route = useRoute()
1112
1213
const homeTaglineTyping = {
1314
typingSpeed: 45,
@@ -86,6 +87,11 @@ const toggleSidebar = () => {
8687
}
8788
8889
const isHomePage = computed(() => frontmatter.value.layout === 'home')
90+
const isWelcomePage = computed(() =>
91+
route.path === '/welcome/' ||
92+
route.path.endsWith('/welcome/') ||
93+
route.path.endsWith('/welcome.html')
94+
)
8995
9096
onMounted(() => {
9197
const saved = clampFontSize(localStorage.getItem(FONT_SIZE_STORAGE_KEY))
@@ -292,7 +298,7 @@ watch(sidebarCollapsed, (collapsed) => {
292298

293299
<template>
294300
<DefaultTheme.Layout>
295-
<template v-if="!isHomePage" #nav-bar-title-before>
301+
<template v-if="!isHomePage && !isWelcomePage" #nav-bar-title-before>
296302
<button
297303
class="ev-sidebar-nav-btn"
298304
type="button"
@@ -430,7 +436,7 @@ watch(sidebarCollapsed, (collapsed) => {
430436
</DefaultTheme.Layout>
431437
<ClientOnly>
432438
<div
433-
v-if="!isHomePage"
439+
v-if="!isHomePage && !isWelcomePage"
434440
class="ev-sidebar-hover-area"
435441
:class="{ collapsed: sidebarCollapsed }"
436442
>

docs/.vitepress/theme/components/HomeFeatures.vue

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const { site, page, lang } = useData()
88
const activeTab = ref('home')
99
const showLangMenu = ref(false)
1010
const topPromoProgress = ref(1)
11+
const WELCOME_SEEN_KEY = 'easy-vibe-welcome-seen'
1112
1213
// Appendix Scroll Logic
1314
const appendixWrapper = ref(null)
@@ -1629,7 +1630,45 @@ const topPromoStyle = computed(() => {
16291630
}
16301631
})
16311632
1633+
const replayIntro = () => {
1634+
const currentPath = window.location.pathname
1635+
router.go(withBase(`/welcome/?next=${encodeURIComponent(currentPath)}`))
1636+
}
1637+
16321638
onMounted(() => {
1639+
const currentPath = window.location.pathname
1640+
const basePath = site.value.base || '/'
1641+
const normalizedBase = basePath.endsWith('/') ? basePath : `${basePath}/`
1642+
const normalizedPath = currentPath.endsWith('/')
1643+
? currentPath
1644+
: `${currentPath}/`
1645+
const localeHomeSuffixes = [
1646+
'/zh-cn/',
1647+
'/en/',
1648+
'/zh-tw/',
1649+
'/ja-jp/',
1650+
'/ko-kr/',
1651+
'/es-es/',
1652+
'/fr-fr/',
1653+
'/de-de/',
1654+
'/ar-sa/',
1655+
'/vi-vn/'
1656+
]
1657+
const isLocaleHome = localeHomeSuffixes.some(
1658+
(suffix) =>
1659+
currentPath.endsWith(suffix) ||
1660+
currentPath.endsWith(`${suffix}index.html`)
1661+
)
1662+
const isRootHome =
1663+
normalizedPath === normalizedBase ||
1664+
currentPath === `${normalizedBase}index.html`
1665+
if (isRootHome && !isLocaleHome) {
1666+
const hasSeenWelcome = window.localStorage.getItem(WELCOME_SEEN_KEY) === '1'
1667+
if (!hasSeenWelcome) {
1668+
router.go(withBase(`/welcome/?next=${encodeURIComponent(currentPath)}`))
1669+
return
1670+
}
1671+
}
16331672
document.addEventListener('click', closeLangMenu)
16341673
if (appendixWrapper.value) {
16351674
appendixWrapper.value.addEventListener('scroll', onAppendixScroll)
@@ -1822,7 +1861,13 @@ const appendixCards = [
18221861
<nav class="sticky-nav glass">
18231862
<div class="nav-content">
18241863
<div class="nav-cluster">
1825-
<span class="nav-title">{{ t.nav.title }}</span>
1864+
<button
1865+
class="nav-title"
1866+
type="button"
1867+
@click="replayIntro"
1868+
>
1869+
{{ t.nav.title }}
1870+
</button>
18261871
<div class="nav-links">
18271872
<button
18281873
:class="{ active: activeTab === 'home' }"
@@ -2247,6 +2292,11 @@ a {
22472292
color: var(--vp-c-text-1) !important;
22482293
flex-shrink: 0;
22492294
letter-spacing: -0.008em;
2295+
background: none;
2296+
border: none;
2297+
padding: 0;
2298+
margin: 0;
2299+
cursor: pointer;
22502300
}
22512301
22522302
.nav-links {

0 commit comments

Comments
 (0)