なにこれ
#- 公開されているHugoテーマをカスタムしていい感じにしたよ
モチベ
#- スタートページにリアルとバーチャルのどちらのプロフィールを表示したい
プロフィールの管理について、私はリアルとバーチャルの存在を分離して捉えています。
Hugo Themeの選定
#Hugoのテーマは
ここにたくさん掲載されています。
詳細なプロフィールは別々に管理した方が良さげだったので、リアルとバーチャル用に次のテーマを選定しました。
Blowfishのページレイアウトのカスタム
#Blowfishユーザーのうち
v-y-sさんの見た目がかなり良かったためこれを参考にして、
heroをベースに作成していきます。
スタートページにリアルとバーチャルの簡単なプロフィールを表示したかったのですが、デフォルトでは対応していません。
そこで、プロフィールをスライドショーのように遷移させるカスタムレイアウトを作成しました。
Blowfishは複数著者をサポートしている関係でdata/authors
に各々のプロフィールを配置できます。
{{ .Site.Data.authors }}
から読み込むとアルファベット順に表示されしまうのでparam
にhomepageOrder
を追加して表示順を制御できるようにしました。
layouts/partials/home/custom.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
| {{ $disableImageOptimization := .Site.Params.disableImageOptimization | default false }}
<article class="max-w-full prose dark:prose-invert">
<div class="fixed inset-x-0 top-0" style="z-index: -10">
<img id="switchableBgImg" class="w-full h-[1000px] object-cover m-0 nozoom" src="" />
</div>
<div
class="fixed opacity-1 inset-x-0 top-0 h-full single_hero_background nozoom"
style="backdrop-filter: blur(8px)"
></div>
<div class="relative">
<div class="absolute inset-x-0 bottom-0 h-1/2 bg-gray-100"></div>
<div class="mx-auto max-w-7xl p-0">
<div class="relative shadow-xl sm:overflow-hidden rounded-2xl">
<div class="relative px-4 py-16 sm:px-6 sm:py-24 lg:py-32 lg:px-8" >
<!-- プロフィールの背景にBlurを強くして見やすくする -->
<div
class="absolute opacity-1 inset-x-0 top-0 h-full single_hero_background nozoom"
style="backdrop-filter: blur(12px)"
></div>
<div
class="relative px-4 py-16 sm:px-6 sm:py-24 lg:py-32 lg:px-8 container mx-auto flex flex-col items-center justify-center text-center"
>
<!-- data/authors以下のプロフィールを読み込む -->
{{ $authorsData := .Site.Data.authors }}
{{ range $author := .Site.Params.homepageOrder }}
{{ $authorData := index $authorsData $author }}
{{- if $authorData -}}
<div class="absolute flex flex-col items-center justify-center text-center opacity-0 slide">
{{ with $authorData.image }}
{{ $authorImage := "" }}
{{ if or (strings.HasPrefix . "http:") (strings.HasPrefix . "https:") }}
{{ $authorImage = resources.GetRemote . }}
{{ else }}
{{ $authorImage = resources.Get . }}
{{ end }}
{{ if $authorImage }}
{{ if not $disableImageOptimization }}
{{ $authorImage = $authorImage.Fill "288x288" }}
{{ end }}
<img
class="mb-2 rounded-full h-36 w-36"
width="144"
height="144"
alt="{{ $authorData.name | default " Author" }}"
src="{{ $authorImage.RelPermalink }}"
/>
{{ end }}
{{ end }}
<h1 class="mb-2 text-4xl font-extrabold">
{{ $authorData.name }}
</h1>
<!-- headlineからbioに変更+h2のクラスにbioを追加 -->
{{ with $authorData.bio }}
<h2 class="bio mt-0 mb-0 text-xl text-neutral-100 dark:text-neutral-200">
{{ . | markdownify | emojify }}
</h2>
{{ end }}
<div class="mt-3 mb-10 text-2xl">
{{ with $authorData.social }}
<div class="flex flex-wrap">
{{ range $links := . }}
{{ range $name, $url := $links }}
<a
class="px-1 hover:text-primary-300 text-primary-200"
href="{{ $url }}"
target="_blank"
aria-label="{{ $name | title }}"
rel="me noopener noreferrer"
>{{ partial
"icon.html" $name
}}</a
>
{{ end }}
{{ end }}
</div>
{{ end }}
</div>
</div>
{{end}}
{{end}}
<section class="prose prose-invert">{{ .Content | emojify }}</section>
</div>
</div>
</div>
</div>
</div>
{{ $jsHome := resources.Get "js/home.js" | resources.Minify | resources.Fingerprint "sha512" }}
<script
defer
type="text/javascript"
src="{{ $jsHome.RelPermalink }}"
integrity="{{ $jsHome.Data.Integrity }}"
></script>
<script src="https://unpkg.com/typeit@8.7.1/dist/index.umd.js"></script>
</div>
</article>
<section>
{{ partial "recent-articles/main.html" . }}
</section>
|
config/_default/language.ja.toml
1
2
| [param]
homepageOrder = ["startpage", "sumi", "sumi-sumi"]
|
javascript12行で書くfadeIn, fadeOutスライドショーにて紹介されていたプログラムのターゲットを画像では無くslide
クラスに向けただけです。
タイプライターのようなテキスト表示ができる
Typeitの起動を追加しています。
assets/js/home.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
| let slideIndex = 0
let shotTime = 0
const startpageShowTime = 8000
const profileShowTime = 11000
const fadeInDelay = 1000
const fadeOutDelay = 1200
const typeitStartDelay = 500
const typeitSpeed = 100
showSlides()
function toMSec2Sec(msec) {
return msec / 1000
}
function fadeOut(element) {
element.style.transition = "opacity " + String(toMSec2Sec(fadeOutDelay)) + "s"
element.style.opacity = "0"
}
function fadeIn(element) {
element.style.transition = "opacity " + String(toMSec2Sec(fadeInDelay)) + "s"
element.style.opacity = "1"
}
function showSlides() {
// スライドの要素を取得
const slides = document.querySelectorAll(".slide")
const bios = document.querySelectorAll(".bio")
slideIndex++
// スライドの数よりもslideIndexが大きくなった場合、最初のスライドに戻る
if (slideIndex > slides.length) {
slideIndex = 1
}
if (slideIndex == 1) {
showTime = startpageShowTime
} else {
showTime = profileShowTime
}
// 現在のスライドを表示(opacityを1に設定)
fadeIn(slides[slideIndex - 1])
// 1つ前のスライドを非表示(opacityを0に設定)
fadeOut(slides[slideIndex - 2 < 0 ? slides.length - 1 : slideIndex - 2])
// headline をタイプライターのように表示
new TypeIt(bios[slideIndex - 1], {
speed: typeitSpeed,
startDelay: typeitStartDelay,
waitUntilVisible: true,
}).go()
// 一定時間後に再度showSlides関数を呼び出す(次のスライドに進むための処理)
setTimeout(showSlides, showTime)
}
|
カラーテーマ変更時の背景画像を差し替え
#ホームページの背景を画像にするとカラーテーマによって文字の視認性が大きく落ちることに気づきました。
そのため、カラーテーマを変更したら背景画像も差し替えるようにしました。
Blowfishのassets/js/appearance.js
をプロジェクト配下のassets/js
にコピーして変更しています。
プログラムは元々存在したupdateLog()
を踏襲して必要な情報に書き換えてswitchableBgImg
クラスを参照するようにしています。
またparam
にsecondaryBackgroundImage
を追加しています。
Blowfishはparams.toml
のdefaultAppearance
で指定されたものがprimary
テーマになります。
背景も同様にdefaultBackgroundImage
がデフォルトでsecondaryBackgroundImage
がカラーテーマ変更時の背景画像になります。
assets/js/appearance.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
| ...
window.addEventListener("DOMContentLoaded", (event) => {
const switcher = document.getElementById("appearance-switcher");
const switcherMobile = document.getElementById("appearance-switcher-mobile");
updateMeta();
this.updateLogo?.(getTargetAppearance());
this.updateBg?.(getTargetAppearance()); // 追記
if (switcher) {
switcher.addEventListener("click", () => {
document.documentElement.classList.toggle("dark");
var targetAppearance = getTargetAppearance();
localStorage.setItem(
"appearance",
targetAppearance
);
updateMeta();
this.updateLogo?.(targetAppearance);
this.updateBg?.(targetAppearance); // 追記
});
switcher.addEventListener("contextmenu", (event) => {
event.preventDefault();
localStorage.removeItem("appearance");
});
}
if (switcherMobile) {
switcherMobile.addEventListener("click", () => {
document.documentElement.classList.toggle("dark");
var targetAppearance = getTargetAppearance();
localStorage.setItem(
"appearance",
targetAppearance
);
updateMeta();
this.updateLogo?.(targetAppearance);
this.updateBg?.(targetAppearance); // 追記
});
switcherMobile.addEventListener("contextmenu", (event) => {
event.preventDefault();
localStorage.removeItem("appearance");
});
}
});
...
// 追記
{{ $primaryBg := "" }}
{{ $secondaryBg := "" }}
{{ with .Site.Params.defaultBackgroundImage }}
{{ $primaryBg = resources.Get . }}
{{ end }}
{{ with .Site.Params.homepage.homepageImage }}
{{ $primaryBg = resources.Get . }}
{{ end }}
{{ with .Site.Params.secondaryBackgroundImage }}
{{ $secondaryBg = resources.Get . }}
{{ end }}
{{ with .Site.Params.homepage.secondaryHomepageImage }}
{{ $secondaryBg = resources.Get . }}
{{ end }}
{{ if and (not (eq $primaryBg "")) (not (eq $secondaryBg "")) }}
var updateBg = (targetAppearance) => {
var elems;
elems = document.querySelectorAll("#switchableBgImg")
targetBGPath =
targetAppearance == "{{ .Site.Params.DefaultAppearance }}" ?
"{{ $primaryBg.RelPermalink }}" : "{{ $secondaryBg.RelPermalink }}"
for (const elem of elems) {
elem.setAttribute("src", targetBGPath)
}
}
{{ end }}
|