Skip to content

Commit d4796fc

Browse files
authored
crop article thumbnails (#225)
1 parent d3a2d6b commit d4796fc

File tree

6 files changed

+91
-12
lines changed

6 files changed

+91
-12
lines changed

contents/articles/2024/11-26_komaba-festival/index.mdx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ categories:
55
- events
66
image: ./image1.jpg
77
author: kmanabe
8+
position: top
89
---
910

1011
ut.code(); は、2024 年 11 月 22 〜 24 日の合計 3 日間駒場祭に企画を出展しました。今回も多くの方にお越しいただきました。3 日間を通して来場してくださった皆様、ありがとうございました!

contents/articles/2024/12-21_kick-off-party-report/index.mdx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ categories:
55
- events
66
image: ./image.jpg
77
author: snakamura
8+
fit: contain
9+
bg_color: "#00693E"
810
---
911

1012
ut.code(); では 2024 年 12 月 21 日にプロジェクト発足会を行いました。

contents/articles/2025/03-24_joint-welcome-session/index.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@
22
title: 東大エンジニア系サークル合同新歓を開催します
33
image: ./thumbnail.png
44
categories:
5-
- event
5+
- event
66
author: ykobayashi
77
date: 2025-03-24
8+
fit: contain
9+
bg_color: "#A5FFD3"
810
---
911

1012
## 📌 イベント概要

contents/articles/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
# 記事ページ
2+
3+
## frontmatter
4+
5+
### base
6+
7+
- title: string
8+
- 記事タイトル。
9+
10+
- date: Date
11+
- **記事を書いた**日。
12+
13+
- author: string & keyof Member
14+
- 著者。
15+
16+
- categories: string[]
17+
- 何なんだろうね。
18+
19+
### image 系
20+
21+
- image: path
22+
- タイトル画像。記事一覧とトップで使うよ。
23+
- 縦横比 3:5 に crop されるよ。
24+
25+
- fit?: "cover" | "contain" | fill" | "none" = "cover"
26+
- `object-fit`
27+
- Astro のビルド段階で Sharp に渡されるよ。
28+
- <https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit>
29+
30+
- position?: "center" | "left" | "right" | "top" | "bottom"
31+
- `object-position`
32+
- Astro のビルド段階で Sharp に渡されるよ。
33+
34+
- bg_color?: string
35+
- ロード中や画像の漏れたところに見せる背景色。
36+
- 設定しないと DaisyUI の `skeleton` を使うよ。

src/components/ArticleList.astro

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,15 @@ const articlesWithExcerpts = await Promise.all(
5252
{
5353
articlesWithExcerpts.map(({ article, text }, i) => {
5454
const isFeatured = enlarge && i % 11 === 0; // 11 記事ごとに大きく表示する
55+
const baseW = 400;
56+
const imageWidth = baseW * (isFeatured ? 2 : 1);
57+
const imageHeight = baseW * (3 / 5) * (isFeatured ? 2 : 1);
58+
59+
console.log(article.data.bg_color);
60+
61+
article.data.fit ??= "cover";
62+
article.data.position ??= "center";
63+
5564
const additionalProps = isFeatured
5665
? {
5766
cellClassName: "md:col-span-2 md:row-span-2",
@@ -75,12 +84,25 @@ const articlesWithExcerpts = await Promise.all(
7584
<Picture
7685
loading={i < 5 ? loading : "lazy"}
7786
formats={["avif", "webp"]}
78-
alt="カバー画像"
87+
position={article.data.position}
88+
width={imageWidth}
89+
height={imageHeight}
90+
alt=""
91+
fit={article.data.fit}
7992
src={article.data.image}
8093
class:list={[
81-
"skeleton min-h-0 w-full rounded-xl object-center",
94+
"min-h-0 w-full rounded-xl",
95+
!article.data["bg_color"] && "skeleton",
8296
additionalProps.imageClassName,
8397
]}
98+
style={`
99+
aspect-ratio: 5 / 3;
100+
object-fit: ${article.data.fit};
101+
${
102+
article.data.bg_color
103+
? `background-color: ${article.data.bg_color}`
104+
: ""
105+
}`}
84106
/>
85107
<div class="mt-4 p-1">
86108
<time class="block text-sm text-gray-500">

src/schema.ts

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,31 @@ export type Member = z.infer<ReturnType<typeof CreateMemberSchema>>;
77
export type Project = z.infer<ReturnType<typeof CreateProjectSchema>>;
88

99
export const CreateArticleSchema = ({ image }: { image: ImageFunction }) =>
10-
z.object({
11-
date: z
12-
.date()
13-
.transform((date) => new TZDate(date).withTimeZone("Asia/Tokyo")),
14-
title: z.string().nullable(),
15-
image: image(),
16-
categories: z.array(z.string()).optional(),
17-
author: reference("members").optional(),
18-
});
10+
z
11+
.object({
12+
// base
13+
title: z.string(),
14+
date: z
15+
.date()
16+
.transform((date) => new TZDate(date).withTimeZone("Asia/Tokyo")),
17+
author: reference("members").optional(),
18+
categories: z.array(z.string()).optional(),
19+
// 画像系
20+
image: image(),
21+
fit: z.enum(["cover", "contain", "fill", "none"]).optional(),
22+
position: z.enum(["center", "top", "bottom", "left", "right"]).optional(),
23+
bg_color: z.string().optional(),
24+
})
25+
.refine(
26+
(self) => {
27+
const bad = self.fit === "contain" && self.bg_color === undefined;
28+
return !bad;
29+
},
30+
{
31+
message: "fit: contain の場合、 bg_color を指定する必要があります",
32+
path: ["bg_color"],
33+
},
34+
);
1935

2036
export const CreateProjectSchema = ({ image }: { image: ImageFunction }) =>
2137
z.object({

0 commit comments

Comments
 (0)