mirror of
https://github.com/sendevia/website.git
synced 2026-03-06 07:40:50 +08:00
feat(theme): 使用配置文件提供全局变量
This commit is contained in:
@@ -25,7 +25,6 @@ export default defineConfig({
|
||||
lazyLoading: true,
|
||||
},
|
||||
},
|
||||
|
||||
head: [
|
||||
["link", { rel: "preconnect", href: "https://fonts.googleapis.com" }],
|
||||
["link", { rel: "preconnect", href: "https://fonts.gstatic.com", crossorigin: "" }],
|
||||
@@ -38,10 +37,16 @@ export default defineConfig({
|
||||
],
|
||||
["link", { href: "https://fonts.googleapis.com/css2?family=Josefin+Sans:ital,wght@0,100..700;1,100..700&display=swap", rel: "stylesheet" }],
|
||||
],
|
||||
vite: {
|
||||
define: {
|
||||
__SITE_VERSION__: JSON.stringify(packageJson.version || "0.0.0"),
|
||||
__DEFAULT_COLOR__: JSON.stringify("#39c5bb"),
|
||||
},
|
||||
},
|
||||
themeConfig: {
|
||||
defaultColor: "#39c5bb",
|
||||
defaultImpression: "/assets/images/116014672_p0.webp",
|
||||
siteVersion: packageJson.version || "0.0.0",
|
||||
navSegment: [
|
||||
{ text: "首页", icon: "home", link: "/" },
|
||||
{ text: "所有文章", icon: "list", link: "/posts" },
|
||||
{ text: "Markdown 示例", icon: "counter_1", link: "/posts/markdown-examples" },
|
||||
{ text: "API 示例", icon: "counter_2", link: "/posts/api-examples" },
|
||||
{ text: "Markdown it", icon: "counter_3", link: "/posts/markdown-it" },
|
||||
],
|
||||
} as any,
|
||||
});
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
|
||||
import { useGlobalData } from "../composables/useGlobalData";
|
||||
const { site, page } = useGlobalData();
|
||||
|
||||
// @ts-ignore
|
||||
const siteVersion = __SITE_VERSION__;
|
||||
|
||||
const { site, page, theme } = useGlobalData();
|
||||
const siteVersion = theme.value.siteVersion;
|
||||
const buildDate = ref("");
|
||||
|
||||
if (typeof window !== "undefined") {
|
||||
fetch("/index.html", { method: "HEAD" })
|
||||
.then((res) => {
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { useGlobalData } from "../composables/useGlobalData";
|
||||
const { frontmatter } = useGlobalData();
|
||||
|
||||
const { page, frontmatter, theme } = useGlobalData();
|
||||
const seed = ref(1);
|
||||
const defaultImpression = theme.value.defaultImpression;
|
||||
|
||||
onMounted(() => {
|
||||
seed.value = Date.now();
|
||||
});
|
||||
@@ -25,14 +27,15 @@ onMounted(() => {
|
||||
</filter>
|
||||
</svg>
|
||||
<div id="header-hero-container">
|
||||
<span id="header-hero-headline">{{ frontmatter.title }}</span>
|
||||
<span id="header-hero-headline">{{ frontmatter.title ? frontmatter.title : page.title }}</span>
|
||||
<span id="header-hero-subtitle">{{ frontmatter.description }}</span>
|
||||
<div id="header-impression">
|
||||
<div id="header-impression-noise"></div>
|
||||
<div
|
||||
id="header-impression-image"
|
||||
:style="{ backgroundImage: frontmatter.impression ? `url('${frontmatter.impression}')` : '' }"
|
||||
:style="{ backgroundImage: frontmatter.impression ? `url('${frontmatter.impression}')` : `url('${defaultImpression}')` }"
|
||||
:impression-color="frontmatter.color"
|
||||
loading="lazy"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from "vue";
|
||||
|
||||
import { useGlobalData } from "../composables/useGlobalData";
|
||||
const { page } = useGlobalData();
|
||||
|
||||
const navItems = computed(() => [
|
||||
{ text: "首页", icon: "home", link: "/" },
|
||||
{ text: "所有文章", icon: "list", link: "/posts" },
|
||||
{ text: "Markdown 示例", icon: "counter_1", link: "/posts/markdown-examples" },
|
||||
{ text: "API 示例", icon: "counter_2", link: "/posts/api-examples" },
|
||||
{ text: "Markdown it", icon: "counter_3", link: "/posts/markdown-it" },
|
||||
]);
|
||||
const { page, theme } = useGlobalData();
|
||||
const navSegment = computed(() => {
|
||||
const items = theme.value.navSegment;
|
||||
if (Array.isArray(items) && items.length > 0) return items;
|
||||
});
|
||||
|
||||
function isActive(link: string) {
|
||||
const current = page.value.relativePath.replace(/(\/index)?\.md$/, "");
|
||||
@@ -25,7 +21,7 @@ function isActive(link: string) {
|
||||
<span>search</span>
|
||||
</a>
|
||||
<ul id="navigation-destinations">
|
||||
<li v-for="item in navItems" :key="item.link" :class="isActive(item.link) ? 'navigation-segment-active' : 'navigation-segment-inactive'">
|
||||
<li v-for="item in navSegment" :key="item.link" :class="isActive(item.link) ? 'navigation-segment-active' : 'navigation-segment-inactive'">
|
||||
<a :href="item.link">
|
||||
<div class="navigation-destination-accent">
|
||||
<div class="navigation-segment-icon">
|
||||
|
||||
@@ -10,14 +10,15 @@ import { generateColorPalette } from "../utils/colorPalette";
|
||||
import { onMounted, nextTick } from "vue";
|
||||
import { useRoute } from "vitepress";
|
||||
import { useGlobalData } from "../composables/useGlobalData";
|
||||
const { site, page, frontmatter } = useGlobalData();
|
||||
|
||||
const { site, page, frontmatter, theme } = useGlobalData();
|
||||
|
||||
/**
|
||||
* 获取图片主色调(取图片左上角像素点的颜色)
|
||||
* @param url 图片地址
|
||||
* @returns Promise<number | null> 返回 ARGB 颜色值,获取失败返回 null
|
||||
*/
|
||||
function getImageMainColor(url: string): Promise<number | null> {
|
||||
async function getImageMainColor(url: string): Promise<number | null> {
|
||||
return new Promise((resolve) => {
|
||||
if (!url) return resolve(null);
|
||||
const img = new window.Image();
|
||||
@@ -40,17 +41,12 @@ function getImageMainColor(url: string): Promise<number | null> {
|
||||
|
||||
/**
|
||||
* 根据头图动态更新调色板
|
||||
* 1. 等待 DOM 更新后查找 id="header-impression-image" 的元素
|
||||
* 2. 如果找不到该元素,则使用默认颜色生成调色板
|
||||
* 3. 如果元素有 impression-color 属性且为合法的 hex 颜色,则用该颜色生成调色板
|
||||
* 4. 否则尝试从元素的 backgroundImage 提取图片 URL,并获取图片主色调
|
||||
* 5. 最终调用 generateColorPalette 生成调色板
|
||||
*/
|
||||
async function updatePalette() {
|
||||
await nextTick();
|
||||
const el = document.getElementById("header-impression-image");
|
||||
// @ts-ignore
|
||||
const defaultColor = __DEFAULT_COLOR__;
|
||||
const defaultColor = theme.value.defaultColor;
|
||||
|
||||
if (!el) {
|
||||
await generateColorPalette(argbFromHex(defaultColor));
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user