feat: enhance typography with new font sources, update footer layout, and improve navigation structure

This commit is contained in:
yuanhau 2025-05-07 00:03:44 +08:00
parent 7c7601a38b
commit d773473eb0
13 changed files with 172 additions and 31 deletions

View file

@ -1,6 +1,8 @@
<script setup lang="ts">
import "bootstrap-icons/font/bootstrap-icons.css";
import "animate.css";
import "@fontsource/fira-sans";
import '@fontsource-variable/noto-sans-tc';
const { t } = useI18n();
</script>
<template>

View file

@ -4,6 +4,9 @@
"": {
"name": "nuxt-app",
"dependencies": {
"@fontsource-variable/noto-sans-tc": "^5.2.5",
"@fontsource/fira-code": "^5.2.6",
"@fontsource/fira-sans": "^5.2.5",
"@heroicons/vue": "^2.2.0",
"@nuxt/image": "1.10.0",
"@nuxtjs/i18n": "9.5.4",
@ -176,6 +179,12 @@
"@fastify/busboy": ["@fastify/busboy@3.1.1", "", {}, "sha512-5DGmA8FTdB2XbDeEwc/5ZXBl6UbBAyBOOLlPuBnZ/N1SwdH9Ii+cOX3tBROlDgcTXxjOYnLMVoKk9+FXAw0CJw=="],
"@fontsource-variable/noto-sans-tc": ["@fontsource-variable/noto-sans-tc@5.2.5", "", {}, "sha512-oaAn5hkLxraNBOWuiqyJ6+t1SmQ9Sszmcs+wJpmAmUO/1dsaHjDU5HXEjutvPpucqVeqdvVNr/kHRx+ghdiPeA=="],
"@fontsource/fira-code": ["@fontsource/fira-code@5.2.6", "", {}, "sha512-wCkIpPm0BqlkCPLYeY4Vui96ODmVUV0/GpEe3OfJ4v8EJn/BF2SlyxvarFsTs1CKiGjrO2cXlIZbBrKi9F+hUQ=="],
"@fontsource/fira-sans": ["@fontsource/fira-sans@5.2.5", "", {}, "sha512-N+GrTGOTIeYE/Wi5tY0RAnc1Tl3ddCdwfZQncvA1zH/lOpKerj9ZS5nfniSXDZ9wrXFRdWTH7anyrRDc+cMpCg=="],
"@heroicons/vue": ["@heroicons/vue@2.2.0", "", { "peerDependencies": { "vue": ">= 3" } }, "sha512-G3dbSxoeEKqbi/DFalhRxJU4mTXJn7GwZ7ae8NuEQzd1bqdd0jAbdaBZlHPcvPD2xI1iGzNVB4k20Un2AguYPw=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],

View file

@ -1,9 +1,12 @@
<template>
<div
class="flex flex-row justify-center align-center text-center absolute inset-x-0"
class="flex flex-col justify-center align-center text-center absolute inset-x-0"
>
<span class="text-xs m-4"
>{{ new Date().getFullYear() }} &copy; 吳元皓</span
<span class="text-sm m-4 mb-0 text-center align-center justify-center"
>{{ new Date().getFullYear() }} &copy; yh</span
>
<span class="text-xs mt-0 m-2 text-center align-center justify-center">
Inspired by Ground.News
</span>
</div>
</template>

View file

@ -1,9 +1,6 @@
<script setup lang="ts">
import { gsap } from "gsap";
import { ScrambleTextPlugin } from "gsap/dist/ScrambleTextPlugin";
gsap.registerPlugin(ScrambleTextPlugin);
const { t, locale, locales } = useI18n();
const localePath = useLocalePath();
const switchLocalePath = useSwitchLocalePath();
const dropdownOpen = ref(false);
@ -17,39 +14,32 @@ const toggleDropdown = () => {
dropdownOpen.value = !dropdownOpen.value;
};
const runAnimation = () => {
gsap.to(title.value, {
duration: 1,
scrambleText: "BlindSpec",
});
};
</script>
<template>
<!--Spent too much time trying to set a Navbar....-->
<div
class="fixed top-0 inset-x-0 bg-[#81611a]/70 backdrop-blur-sm h-[55px] flex align-center flex-row text-white pl-4 pt-2 gap-x-5 justify-between z-50 rounded-3xl m-2"
class="fixed top-0 inset-x-0 bg-[#81611a]/70 backdrop-blur-sm h-[55px] flex align-center items-center flex-row text-white pl-4 gap-x-5 justify-between z-50 rounded-3xl m-2"
>
<div class="text-3xl text-bold">
<!--Use mouseenter instead of hover-->
<a href="/" @mouseenter="runAnimation" ref="title"> BlindSpec </a>
<NuxtLink :to="localePath('home')" ref="title">BlindSpec</NuxtLink>
</div>
<div class="text-[0.9em] text-center align-center">
<a
href="/"
<div class="text-[0.9em] left-1/2 absolute transform -translate-x-1/2 space-x-4 items-center">
<NuxtLink
:to="localePath('home')"
class="hover:text-blue-500 cursor-pointer transiton-all duration-100"
>{{ t("nav.home") }}</a
>{{ t("nav.home") }}</NuxtLink
>
&nbsp;
<a
href="/dailybriefing"
<NuxtLink
:to="localePath('dailybriefing')"
class="hover:text-blue-500 cursor-pointer transiton-all duration-100"
>{{ t("nav.dailybriefing") }}</a
>{{ t("nav.dailybriefing") }}</NuxtLink
>
</div>
<div class="relative">
<button
@click="toggleDropdown"
class="flex items-center space-x-2 px-4 py-2 rounded hover:bg-gray-900 transition-all duration-100"
class="flex items-center space-x-1 px-4 py-2 rounded hover:bg-gray-900 transition-all duration-100 mr-5"
>
<span>{{ locale }}</span>
<svg
@ -68,8 +58,8 @@ const runAnimation = () => {
</button>
<Transition
enter-active-class="animate__animated animate__fadeInDown animate__faster"
leave-active-class="animate__animated animate__fadeOutUp animate__faster"
enter-active-class="animate__animated animate__fadeInDown animate_fastest"
leave-active-class="animate__animated animate__fadeOutUp animate_fastest"
>
<div
v-if="dropdownOpen"
@ -89,3 +79,8 @@ const runAnimation = () => {
</div>
</div>
</template>
<style scoped>
.animate_fastest {
--animate-duration: 0.2s;
}
</style>

View file

@ -6,6 +6,15 @@
"home": "Home",
"dailybriefing": "Daily Briefing"
},
"home": {
"nonMoving": "Hi! This is your ",
"moving": {
"newsPlatform": "News Platform",
"miniWikipedia": "Mini Wikipedia",
"newsComparePlatform": "news comparison platform"
},
"startusing": "Let's Start!"
},
"dailybriefing": "Daily Briefing",
"Welcome": "Welcome",
"loading": "Loading..."

View file

@ -6,6 +6,15 @@
"home": "首頁",
"dailybriefing": "今日報導"
},
"home": {
"nonMoving": "嗨!這是你的",
"moving": {
"newsPlatform": "新聞平台",
"miniWikipedia": "米你維基百科",
"newsComparePlatform": "新聞觀點比對平台"
},
"startusing": "開始使用!"
},
"dailybriefing": "今日報導",
"Welcome": "歡迎",
"loading": "載入中..."

View file

@ -11,6 +11,9 @@
"prettier": "prettier --write ."
},
"dependencies": {
"@fontsource-variable/noto-sans-tc": "^5.2.5",
"@fontsource/fira-code": "^5.2.6",
"@fontsource/fira-sans": "^5.2.5",
"@heroicons/vue": "^2.2.0",
"@nuxt/image": "1.10.0",
"@nuxtjs/i18n": "9.5.4",

3
pages/dailybriefing.vue Normal file
View file

@ -0,0 +1,3 @@
<template>
</template>

View file

@ -1,5 +1,48 @@
<script setup lang="ts">
import { gsap } from 'gsap'
import { TextPlugin } from 'gsap/TextPlugin'
gsap.registerPlugin(TextPlugin)
const { t } = useI18n();
const popMessage = ref(null);
const messages = [t("home.moving.newsPlatform"), t("home.moving.miniWikipedia"), t("home.moving.newsComparePlatform"), "BlindSpec"];
onMounted(() => {
const tl = gsap.timeline({ repeat: -1 })
messages.forEach((message) => {
tl.to(popMessage.value, {
duration:0.5,
text:message,
ease: "none."
}).to(popMessage.value, {
duration:2,
text:message,
ease: "none."
})
for (let i = message.length; i >=0; i--) {
tl.to(popMessage.value, {
duration:0.06,
text:message.substring(0, i),
ease: "none"
})
}
})
})
</script>
<template>
<div>
<h1 class="text-3xl font-bold text-center"></h1>
<div class="flex flex-col justify-center align-center text-center absolute w-full h-screen inset-x-0 inset-y-0">
<span class="text-3xl">
<span class="bg-gradient-to-b from-[#eee] to-[#333] bg-clip-text text-transparent">{{ t("home.nonMoving") }}</span>
<span ref="popMessage" class="bg-gradient-to-r from-[#2a7b9b] then-[#8d57c7] to-[#ed4242] bg-clip-text text-transparent"></span></span>
<NuxtLink>
<button class="m-4 bg-[#8C9393] text-white p-3 rounded-full bg-gradient-to-l from-sky-500 to-purple-600 transition-all duration-100">
<span>{{ t("home.startusing") }}</span>
</button>
</NuxtLink>
</div>
<div class="h-screen"></div>
</div>
</template>

View file

@ -26,6 +26,20 @@ const {
},
});
const {
data: fetchOtherData,
pending: fetchOtherDataPending,
error: fetchOtherDataError,
} = useFetch("/api/getData/fetchSidebarData", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: {
lang: locale,
}
})
watchEffect(() => {
loading.value = pending.value;
});
@ -46,10 +60,10 @@ onMounted(() => {
import { GlobeAltIcon } from "@heroicons/vue/24/outline";
</script>
<template>
<div>
<div class="text-center align-center justify-center">
<div class="flex flex-row flex-wrap w-full mt-2">
<div class="text-center align-center justify-center w-[70%]">
<div
class="flex flex-row bg-[#AAACAAFF] rounded-3xl p-3 gap-3 m-3 scale-5"
class="flex flex-row bg-[#AAACAA61] rounded-3xl p-3 gap-3 m-3 scale-5"
>
<NuxtImg
:src="fetchNewsOrgInfo?.logoUrl"
@ -76,5 +90,28 @@ import { GlobeAltIcon } from "@heroicons/vue/24/outline";
>
</div>
</div>
<div class="flex flex-col gap-3 text-left justify-right align-right bg-[#AAACAA61] w-[28%] rounded-3xl p-3 mt-3 h-screen">
<h3 class="text-2xl mt-2s">其他媒體</h3>
<hr/>
<div v-for="data in fetchOtherData" :key="data.id" class="flex flex-col">
<NuxtImg :src="data.image"></NuxtImg>
<div class="flex flex-row">
<h1 class="text-xl text-bold">{{ data.title }}</h1>
<span class="text-ms ml-2 align-center justify-center text-center">
(
<span>{{ data.lean }}</span>
-
<span>文章分數:
<span>{{ data.score }}</span>
</span> )
</span>
</div>
</div>
<NuxtLink class="justify-center align-center text-center">
<button class="bg-red-500 text-black p-2 rounded-full justify-center align-center">
<span>查看更多</span>
</button>
</NuxtLink>
</div>
</div>
</template>

3
pages/newsOrgs.vue Normal file
View file

@ -0,0 +1,3 @@
<template>
</template>

View file

@ -0,0 +1,13 @@
export default defineEventHandler(async (event) => {
const body = await readBody(event);
return {
0: {
id: "1",
image: "whatever",
tags: [],
title: "三立新聞",
lean: "left",
score: "40"
}
};
});

View file

@ -9,4 +9,16 @@
body {
@apply bg-black m-0 p-0 min-h-screen text-white;
}
html,body {
font-family: 'Noto Sans TC Variable', "Fira Sans", sans-serif;
}
}
/* noto-sans-tc-chinese-traditional-wght-normal */
@font-face {
font-family: 'Noto Sans TC Variable';
font-style: normal;
font-display: auto;
font-weight: 100 900;
src: url(@fontsource-variable/noto-sans-tc/files/noto-sans-tc-chinese-traditional-wght-normal.woff2) format('woff2-variations');
}