Skip to content

Commit 1d3bf4b

Browse files
authored
Merge pull request #72 from UIGF-org/71-proj-card-dev
2 parents 9163784 + 2e297a0 commit 1d3bf4b

File tree

13 files changed

+871
-958
lines changed

13 files changed

+871
-958
lines changed

README.md

+21-20
Original file line numberDiff line numberDiff line change
@@ -26,30 +26,31 @@
2626
3. 在正确的标准区域中,复制以下代码并填入你项目的信息
2727

2828
```html
29-
<RelativeProject
30-
name=""
31-
desc=""
32-
logo=""
33-
url=""
34-
:thirdparty="[
35-
{type: 'github', url: ''},
36-
{type: 'gitlab', url: ''},
37-
{type: 'gitee', url: ''},
38-
{type: 'other', url: '', title: ''},
39-
]"
40-
version=""
41-
preview=""
42-
/>
29+
<Pcd
30+
bg=""
31+
icon=""
32+
repo=""
33+
site=""
34+
title=""
35+
desc="">
36+
<Pcb label="UIGF vx.x" :games="['ys', 'sr', 'zzz_']" bg=""></Pcb>
37+
<Pcb bg="">Text</Pcb>
38+
</Pcd>
4339
```
4440

4541
- 字段解释
46-
- **`name`**: 你的项目名称
42+
- **`bg`**: 项目截图或宣传图的 URL
43+
- **`icon`**: 项目图标的 URL
44+
- **`repo`**: 项目代码库的 URL
45+
- **`site`**: 项目主页的 URL
46+
- **`title`**: 你的项目名称
4747
- **`desc`**: 你的项目介绍
48-
- **`logo`**: 项目图标的 URL
49-
- **`url`**: 项目主页的 URL
50-
- **`thirdparty`**: 项目代码库的 URL,支持 GitHub、GitLab、Gitee 和其它
51-
- **`version`**:项目所支持的标准及其版本,例如“UIGF v2.3”
52-
- **`preview`**: 项目截图或宣传图的 URL
48+
- **`games`**: 你的项目支持的游戏列表,可选值为 `ys`,`ys_`,`sr`,`sr_`,`zzz`,`zzz_`,后面的 `_` 表示不支持,按照原神、星铁、绝区零的顺序填写
49+
- 项目支持 UIGF v4.0且支持原神、星铁、绝区零,应填写 `label="UIGF v4.0" :games="['ys', 'sr', 'zzz']"`
50+
- 项目支持 UIGF v2.2,应填写 `label="UIGF v2.2" :games="['ys']"`
51+
- 若有追加说明,可使用 `<Pcb>Text</Pcb>` 标签,其中 `Text` 为你的说明文字
52+
- **`bg`**: 可选字段,你的说明文字的背景颜色,可选值为 `red`, `blue`, `green`, `yellow`, `purple`,`white`
53+
5354
- 我们建议在本项目的 `docs/.vuepress/public/partnerships` 目录下以你的项目名称创建一个文件夹,并上传相关图片资源。 如果你创建的资源路径为 `docs/.vuepress/public/partnerships/sample-project/logo.png`,则其 URL 路径可以写为`https://uigf.org/partnerships/sample-project/logo.png``/partnerships/sample-project/logo.png`
5455

5556
4. 保存你的更改;开启一个 Pull Request 将更改提交到本库的主分支中

docs/.vuepress/client.ts

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
11
import { defineClientConfig } from "vuepress/client";
2-
import RelativeProject from "./components/RelativeProject.vue";
2+
import Pcd from "./components/ProjCardDev.vue";
3+
import Pcb from "./components/ProjCardBadge.vue";
34
import RelativeProjectPanel from "./components/RelativeProjectPanel.vue";
45

56
export default defineClientConfig({
67
enhance(ctx) {
78
const comps = {
8-
RelativeProject,
9+
Pcd,
10+
Pcb,
911
RelativeProjectPanel,
1012
};
11-
1213
for (const name in comps) {
1314
if (Object.prototype.hasOwnProperty.call(comps, name)) {
1415
ctx.app.component(name, comps[name]);
+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
<template>
2+
<div
3+
class="proj-card-badge"
4+
:style="{backgroundColor: getBgColor(props.bg)}"
5+
:title="props.label"
6+
v-if="!props.games"
7+
>
8+
<slot></slot>
9+
</div>
10+
<div v-else>
11+
<div class="proj-game-badge" :style="{backgroundColor: getBgColor(props.bg)}">
12+
<span>{{ props.label }}</span>
13+
<div class="proj-games">
14+
<div class="proj-game" v-for="game in props.games" :key="game">
15+
<div class="proj-game-lock" v-if="game.endsWith('_')" />
16+
<img :src="getGameIcon(game)" :alt="game" />
17+
</div>
18+
</div>
19+
</div>
20+
</div>
21+
</template>
22+
<script lang="ts" setup>
23+
type PcbBgColor = "white" | "red" | "purple" | "blue" | "green" | "orange" | "unknown";
24+
type PcbGameType = "ys" | "ys_" | "sr" | "sr_" | "zzz" | "zzz_"
25+
type PcbProps = {
26+
bg: PcbBgColor;
27+
label?: string;
28+
games?: Array<PcbGameType>;
29+
}
30+
31+
function getBgColor(bgColor: PcbBgColor): string {
32+
switch (bgColor) {
33+
case "white":
34+
return "#abb2bf";
35+
case "red":
36+
return "#de6a73";
37+
case "purple":
38+
return "#c678dd";
39+
case "blue":
40+
return "#61afef";
41+
case "green":
42+
return "#98c379";
43+
case "orange":
44+
return "#d19a66";
45+
default:
46+
return "var(--theme-color)";
47+
}
48+
}
49+
50+
function getGameIcon(gameType: PcbGameType): string {
51+
if (gameType.startsWith("ys")) {
52+
return "/games/ys.webp";
53+
}
54+
if (gameType.startsWith("sr")) {
55+
return "/games/sr.webp";
56+
}
57+
return "/games/zzz.webp";
58+
}
59+
60+
const props = withDefaults(defineProps<PcbProps>(), { bg: "unknown" });
61+
</script>
62+
<style lang="css" scoped>
63+
.proj-card-badge,
64+
.proj-game-badge {
65+
display: flex;
66+
font-size: 12px;
67+
height: 28px;
68+
transition: background-color 0.3s, color 0.3s;
69+
color: white;
70+
padding: 2px 6px;
71+
font-weight: bold;
72+
}
73+
74+
.proj-card-badge {
75+
align-items: center;
76+
justify-content: center;
77+
}
78+
79+
.proj-game-badge {
80+
align-items: center;
81+
justify-content: space-between;
82+
border-radius: 15px;
83+
column-gap: 1em;
84+
}
85+
86+
.proj-games {
87+
display: flex;
88+
gap: 4px;
89+
}
90+
91+
.proj-game {
92+
display: flex;
93+
align-items: center;
94+
gap: 4px;
95+
96+
img {
97+
width: 20px;
98+
height: 20px;
99+
border-radius: 50%;
100+
cursor: initial !important;
101+
pointer-events: none;
102+
}
103+
}
104+
105+
.proj-game-lock {
106+
position: absolute;
107+
display: flex;
108+
align-items: center;
109+
justify-content: center;
110+
width: 20px;
111+
height: 20px;
112+
border-radius: 50%;
113+
background-color: rgb(0 0 0 / 50%);
114+
}
115+
</style>
+166
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
<template>
2+
<div class="proj-card-dev">
3+
<div class="proj-card-bg">
4+
<div class="proj-card-extra">
5+
<i class="iconfont icon-github" v-if="props.repo" @click="toRepo" :title="props.repo" />
6+
<i class="iconfont icon-link" v-if="props.site" @click="toSite" :title="props.site" />
7+
</div>
8+
<img :src="props.bg" alt="background" />
9+
</div>
10+
<div class="proj-card-content">
11+
<div class="proj-card-main">
12+
<img :src="props.icon" alt="icon" />
13+
<div class="proj-card-info">
14+
<div class="proj-card-title" :title="props.title">{{ props.title }}</div>
15+
<div class="proj-card-desc" :title="props.desc">{{ props.desc }}</div>
16+
</div>
17+
</div>
18+
<div class="proj-card-badges">
19+
<slot></slot>
20+
</div>
21+
</div>
22+
</div>
23+
</template>
24+
<script lang="ts" setup>
25+
import { computed } from "vue";
26+
import { useLocalStorage } from "@vueuse/core";
27+
28+
interface ProjCardDevProps {
29+
bg: string;
30+
icon: string;
31+
title: string;
32+
desc: string;
33+
repo?: string;
34+
site?: string;
35+
}
36+
37+
const props = defineProps<ProjCardDevProps>();
38+
39+
function isDarkTheme(): boolean | null {
40+
const theme = useLocalStorage<"auto" | "dark" | "light">("vuepress-theme-hope-scheme", "auto");
41+
if (theme.value === "auto" && typeof window === "undefined") return null;
42+
return theme.value === "auto"
43+
? window.matchMedia("(prefers-color-scheme: dark)").matches
44+
: theme.value === "dark";
45+
}
46+
47+
const contentBg = computed(() => {
48+
const theme = isDarkTheme();
49+
if (theme === null) return "transparent";
50+
return theme ? "#333333" : "#ffffff";
51+
});
52+
const shadowColor = computed(() => {
53+
const theme = isDarkTheme();
54+
if (theme === null) return "rgba(0,0,0,0.48)";
55+
return theme ? "rgba(255,223,0,0.48)" : "#d9d9d9";
56+
});
57+
58+
function toRepo() {
59+
window.open(props.repo, "_blank");
60+
}
61+
62+
function toSite() {
63+
window.open(props.site, "_blank");
64+
}
65+
</script>
66+
<style lang="css" scoped>
67+
.proj-card-dev {
68+
position: relative;
69+
width: 100%;
70+
height: 100%;
71+
border-radius: 10px;
72+
overflow: hidden;
73+
box-shadow: 0 0 8px v-bind(shadowColor);
74+
display: flex;
75+
flex-direction: column;
76+
background: v-bind(contentBg);
77+
}
78+
79+
.proj-card-bg {
80+
position: relative;
81+
width: 100%;
82+
aspect-ratio: 2 / 1;
83+
overflow: hidden;
84+
85+
img {
86+
width: 100%;
87+
height: 100%;
88+
object-fit: cover;
89+
transition: transform 0.3s linear;
90+
}
91+
92+
img:hover {
93+
cursor: pointer;
94+
transform: scale(1.1);
95+
transition: transform 0.3s linear;
96+
}
97+
}
98+
99+
.proj-card-extra {
100+
position: absolute;
101+
bottom: 0;
102+
right: 0;
103+
display: flex;
104+
padding: 5px;
105+
column-gap: 5px;
106+
107+
i {
108+
background: white;
109+
padding: 5px;
110+
border-radius: 50%;
111+
cursor: pointer;
112+
color: black;
113+
box-shadow: 0 0 5px #000000;
114+
}
115+
116+
i:hover {
117+
color: var(--theme-color)
118+
}
119+
}
120+
121+
.proj-card-content {
122+
padding: 1em;
123+
display: flex;
124+
flex-direction: column;
125+
align-items: flex-start;
126+
justify-content: center;
127+
row-gap: 1em;
128+
}
129+
130+
.proj-card-main {
131+
display: flex;
132+
align-items: flex-start;
133+
justify-content: flex-start;
134+
column-gap: 12px;
135+
136+
img {
137+
width: 4em;
138+
height: 4em;
139+
border-radius: 8px;
140+
cursor: initial !important;
141+
pointer-events: none;
142+
}
143+
}
144+
145+
.proj-card-info {
146+
height: 100%;
147+
display: flex;
148+
flex-direction: column;
149+
align-items: flex-start;
150+
justify-content: flex-start;
151+
gap: 0.5em;
152+
}
153+
154+
.proj-card-title {
155+
font-size: 1.5em;
156+
font-weight: bold;
157+
}
158+
159+
.proj-card-badges {
160+
display: flex;
161+
justify-content: flex-start;
162+
align-items: center;
163+
flex-wrap: wrap;
164+
gap: 4px;
165+
}
166+
</style>

0 commit comments

Comments
 (0)