修复顺序bug,修改时间轴布局
This commit is contained in:
143
frontend/App.vue
143
frontend/App.vue
@@ -54,7 +54,7 @@
|
||||
<div class="route-toolbar">
|
||||
<button class="mini-btn" @click="selectTopRoutes">显示高频路线</button>
|
||||
<button class="mini-btn" @click="clearAllRoutes">清空</button>
|
||||
<button class="mini-btn" :class="{ active: showRouteOrder }" @click="showRouteOrder = !showRouteOrder">
|
||||
<button class="mini-btn" :class="{ active: showRouteOrder }" @click="toggleRouteOrderMarkers">
|
||||
{{ showRouteOrder ? '顺序标记:开' : '顺序标记:关' }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -108,29 +108,7 @@
|
||||
</div>
|
||||
|
||||
<div class="chapter-panel">
|
||||
<h3>卷册进度</h3>
|
||||
<div class="vol-slider-wrap">
|
||||
<input
|
||||
type="range"
|
||||
class="chapter-slider"
|
||||
v-model.number="currentVol"
|
||||
:min="1"
|
||||
:max="TOTAL_VOLS"
|
||||
@input="onVolSliderChange"
|
||||
>
|
||||
<div class="vol-ticks">
|
||||
<span
|
||||
v-for="tick in volTicks"
|
||||
:key="tick.vol"
|
||||
class="tick-label"
|
||||
:style="{ left: tick.pct + '%' }"
|
||||
>{{ tick.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vol-info">
|
||||
当前:{{ currentVolLabel }} | 已加载 {{ loadedCount }} / {{ TOTAL_VOLS }} {{ currentNovel.volsLabel }}
|
||||
</div>
|
||||
|
||||
<h3>地图搜索与事件</h3>
|
||||
<div class="search-panel">
|
||||
<div class="events-title">地图搜索</div>
|
||||
<input
|
||||
@@ -167,6 +145,31 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="timeline-dock">
|
||||
<div class="timeline-head">
|
||||
<span>卷册进度时间轴</span>
|
||||
<span class="timeline-meta">{{ currentVolLabel }} · {{ loadedCount }} / {{ TOTAL_VOLS }} {{ currentNovel.volsLabel }}</span>
|
||||
</div>
|
||||
<div class="vol-slider-wrap timeline-wrap">
|
||||
<input
|
||||
type="range"
|
||||
class="chapter-slider"
|
||||
v-model.number="currentVol"
|
||||
:min="1"
|
||||
:max="TOTAL_VOLS"
|
||||
@input="onVolSliderChange"
|
||||
>
|
||||
<div class="vol-ticks">
|
||||
<span
|
||||
v-for="tick in volTicks"
|
||||
:key="tick.vol"
|
||||
class="tick-label"
|
||||
:style="{ left: tick.pct + '%' }"
|
||||
>{{ tick.label }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="info-panel" v-if="selectedFaction">
|
||||
<span class="close-btn" @click="selectedFaction = null">×</span>
|
||||
<h3 :style="{ color: selectedFaction.color }">{{ selectedFaction.name }}</h3>
|
||||
@@ -773,6 +776,11 @@ function clearRouteFocus() {
|
||||
drawRoutesOnly()
|
||||
}
|
||||
|
||||
function toggleRouteOrderMarkers() {
|
||||
showRouteOrder.value = !showRouteOrder.value
|
||||
drawRoutesOnly()
|
||||
}
|
||||
|
||||
function clearAllRoutes() {
|
||||
selectedRoutes.value = []
|
||||
focusedRouteName.value = ''
|
||||
@@ -1176,7 +1184,7 @@ function scrollToChatBottom() {
|
||||
|
||||
.chapter-panel {
|
||||
right: 12px;
|
||||
bottom: 14px;
|
||||
bottom: 128px;
|
||||
width: 360px;
|
||||
max-height: calc(100vh - 140px);
|
||||
overflow-y: auto;
|
||||
@@ -1189,6 +1197,40 @@ function scrollToChatBottom() {
|
||||
color: #e6c27a;
|
||||
}
|
||||
|
||||
.timeline-dock {
|
||||
left: 50%;
|
||||
bottom: 10px;
|
||||
transform: translateX(-50%);
|
||||
width: min(980px, calc(100vw - 32px));
|
||||
border-radius: 14px;
|
||||
padding: 10px 14px 8px;
|
||||
position: absolute;
|
||||
z-index: 1000;
|
||||
background: linear-gradient(160deg, rgba(10, 15, 26, 0.94), rgba(28, 22, 19, 0.9));
|
||||
border: 1px solid rgba(201, 169, 110, 0.58);
|
||||
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.4);
|
||||
backdrop-filter: blur(4px);
|
||||
}
|
||||
|
||||
.timeline-head {
|
||||
display: flex;
|
||||
align-items: baseline;
|
||||
justify-content: space-between;
|
||||
gap: 10px;
|
||||
font-size: 12px;
|
||||
color: #e7c986;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.timeline-meta {
|
||||
color: #c8bfad;
|
||||
font-size: 11px;
|
||||
}
|
||||
|
||||
.timeline-wrap {
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.vol-slider-wrap {
|
||||
position: relative;
|
||||
padding-bottom: 22px;
|
||||
@@ -1200,6 +1242,43 @@ function scrollToChatBottom() {
|
||||
accent-color: #c9a96e;
|
||||
}
|
||||
|
||||
.timeline-dock .chapter-slider {
|
||||
margin-top: 4px;
|
||||
}
|
||||
|
||||
.timeline-dock .chapter-slider::-webkit-slider-runnable-track {
|
||||
height: 6px;
|
||||
background: linear-gradient(90deg, #6f5632, #d8bb7e);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.timeline-dock .chapter-slider::-webkit-slider-thumb {
|
||||
-webkit-appearance: none;
|
||||
appearance: none;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
margin-top: -5px;
|
||||
border: 2px solid #f6e6c4;
|
||||
background: #1f2432;
|
||||
box-shadow: 0 0 0 2px rgba(201, 169, 110, 0.35);
|
||||
}
|
||||
|
||||
.timeline-dock .chapter-slider::-moz-range-track {
|
||||
height: 6px;
|
||||
background: linear-gradient(90deg, #6f5632, #d8bb7e);
|
||||
border-radius: 999px;
|
||||
}
|
||||
|
||||
.timeline-dock .chapter-slider::-moz-range-thumb {
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
border-radius: 50%;
|
||||
border: 2px solid #f6e6c4;
|
||||
background: #1f2432;
|
||||
box-shadow: 0 0 0 2px rgba(201, 169, 110, 0.35);
|
||||
}
|
||||
|
||||
.vol-ticks {
|
||||
position: relative;
|
||||
height: 18px;
|
||||
@@ -1541,11 +1620,23 @@ function scrollToChatBottom() {
|
||||
|
||||
.chapter-panel {
|
||||
right: 8px;
|
||||
bottom: calc(36vh + 16px);
|
||||
bottom: calc(36vh + 98px);
|
||||
width: calc(100vw - 16px);
|
||||
max-height: 30vh;
|
||||
}
|
||||
|
||||
.timeline-dock {
|
||||
width: calc(100vw - 16px);
|
||||
bottom: 8px;
|
||||
padding: 8px 10px 7px;
|
||||
}
|
||||
|
||||
.timeline-head {
|
||||
flex-direction: column;
|
||||
align-items: flex-start;
|
||||
gap: 2px;
|
||||
}
|
||||
|
||||
.info-panel {
|
||||
top: 130px;
|
||||
right: 8px;
|
||||
|
||||
Reference in New Issue
Block a user