slidev-theme-watabegg 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (141) hide show
  1. package/README.ja.md +132 -0
  2. package/README.md +142 -0
  3. package/components/KaTexReveal.vue +64 -0
  4. package/components/QuestionList.vue +252 -0
  5. package/components/TextBox.vue +109 -0
  6. package/dist/404.html +22 -0
  7. package/dist/_redirects +1 -0
  8. package/dist/assets/404-DpjNfLw1.css +1 -0
  9. package/dist/assets/DrawingControls-Cxk9a9ub.css +1 -0
  10. package/dist/assets/KaTeX_AMS-Regular-BQhdFMY1.woff2 +0 -0
  11. package/dist/assets/KaTeX_AMS-Regular-DMm9YOAa.woff +0 -0
  12. package/dist/assets/KaTeX_AMS-Regular-DRggAlZN.ttf +0 -0
  13. package/dist/assets/KaTeX_Caligraphic-Bold-ATXxdsX0.ttf +0 -0
  14. package/dist/assets/KaTeX_Caligraphic-Bold-BEiXGLvX.woff +0 -0
  15. package/dist/assets/KaTeX_Caligraphic-Bold-Dq_IR9rO.woff2 +0 -0
  16. package/dist/assets/KaTeX_Caligraphic-Regular-CTRA-rTL.woff +0 -0
  17. package/dist/assets/KaTeX_Caligraphic-Regular-Di6jR-x-.woff2 +0 -0
  18. package/dist/assets/KaTeX_Caligraphic-Regular-wX97UBjC.ttf +0 -0
  19. package/dist/assets/KaTeX_Fraktur-Bold-BdnERNNW.ttf +0 -0
  20. package/dist/assets/KaTeX_Fraktur-Bold-BsDP51OF.woff +0 -0
  21. package/dist/assets/KaTeX_Fraktur-Bold-CL6g_b3V.woff2 +0 -0
  22. package/dist/assets/KaTeX_Fraktur-Regular-CB_wures.ttf +0 -0
  23. package/dist/assets/KaTeX_Fraktur-Regular-CTYiF6lA.woff2 +0 -0
  24. package/dist/assets/KaTeX_Fraktur-Regular-Dxdc4cR9.woff +0 -0
  25. package/dist/assets/KaTeX_Main-Bold-Cx986IdX.woff2 +0 -0
  26. package/dist/assets/KaTeX_Main-Bold-Jm3AIy58.woff +0 -0
  27. package/dist/assets/KaTeX_Main-Bold-waoOVXN0.ttf +0 -0
  28. package/dist/assets/KaTeX_Main-BoldItalic-DxDJ3AOS.woff2 +0 -0
  29. package/dist/assets/KaTeX_Main-BoldItalic-DzxPMmG6.ttf +0 -0
  30. package/dist/assets/KaTeX_Main-BoldItalic-SpSLRI95.woff +0 -0
  31. package/dist/assets/KaTeX_Main-Italic-3WenGoN9.ttf +0 -0
  32. package/dist/assets/KaTeX_Main-Italic-BMLOBm91.woff +0 -0
  33. package/dist/assets/KaTeX_Main-Italic-NWA7e6Wa.woff2 +0 -0
  34. package/dist/assets/KaTeX_Main-Regular-B22Nviop.woff2 +0 -0
  35. package/dist/assets/KaTeX_Main-Regular-Dr94JaBh.woff +0 -0
  36. package/dist/assets/KaTeX_Main-Regular-ypZvNtVU.ttf +0 -0
  37. package/dist/assets/KaTeX_Math-BoldItalic-B3XSjfu4.ttf +0 -0
  38. package/dist/assets/KaTeX_Math-BoldItalic-CZnvNsCZ.woff2 +0 -0
  39. package/dist/assets/KaTeX_Math-BoldItalic-iY-2wyZ7.woff +0 -0
  40. package/dist/assets/KaTeX_Math-Italic-DA0__PXp.woff +0 -0
  41. package/dist/assets/KaTeX_Math-Italic-flOr_0UB.ttf +0 -0
  42. package/dist/assets/KaTeX_Math-Italic-t53AETM-.woff2 +0 -0
  43. package/dist/assets/KaTeX_SansSerif-Bold-CFMepnvq.ttf +0 -0
  44. package/dist/assets/KaTeX_SansSerif-Bold-D1sUS0GD.woff2 +0 -0
  45. package/dist/assets/KaTeX_SansSerif-Bold-DbIhKOiC.woff +0 -0
  46. package/dist/assets/KaTeX_SansSerif-Italic-C3H0VqGB.woff2 +0 -0
  47. package/dist/assets/KaTeX_SansSerif-Italic-DN2j7dab.woff +0 -0
  48. package/dist/assets/KaTeX_SansSerif-Italic-YYjJ1zSn.ttf +0 -0
  49. package/dist/assets/KaTeX_SansSerif-Regular-BNo7hRIc.ttf +0 -0
  50. package/dist/assets/KaTeX_SansSerif-Regular-CS6fqUqJ.woff +0 -0
  51. package/dist/assets/KaTeX_SansSerif-Regular-DDBCnlJ7.woff2 +0 -0
  52. package/dist/assets/KaTeX_Script-Regular-C5JkGWo-.ttf +0 -0
  53. package/dist/assets/KaTeX_Script-Regular-D3wIWfF6.woff2 +0 -0
  54. package/dist/assets/KaTeX_Script-Regular-D5yQViql.woff +0 -0
  55. package/dist/assets/KaTeX_Size1-Regular-C195tn64.woff +0 -0
  56. package/dist/assets/KaTeX_Size1-Regular-Dbsnue_I.ttf +0 -0
  57. package/dist/assets/KaTeX_Size1-Regular-mCD8mA8B.woff2 +0 -0
  58. package/dist/assets/KaTeX_Size2-Regular-B7gKUWhC.ttf +0 -0
  59. package/dist/assets/KaTeX_Size2-Regular-Dy4dx90m.woff2 +0 -0
  60. package/dist/assets/KaTeX_Size2-Regular-oD1tc_U0.woff +0 -0
  61. package/dist/assets/KaTeX_Size3-Regular-CTq5MqoE.woff +0 -0
  62. package/dist/assets/KaTeX_Size3-Regular-DgpXs0kz.ttf +0 -0
  63. package/dist/assets/KaTeX_Size4-Regular-BF-4gkZK.woff +0 -0
  64. package/dist/assets/KaTeX_Size4-Regular-DWFBv043.ttf +0 -0
  65. package/dist/assets/KaTeX_Size4-Regular-Dl5lxZxV.woff2 +0 -0
  66. package/dist/assets/KaTeX_Typewriter-Regular-C0xS9mPB.woff +0 -0
  67. package/dist/assets/KaTeX_Typewriter-Regular-CO6r4hn1.woff2 +0 -0
  68. package/dist/assets/KaTeX_Typewriter-Regular-D3Ib7_Hf.ttf +0 -0
  69. package/dist/assets/KaTexReveal-CPYYcbYL.js +261 -0
  70. package/dist/assets/KaTexReveal-DIQR78zC.css +1 -0
  71. package/dist/assets/NoteDisplay-DcLBOPDP.css +1 -0
  72. package/dist/assets/QuestionList-C2CV4WSw.js +56 -0
  73. package/dist/assets/QuestionList-CJKXL5Yq.css +1 -0
  74. package/dist/assets/SlideWrapper-B94O8a9G.css +1 -0
  75. package/dist/assets/entry-DeH8BBA6.css +1 -0
  76. package/dist/assets/index-BVsB-lMI.js +76 -0
  77. package/dist/assets/index-FlrlSOFu.css +1 -0
  78. package/dist/assets/link-Vmiqc0hc.js +1 -0
  79. package/dist/assets/logo-BYkHSa_O.png +0 -0
  80. package/dist/assets/md-8VraByb9.js +1 -0
  81. package/dist/assets/md-Bby241ZI.js +1 -0
  82. package/dist/assets/md-BqJwdePd.js +1 -0
  83. package/dist/assets/md-C0a547wx.js +3 -0
  84. package/dist/assets/md-C3C29Y15.css +1 -0
  85. package/dist/assets/md-CBmwngYy.js +1 -0
  86. package/dist/assets/md-DrNACvG6.js +3 -0
  87. package/dist/assets/md-DyJRgKOq.css +1 -0
  88. package/dist/assets/md-FY1NEgjs.js +1 -0
  89. package/dist/assets/md-RVqvqjSV.js +1 -0
  90. package/dist/assets/md-Un85CPx3.js +1 -0
  91. package/dist/assets/md-fq9C6Jm7.js +1 -0
  92. package/dist/assets/md-lcsTx_QH.css +1 -0
  93. package/dist/assets/md-nHLnZfr4.js +1 -0
  94. package/dist/assets/md-nyxGgl0C.js +1 -0
  95. package/dist/assets/md-rpN_jFpy.css +1 -0
  96. package/dist/assets/md-tn0RQdqM.css +0 -0
  97. package/dist/assets/modules/file-saver-BQwH87cS.js +1 -0
  98. package/dist/assets/modules/shiki-CNnpvYpa.js +1 -0
  99. package/dist/assets/modules/shiki-CozCpemh.css +1 -0
  100. package/dist/assets/modules/unplugin-icons-D4kCmVGc.js +1 -0
  101. package/dist/assets/modules/vue--QWtT9ew.js +40 -0
  102. package/dist/assets/play-D_7yfuao.css +1 -0
  103. package/dist/assets/presenter-BM7ZLO4O.css +1 -0
  104. package/dist/assets/shortcuts-DMsk7WYF.css +1 -0
  105. package/dist/assets/slidev/404-DWvVMASK.js +1 -0
  106. package/dist/assets/slidev/CodeBlockWrapper.vue_vue_type_script_setup_true_lang-DTUx4GGs.js +1 -0
  107. package/dist/assets/slidev/DrawingControls-kHEnsAlc.js +1 -0
  108. package/dist/assets/slidev/DrawingControls.vue_vue_type_style_index_0_lang-Bci_r_Jk.js +1 -0
  109. package/dist/assets/slidev/DrawingLayer-BGgDMhMm.js +1 -0
  110. package/dist/assets/slidev/IconButton.vue_vue_type_script_setup_true_lang-Di5pfAKC.js +1 -0
  111. package/dist/assets/slidev/NoteDisplay.vue_vue_type_style_index_0_lang-B00W6JVQ.js +1 -0
  112. package/dist/assets/slidev/SlideWrapper-n2BtjyCi.js +1 -0
  113. package/dist/assets/slidev/context-Db_2Hcpr.js +1 -0
  114. package/dist/assets/slidev/default-By-tXFz1.js +1 -0
  115. package/dist/assets/slidev/entry-BWgjvGUN.js +1 -0
  116. package/dist/assets/slidev/md-wS_Ed_8x.js +1 -0
  117. package/dist/assets/slidev/notes-Dv602Bu1.js +1 -0
  118. package/dist/assets/slidev/overview-BDs3_v07.js +1 -0
  119. package/dist/assets/slidev/play-CQ4qi9O0.js +2 -0
  120. package/dist/assets/slidev/presenter-CA_kPq3V.js +1 -0
  121. package/dist/assets/slidev/shortcuts-nzRDDQcI.js +4 -0
  122. package/dist/assets/useThemePalette-CeNaXTPl.js +1 -0
  123. package/dist/index.html +22 -0
  124. package/example.md +191 -0
  125. package/global-bottom.vue +70 -0
  126. package/layouts/cover.vue +64 -0
  127. package/layouts/end.vue +33 -0
  128. package/layouts/image-scroll.vue +138 -0
  129. package/layouts/image.vue +22 -0
  130. package/layouts/two-cols.vue +23 -0
  131. package/package.json +43 -0
  132. package/setup/shiki.ts +11 -0
  133. package/setup/shortcuts.ts +18 -0
  134. package/slidev-theme-watabegg-1.0.0.tgz +0 -0
  135. package/styles/globals.css +160 -0
  136. package/styles/index.ts +5 -0
  137. package/styles/layout.css +142 -0
  138. package/utils/colors.ts +57 -0
  139. package/utils/link.ts +17 -0
  140. package/utils/render.ts +5 -0
  141. package/utils/useThemePalette.ts +49 -0
package/example.md ADDED
@@ -0,0 +1,191 @@
1
+ ---
2
+ theme: ./
3
+ title: Theme Demo
4
+ subtitle: slidevのテーマ watabeggの紹介
5
+ author: watabegg
6
+ date: '2025/08/03'
7
+ link: 'https://example.com'
8
+ color: blue
9
+ ---
10
+
11
+ # 基本機能とスタイル
12
+
13
+ このスライドではテーマの基本スタイルをテストします。
14
+
15
+ - **太字** / *斜体* / `code`
16
+ - 入れ子リスト
17
+ - 第二階層
18
+ - もう一つ
19
+ - テーマカラーは frontmatter の `color` で `red | yellow | green | blue | purple` から選択
20
+
21
+ ```ts
22
+ function hello(name: string) {
23
+ console.log(`Hello, ${name}`)
24
+ }
25
+ ```
26
+
27
+ > ヒント: 最初の h1 は固定ヘッダになります。
28
+
29
+ ---
30
+ layout: two-cols
31
+ title: 2カラムレイアウト
32
+ ---
33
+
34
+ ::left::
35
+ ### 左側
36
+ - ポイント1
37
+ - ポイント2
38
+ - ポイント3
39
+
40
+ 固定ヘッダとフッターの余白を意識した構造。
41
+
42
+ ::right::
43
+ ### 右側
44
+ ```js
45
+ const nums = [1,2,3]
46
+ const doubled = nums.map(n=>n*2)
47
+ console.log(doubled)
48
+ ```
49
+ 図表 / コード / 説明などを分割表示。
50
+
51
+ ---
52
+
53
+ # QuestionList 基本
54
+
55
+ <QuestionList
56
+ :items="[
57
+ '最初の項目 **Markdown OK**',
58
+ {
59
+ text: '2番目 (子を含む)',
60
+ items: [
61
+ { label: 'A', text: 'A の内容'},
62
+ { label: 'B', text: 'B の内容'},
63
+ { text: 'さらにネスト', items: ['深い1', '深い2'] }
64
+ ]
65
+ },
66
+ { label: '★', text: 'カスタムラベル' }
67
+ ]"
68
+ :styles="['decimal-circle','katakana-paren','loweralpha-dot']"
69
+ />
70
+
71
+ ---
72
+
73
+ # QuestionList start 指定
74
+
75
+ <QuestionList
76
+ :items="[
77
+ { text: '大問1: サブ', items: ['1つ目','2つ目'] },
78
+ { text: '大問2: サブ', items: ['A','B','C'] }
79
+ ]"
80
+ :styles="['decimal-q','hiragana-paren']"
81
+ :start="[1,1]"
82
+ />
83
+
84
+ ---
85
+
86
+ # KaTeX と QuestionList
87
+
88
+ <KaTexReveal formula="\\int_0^{2\\pi} \\sin x\\,dx = 0" block class="text-2xl" />
89
+
90
+ <KaTexReveal
91
+ formula="E = mc^2"
92
+ :block="false"
93
+ class="text-primary font-bold"
94
+ v-click="1"
95
+ />
96
+
97
+ ---
98
+ layout: center
99
+ ---
100
+
101
+ # KaTeX と Markdown の混在
102
+
103
+ <QuestionList
104
+ :items="[
105
+ {
106
+ label: '①',
107
+ text: 'Markdownと **KaTeX** を混在',
108
+ items: [
109
+ { formula: 'a^2 + b^2 = c^2', block: true, class: 'text-lg text-center', tex: true },
110
+ { text: '$$\\frac{d}{dx} \\sin x = \\cos x$$' }
111
+ ]
112
+ },
113
+ {
114
+ label: '②',
115
+ formula: '\\sum_{k=1}^n k = \\frac{n(n+1)}{2}',
116
+ block: false,
117
+ class: 'text-xl'
118
+ }
119
+ ]"
120
+ :styles="['decimal-circle','loweralpha-paren']"
121
+ :start="[1]"
122
+ />
123
+
124
+ ---
125
+ layout: image
126
+ image: 'https://images.unsplash.com/photo-1501594907352-04cda38ebc29?auto=format&fit=crop&w=2370&q=80'
127
+ ---
128
+
129
+ <TextBox :x="80" :y="140" :width="360" v-click="1">**1番目** に表示される注釈。</TextBox>
130
+ <TextBox :x="200" :y="380" :width="340" textBg="green" v-click="2">背景色付き 2番目。</TextBox>
131
+ <TextBox :x="500" :y="120" :width="300" color="blue">常時表示 (青文字)。</TextBox>
132
+ <TextBox :x="40" :y="20" :width="420" textBg="yellow" v-click="3">最後に表示される黄色背景。</TextBox>
133
+
134
+ ---
135
+
136
+ # ユーティリティ
137
+
138
+ 普通のテキストと <span class="text-highlight">ハイライト</span>。
139
+
140
+ <div class="card mt-8" v-click="1">
141
+ <h3>カードスタイル</h3>
142
+ <p>重要事項をまとめるのに便利です。</p>
143
+ </div>
144
+
145
+ ---
146
+
147
+ # フッターとショートカット
148
+
149
+ このテーマでは Enter / Backspace キーで進行を制御できます。
150
+
151
+ - Enter: 次のスライド / v-click
152
+ - Backspace: 前へ戻る
153
+ - フッター: (cover / image 以外) 日付 + ページ番号
154
+
155
+ ---
156
+
157
+ # まとめ
158
+
159
+ - レイアウト: cover / two-cols / image
160
+ - コンポーネント: QuestionList / TextBox
161
+ - 自動フッター & 固定ヘッダ
162
+ - ラベルスタイル多彩 & Markdown 埋め込み
163
+
164
+ ご利用ありがとうございます 🎓
165
+
166
+ ---
167
+
168
+ # 終了
169
+
170
+ <div class="text-center mt-16">
171
+ <div class="text-4xl mb-4">🎓</div>
172
+ <div class="text-xl opacity-80">slidev-theme-watabegg</div>
173
+ <div class="text-lg opacity-60 mt-4">watabegg Slidev テーマ</div>
174
+ </div>
175
+
176
+ ---
177
+ layout: image-scroll
178
+ image: 'https://images.unsplash.com/photo-1501785888041-af3ef285b470?auto=format&fit=crop&w=2400&q=80'
179
+ ---
180
+
181
+ # image-scroll レイアウト
182
+
183
+ - マウスホイール: 拡大
184
+ - Shift + ホイール: 縮小
185
+ - 左クリックホールド + ドラッグ: 移動
186
+
187
+ 画像を全画面で扱いつつ、ズーム・パンを試せます。
188
+
189
+ ---
190
+ layout: end
191
+ ---
@@ -0,0 +1,70 @@
1
+ <script setup lang="ts">
2
+ import { watchEffect } from 'vue'
3
+ import { useSlideContext } from '@slidev/client'
4
+
5
+ import { useActiveThemePalette } from './utils/useThemePalette'
6
+ import getLink from './utils/link'
7
+
8
+ const { $frontmatter, $nav, $slidev } = useSlideContext()
9
+
10
+ const link = getLink({
11
+ frontmatter: $frontmatter,
12
+ slidevConfigs: $slidev?.configs as Record<string, unknown> | undefined,
13
+ })
14
+
15
+ const { palette: currentPalette } = useActiveThemePalette(() => $frontmatter.color)
16
+
17
+ watchEffect(() => {
18
+ if (typeof document === 'undefined')
19
+ return
20
+
21
+ const palette = currentPalette.value
22
+ const root = document.documentElement
23
+
24
+ root.style.setProperty('--slidev-theme-primary', palette.primary)
25
+ root.style.setProperty('--cover-gradient-start', palette.gradientStart)
26
+ root.style.setProperty('--cover-gradient-end', palette.gradientEnd)
27
+ root.style.setProperty('--cover-accent', palette.accent)
28
+ })
29
+ </script>
30
+
31
+ <template>
32
+ <footer
33
+ v-if="$nav.currentLayout !== 'cover' && $nav.currentLayout !== 'image'"
34
+ class="exam-prep-footer"
35
+ >
36
+ <div class="footer-left">
37
+ </div>
38
+ <div class="footer-right">
39
+ <span>{{ $nav.currentPage }} / {{ $nav.total }}</span>
40
+ <a v-if="link" :href="link">ホームに戻る</a>
41
+ <span v-else>ホームリンク未設定</span>
42
+ </div>
43
+ </footer>
44
+ </template>
45
+
46
+ <style scoped>
47
+ .exam-prep-footer {
48
+ position: fixed;
49
+ bottom: 0;
50
+ left: 0;
51
+ right: 0;
52
+ height: 3rem;
53
+ display: flex;
54
+ justify-content: space-between;
55
+ align-items: center;
56
+ padding: 0 2rem;
57
+ background: var(--slidev-theme-background);
58
+ border-top: 1px solid var(--slidev-theme-border);
59
+ font-size: 0.9rem;
60
+ color: var(--slidev-theme-text-secondary);
61
+ z-index: 20;
62
+ }
63
+
64
+ .footer-left,
65
+ .footer-right {
66
+ display: flex;
67
+ flex-direction: column;
68
+ align-items: center;
69
+ }
70
+ </style>
@@ -0,0 +1,64 @@
1
+ <template>
2
+ <div class="slidev-layout cover" :style="cssVars">
3
+ <div class="content">
4
+ <h1 v-if="$frontmatter.title">{{ $frontmatter.title }}</h1>
5
+ <h2 v-if="$frontmatter.subtitle">{{ $frontmatter.subtitle }}</h2>
6
+ </div>
7
+ <div v-if="$frontmatter.date" class="date">
8
+ {{ $frontmatter.date }}
9
+ </div>
10
+ <div v-if="$frontmatter.author" class="author">
11
+ {{ $frontmatter.author }}
12
+ </div>
13
+ <div class="wave">
14
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1280 700" width="100%" height="100%" preserveAspectRatio="none">
15
+ <defs>
16
+ <linearGradient id="wave-1754178473929" gradientUnits="userSpaceOnUse" x1="0" y1="0" x2="700" y2="700" gradientTransform="scale(1.83, 1)">
17
+ <stop offset="0%" :stop-color="currentPalette.gradientStart"/>
18
+ <stop offset="100%" :stop-color="currentPalette.gradientEnd"/>
19
+ </linearGradient>
20
+ </defs>
21
+ <path d="M -1049.6 400 Q -729.6 400 -409.6 550 Q 230.4 850 870.4 550 Q 1190.4 400 1510.4 400 Q 1830.4 400 2150.4 550 Q 2790.4 850 3430.4 550 Q 3750.4 400 4070.4 400 L 1280 0 L 0 0 Z" fill="url(#wave-1754178473929)"></path>
22
+ </svg>
23
+ </div>
24
+ </div>
25
+ </template>
26
+
27
+ <script setup lang="ts">
28
+ import { computed } from 'vue'
29
+ import { useSlideContext } from '@slidev/client'
30
+
31
+ import { useActiveThemePalette } from '../utils/useThemePalette'
32
+
33
+ const { $frontmatter } = useSlideContext()
34
+
35
+ const { palette: currentPalette } = useActiveThemePalette(() => $frontmatter.color)
36
+
37
+ const cssVars = computed(() => ({
38
+ '--slidev-theme-primary': currentPalette.value.primary,
39
+ '--cover-gradient-start': currentPalette.value.gradientStart,
40
+ '--cover-gradient-end': currentPalette.value.gradientEnd,
41
+ '--cover-accent': currentPalette.value.accent,
42
+ }))
43
+ </script>
44
+
45
+ <style scoped>
46
+ .content {
47
+ z-index: 10;
48
+ position: relative;
49
+ }
50
+
51
+ .default {
52
+ margin-top: 2rem;
53
+ color: white;
54
+ }
55
+
56
+ .wave {
57
+ position: absolute;
58
+ bottom: 0;
59
+ left: 0;
60
+ width: 100%;
61
+ height: 100%;
62
+ overflow: hidden;
63
+ }
64
+ </style>
@@ -0,0 +1,33 @@
1
+ <template>
2
+ <div class="slidev-layout end">
3
+ <div class="content">
4
+ <h1>ご清聴ありがとうございました</h1>
5
+ <a :href="link">戻る</a>
6
+ </div>
7
+ </div>
8
+ </template>
9
+
10
+ <script setup lang="ts">
11
+ import { useSlideContext } from '@slidev/client'
12
+ const { $frontmatter, $slidev } = useSlideContext()
13
+ import getLink from '../utils/link'
14
+
15
+ const link = getLink({
16
+ frontmatter: $frontmatter,
17
+ slidevConfigs: $slidev?.configs as Record<string, unknown> | undefined,
18
+ })
19
+
20
+ </script>
21
+
22
+ <style scoped>
23
+ .content {
24
+ z-index: 10;
25
+ position: relative;
26
+ }
27
+
28
+ .default {
29
+ margin-top: 2rem;
30
+ color: white;
31
+ }
32
+
33
+ </style>
@@ -0,0 +1,138 @@
1
+ <template>
2
+ <div
3
+ class="slidev-layout image-scroll"
4
+ ref="wrapperRef"
5
+ @wheel="onWheel"
6
+ @mousedown="onMouseDown"
7
+ >
8
+ <div class="image-layer" :class="{ 'is-panning': isPanning }">
9
+ <img
10
+ v-if="imageSrc"
11
+ :src="imageSrc"
12
+ alt="Scrollable background"
13
+ :style="imageStyle"
14
+ draggable="false"
15
+ />
16
+ </div>
17
+ <div class="content">
18
+ <slot />
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script setup lang="ts">
24
+ import { computed, onBeforeUnmount, onMounted, reactive, ref, watch } from 'vue'
25
+ import { useSlideContext } from '@slidev/client'
26
+
27
+ const { $frontmatter } = useSlideContext()
28
+
29
+ const imageSrc = computed(() => $frontmatter.image)
30
+
31
+ const wrapperRef = ref<HTMLElement | null>(null)
32
+ const scale = ref(1)
33
+ const position = reactive({ x: 0, y: 0 })
34
+ const isPanning = ref(false)
35
+ const lastPointer = reactive({ x: 0, y: 0 })
36
+
37
+ const MIN_SCALE = 0.4
38
+ const MAX_SCALE = 4
39
+ const ZOOM_STEP = 0.12
40
+
41
+ const clamp = (val: number, min: number, max: number) => Math.min(max, Math.max(min, val))
42
+
43
+ const resetTransform = () => {
44
+ scale.value = 1
45
+ position.x = 0
46
+ position.y = 0
47
+ }
48
+
49
+ const onWheel = (event: WheelEvent) => {
50
+ if (!imageSrc.value) return
51
+
52
+ // Default: wheelで拡大。Shift押下時は縮小方向を優先。
53
+ const direction = event.shiftKey ? -1 : event.deltaY < 0 ? 1 : -1
54
+ const next = clamp(scale.value + direction * ZOOM_STEP, MIN_SCALE, MAX_SCALE)
55
+
56
+ if (next === scale.value) return
57
+
58
+ event.preventDefault()
59
+ scale.value = next
60
+ }
61
+
62
+ const onMouseDown = (event: MouseEvent) => {
63
+ if (!imageSrc.value || event.button !== 0) return
64
+ isPanning.value = true
65
+ lastPointer.x = event.clientX
66
+ lastPointer.y = event.clientY
67
+ window.addEventListener('mousemove', onMouseMove)
68
+ window.addEventListener('mouseup', onMouseUp)
69
+ }
70
+
71
+ const onMouseMove = (event: MouseEvent) => {
72
+ if (!isPanning.value) return
73
+ const dx = event.clientX - lastPointer.x
74
+ const dy = event.clientY - lastPointer.y
75
+ position.x += dx
76
+ position.y += dy
77
+ lastPointer.x = event.clientX
78
+ lastPointer.y = event.clientY
79
+ event.preventDefault()
80
+ }
81
+
82
+ const onMouseUp = () => {
83
+ isPanning.value = false
84
+ window.removeEventListener('mousemove', onMouseMove)
85
+ window.removeEventListener('mouseup', onMouseUp)
86
+ }
87
+
88
+ const imageStyle = computed(() => ({
89
+ transform: `translate(${position.x}px, ${position.y}px) scale(${scale.value})`,
90
+ }))
91
+
92
+ onMounted(() => {
93
+ resetTransform()
94
+ })
95
+
96
+ onBeforeUnmount(() => {
97
+ window.removeEventListener('mousemove', onMouseMove)
98
+ window.removeEventListener('mouseup', onMouseUp)
99
+ })
100
+
101
+ watch(imageSrc, () => {
102
+ resetTransform()
103
+ })
104
+ </script>
105
+
106
+ <style scoped>
107
+ .slidev-layout.image-scroll {
108
+ position: relative;
109
+ height: 100%;
110
+ overflow: hidden;
111
+ }
112
+
113
+ .image-layer {
114
+ position: absolute;
115
+ inset: 0;
116
+ overflow: hidden;
117
+ cursor: grab;
118
+ }
119
+
120
+ .image-layer.is-panning {
121
+ cursor: grabbing;
122
+ }
123
+
124
+ .image-layer img {
125
+ width: 100%;
126
+ height: 100%;
127
+ object-fit: cover;
128
+ will-change: transform;
129
+ transition: transform 80ms ease-out;
130
+ }
131
+
132
+ .content {
133
+ position: relative;
134
+ z-index: 1;
135
+ height: 100%;
136
+ padding: 2rem;
137
+ }
138
+ </style>
@@ -0,0 +1,22 @@
1
+ <template>
2
+ <div class="slidev-layout image">
3
+ <img
4
+ v-if="$frontmatter.image"
5
+ :src="$frontmatter.image"
6
+ class="background-image"
7
+ alt="Background"
8
+ />
9
+ <div class="content">
10
+ <slot />
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ import { useSlideContext } from '@slidev/client'
17
+ const { $frontmatter } = useSlideContext()
18
+ </script>
19
+
20
+ <style scoped>
21
+ /* Image layout styles are in the main layout.css */
22
+ </style>
@@ -0,0 +1,23 @@
1
+ <template>
2
+ <div class="slidev-layout two-cols">
3
+ <h1 v-if="$frontmatter.title">{{ $frontmatter.title }}</h1>
4
+ <div class="slidev-grid-container">
5
+ <div class="col-left">
6
+ <slot name="left" />
7
+ </div>
8
+ <div class="col-right">
9
+ <slot name="right" />
10
+ </div>
11
+ </div>
12
+ </div>
13
+ </template>
14
+
15
+ <script setup lang="ts">
16
+ import { useSlideContext } from '@slidev/client'
17
+
18
+ const { $frontmatter } = useSlideContext()
19
+ </script>
20
+
21
+ <style scoped>
22
+ /* Additional scoped styles if needed */
23
+ </style>
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "slidev-theme-watabegg",
3
+ "version": "1.0.0",
4
+ "type": "module",
5
+ "description": "watabeggが使うためのSlidevテーマ",
6
+ "keywords": [
7
+ "slidev-theme",
8
+ "slidev",
9
+ "education",
10
+ "exam",
11
+ "teaching"
12
+ ],
13
+ "engines": {
14
+ "node": ">=18.0.0"
15
+ },
16
+ "scripts": {
17
+ "build": "slidev build example.md",
18
+ "dev": "slidev example.md",
19
+ "export": "slidev export example.md",
20
+ "screenshot": "slidev export example.md --format png"
21
+ },
22
+ "dependencies": {
23
+ "@slidev/types": "^52.1.0",
24
+ "katex": "^0.16.25"
25
+ },
26
+ "devDependencies": {
27
+ "@slidev/cli": "^52.1.0",
28
+ "bumpp": "^10.3.2",
29
+ "playwright-chromium": "^1.54.2"
30
+ },
31
+ "//": "Learn more: https://sli.dev/guide/write-theme.html",
32
+ "slidev": {
33
+ "colorSchema": "light",
34
+ "defaults": {
35
+ "background": "#FFFFFF",
36
+ "fonts": {
37
+ "sans": "M PLUS 2",
38
+ "mono": "Fira Code"
39
+ },
40
+ "lineNumbers": false
41
+ }
42
+ }
43
+ }
package/setup/shiki.ts ADDED
@@ -0,0 +1,11 @@
1
+ import type { ShikiSetupReturn } from '@slidev/types'
2
+ import { defineShikiSetup } from '@slidev/types'
3
+
4
+ export default defineShikiSetup((): ShikiSetupReturn => {
5
+ return {
6
+ themes: {
7
+ dark: 'vitesse-dark',
8
+ light: 'vitesse-light',
9
+ },
10
+ }
11
+ })
@@ -0,0 +1,18 @@
1
+ import type { NavOperations, ShortcutOptions } from '@slidev/types'
2
+ import { defineShortcutsSetup } from '@slidev/types'
3
+
4
+ export default defineShortcutsSetup((nav: NavOperations, base: ShortcutOptions[]) => {
5
+ return [
6
+ ...base, // keep the existing shortcuts
7
+ {
8
+ key: 'enter',
9
+ fn: () => nav.next(),
10
+ autoRepeat: true,
11
+ },
12
+ {
13
+ key: 'backspace',
14
+ fn: () => nav.prev(),
15
+ autoRepeat: true,
16
+ },
17
+ ]
18
+ })
Binary file