style: 添加案例部分的分类行映射和样式,优化滚动显示效果

This commit is contained in:
Jafeng 2026-05-06 16:27:46 +08:00
parent 02d477d1a7
commit 19b3fcc0e3
2 changed files with 58 additions and 4 deletions

View File

@ -6,6 +6,14 @@ import SectionTitle from './SectionTitle.vue'
const active = ref(caseCategories[0]) const active = ref(caseCategories[0])
const filteredCases = computed(() => cases.filter(item => item.category === active.value)) const filteredCases = computed(() => cases.filter(item => item.category === active.value))
const activeIndex = computed(() => caseCategories.findIndex(category => category === active.value)) const activeIndex = computed(() => caseCategories.findIndex(category => category === active.value))
const categoryLineMap = {
国家医学中心: ['国家医学', '中心'],
公立医院: ['公立医院'],
妇幼保健客户: ['妇幼保健', '客户'],
医疗集团客户: ['医疗集团', '客户']
}
const getCategoryLines = (category) => categoryLineMap[category] ?? [category]
const selectCategory = (category) => { const selectCategory = (category) => {
active.value = category active.value = category
@ -56,7 +64,9 @@ const handleCategoryKeydown = (event, index) => {
@click="selectCategory(category)" @click="selectCategory(category)"
@keydown="handleCategoryKeydown($event, index)" @keydown="handleCategoryKeydown($event, index)"
> >
{{ category }} <span class="case-filter-text">
<span v-for="line in getCategoryLines(category)" :key="line">{{ line }}</span>
</span>
</button> </button>
<span class="case-tab-indicator" :style="{ transform: `translateX(${activeIndex * 100}%)` }"></span> <span class="case-tab-indicator" :style="{ transform: `translateX(${activeIndex * 100}%)` }"></span>
</aside> </aside>

View File

@ -56,6 +56,21 @@ button {
overflow: hidden; overflow: hidden;
} }
.reveal-on-scroll {
opacity: 0;
transform: translateY(22px);
transition:
opacity 0.62s ease,
transform 0.62s cubic-bezier(0.22, 1, 0.36, 1),
box-shadow 0.2s ease;
transition-delay: var(--reveal-delay, 0ms);
}
.reveal-on-scroll.is-visible {
opacity: 1;
transform: translateY(0);
}
.site-header { .site-header {
position: sticky; position: sticky;
top: 0; top: 0;
@ -735,6 +750,12 @@ button {
display: none; display: none;
} }
.case-filter-text {
display: inline-grid;
place-items: center;
gap: 1px;
}
.case-card { .case-card {
height: 116px; height: 116px;
display: flex; display: flex;
@ -1090,14 +1111,15 @@ button {
position: relative; position: relative;
z-index: 2; z-index: 2;
min-width: 0; min-width: 0;
min-height: 40px; min-height: 42px;
padding: 0 6px; padding: 0 2px;
border-color: transparent; border-color: transparent;
border-radius: 12px; border-radius: 12px;
background: transparent; background: transparent;
font-size: 13px; font-size: 13px;
line-height: 1.25; line-height: 1.2;
white-space: normal; white-space: normal;
word-break: keep-all;
box-shadow: none; box-shadow: none;
} }
.case-filter-btn.active { .case-filter-btn.active {
@ -1212,6 +1234,7 @@ button {
min-height: 112px; min-height: 112px;
gap: 15px; gap: 15px;
padding: 18px; padding: 18px;
animation: case-card-in 0.32s ease both;
} }
.case-logo-slot { .case-logo-slot {
flex-basis: 88px; flex-basis: 88px;
@ -1277,3 +1300,24 @@ button {
line-height: 1.25; line-height: 1.25;
} }
} }
@keyframes case-card-in {
from {
opacity: 0;
transform: translateY(10px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
@media (prefers-reduced-motion: reduce) {
.reveal-on-scroll,
.case-card {
animation: none;
opacity: 1;
transform: none;
transition: none;
}
}