Fixed responsive stlying
This commit is contained in:
@@ -5,12 +5,19 @@
|
||||
分からなかったらリストにはられているリンクを参照すること。
|
||||
|
||||
* HTML, CSS, JavaScriptの基本的な知識 [MDN Web Docs](https://developer.mozilla.org/ja/docs/Web)
|
||||
* (Optional) TypeScript [The TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
|
||||
* TypeScript [The TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/intro.html)
|
||||
* フロントエンド([Vue.js](https://ja.vuejs.org/)/[Nuxt](https://nuxt.com), [htmx](https://htmx.org/))とバックエンド([sqlite](https://www.sqlite.org/), Nuxt, [Express](https://expressjs.com/))の基本的な知識
|
||||
* GitとGitHubの基本的な知識 [GitHubとGitについて](https://docs.github.com/ja/get-started/start-your-journey/about-github-and-git)
|
||||
* Markdownの基本的な知識 [Markdown記法一覧](https://qiita.com/oreo/items/82183bfbaac69971917f)
|
||||
* 中学卒業レベル以上の英語力 [**頑張れ**](https://jstc.jma.or.jp/)
|
||||
|
||||
その他資料:
|
||||
* [TypeScriptの特徴とは?JavaScriptとの違いを交えて解説](https://hnavi.co.jp/knowledge/blog/typescript/)
|
||||
* [Vue.js入門(Vue.jsの初心者は必ず読め‼︎)](https://qiita.com/Hashimoto-Noriaki/items/ea60d5932f13a9cd5707)
|
||||
* [Nuxt.jsとは、Vue.jsを効果的に使うためのフレームワーク!導入のメリットは?【入門編】](https://www.webstaff.jp/guide/trend/webit/nuxtjs/)
|
||||
* [Express.js完全入門](https://qiita.com/ryome/items/16659012ed8aa0aa1fac)
|
||||
* [htmxとは何なのか? その背景にある思想について](https://qiita.com/tsmd/items/0d07feb8e02cfa213cc4)
|
||||
|
||||
## レポジトリの構成
|
||||
|
||||
このレポジトリには2つのプロジェクトが存在する:
|
||||
@@ -20,7 +27,7 @@
|
||||
|
||||
## 問題の報告・新仕様の提案
|
||||
|
||||
ウェブサイトで起こったバグの報告や新しい仕様の提案はIssueから行う。
|
||||
ウェブサイトで起こったバグの報告や新しい仕様・ページデザイン案等の提案はIssueから行う。
|
||||
|
||||
### バグ報告
|
||||
|
||||
@@ -72,7 +79,24 @@
|
||||
### PRテンプレート
|
||||
|
||||
```markdown
|
||||
**タイトル** [簡潔で明確に問題やリクエストを記述してください]
|
||||
|
||||
**PRタイプ** [以下から選ぶ:]
|
||||
|
||||
- [ ] バグ修正
|
||||
- [ ] 新仕様実装
|
||||
|
||||
**関連するISSUE** [ISSUE番号を列挙します。(例;#1、#123)]
|
||||
|
||||
**変更とその理由** [1、2文で簡潔に変更箇所を書き、その理由を述べる]
|
||||
|
||||
**確認箇所** [以下のチェックリストに従う;]
|
||||
|
||||
- [ ] 書いたコードは`CONTRIBUTING.md`内のコーディング規約に従っているか
|
||||
- [ ] `npm run lint`, `npm run format`を最低1回実行したか
|
||||
- [ ] (任意) 新たな型定義等でJSDoc対応のコメントを残し、`npm run documentation`でドキュメンテーションを生成したか
|
||||
|
||||
**補足** [その他必要だと思う情報を書き足す]
|
||||
```
|
||||
|
||||
## コーディング規約
|
||||
@@ -81,16 +105,16 @@
|
||||
|
||||
#### ファイル
|
||||
|
||||
* タブ・インデントは半角スペース4個分とし、タブ文字は使わないとする
|
||||
* タブ・インデントは半角スペース4個分とし、タブ文字は**使わない**とする
|
||||
* ファイルは**必ず**UTF-8で保存する
|
||||
|
||||
#### 変数、定数など
|
||||
|
||||
##### 命名規則
|
||||
|
||||
* 変数、定数、型名、関数名にローマ字を使用しない
|
||||
* 変数、定数、型名、関数名での連番は極力避ける
|
||||
* 変数、定数、型名、関数名には3文字以上の略称でない意味のある名前をつける
|
||||
* 変数、定数、型名、関数名に**ローマ字を使用しない**
|
||||
* 変数、定数、型名、関数名での連番は**極力避ける**
|
||||
* 変数、定数、型名、関数名には3文字以上の略称でない**意味のある名前をつける**
|
||||
* 変数、定数、関数名にはcamelCase
|
||||
* クラス名、型名、`components/`下のVueコンポーネントファイル名にはPascalCase
|
||||
* CSSクラス、id、`pages/`下のVueファイル・フォルダにはkebab-case
|
||||
@@ -98,19 +122,18 @@
|
||||
|
||||
##### その他
|
||||
|
||||
* (TypeScript): 関数名・クラス名から判断できる場合のみ型の明記を省略しても良い、それ以外は明記する必要がある
|
||||
* 変数・定数定義以外でMagic Values(生の値)の使用は極力避け、代わりに列挙体や定数を使う
|
||||
* (TypeScript): 関数名・クラス名から**判断できる場合のみ**型の明記を省略しても良い、それ以外は**明記する必要がある**
|
||||
* 変数・定数定義以外でMagic Values(生の値)の使用は**極力避け**、代わりに列挙体や定数を使う
|
||||
* 変数・定数には内容に合った型を明記する(TypeScript)
|
||||
|
||||
#### 括弧の使用について
|
||||
|
||||
* if文、for文、while文、関数定義、CSSのセレクターの中括弧は同じ行に書く
|
||||
* if文、for文、while文の内容が1行だけならば中括弧は省略しても良いとする
|
||||
* JavaScript/TypeScriptでのネスティングは4段以上にしない(参照:[Why You Shouldn't Nest Your Code](https://www.youtube.com/watch?v=CFRhGnuXG-4))
|
||||
* JavaScript/TypeScriptでのネスティングは**4段以上にしない**(参照:[Why You Shouldn't Nest Your Code](https://www.youtube.com/watch?v=CFRhGnuXG-4))
|
||||
|
||||
#### プログラミングパラダイム
|
||||
|
||||
* JavaScript/TypeScriptでクラスを使用したい場合、継承を避け、合成を採用する。抽象化は冗長解消より本来のモノの概念をソースに起こすことを優先する(参照:[The Flaws of Inheritance](https://www.youtube.com/watch?v=hxGOiiR9ZKg), [Abstracion Can Make Your Code Worse](https://www.youtube.com/watch?v=rQlMtztiAoA))
|
||||
* JavaScript/TypeScriptでオブジェクト指向プログラミングを使用したい場合、継承を避け、合成を採用する。抽象化は冗長解消より本来のモノの概念をソースに起こすことを優先する(参照:[The Flaws of Inheritance](https://www.youtube.com/watch?v=hxGOiiR9ZKg), [Abstracion Can Make Your Code Worse](https://www.youtube.com/watch?v=rQlMtztiAoA))
|
||||
* 関数型言語の特徴を取り入れても良いとする
|
||||
|
||||
#### コメント・ドキュメンテーション
|
||||
@@ -119,6 +142,7 @@
|
||||
* 無駄で間違ったコメントは書かない(参照:[Don't Write Comments](https://www.youtube.com/watch?v=Bf7vDBBOBUA&ab_channel=CodeAesthetic))
|
||||
* 仕様、使い方についてはコメントではなくドキュメンテーションに記載する
|
||||
* APIには簡潔な英語のドキュメンテーションを書く([JSdoc](https://www.typescriptlang.org/ja/docs/handbook/jsdoc-supported-types.html))
|
||||
* `composables/`, `server/`, `utils/`, `src-manager/`下に記載された関数や型定義等は**必ず**ドキュメンテーションを書くこと、それ以外は任意で記載する
|
||||
|
||||
#### その他
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
|
||||
#App {
|
||||
display: grid;
|
||||
height: max-content;
|
||||
}
|
||||
|
||||
body {
|
||||
@@ -25,10 +26,10 @@ body {
|
||||
|
||||
main {
|
||||
margin: var(--main-margin-top-bottom) var(--main-margin-left-right);
|
||||
min-height: 64vh;
|
||||
}
|
||||
|
||||
html {
|
||||
font-size: 16px;
|
||||
scrollbar-width: none;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
main {
|
||||
display: grid;
|
||||
width: 50%;
|
||||
min-height: 75vh;
|
||||
justify-self: center;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,8 +19,8 @@ const triggerDistance = 100;
|
||||
position: fixed;
|
||||
bottom: 2rem;
|
||||
right: 2rem;
|
||||
z-index: 5;
|
||||
display: flex;
|
||||
justify-self: end;
|
||||
width: 6rem;
|
||||
height: 6rem;
|
||||
border-radius: 5rem;
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { DropDownAlignment, type DropDownProperty } from "#imports";
|
||||
import {
|
||||
DropDownAlignment,
|
||||
type DropDownProperty,
|
||||
} from "~/utils/types/dropDown";
|
||||
|
||||
const property = defineProps<DropDownProperty>();
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { HamburgerMenuProperty } from "#imports";
|
||||
import type { HamburgerMenuProperty } from "~/utils/types/hamburgerMenu";
|
||||
|
||||
const property = defineProps<HamburgerMenuProperty>();
|
||||
|
||||
@@ -69,7 +69,7 @@ const handleClickEvent = () => {
|
||||
}
|
||||
|
||||
.hamburger-menu-item-list {
|
||||
--menu-width: 45vw;
|
||||
--menu-width: max(16rem, 45vw);
|
||||
display: block;
|
||||
background: var(--neptune1);
|
||||
color: var(--starlight);
|
||||
@@ -81,6 +81,7 @@ const handleClickEvent = () => {
|
||||
width: var(--menu-width);
|
||||
height: 100vh;
|
||||
text-wrap: nowrap;
|
||||
overflow-y: scroll;
|
||||
& button {
|
||||
--button-size: 2.5rem;
|
||||
display: flex;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { LinkCardProperty } from "~/utils/linkCard";
|
||||
import type { LinkCardProperty } from "~/utils/types/linkCard";
|
||||
const property = defineProps<LinkCardProperty>();
|
||||
const doesNotHaveImage = ref<boolean>(property.imagePath === undefined);
|
||||
</script>
|
||||
@@ -20,7 +20,7 @@ const doesNotHaveImage = ref<boolean>(property.imagePath === undefined);
|
||||
a {
|
||||
display: grid;
|
||||
width: 25rem;
|
||||
height: 30rem;
|
||||
height: clamp(10rem, 15vh, max(30rem, fit-content));
|
||||
grid: 2fr 1fr 1.5fr / 1fr;
|
||||
background-color: var(--starlight);
|
||||
border-radius: 1rem;
|
||||
@@ -39,7 +39,6 @@ a > * {
|
||||
|
||||
.withoutImage {
|
||||
grid: 1fr 1.5fr / 1fr;
|
||||
height: 15rem;
|
||||
}
|
||||
|
||||
.image {
|
||||
@@ -58,10 +57,11 @@ h2 {
|
||||
color: var(--neptune1);
|
||||
background-color: var(--starlight5);
|
||||
border-radius: 1rem;
|
||||
margin: 0 2rem;
|
||||
margin: 0.75rem 2rem;
|
||||
padding: 1rem 1.75rem;
|
||||
align-self: center;
|
||||
line-height: 2rem;
|
||||
font-size: clamp(16pt, 3vw, 20pt);
|
||||
}
|
||||
|
||||
h2::after {
|
||||
@@ -69,9 +69,10 @@ h2::after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 7px;
|
||||
height: 2rem;
|
||||
top: 1rem;
|
||||
height: max(2rem, 60%);
|
||||
top: 50%;
|
||||
left: 0.75rem;
|
||||
transform: translateY(-50%);
|
||||
background-color: var(--neptune1);
|
||||
border-radius: 3px;
|
||||
}
|
||||
@@ -84,13 +85,9 @@ p {
|
||||
@media screen and (max-width: 1024px) {
|
||||
a {
|
||||
width: 20rem;
|
||||
height: 25rem;
|
||||
}
|
||||
a > * {
|
||||
margin: 0 1rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 16pt;
|
||||
margin: unset 0.25rem;
|
||||
}
|
||||
.image {
|
||||
width: 16rem;
|
||||
@@ -101,13 +98,9 @@ p {
|
||||
@media screen and (max-width: 640px) {
|
||||
a {
|
||||
width: 16rem;
|
||||
height: 21rem;
|
||||
}
|
||||
a > * {
|
||||
margin: 0 0.75rem;
|
||||
}
|
||||
h2 {
|
||||
font-size: 16pt;
|
||||
margin: unset 0.75rem;
|
||||
}
|
||||
.image {
|
||||
width: 12rem;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { NewsCardProperty } from "~/utils/newsCard";
|
||||
import type { NewsCardProperty } from "~/utils/types/newsCard";
|
||||
import { marked } from "marked";
|
||||
|
||||
const property = defineProps<NewsCardProperty>();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { PageTopProperty } from "~/utils/pageTop";
|
||||
import type { PageTopProperty } from "~/utils/types/pageTop";
|
||||
|
||||
const property = defineProps<PageTopProperty>();
|
||||
</script>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<script setup lang="ts">
|
||||
import PankuzuEntries from "~/assets/pankuzuEntries.json";
|
||||
import type { PankuzuListProperty } from "~/utils/pankuzuList";
|
||||
import type { PankuzuListProperty } from "~/utils/types/pankuzuList";
|
||||
|
||||
const property = defineProps<PankuzuListProperty>();
|
||||
const route = useRoute();
|
||||
@@ -36,6 +36,7 @@ nav {
|
||||
height: 5rem;
|
||||
display: flex;
|
||||
align-content: center;
|
||||
container: pankuzu / inline-size;
|
||||
}
|
||||
|
||||
ul {
|
||||
@@ -43,8 +44,8 @@ ul {
|
||||
list-style-type: none;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
width: var(--list-width);
|
||||
padding: 0 0 0 max(3rem, calc(50vw - var(--list-width)));
|
||||
width: fit-content;
|
||||
padding: 0 0 0 max(2rem, calc(50vw - var(--list-width)));
|
||||
}
|
||||
|
||||
ul li {
|
||||
@@ -94,4 +95,10 @@ ul li:not(:first-of-type) p:first-of-type {
|
||||
height: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@container pankuzu (width < 640px) {
|
||||
ul li {
|
||||
font-size: smaller;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
<script setup lang="ts">
|
||||
import type { QAndABoxProperty } from "~/utils/qAndABox";
|
||||
import type { QAndABoxProperty } from "~/utils/types/qAndABox";
|
||||
const property = defineProps<QAndABoxProperty>();
|
||||
</script>
|
||||
|
||||
|
||||
@@ -1,10 +1,17 @@
|
||||
<script setup lang="ts">
|
||||
import type { SlideProperty, SlideEntry } from "~/utils/slide.ts";
|
||||
import type { SlideProperty, SlideEntry } from "~/utils/types/slide.ts";
|
||||
|
||||
const property = defineProps<SlideProperty>();
|
||||
const { viewPortOrientation } = useWindowDimensions();
|
||||
|
||||
const UnitREM = 16;
|
||||
const fourREM = 4 * UnitREM;
|
||||
const halfREM = 0.5 * UnitREM;
|
||||
|
||||
const width = property.width;
|
||||
const height = property.height;
|
||||
const controlerWidth = (property.entries.length + 1) * (fourREM + halfREM);
|
||||
const controlerWidthCSSValue = controlerWidth.toString() + "px";
|
||||
let timer: NodeJS.Timeout;
|
||||
|
||||
const controlIcons = ["ic:baseline-pause", "ic:baseline-play-arrow"];
|
||||
@@ -28,9 +35,18 @@ const previewAnimationTiming: KeyframeEffectOptions = {
|
||||
};
|
||||
|
||||
const slideAnimationTimingMargin = 100;
|
||||
const slideAnimationFirstStageOffset = 0.2;
|
||||
const slideAnimationSecondStageOffset = 0.5;
|
||||
const slideAnimationThirdStageOffset = 0.8;
|
||||
const slideAnimation = {
|
||||
opacity: [0, 1, 1, 1, 0],
|
||||
offset: [0, 0.2, 0.5, 0.8, 1],
|
||||
offset: [
|
||||
0,
|
||||
slideAnimationFirstStageOffset,
|
||||
slideAnimationSecondStageOffset,
|
||||
slideAnimationThirdStageOffset,
|
||||
1.0,
|
||||
],
|
||||
easing: ["ease-in", "ease-out"],
|
||||
};
|
||||
|
||||
@@ -198,6 +214,8 @@ onUnmounted(() => {
|
||||
position: relative;
|
||||
width: v-bind(width);
|
||||
height: v-bind(height);
|
||||
container-name: slide;
|
||||
container-type: size;
|
||||
}
|
||||
|
||||
.slides {
|
||||
@@ -227,14 +245,15 @@ ul {
|
||||
|
||||
.content {
|
||||
position: absolute;
|
||||
top: 20%;
|
||||
top: 25%;
|
||||
left: 50%;
|
||||
transform: translateX(-50%) translateY(-1.5vw);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: max(80%, 16rem);
|
||||
& > h1 {
|
||||
margin: auto 0;
|
||||
font-size: clamp(3rem, 3vw, 5rem);
|
||||
font-size: clamp(3rem, 3cqw, 52pt);
|
||||
text-align: center;
|
||||
color: var(--starlight);
|
||||
}
|
||||
@@ -242,7 +261,7 @@ ul {
|
||||
height: 3rem;
|
||||
justify-self: center;
|
||||
color: var(--starlight);
|
||||
font-size: clamp(14pt, 1.5vw, 24pt);
|
||||
font-size: clamp(14pt, 1.5cqw, 24pt);
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
}
|
||||
@@ -250,11 +269,12 @@ ul {
|
||||
width: fit-content;
|
||||
border: var(--starlight) 3px solid;
|
||||
background-color: transparent;
|
||||
padding: 0.5rem 2rem;
|
||||
margin-top: 5cqh;
|
||||
padding: 0.5rem 1.5rem;
|
||||
color: var(--uranus);
|
||||
text-decoration: none;
|
||||
font-weight: bold;
|
||||
font-size: clamp(16pt, 1.5vw, 20pt);
|
||||
font-size: clamp(16pt, 2cqw, 20pt);
|
||||
place-self: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
@@ -273,6 +293,9 @@ ul {
|
||||
position: absolute;
|
||||
bottom: 1rem;
|
||||
right: 1rem;
|
||||
width: v-bind(controlerWidthCSSValue);
|
||||
height: 4rem;
|
||||
align-items: center;
|
||||
& > button {
|
||||
display: flex;
|
||||
border: none;
|
||||
@@ -280,7 +303,8 @@ ul {
|
||||
background-color: rgba(100, 100, 100, 0.8);
|
||||
width: 4rem;
|
||||
height: 4rem;
|
||||
margin-inline: 0.25rem;
|
||||
margin-inline: 0.0625rem;
|
||||
scale: 90%;
|
||||
}
|
||||
& > button:hover {
|
||||
cursor: pointer;
|
||||
@@ -300,7 +324,8 @@ ul {
|
||||
position: relative;
|
||||
width: var(--calculated-size);
|
||||
height: var(--calculated-size);
|
||||
margin-inline: 0.25rem;
|
||||
margin-inline: 0.0625rem;
|
||||
scale: 90%;
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -329,12 +354,29 @@ ul {
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 960px) {
|
||||
.controler {
|
||||
flex-direction: column;
|
||||
}
|
||||
.preview {
|
||||
margin: 0.25rem 0;
|
||||
@container slide (width < 640px) {
|
||||
.content {
|
||||
width: 16rem;
|
||||
transform: translateX(-55%);
|
||||
}
|
||||
}
|
||||
|
||||
@container slide (width < 960px) {
|
||||
.controler {
|
||||
flex-direction: column;
|
||||
scale: 80%;
|
||||
bottom: -2rem;
|
||||
right: 0rem;
|
||||
width: 4rem;
|
||||
height: v-bind(controlerWidthCSSValue);
|
||||
}
|
||||
.preview {
|
||||
margin: calc(1rem / 16) 0;
|
||||
}
|
||||
}
|
||||
|
||||
.portrait-controler {
|
||||
flex-direction: column;
|
||||
right: 0rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import LogoSVG from "public/sera-logo-no-text.svg";
|
||||
import SiteInfo from "~/assets/siteinfo.json";
|
||||
import type { DropDownEntry } from "~/utils/dropDown";
|
||||
import type { DropDownEntry } from "~/utils/types/dropDown";
|
||||
|
||||
const { viewPortType } = useWindowDimensions();
|
||||
|
||||
|
||||
@@ -19,6 +19,16 @@ const enum ViewPortType {
|
||||
MOBILE,
|
||||
}
|
||||
|
||||
/**
|
||||
* Enums for viewport orientation
|
||||
* @readonly
|
||||
* @enum {number}
|
||||
*/
|
||||
const enum ViewPortOrientation {
|
||||
LANDSCAPE,
|
||||
PORTRAIT,
|
||||
}
|
||||
|
||||
/**
|
||||
* Vue Composable for getting window dimensions and viewport type based on width
|
||||
* @returns {object} returns the references of width, height, and viewport type
|
||||
@@ -27,10 +37,15 @@ function useWindowDimensions() {
|
||||
const width = ref<number>(0);
|
||||
const height = ref<number>(0);
|
||||
const viewPortType = ref<ViewPortType>(ViewPortType.DESKTOP);
|
||||
const viewPortOrientation = ref<ViewPortOrientation>(
|
||||
ViewPortOrientation.LANDSCAPE
|
||||
);
|
||||
|
||||
function update(event: Event | undefined) {
|
||||
function update() {
|
||||
width.value = window.innerWidth;
|
||||
height.value = window.innerHeight;
|
||||
viewPortOrientation.value = (width.value <
|
||||
height.value) as unknown as number;
|
||||
if (width.value > largeTabletMaxWidth) {
|
||||
viewPortType.value = ViewPortType.DESKTOP;
|
||||
} else if (width.value > mediumTabletMaxWidth) {
|
||||
@@ -43,13 +58,13 @@ function useWindowDimensions() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
update(undefined);
|
||||
update();
|
||||
window.addEventListener("resize", update);
|
||||
});
|
||||
|
||||
onUnmounted(() => window.removeEventListener("resize", update));
|
||||
|
||||
return { width, height, viewPortType };
|
||||
return { width, height, viewPortType, viewPortOrientation };
|
||||
}
|
||||
|
||||
export { useWindowDimensions, ViewPortType };
|
||||
export { useWindowDimensions, ViewPortType, ViewPortOrientation };
|
||||
|
||||
@@ -16,6 +16,7 @@ const basicRules = {
|
||||
{
|
||||
"ignoreArrayIndexes": true,
|
||||
"ignoreClassFieldInitialValues": true,
|
||||
"ignoreDefaultValues": true,
|
||||
"enforceConst": true,
|
||||
"ignore": [0, 1, -1]
|
||||
}
|
||||
|
||||
@@ -7,6 +7,9 @@ export default defineNuxtConfig({
|
||||
'/news/**': { prerender: true },
|
||||
'/projects/**': { prerender: true }
|
||||
},
|
||||
imports: {
|
||||
dirs: ["utils/types"],
|
||||
},
|
||||
devtools: { enabled: true },
|
||||
modules: [
|
||||
'@nuxt/image',
|
||||
|
||||
2501
package-lock.json
generated
2501
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -8,7 +8,7 @@
|
||||
"generate": "nuxt generate",
|
||||
"preview": "nuxt preview",
|
||||
"postinstall": "nuxt prepare",
|
||||
"documentation": "typedoc utils/*.ts server/api/*.ts composables/*.ts",
|
||||
"documentation": "typedoc utils/*.ts utils/types/*.ts server/api/*.ts composables/*.ts",
|
||||
"lint": "eslint .",
|
||||
"format": "prettier . --write"
|
||||
},
|
||||
@@ -22,6 +22,8 @@
|
||||
"devDependencies": {
|
||||
"@iconify-json/hugeicons": "^1.2.1",
|
||||
"@iconify-json/ic": "^1.2.1",
|
||||
"@iconify-json/material-symbols": "^1.2.6",
|
||||
"@iconify-json/simple-icons": "^1.2.11",
|
||||
"@nuxt/icon": "^1.5.1",
|
||||
"@nuxt/image": "^1.7.0",
|
||||
"@nuxtjs/sitemap": "^6.0.1",
|
||||
|
||||
@@ -11,8 +11,6 @@ const imagePathViewer = ref<string>("");
|
||||
const captionViewer = ref<string>("");
|
||||
const indexViewer = ref<number>(0);
|
||||
|
||||
const scrollDistance = useScrollDistance();
|
||||
|
||||
const openViewer = (entry: GalleryEntry) => {
|
||||
showViewer.value = true;
|
||||
imagePathViewer.value = entry.imagePath;
|
||||
@@ -95,6 +93,7 @@ main {
|
||||
|
||||
.image-list {
|
||||
width: 80%;
|
||||
min-width: 20rem;
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, 20rem);
|
||||
grid-template-rows: auto;
|
||||
@@ -133,8 +132,8 @@ main {
|
||||
}
|
||||
|
||||
.image-viewer {
|
||||
position: absolute;
|
||||
top: v-bind(scrollDistance + "px");
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
z-index: 10;
|
||||
display: grid;
|
||||
@@ -150,12 +149,12 @@ main {
|
||||
}
|
||||
|
||||
.image-viewer img {
|
||||
width: min(60vw, auto);
|
||||
height: auto;
|
||||
max-height: 80vh;
|
||||
width: clamp(10rem, 50%, 50rem);
|
||||
height: clamp(10rem, 60vh, 50rem);
|
||||
grid-area: image;
|
||||
justify-self: center;
|
||||
align-self: center;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.image-viewer p {
|
||||
@@ -217,6 +216,7 @@ main {
|
||||
@media screen and (max-width: 640px) {
|
||||
main {
|
||||
margin-inline: 1rem;
|
||||
width: calc(100vw - (2 * 1rem));
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
130
pages/index.vue
130
pages/index.vue
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { marked } from "marked";
|
||||
import { EntryType } from "#imports";
|
||||
import type { SlideEntry } from "#imports";
|
||||
import { EntryType, type NewsEntry } from "~/utils/types/news";
|
||||
import type { SlideEntry } from "~/utils/types/slide";
|
||||
|
||||
const { data } = await useFetch("/api/getNewsList");
|
||||
|
||||
@@ -57,6 +57,30 @@ const slidesForProjects: Array<SlideEntry> = [
|
||||
},
|
||||
];
|
||||
|
||||
interface QuickLinkEntry {
|
||||
label: string;
|
||||
imagePath: string;
|
||||
link: string;
|
||||
}
|
||||
|
||||
const quickLinkEntries: Array<QuickLinkEntry> = [
|
||||
{
|
||||
label: "NEWS",
|
||||
imagePath: "/images/news-top.jpg",
|
||||
link: "/news",
|
||||
},
|
||||
{
|
||||
label: "About",
|
||||
imagePath: "/images/page-top.jpg",
|
||||
link: "/about",
|
||||
},
|
||||
{
|
||||
label: "Projects",
|
||||
imagePath: "/images/kosen1_gunma-cgv5-a.JPG",
|
||||
link: "/projects",
|
||||
},
|
||||
];
|
||||
|
||||
let slideEntries = ref<Array<SlideEntry>>(
|
||||
welcomeSlide.concat(getNewsEntriesForSlide(), slidesForProjects)
|
||||
);
|
||||
@@ -85,9 +109,23 @@ useSeoMeta(
|
||||
:entries="slideEntries"
|
||||
:duration="6000"
|
||||
width="100vw"
|
||||
height="calc(100svh - 104px)"
|
||||
height="max(50svh, 30rem)"
|
||||
id="slide"
|
||||
/>
|
||||
<div id="quick-links-container">
|
||||
<div id="quick-links">
|
||||
<div
|
||||
class="quick-link-entry"
|
||||
v-for="entry in quickLinkEntries"
|
||||
:key="quickLinkEntries.indexOf(entry)"
|
||||
:style="{ backgroundImage: `url('${entry.imagePath}')` }"
|
||||
>
|
||||
<NuxtLink :to="entry.link">
|
||||
<h2>{{ entry.label }}</h2>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="news-board">
|
||||
<h3>News</h3>
|
||||
<div></div>
|
||||
@@ -143,22 +181,88 @@ useSeoMeta(
|
||||
<style scoped>
|
||||
main {
|
||||
display: grid;
|
||||
grid: auto auto / 3fr 2fr;
|
||||
grid: auto auto auto / 3fr 2fr;
|
||||
grid-template-areas:
|
||||
"slide slide"
|
||||
"quick-links quick-links"
|
||||
"news twitter";
|
||||
margin: 0;
|
||||
width: 100vw;
|
||||
}
|
||||
|
||||
main > *:not(#slide) {
|
||||
margin: var(--main-margin-top-bottom) var(--main-margin-left-right);
|
||||
main > *:not(#slide, #quick-links-container) {
|
||||
margin-inline: var(--main-margin-left-right);
|
||||
}
|
||||
|
||||
main:last-child {
|
||||
margin-bottom: var(--main-margin-top-bottom);
|
||||
}
|
||||
|
||||
#slide {
|
||||
grid-area: slide;
|
||||
}
|
||||
|
||||
#quick-links-container {
|
||||
display: block;
|
||||
margin: 0 0 2rem 0;
|
||||
grid-area: quick-links;
|
||||
container: quick-links-container / inline-size;
|
||||
background-color: var(--astronaut);
|
||||
}
|
||||
|
||||
#quick-links {
|
||||
--quick-link-margin: 1rem;
|
||||
display: grid;
|
||||
width: calc(100vw - 40 * var(--quick-link-margin));
|
||||
height: calc(100vw / 3 * 1 / 3);
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
grid-template-rows: 1fr;
|
||||
margin: var(--quick-link-margin) calc(20 * var(--quick-link-margin));
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.quick-link-entry {
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: auto;
|
||||
aspect-ratio: 3/1;
|
||||
background-position: center;
|
||||
background-size: cover;
|
||||
background-color: #414141cb;
|
||||
background-blend-mode: overlay;
|
||||
transition: all 0.5s ease-in-out;
|
||||
& > a {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
color: var(--starlight);
|
||||
text-decoration: none;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
& > a > h2 {
|
||||
font-size: 3cqi;
|
||||
}
|
||||
}
|
||||
|
||||
.quick-link-entry:hover {
|
||||
transition: all 0.25s ease-in-out;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
@container quick-links-container (width < 640px) {
|
||||
#quick-links {
|
||||
width: 100vw;
|
||||
height: 100vw;
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-rows: repeat(3, 1fr);
|
||||
margin-inline: 0;
|
||||
}
|
||||
.quick-link-entry > a > h2 {
|
||||
font-size: 7cqi;
|
||||
}
|
||||
}
|
||||
|
||||
#news-board {
|
||||
max-width: 60rem;
|
||||
max-height: 50rem;
|
||||
@@ -230,7 +334,7 @@ main > *:not(#slide) {
|
||||
max-width: 100%;
|
||||
overflow-x: hidden;
|
||||
grid-area: twitter;
|
||||
& > .twitter-timeline-rendered {
|
||||
& > .twitter-timeline {
|
||||
display: unset !important;
|
||||
width: unset !important;
|
||||
max-width: unset !important;
|
||||
@@ -242,12 +346,16 @@ main > *:not(#slide) {
|
||||
main {
|
||||
place-self: center;
|
||||
place-content: center;
|
||||
grid-template-rows: repeat(3, auto);
|
||||
grid-template-rows: repeat(4, auto);
|
||||
grid-template-columns: 1fr;
|
||||
grid-template-areas:
|
||||
"slide"
|
||||
"quick-links"
|
||||
"news"
|
||||
"tweet";
|
||||
& > * {
|
||||
margin-inline: 0 !important;
|
||||
}
|
||||
}
|
||||
|
||||
#slide {
|
||||
@@ -279,15 +387,15 @@ main > *:not(#slide) {
|
||||
}
|
||||
|
||||
#twitter {
|
||||
margin: 1rem 0;
|
||||
width: calc(90vw - 4rem);
|
||||
height: fit-content;
|
||||
justify-self: center;
|
||||
justify-content: center;
|
||||
position: relative;
|
||||
grid-column-start: 1;
|
||||
grid-column-end: 2;
|
||||
grid-row-start: 3;
|
||||
grid-row-end: 4;
|
||||
grid-row-start: 4;
|
||||
grid-row-end: 5;
|
||||
& > .twitter-timeline-rendered iframe {
|
||||
position: absolute;
|
||||
inset: 50% auto auto 50%;
|
||||
|
||||
6
src-manager/package-lock.json
generated
6
src-manager/package-lock.json
generated
@@ -1969,9 +1969,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/object-inspect": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
|
||||
"integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
|
||||
"version": "1.13.3",
|
||||
"resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.3.tgz",
|
||||
"integrity": "sha512-kDCGIbxkDSXE3euJZZXzc6to7fCrKHNI/hSRQnRuQ+BWjFNzZwiFF8fj/6o2t2G9/jTj8PSIYTfCLelLZEeRpA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
|
||||
Reference in New Issue
Block a user