style: 簡介頁碼

This commit is contained in:
skytek_xinliang
2026-09-16 14:37:31 +08:00
parent 8b28112cbf
commit ea8793e34c
@@ -1,4 +1,5 @@
<script setup lang="ts">
import { shallowRef } from "vue";
import expoParkOverviewImage from "@/assets/introduction/expo_park_open/open_00.jpg";
import sportsEmpowerHubImage from "@/assets/introduction/expo_park_open/open_01.jpg";
import fitnessResearchImage from "@/assets/introduction/expo_park_open/open_02.jpg";
@@ -23,6 +24,8 @@ const slides = [
src: expoParkZonesImage,
},
];
const activeSlide = shallowRef(0);
</script>
<template>
@@ -36,11 +39,12 @@ const slides = [
計畫簡介
</v-card-title>
<div class="carousel-shell">
<v-carousel
v-model="activeSlide"
class="introduction-carousel"
color="secondary"
delimiter-icon="mdi-square"
hide-delimiter-background
hide-delimiters
show-arrows="hover"
>
<v-carousel-item
@@ -50,6 +54,24 @@ const slides = [
:src="slide.src"
/>
</v-carousel>
<nav class="carousel-pagination" aria-label="計畫簡介輪播頁碼">
<button
v-for="(slide, index) in slides"
:key="slide.title"
class="carousel-page"
:class="{ 'carousel-page--active': activeSlide === index }"
type="button"
:aria-current="activeSlide === index ? 'page' : undefined"
:aria-label="`前往第 ${index + 1} 頁:${slide.title}`"
@click="activeSlide = index"
>
<span class="carousel-page-number">
{{ String(index + 1).padStart(2, "0") }}
</span>
</button>
</nav>
</div>
</v-card>
</template>
</Layout>
@@ -62,6 +84,10 @@ const slides = [
max-height: 680px;
}
.carousel-shell {
margin-top: 12px;
}
.introduction-carousel :deep(.v-window__container),
.introduction-carousel :deep(.v-window-item),
.introduction-carousel :deep(.v-responsive),
@@ -81,14 +107,67 @@ const slides = [
}
}
.introduction-carousel :deep(.v-carousel__controls__item .v-icon) {
color: rgb(var(--v-theme-accent)) !important;
opacity: 1;
.carousel-pagination {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 8px;
max-width: 520px;
margin: 14px auto 0;
padding: 0 12px 8px;
}
.introduction-carousel :deep(.v-carousel__controls__item.v-btn--active .v-icon),
.introduction-carousel :deep(.v-carousel__controls__item--active .v-icon) {
color: rgb(var(--v-theme-secondary)) !important;
opacity: 1;
.carousel-page {
display: flex;
min-width: 0;
align-items: center;
justify-content: center;
padding: 8px 10px;
border: 0;
border-radius: 999px;
color: rgb(var(--v-theme-primary));
background-color: rgba(var(--v-theme-primary), 0.09);
cursor: pointer;
font: inherit;
transition:
color 220ms cubic-bezier(0.32, 0.72, 0, 1),
background-color 220ms cubic-bezier(0.32, 0.72, 0, 1),
transform 220ms cubic-bezier(0.32, 0.72, 0, 1);
}
.carousel-page:hover {
color: #ffffff;
background-color: rgb(var(--v-theme-secondary));
}
.carousel-page:active {
transform: scale(0.97);
}
.carousel-page:focus-visible {
outline: 3px solid rgba(var(--v-theme-secondary), 0.42);
outline-offset: 2px;
}
.carousel-page--active {
color: #ffffff;
background-color: rgb(var(--v-theme-secondary));
}
.carousel-page-number {
font-size: 0.78rem;
font-weight: 900;
line-height: 1;
}
@media (max-width: 600px) {
.carousel-pagination {
gap: 6px;
margin-top: 10px;
padding-inline: 4px;
}
.carousel-page {
padding: 8px;
}
}
</style>