Compare commits

..

No commits in common. "dev" and "v4.1.4" have entirely different histories.
dev ... v4.1.4

18 changed files with 3229 additions and 3974 deletions

View File

@ -26,7 +26,7 @@ VITE_DESC_TEXT_OTHER = "哎呀,这都被你发现了( 再点击一次可关
## 请注意不是 Web端 (JS API),免费申请,每日上限 5000 次 ## 请注意不是 Web端 (JS API),免费申请,每日上限 5000 次
## 此处提供的服务可能会超量从而无法访问,请自行申请!请自行申请!请自行申请! ## 此处提供的服务可能会超量从而无法访问,请自行申请!请自行申请!请自行申请!
## 若此处设为空则调用 教书先生 API https://api.oioweb.cn/doc/weather/GetWeather ## 若此处设为空则调用 教书先生 API https://api.oioweb.cn/doc/weather/GetWeather
VITE_WEATHER_KEY = "" VITE_WEATHER_KEY = "6c13af6fc30868bee488faf2cc652ab4"
# 建站日期 # 建站日期
## 若不需要,请设为空即可 ## 若不需要,请设为空即可
@ -48,4 +48,4 @@ VITE_SONG_SERVER = "netease"
# 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 ) # 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
VITE_SONG_TYPE = "playlist" VITE_SONG_TYPE = "playlist"
# 播放 ID ( 若无需播放器,请设为空即可 ) # 播放 ID ( 若无需播放器,请设为空即可 )
VITE_SONG_ID = "9379831714" VITE_SONG_ID = "7452421335"

View File

@ -22,14 +22,6 @@ jobs:
uses: actions/setup-node@v4.0.0 uses: actions/setup-node@v4.0.0
with: with:
node-version: "18.x" node-version: "18.x"
# 复制环境变量文件
- name: Copy .env.example
run: |
if (-not (Test-Path .env)) {
Copy-Item .env.example .env
} else {
Write-Host ".env file already exists. Skipping the copy step."
}
# 安装项目依赖 # 安装项目依赖
- name: Install Dependencies - name: Install Dependencies
run: npm install run: npm install

1
.gitignore vendored
View File

@ -11,7 +11,6 @@ node_modules
dist dist
dist-ssr dist-ssr
*.local *.local
.env
# Editor directories and files # Editor directories and files
.vscode/* .vscode/*

View File

@ -4,7 +4,6 @@ WORKDIR /app
COPY package*.json ./ COPY package*.json ./
RUN npm install RUN npm install
COPY . . COPY . .
RUN [ ! -e ".env" ] && cp .env.example .env || true
RUN npm run build RUN npm run build
# 最小化镜像 # 最小化镜像

482
README.md
View File

@ -1,244 +1,238 @@
简体中文 | [English](./README_EN.md) 简体中文 | [English](./README_EN.md)
<p> <p>
<strong><h2>無名の主页</h2></strong> <strong><h2>無名の主页</h2></strong>
简单的小主页,原来的看够了,重新弄了一个 简单的小主页,原来的看够了,重新弄了一个
</p> </p>
![無名の主页](/screenshots/main.jpg) ![無名の主页](/screenshots/main.jpg)
> 主页的 Logo 字体已经过压缩,若用本站 Logo 以外的字母会变回默认字体,这里是 [完整字体](https://file.imsyy.top/font/Other/Pacifico-Regular.ttf),若无法下载,可将字体目录下的 `Pacifico-Regular-all.ttf` 进行替换 >主页的 Logo 字体已经过压缩,若用本站 Logo 以外的字母会变回默认字体,这里是 [完整字体](https://file.imsyy.top/font/Other/Pacifico-Regular.ttf),若无法下载,可将字体目录下的 `Pacifico-Regular-all.ttf` 进行替换
### 👀 Demo ### Demo
> 由于 CDN 缓存原因,查看最新效果可能需要 `Ctrl` + `F5` 强制刷新浏览器缓存 >由于 CDN 缓存原因,查看最新效果可能需要 `Ctrl` + `F5` 强制刷新浏览器缓存
- [無名の主页](https://www.imsyy.top) - [無名の主页](https://www.imsyy.top)
- [無名の主页 - Dev](https://home-imsyy.vercel.app) - [無名の主页 - Dev](https://home-imsyy.vercel.app)
- [無名の主页 - 备用线路](https://home-5iw.pages.dev) - [無名の主页 - 备用线路](https://home-5iw.pages.dev)
### 🎉 功能 ### 功能
- [x] 载入动画 - [x] 载入动画
- [x] 站点简介 - [x] 站点简介
- [x] Hitokoto 一言 - [x] Hitokoto 一言
- [x] 日期及时间 - [x] 日期及时间
- [x] 实时天气 - [x] 实时天气
- [x] 时光进度条 - [x] 时光进度条
- [x] 音乐播放器 - [x] 音乐播放器
- [x] 移动端适配 - [x] 移动端适配
### ⚙️ 自动部署 ### 自动部署
如果遇到构建环境或者打包过程出现错误,则可以采用 `Github Actions` 来进行自动构建 如果遇到构建环境或者打包过程出现错误,则可以采用 `Github Actions` 来进行自动构建
- 在成功 `fork` 仓库后,前往 `Actions` 页面,若您是首次开启,则会出现下面的提示,点击开启 - 在成功 `fork` 仓库后,前往 `Actions` 页面,若您是首次开启,则会出现下面的提示,点击开启
![步骤1](/screenshots/step1.jpg) ![步骤1](/screenshots/step1.jpg)
- 然后在仓库中进行任意修改后均会触发工作流的运行,在工作流完成后,会在下方生成一个可供下载的压缩包,这就是构建出的静态文件,可自行上传至服务器 - 然后在仓库中进行任意修改后均会触发工作流的运行,在工作流完成后,会在下方生成一个可供下载的压缩包,这就是构建出的静态文件,可自行上传至服务器
![步骤2](/screenshots/step2.jpg) ![步骤2](/screenshots/step2.jpg)
### ⚙️ 手动部署 ### 手动部署
- **安装** [node.js](https://nodejs.org/zh-cn/) **环境** * **安装** [node.js](https://nodejs.org/zh-cn/) **环境**
> node > 16.16.0 > node > 16.16.0
> npm > 8.15.0 > npm > 8.15.0
- 然后以 **管理员权限** 运行 `cmd` 终端,并 `cd` 到 项目根目录 * 然后以 **管理员权限** 运行 `cmd` 终端,并 `cd` 到 项目根目录
- 在 `终端` 中输入: * 在 `终端` 中输入:
```bash ```bash
# 安装 pnpm # 安装 pnpm
npm install -g pnpm npm install -g pnpm
# 安装依赖 # 安装依赖
pnpm install pnpm install
# 预览 # 预览
pnpm dev pnpm dev
# 构建 # 构建
pnpm build pnpm build
``` ```
> 构建完成后,静态资源会在 **`dist` 目录** 中生成,可将 **`dist` 文件夹下的文件**上传至服务器,也可使用 `Vercel` 等托管平台一键导入并自动部署
> 构建完成后,静态资源会在 **`dist` 目录** 中生成,可将 **`dist` 文件夹下的文件**上传至服务器,也可使用 `Vercel` 等托管平台一键导入并自动部署
### Docker 部署
### ⚙️ Docker 部署
> 安装及配置 Docker 将不在此处说明,请自行解决
> 安装及配置 Docker 将不在此处说明,请自行解决
```bash
```bash # 构建
# 构建 docker build -t home .
docker build -t home . # 运行
# 运行 docker run -p 12445:12445 -d home
docker run -p 12445:12445 -d home ```
```
### 网站链接
### ⚙️ Vercel 部署
`src/assets/siteLinks.json` 中可以自定义网站链接(以指向自己的网站):
> 其他部署平台大致相同,在此不做说明
```json
1. 点击本仓库右上角的 `Fork`,复制本仓库到你的 `GitHub` 账号 {
2. 复制 `/.env.example` 文件并重命名为 `/.env` 重要 "icon": "Blog",
3. 按需修改 `/.env` 文件中的配置 "name": "博客",
4. 点击 `Deploy`,即可成功部署 "link": "https://blog.imsyy.top/"
},
### 网站链接 ```
`src/assets/siteLinks.json` 中可以自定义网站链接(以指向自己的网站): 其中 `icon` 网站链接的图标可以在 `src/components/Links/index.vue` 中添加:
```json ```js
{ // 可前往 https://www.xicons.org 自行挑选并在此处引入
"icon": "Blog", // 此处引入的是 fa 类型
"name": "博客", import {
"link": "https://blog.imsyy.top/" Link,
}, Blog,
``` CompactDisc,
Cloud,
其中 `icon` 网站链接的图标可以在 `src/components/Links/index.vue` 中添加: Compass,
Book,
```js Fire,
// 可前往 https://www.xicons.org 自行挑选并在此处引入 LaptopCode,
// 此处引入的是 fa 类型 } from "@vicons/fa";
import {
Link, ...
Blog,
CompactDisc, // 网站链接图标
Cloud, const siteIcon = {
Compass, Blog,
Book, Cloud,
Fire, CompactDisc,
LaptopCode, Compass,
} from "@vicons/fa"; Book,
Fire,
... LaptopCode,
};
// 网站链接图标 ```
const siteIcon = {
Blog, ### 社交链接
Cloud,
CompactDisc, `src/assets/socialLinks.json` 中可以自定义社交链接。
Compass,
Book, ### 天气
Fire,
LaptopCode, 天气及地区获取需要 `高德开放平台` 相关 API
};
``` - 前往 [高德开放平台控制台](https://console.amap.com/dev/index) 创建一个 `Web 服务` 类型的 `Key`,并将 `Key` 填入 `.env` 中的 `VITE_WEATHER_KEY`
### 社交链接 也可自行更换其他方式
`src/assets/socialLinks.json` 中可以自定义社交链接。
### 音乐
### 天气
>本项目采用了基于 `MetingJS``Aplayer` 音乐播放器,可实现快速自定义歌单
天气及地区获取需要 `高德开放平台` 相关 API >*仅支持 **中国大陆地区**
- 前往 [高德开放平台控制台](https://console.amap.com/dev/index) 创建一个 `Web 服务` 类型的 `Key`,并将 `Key` 填入 `.env` 中的 `VITE_WEATHER_KEY` 请在 `.env` 文件中更改歌曲相关参数即可实现自定义歌单列表
也可自行更换其他方式 ```bash
# 歌曲 API 地址
### 音乐 VITE_SONG_API = "https://api-meting.imsyy.top"
# 歌曲服务器 ( netease-网易云, tencent-qq音乐 )
> 本项目采用了基于 `MetingJS``Aplayer` 音乐播放器,可实现快速自定义歌单 VITE_SONG_SERVER = "netease"
> \*仅支持 **中国大陆地区** # 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
VITE_SONG_TYPE = "playlist"
请在 `.env` 文件中更改歌曲相关参数即可实现自定义歌单列表 # 播放 ID
VITE_SONG_ID = "7452421335"
```bash ```
# 歌曲 API 地址
VITE_SONG_API = "https://api-meting.imsyy.top" ### 字体
# 歌曲服务器 ( netease-网易云, tencent-qq音乐 )
VITE_SONG_SERVER = "netease" 现采用 `HarmonyOS Sans` 开源字体,采用字体拆分,提升加载速度
# 播放类型 ( song-歌曲, playlist-播放列表, album-专辑, search-搜索, artist-艺术家 )
VITE_SONG_TYPE = "playlist" >由于本站 `CDN` 已开启防盗链,**非本站域名不可访问**,请将字体引入链接更改为下方内容,否则 **自定义字体将失效**
# 播放 ID >
VITE_SONG_ID = "7452421335" >`https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css`
```
<details>
### 字体 <summary>旧版方式</summary>
现采用 `HarmonyOS Sans` 开源字体,采用字体拆分,提升加载速度 >由于本项目引入了中文字体,需要压缩中文字体以提高网页加载速度( 也可以取消使用中文字体
> 由于本站 `CDN` 已开启防盗链,**非本站域名不可访问**,请将字体引入链接更改为下方内容,否则 **自定义字体将失效** #### 中文字体去除繁体
>
> `https://s1.hdslb.com/bfs/static/jinkela/long/font/regular.css` - 安装 `Python 3.7``pip`
- 运行 `pip install fonttools`
<details> - 下载 [sc_unicode.txt](https://gist.githubusercontent.com/imaegoo/d64e5088b723c2e02c40985f55ff12db/raw/5ebd2ce49418c73459a9dfe050483409306a6c1d/sc_unicode.txt)
<summary>旧版方式</summary> - 运行 `pyftsubset 字体名称.ttf --unicodes-file=sc_unicode.txt`
> 由于本项目引入了中文字体,需要压缩中文字体以提高网页加载速度( 也可以取消使用中文字体 #### 字体进一步压缩
#### 中文字体去除繁体 - 编译安装 `Google woff2`
- 安装 `Python 3.7``pip` ```bash
- 运行 `pip install fonttools` sudo apt-get install -y git g++ make
- 下载 [sc_unicode.txt](https://gist.githubusercontent.com/imaegoo/d64e5088b723c2e02c40985f55ff12db/raw/5ebd2ce49418c73459a9dfe050483409306a6c1d/sc_unicode.txt) git clone --recursive https://github.com/google/woff2.git
- 运行 `pyftsubset 字体名称.ttf --unicodes-file=sc_unicode.txt` cd woff2
make clean all
#### 字体进一步压缩 ```
- 编译安装 `Google woff2` - 再压缩字体
```bash ```
sudo apt-get install -y git g++ make ./woff2_compress ./字体名称.ttf
git clone --recursive https://github.com/google/woff2.git ```
cd woff2
make clean all - 最终可对原字体进行缓加载,**先行加载压缩后的字体**
```
>详细信息可前往 [虹墨空间站](https://www.imaegoo.com/2020/chinese-font-compress/) 查看原文
- 再压缩字体
</details>
```
./woff2_compress ./字体名称.ttf ### 网站图标及网站背景
```
#### 网站背景
- 最终可对原字体进行缓加载,**先行加载压缩后的字体**
可以在 `public/images` 中修改网站背景
> 详细信息可前往 [虹墨空间站](https://www.imaegoo.com/2020/chinese-font-compress/) 查看原文
如果想要添加更多的本地图片作为网站背景,可以将图片重命名 `background+数字` 的形式,并在 `src/components/Background/index.vue` 中进行修改:
</details>
```js
### 网站图标及网站背景
if (type == 0) {
#### 网站背景 // 修改此处 Math.random() 后面的第一个数字为图片的数量
bgUrl.value = `/images/background${Math.floor(
可以在 `public/images` 中修改网站背景 Math.random() * 10 + 1
)}.webp`;
如果想要添加更多的本地图片作为网站背景,可以将图片重命名 `background+数字` 的形式,并在 `src/components/Background/index.vue` 中进行修改: }
```
```js
if (type == 0) { #### 网站图标
// 修改此处 Math.random() 后面的第一个数字为图片的数量
bgUrl.value = `/images/background${Math.floor(Math.random() * 10 + 1)}.webp`; 可以在 `public/images/icon` 中修改网站图标。
}
``` ### 技术栈
#### 网站图标 * [Vue](https://cn.vuejs.org/)
* [Vite](https://vitejs.cn/vite3-cn/)
可以在 `public/images/icon` 中修改网站图标。 * [Pinia](https://pinia.vuejs.org/zh/)
* [IconPark](https://iconpark.oceanengine.com/official)
### 技术栈 * [xicons](https://xicons.org/)
* [Aplayer](https://aplayer.js.org/)
- [Vue](https://cn.vuejs.org/)
- [Vite](https://vitejs.cn/vite3-cn/) ### API
- [Pinia](https://pinia.vuejs.org/zh/)
- [IconPark](https://iconpark.oceanengine.com/official) * [小歪 API](https://api.aixiaowai.cn)
- [xicons](https://xicons.org/) * [搏天 API](https://api.btstu.cn/doc/sjbz.php)
- [Aplayer](https://aplayer.js.org/) * [教书先生 API](https://api.oioweb.cn/doc/weather/GetWeather)
* [高德开放平台](https://lbs.amap.com/)
### API * [Hitokoto 一言](https://hitokoto.cn/)
- [韩小韩 WebAPI 接口](https://api.vvhan.com/) ## Star History
- [搏天 API](https://api.btstu.cn/doc/sjbz.php)
- [教书先生 API](https://api.oioweb.cn/doc/weather/GetWeather) [![Star History Chart](https://api.star-history.com/svg?repos=imsyy/home&type=Date)](https://star-history.com/#imsyy/home&Date)
- [高德开放平台](https://lbs.amap.com/)
- [Hitokoto 一言](https://hitokoto.cn/) <a title="SSL" target="_blank" href="https://myssl.com/seal/detail?domain=blog.imsyy.top"><img src="https://img.shields.io/badge/MySSL-安全认证-brightgreen"></a>&nbsp;<a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a>&nbsp;<a title="Copyright" target="_blank" href="https://imsyy.top/"><img src="https://img.shields.io/badge/Copyright%20%C2%A9%202020--2023-%E7%84%A1%E5%90%8D-red"></a>
## Star History
[![Star History Chart](https://api.star-history.com/svg?repos=imsyy/home&type=Date)](https://star-history.com/#imsyy/home&Date)
<a title="SSL" target="_blank" href="https://myssl.com/seal/detail?domain=blog.imsyy.top"><img src="https://img.shields.io/badge/MySSL-安全认证-brightgreen"></a>&nbsp;<a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a>&nbsp;<a title="Copyright" target="_blank" href="https://imsyy.top/"><img src="https://img.shields.io/badge/Copyright%20%C2%A9%202020--2023-%E7%84%A1%E5%90%8D-red"></a>

View File

@ -1,144 +1,144 @@
English | [Chinese](./README.md) English | [Chinese](./README.md)
<p> <p>
<strong><h2>無名の主页</h2></strong> <strong><h2>無名の主页</h2></strong>
Simple little homepage, had enough of the original one and made a new one Simple little homepage, had enough of the original one and made a new one
</p> </p>
![無名の主页](https://s2.loli.net/2022/07/14/K5JigfvDoNewtuS.webp) ![無名の主页](https://s2.loli.net/2022/07/14/K5JigfvDoNewtuS.webp)
>The logo font on the home page has been compressed, so if you use a font other than this logo, it will change back to the default font, Here is the [full font](https://file.4everland.app/font/Other/Pacifico-Regular.ttf) >The logo font on the home page has been compressed, so if you use a font other than this logo, it will change back to the default font, Here is the [full font](https://file.4everland.app/font/Other/Pacifico-Regular.ttf)
### Demo ### Demo
>Due to CDN caching, you may need `Ctrl` + `F5` to force a browser cache refresh to see the latest results >Due to CDN caching, you may need `Ctrl` + `F5` to force a browser cache refresh to see the latest results
- [無名の主页](https://www.imsyy.top) - [無名の主页](https://www.imsyy.top)
- [無名の主页 - Dev](https://home-imsyy.vercel.app) - [無名の主页 - Dev](https://home-imsyy.vercel.app)
- [無名の主页 - Standby](https://home-5iw.pages.dev) - [無名の主页 - Standby](https://home-5iw.pages.dev)
### Functions ### Functions
- [x] Loading animation - [x] Loading animation
- [x] Site description - [x] Site description
- [x] Hitokoto - [x] Hitokoto
- [x] Date and time - [x] Date and time
- [x] Live weather - [x] Live weather
- [x] Time progress bar - [x] Time progress bar
- [x] Music player - [x] Music player
- [x] Mobile adaptation - [x] Mobile adaptation
* [ ] Player cancels using Aplayer * [ ] Player cancels using Aplayer
### Deployment ### Deployment
* **Installation** [node.js](https://nodejs.org/zh-cn/) **Environment** * **Installation** [node.js](https://nodejs.org/zh-cn/) **Environment**
> node > 16.16.0 > node > 16.16.0
> npm > 8.15.0 > npm > 8.15.0
* Then run the `cmd` terminal with **administrator privileges** and `cd` to the project root directory * Then run the `cmd` terminal with **administrator privileges** and `cd` to the project root directory
* In the `terminal` type: * In the `terminal` type:
```bash ```bash
# Install pnpm # Install pnpm
npm install -g pnpm npm install -g pnpm
# Install the dependencies # Install the dependencies
pnpm install pnpm install
# Preview # Preview
pnpm dev pnpm dev
# Build # Build
pnpm build pnpm build
``` ```
> Once the build is complete, the files in the `dist` folder can be uploaded to the server or imported and automatically deployed with one click using a hosting platform such as `Vercel`. > Once the build is complete, the files in the `dist` folder can be uploaded to the server or imported and automatically deployed with one click using a hosting platform such as `Vercel`.
### Weather ### Weather
Weather and area access requires `高德开放平台` related API Weather and area access requires `高德开放平台` related API
- Go to [高德开放平台控制台](https://console.amap.com/dev/index) to create a `Key` of type `Web Service` and fill the `Key` into `VITE_WEATHER_KEY` in `.env` - Go to [高德开放平台控制台](https://console.amap.com/dev/index) to create a `Key` of type `Web Service` and fill the `Key` into `VITE_WEATHER_KEY` in `.env`
It can also be replaced by other methods It can also be replaced by other methods
### Music ### Music
>This project uses the `Aplayer` music player based on `MetingJS` for quick song list customization >This project uses the `Aplayer` music player based on `MetingJS` for quick song list customization
>*Only supported in **Mainland China** >*Only supported in **Mainland China**
Please change the song related parameters in the `.env` file to customize the song list Please change the song related parameters in the `.env` file to customize the song list
```bash ```bash
# Songs API address # Songs API address
VITE_SONG_API = "https://api-meting.imsyy.top" VITE_SONG_API = "https://api-meting.imsyy.top"
# Song server ( netease-netease, tencent-qq music ) # Song server ( netease-netease, tencent-qq music )
VITE_SONG_SERVER = "netease" VITE_SONG_SERVER = "netease"
# Playback type ( song-song, playlist-playlist, album-album, search-search, artist-artist ) # Playback type ( song-song, playlist-playlist, album-album, search-search, artist-artist )
VITE_SONG_TYPE = "playlist" VITE_SONG_TYPE = "playlist"
# Playback ID # Playback ID
VITE_SONG_ID = "7452421335" VITE_SONG_ID = "7452421335"
``` ```
### Fonts ### Fonts
Now using `HarmonyOS Sans` open source font, using font splitting to improve loading speed Now using `HarmonyOS Sans` open source font, using font splitting to improve loading speed
>Because this site's `CDN` has opened anti-leech, **non-site domain name is not accessible**, please change the font import link to the following content, otherwise **custom fonts will be invalid** >Because this site's `CDN` has opened anti-leech, **non-site domain name is not accessible**, please change the font import link to the following content, otherwise **custom fonts will be invalid**
> >
>`https://cdn.jsdelivr.net/gh/imsyy/file/font/HarmonyOS_Sans/regular.min.css` >`https://cdn.jsdelivr.net/gh/imsyy/file/font/HarmonyOS_Sans/regular.min.css`
<details> <details>
<summary>old way</summary> <summary>old way</summary>
>As Chinese fonts are introduced in this project, Chinese fonts need to be compressed to improve the loading speed of the page (you can also cancel the use of Chinese fonts) >As Chinese fonts are introduced in this project, Chinese fonts need to be compressed to improve the loading speed of the page (you can also cancel the use of Chinese fonts)
#### Chinese font removal traditional #### Chinese font removal traditional
- Install `Python 3.7` and `pip` - Install `Python 3.7` and `pip`
- Run `pip install fonttools` - Run `pip install fonttools`
- Download [sc_unicode.txt](https://gist.githubusercontent.com/imaegoo/d64e5088b723c2e02c40985f55ff12db/raw/5ebd2ce49418c73459a9dfe050483409306a6c1d/sc_unicode.txt) - Download [sc_unicode.txt](https://gist.githubusercontent.com/imaegoo/d64e5088b723c2e02c40985f55ff12db/raw/5ebd2ce49418c73459a9dfe050483409306a6c1d/sc_unicode.txt)
- Run `pyftsubset font-name.ttf --unicodes-file=sc_unicode.txt` - Run `pyftsubset font-name.ttf --unicodes-file=sc_unicode.txt`
#### fonts further compressed #### fonts further compressed
- Compile and install ``Google woff2`` - Compile and install ``Google woff2``
```bash ```bash
sudo apt-get install -y git g++ make sudo apt-get install -y git g++ make
git clone --recursive https://github.com/google/woff2.git git clone --recursive https://github.com/google/woff2.git
cd woff2 cd woff2
make clean all make clean all
``` ```
- Compress the font again - Compress the font again
``` ```
. /woff2_compress . /font_name.ttf . /woff2_compress . /font_name.ttf
``` ```
- Eventually the original font can be slow loaded, **load the compressed font first** - Eventually the original font can be slow loaded, **load the compressed font first**
>For more information, please go to [虹墨空间站](https://www.imaegoo.com/2020/chinese-font-compress/) to view the original article >For more information, please go to [虹墨空间站](https://www.imaegoo.com/2020/chinese-font-compress/) to view the original article
</details> </details>
### Technology Stack ### Technology Stack
* [Vue](https://cn.vuejs.org/) * [Vue](https://cn.vuejs.org/)
* [Vite](https://vitejs.cn/vite3-cn/) * [Vite](https://vitejs.cn/vite3-cn/)
* [Pinia](https://pinia.vuejs.org/zh/) * [Pinia](https://pinia.vuejs.org/zh/)
* [IconPark](https://iconpark.oceanengine.com/official) * [IconPark](https://iconpark.oceanengine.com/official)
* [xicons](https://xicons.org/) * [xicons](https://xicons.org/)
* [Aplayer](https://aplayer.js.org/) * [Aplayer](https://aplayer.js.org/)
### API ### API
* [韩小韩 WebAPI 接口](https://api.vvhan.com/) * [MetingAPI By 武恩赐](https://api.wuenci.com/meting/api/)
* [搏天 API](https://api.btstu.cn/doc/sjbz.php) * [搏天 API](https://api.btstu.cn/doc/sjbz.php)
* [高德开放平台](https://lbs.amap.com/) * [高德开放平台](https://lbs.amap.com/)
* [Hitokoto 一言](https://hitokoto.cn/) * [Hitokoto 一言](https://hitokoto.cn/)
<a title="SSL" target="_blank" href="https://myssl.com/seal/detail?domain=blog.imsyy.top"><img src="https://img.shields.io/badge/MySSL-安全认证-brightgreen"></a>&nbsp;<a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a>&nbsp;<a title="Copyright" target="_blank" href="https://imsyy.top/"><img src="https://img.shields.io/badge/Copyright%20%C2%A9%202020--2023-%E7%84%A1%E5%90%8D-red"></a> <a title="SSL" target="_blank" href="https://myssl.com/seal/detail?domain=blog.imsyy.top"><img src="https://img.shields.io/badge/MySSL-安全认证-brightgreen"></a>&nbsp;<a title="CDN" target="_blank" href="https://cdnjs.com/"><img src="https://img.shields.io/badge/CDN-Cloudflare-blue"></a>&nbsp;<a title="Copyright" target="_blank" href="https://imsyy.top/"><img src="https://img.shields.io/badge/Copyright%20%C2%A9%202020--2023-%E7%84%A1%E5%90%8D-red"></a>

57
auto-imports.d.ts vendored
View File

@ -1,57 +0,0 @@
// Generated by 'unplugin-auto-import'
export {}
declare global {
const EffectScope: typeof import('vue')['EffectScope']
const ElMessage: typeof import('element-plus/es')['ElMessage']
const computed: typeof import('vue')['computed']
const createApp: typeof import('vue')['createApp']
const customRef: typeof import('vue')['customRef']
const defineAsyncComponent: typeof import('vue')['defineAsyncComponent']
const defineComponent: typeof import('vue')['defineComponent']
const effectScope: typeof import('vue')['effectScope']
const getCurrentInstance: typeof import('vue')['getCurrentInstance']
const getCurrentScope: typeof import('vue')['getCurrentScope']
const h: typeof import('vue')['h']
const inject: typeof import('vue')['inject']
const isProxy: typeof import('vue')['isProxy']
const isReactive: typeof import('vue')['isReactive']
const isReadonly: typeof import('vue')['isReadonly']
const isRef: typeof import('vue')['isRef']
const markRaw: typeof import('vue')['markRaw']
const nextTick: typeof import('vue')['nextTick']
const onActivated: typeof import('vue')['onActivated']
const onBeforeMount: typeof import('vue')['onBeforeMount']
const onBeforeUnmount: typeof import('vue')['onBeforeUnmount']
const onBeforeUpdate: typeof import('vue')['onBeforeUpdate']
const onDeactivated: typeof import('vue')['onDeactivated']
const onErrorCaptured: typeof import('vue')['onErrorCaptured']
const onMounted: typeof import('vue')['onMounted']
const onRenderTracked: typeof import('vue')['onRenderTracked']
const onRenderTriggered: typeof import('vue')['onRenderTriggered']
const onScopeDispose: typeof import('vue')['onScopeDispose']
const onServerPrefetch: typeof import('vue')['onServerPrefetch']
const onUnmounted: typeof import('vue')['onUnmounted']
const onUpdated: typeof import('vue')['onUpdated']
const provide: typeof import('vue')['provide']
const reactive: typeof import('vue')['reactive']
const readonly: typeof import('vue')['readonly']
const ref: typeof import('vue')['ref']
const resolveComponent: typeof import('vue')['resolveComponent']
const resolveDirective: typeof import('vue')['resolveDirective']
const shallowReactive: typeof import('vue')['shallowReactive']
const shallowReadonly: typeof import('vue')['shallowReadonly']
const shallowRef: typeof import('vue')['shallowRef']
const toRaw: typeof import('vue')['toRaw']
const toRef: typeof import('vue')['toRef']
const toRefs: typeof import('vue')['toRefs']
const triggerRef: typeof import('vue')['triggerRef']
const unref: typeof import('vue')['unref']
const useAttrs: typeof import('vue')['useAttrs']
const useCssModule: typeof import('vue')['useCssModule']
const useCssVars: typeof import('vue')['useCssVars']
const useSlots: typeof import('vue')['useSlots']
const watch: typeof import('vue')['watch']
const watchEffect: typeof import('vue')['watchEffect']
const watchPostEffect: typeof import('vue')['watchPostEffect']
const watchSyncEffect: typeof import('vue')['watchSyncEffect']
}

35
components.d.ts vendored
View File

@ -1,35 +0,0 @@
// generated by unplugin-vue-components
// We suggest you to commit this file into source control
// Read more: https://github.com/vuejs/core/pull/3399
import '@vue/runtime-core'
export {}
declare module '@vue/runtime-core' {
export interface GlobalComponents {
Background: typeof import('./src/components/Background.vue')['default']
ElCard: typeof import('element-plus/es')['ElCard']
ElCol: typeof import('element-plus/es')['ElCol']
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElProgress: typeof import('element-plus/es')['ElProgress']
ElRadio: typeof import('element-plus/es')['ElRadio']
ElRadioGroup: typeof import('element-plus/es')['ElRadioGroup']
ElRow: typeof import('element-plus/es')['ElRow']
ElSlider: typeof import('element-plus/es')['ElSlider']
ElSwitch: typeof import('element-plus/es')['ElSwitch']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
Footer: typeof import('./src/components/Footer.vue')['default']
Hitokoto: typeof import('./src/components/Hitokoto.vue')['default']
Links: typeof import('./src/components/Links.vue')['default']
Loading: typeof import('./src/components/Loading.vue')['default']
Message: typeof import('./src/components/Message.vue')['default']
MoreContent: typeof import('./src/components/MoreContent.vue')['default']
Music: typeof import('./src/components/Music.vue')['default']
Player: typeof import('./src/components/Player.vue')['default']
Set: typeof import('./src/components/Set.vue')['default']
SocialLinks: typeof import('./src/components/SocialLinks.vue')['default']
TimeCapsule: typeof import('./src/components/TimeCapsule.vue')['default']
Weather: typeof import('./src/components/Weather.vue')['default']
}
}

View File

@ -16,14 +16,13 @@
"dependencies": { "dependencies": {
"@worstone/vue-aplayer": "^1.0.6", "@worstone/vue-aplayer": "^1.0.6",
"aplayer": "^1.10.1", "aplayer": "^1.10.1",
"axios": "^1.6.8", "axios": "^1.6.7",
"dayjs": "^1.11.10", "element-plus": "^2.6.1",
"element-plus": "^2.7.1",
"fetch-jsonp": "^1.3.0", "fetch-jsonp": "^1.3.0",
"pinia": "^2.1.7", "pinia": "^2.1.7",
"pinia-plugin-persistedstate": "^3.2.1", "pinia-plugin-persistedstate": "^3.2.1",
"swiper": "^11.1.1", "swiper": "^9.4.1",
"vue": "^3.4.24" "vue": "^3.4.21"
}, },
"devDependencies": { "devDependencies": {
"@icon-park/vue-next": "^1.4.2", "@icon-park/vue-next": "^1.4.2",
@ -31,13 +30,13 @@
"@vicons/utils": "^0.1.4", "@vicons/utils": "^0.1.4",
"@vitejs/plugin-vue": "^4.6.2", "@vitejs/plugin-vue": "^4.6.2",
"eslint": "^8.57.0", "eslint": "^8.57.0",
"eslint-plugin-vue": "^9.25.0", "eslint-plugin-vue": "^9.22.0",
"prettier": "^3.2.5", "prettier": "^3.2.5",
"sass": "^1.75.0", "sass": "^1.71.1",
"terser": "^5.30.4", "terser": "^5.29.1",
"unplugin-auto-import": "^0.11.5", "unplugin-auto-import": "^0.11.5",
"unplugin-vue-components": "^0.22.12", "unplugin-vue-components": "^0.22.12",
"vite": "^4.5.3", "vite": "^4.5.2",
"vite-plugin-compression": "^0.5.1", "vite-plugin-compression": "^0.5.1",
"vite-plugin-pwa": "^0.14.7" "vite-plugin-pwa": "^0.14.7"
} }

File diff suppressed because it is too large Load Diff

View File

@ -43,9 +43,9 @@ const changeBg = (type) => {
} else if (type == 1) { } else if (type == 1) {
bgUrl.value = "https://api.dujin.org/bing/1920.php"; bgUrl.value = "https://api.dujin.org/bing/1920.php";
} else if (type == 2) { } else if (type == 2) {
bgUrl.value = "https://api.vvhan.com/api/wallpaper/views"; bgUrl.value = "https://api.aixiaowai.cn/gqapi/gqapi.php";
} else if (type == 3) { } else if (type == 3) {
bgUrl.value = "https://api.vvhan.com/api/wallpaper/acg"; bgUrl.value = "https://api.aixiaowai.cn/api/api.php";
} }
}; };

View File

@ -46,7 +46,7 @@ import { Icon } from "@vicons/utils";
import { Link, Blog, CompactDisc, Cloud, Compass, Book, Fire, LaptopCode } from "@vicons/fa"; // 使 import { Link, Blog, CompactDisc, Cloud, Compass, Book, Fire, LaptopCode } from "@vicons/fa"; // 使
import { mainStore } from "@/store"; import { mainStore } from "@/store";
import { Swiper, SwiperSlide } from "swiper/vue"; import { Swiper, SwiperSlide } from "swiper/vue";
import { Pagination, Mousewheel } from "swiper/modules"; import { Pagination, Mousewheel } from "swiper";
import siteLinks from "@/assets/siteLinks.json"; import siteLinks from "@/assets/siteLinks.json";
const store = mainStore(); const store = mainStore();
@ -109,22 +109,14 @@ onMounted(() => {
height: 100%; height: 100%;
} }
.swiper-pagination { .swiper-pagination {
margin-top: 12px; position: static;
display: flex; margin-top: 4px;
flex-direction: row;
align-items: center;
justify-content: center;
:deep(.swiper-pagination-bullet) { :deep(.swiper-pagination-bullet) {
background-color: #fff; background-color: #fff;
width: 20px; width: 18px;
height: 4px; height: 4px;
margin: 0 4px;
border-radius: 4px; border-radius: 4px;
opacity: 0.2;
transition: opacity 0.3s; transition: opacity 0.3s;
&.swiper-pagination-bullet-active {
opacity: 1;
}
&:hover { &:hover {
opacity: 1; opacity: 1;
} }

View File

@ -15,12 +15,10 @@
<Icon size="16"> <Icon size="16">
<QuoteLeft /> <QuoteLeft />
</Icon> </Icon>
<Transition name="fade" mode="out-in"> <div class="text">
<div :key="descriptionText.hello + descriptionText.text" class="text"> <p>{{ descriptionText.hello }}</p>
<p>{{ descriptionText.hello }}</p> <p>{{ descriptionText.text }}</p>
<p>{{ descriptionText.text }}</p> </div>
</div>
</Transition>
<Icon size="16"> <Icon size="16">
<QuoteRight /> <QuoteRight />
</Icon> </Icon>
@ -148,7 +146,6 @@ watch(
margin: 0.75rem 1rem; margin: 0.75rem 1rem;
line-height: 2rem; line-height: 2rem;
margin-right: auto; margin-right: auto;
transition: opacity 0.2s;
p { p {
&:nth-of-type(1) { &:nth-of-type(1) {

View File

@ -12,12 +12,10 @@
</div> </div>
<div class="control"> <div class="control">
<go-start theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(0)" /> <go-start theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(0)" />
<Transition name="fade" mode="out-in"> <div class="state" @click="changePlayState">
<div :key="store.playerState" class="state" @click="changePlayState"> <play-one theme="filled" size="50" fill="#efefef" v-show="!store.playerState" />
<play-one theme="filled" size="50" fill="#efefef" v-show="!store.playerState" /> <pause theme="filled" size="50" fill="#efefef" v-show="store.playerState" />
<pause theme="filled" size="50" fill="#efefef" v-show="store.playerState" /> </div>
</div>
</Transition>
<go-end theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(1)" /> <go-end theme="filled" size="30" fill="#efefef" @click="changeMusicIndex(1)" />
</div> </div>
<div class="menu"> <div class="menu">
@ -122,7 +120,7 @@ onMounted(() => {
// //
window.addEventListener("keydown", (e) => { window.addEventListener("keydown", (e) => {
if (!store.musicIsOk) { if (!store.musicIsOk) {
return; return ;
} }
if (e.code == "Space") { if (e.code == "Space") {
changePlayState(); changePlayState();
@ -179,7 +177,6 @@ watch(
justify-content: space-evenly; justify-content: space-evenly;
width: 100%; width: 100%;
.state { .state {
transition: opacity 0.1s;
.i-icon { .i-icon {
width: 50px; width: 50px;
height: 50px; height: 50px;

View File

@ -4,24 +4,23 @@
<hourglass-full theme="two-tone" size="24" :fill="['#efefef', '#00000020']" /> <hourglass-full theme="two-tone" size="24" :fill="['#efefef', '#00000020']" />
<span>时光胶囊</span> <span>时光胶囊</span>
</div> </div>
<div v-if="timeData" class="all-capsule"> <span class="text">今日已经度过了&nbsp;{{ timeData.day.elapsed }}&nbsp;小时</span>
<div v-for="(item, tag, index) in timeData" :key="index" class="capsule-item"> <el-progress :text-inside="true" :stroke-width="20" :percentage="timeData.day.pass" />
<div class="item-title"> <span class="text">本周已经度过了&nbsp;{{ timeData.week.elapsed }}&nbsp;</span>
<span class="percentage"> <el-progress :text-inside="true" :stroke-width="20" :percentage="timeData.week.pass" />
{{ item.name }}已度过 <span class="text">本月已经度过了&nbsp;{{ timeData.month.elapsed }}&nbsp;</span>
<strong>{{ item.passed }}</strong> <el-progress :text-inside="true" :stroke-width="20" :percentage="timeData.month.pass" />
{{ tag === "day" ? "小时" : "天" }} <span class="text">今年已经度过了&nbsp;{{ timeData.year.elapsed }}&nbsp;个月</span>
</span> <el-progress :text-inside="true" :stroke-width="20" :percentage="timeData.year.pass" />
<span class="remaining"> <div v-if="startDate?.length >= 4 && store.siteStartShow">
剩余&nbsp;{{ item.remaining }}&nbsp;{{ tag === "day" ? "小时" : "天" }} <span class="text" v-html="startDateText" />
</span> <!-- <el-progress
</div> :show-text="false"
<el-progress :text-inside="true" :stroke-width="20" :percentage="item.percentage" /> :indeterminate="true"
</div> :stroke-width="6"
<!-- 建站日期 --> :percentage="80"
<div v-if="store.siteStartShow" class="capsule-item start"> :duration="2"
<div class="item-title">{{ startDateText }}</div> /> -->
</div>
</div> </div>
</div> </div>
</template> </template>
@ -66,33 +65,10 @@ onBeforeUnmount(() => {
margin-right: 6px; margin-right: 6px;
} }
} }
.all-capsule { .text {
.capsule-item { display: block;
margin-bottom: 1rem; margin: 1rem 0rem 0.5rem 0rem;
.item-title { font-size: 0.95rem;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-between;
margin: 1rem 0rem 0.5rem 0rem;
font-size: 0.95rem;
.remaining {
opacity: 0.6;
font-size: 0.85rem;
font-style: oblique;
}
}
&:last-child {
margin-bottom: 0;
}
&.start {
.item-title {
justify-content: center;
opacity: 0.8;
font-size: 0.85rem;
}
}
}
} }
} }
</style> </style>

View File

@ -5,7 +5,8 @@ import App from "@/App.vue";
import { createPinia } from "pinia"; import { createPinia } from "pinia";
import piniaPluginPersistedstate from "pinia-plugin-persistedstate"; import piniaPluginPersistedstate from "pinia-plugin-persistedstate";
// swiper // swiper
import "swiper/css"; import "swiper/scss";
import "swiper/scss/pagination";
const app = createApp(App); const app = createApp(App);
const pinia = createPinia(); const pinia = createPinia();

View File

@ -13,8 +13,6 @@ html,
body { body {
width: 100%; width: 100%;
height: 100%; height: 100%;
// width: 100dvh;
// height: 100dvh;
margin: 0; margin: 0;
padding: 0; padding: 0;
background-color: #333; background-color: #333;
@ -55,8 +53,8 @@ p {
position: fixed; position: fixed;
top: 0; top: 0;
left: 0; left: 0;
width: 100%; width: 100vw;
height: 100%; height: 100vh;
z-index: 0; z-index: 0;
} }

View File

@ -1,6 +1,5 @@
import { h } from "vue"; import { h } from "vue";
import { SpaCandle } from "@icon-park/vue-next"; import { SpaCandle } from "@icon-park/vue-next";
import dayjs from "dayjs";
// 时钟 // 时钟
export const getCurrentTime = () => { export const getCurrentTime = () => {
@ -26,48 +25,47 @@ export const getCurrentTime = () => {
// 时光胶囊 // 时光胶囊
export const getTimeCapsule = () => { export const getTimeCapsule = () => {
const now = dayjs(); // 日进度
const dayText = { const todayStartDate = new Date(new Date().toLocaleDateString()).getTime();
day: "今日", const todayPassHours = (new Date() - todayStartDate) / 1000 / 60 / 60;
week: "本周", const todayPassHoursPercent = (todayPassHours / 24) * 100;
month: "本月",
year: "本年", // 周进度
}; const weeks = [7, 1, 2, 3, 4, 5, 6];
/** const weekDay = weeks[new Date().getDay()];
* 计算时间差的函数 const weekDayPassPercent = (weekDay / 7) * 100;
* @param {String} unit 时间单位可以是 'day', 'week', 'month', 'year'
*/ // 月进度
const getDifference = (unit) => { const year = new Date().getFullYear();
// 获取当前时间单位的开始时间 const date = new Date().getDate();
const start = now.startOf(unit); const month = new Date().getMonth() + 1;
// 获取当前时间单位的结束时间 const monthAll = new Date(year, month, 0).getDate();
const end = now.endOf(unit); const monthPassPercent = (date / monthAll) * 100;
// 计算总的天数或小时数
const total = end.diff(start, unit === "day" ? "hour" : "day") + 1; // 年进度
// 计算已经过去的天数或小时数 const yearStartDate = new Date(year, 0, 1).getTime();
let passed; const yearEndDate = new Date(year + 1, 0, 1).getTime();
if (unit === "week" && now.day() === 0) { const yearPassHours = (new Date() - yearStartDate) / 1000 / 60 / 60;
// 如果是星期日 const yearTotalHours = (yearEndDate - yearStartDate) / 1000 / 60 / 60;
passed = total - 1; const yearPassPercent = (yearPassHours / yearTotalHours) * 100;
} else {
passed = now.diff(start, unit === "day" ? "hour" : "day");
}
const remaining = total - passed;
const percentage = (passed / total) * 100;
// 返回数据
return {
name: dayText[unit],
total: total,
passed: passed,
remaining: remaining,
percentage: percentage.toFixed(2),
};
};
return { return {
day: getDifference("day"), day: {
week: getDifference("week"), elapsed: Math.floor(todayPassHours),
month: getDifference("month"), pass: Math.floor(todayPassHoursPercent),
year: getDifference("year"), },
week: {
elapsed: weekDay,
pass: Math.floor(weekDayPassPercent),
},
month: {
elapsed: date,
pass: Math.floor(monthPassPercent),
},
year: {
elapsed: month - 1,
pass: Math.floor(yearPassPercent),
},
}; };
}; };