From dbe4d54f10a13b9265d45968e012cc995b0e750e Mon Sep 17 00:00:00 2001 From: 2977094657 <2977094657@qq.com> Date: Mon, 2 Feb 2026 00:07:45 +0800 Subject: [PATCH] =?UTF-8?q?improvement(wrapped-ui):=20=E5=AE=8C=E5=96=84?= =?UTF-8?q?=20Win98=20=E4=B8=BB=E9=A2=98=E7=9A=84=E5=8F=AF=E8=A7=86?= =?UTF-8?q?=E5=8C=96=E9=80=82=E9=85=8D=E5=B9=B6=E4=BC=98=E5=8C=96=E8=81=8A?= =?UTF-8?q?=E5=A4=A9=E5=9B=9E=E6=94=BE=E4=BF=A1=E6=81=AF=E5=8C=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - ChatReplayAnimation:时间戳移到顶栏,简化气泡尾巴;补齐 Game Boy/DOS/Win98 顶栏文案颜色与边框风格 - 热力图:新增 win98 配色分支,并为 heatmap/legend 单元加硬边框 - Overview/MessageChars 等可视化补充 Win98 主题样式(键盘/进度条/雷达图等) --- .../visualizations/ChatReplayAnimation.vue | 98 +++++++---- .../visualizations/GlobalOverviewChart.vue | 47 ++++++ .../visualizations/MessageCharsChart.vue | 159 ++++++++++++++++++ .../visualizations/WeekdayHourHeatmap.vue | 11 ++ frontend/utils/wrapped/heatmap.js | 7 + 5 files changed, 293 insertions(+), 29 deletions(-) diff --git a/frontend/components/wrapped/visualizations/ChatReplayAnimation.vue b/frontend/components/wrapped/visualizations/ChatReplayAnimation.vue index 173d90e..98f4539 100644 --- a/frontend/components/wrapped/visualizations/ChatReplayAnimation.vue +++ b/frontend/components/wrapped/visualizations/ChatReplayAnimation.vue @@ -23,7 +23,12 @@ -
聊天回放
+
+
聊天回放
+
+ {{ date }} {{ time }} +
+
@@ -44,9 +49,6 @@ -
- {{ date }} {{ time }} -
@@ -195,6 +197,15 @@ watch( border-bottom: none; } +.wrapped-chat-replay__top-right { + margin-left: auto; + display: flex; + flex-direction: column; + align-items: flex-end; + gap: 2px; + text-align: right; +} + .wrapped-chat-replay__top-left { display: flex; align-items: center; @@ -260,23 +271,6 @@ watch( padding: 10px 12px; } -.wrapped-chat-replay__typing::after, -.wrapped-chat-replay__bubble::after { - content: ''; - position: absolute; - right: -6px; - top: 10px; - width: 0; - height: 0; - border-style: solid; - border-width: 6px 0 6px 6px; - border-color: transparent transparent transparent var(--wr-chat-bubble-tail); -} - -.wrapped-chat-replay__typing::after { - border-color: transparent transparent transparent var(--wr-chat-typing-bg); -} - .wrapped-chat-replay__bubble-text { color: var(--wr-chat-bubble-text) !important; font-size: 13px; @@ -285,11 +279,6 @@ watch( word-break: break-word; } -.wrapped-chat-replay__timestamp { - margin-top: 8px; - text-align: right; -} - .wrapped-chat-replay__dot { width: 6px; height: 6px; @@ -355,6 +344,11 @@ watch( inset 2px 2px 0 0 #9bbc0f; } +.wrapped-theme-gameboy .wrapped-chat-replay__top .wrapped-label, +.wrapped-theme-gameboy .wrapped-chat-replay__top .wrapped-body { + color: #0f380f !important; +} + .wrapped-theme-gameboy .wrapped-chat-replay__bubble-text { font-family: var(--font-pixel-10), 'Courier New', monospace; } @@ -382,13 +376,59 @@ watch( box-shadow: 0 0 6px rgba(51, 255, 51, 0.18); } -.wrapped-theme-dos .wrapped-chat-replay__typing::after, -.wrapped-theme-dos .wrapped-chat-replay__bubble::after { - box-shadow: 1px 0 0 #33ff33; +.wrapped-theme-dos .wrapped-chat-replay__top .wrapped-label, +.wrapped-theme-dos .wrapped-chat-replay__top .wrapped-body { + color: #33ff33 !important; + text-shadow: 0 0 3px rgba(51, 255, 51, 0.6); } .wrapped-theme-dos .wrapped-chat-replay__bubble-text { font-family: 'Courier New', monospace; text-shadow: 0 0 3px rgba(51, 255, 51, 0.6); } + +/* ========== Win98 主题 ========== */ +.wrapped-theme-win98 .wrapped-chat-replay { + --wr-chat-frame-bg: #c0c0c0; + --wr-chat-top-bg: linear-gradient(90deg, #000080, #1084d0); + --wr-chat-chat-bg: #ffffff; + --wr-chat-border: #808080; + + --wr-chat-bubble-bg: #ffffff; + --wr-chat-bubble-tail: #ffffff; + --wr-chat-bubble-text: #000000; + + --wr-chat-typing-bg: #ffffff; + --wr-chat-typing-dot: #000000; + + border-radius: 0; + border: 1px solid #808080; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000; +} + +.wrapped-theme-win98 .wrapped-chat-replay__top { + border-bottom: 1px solid #808080; +} + +.wrapped-theme-win98 .wrapped-chat-replay__top .wrapped-label, +.wrapped-theme-win98 .wrapped-chat-replay__top .wrapped-body { + /* Title-bar text should be white on the Win98 blue gradient. */ + color: #ffffff !important; + text-shadow: 1px 1px 0 rgba(0, 0, 0, 0.35); +} + +.wrapped-theme-win98 .wrapped-chat-replay__avatar-fallback { + color: rgba(255, 255, 255, 0.9); +} + +.wrapped-theme-win98 .wrapped-chat-replay__typing, +.wrapped-theme-win98 .wrapped-chat-replay__bubble { + border-radius: 0; + border: 1px solid #808080; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000; +} diff --git a/frontend/components/wrapped/visualizations/GlobalOverviewChart.vue b/frontend/components/wrapped/visualizations/GlobalOverviewChart.vue index aa64d54..47f6555 100644 --- a/frontend/components/wrapped/visualizations/GlobalOverviewChart.vue +++ b/frontend/components/wrapped/visualizations/GlobalOverviewChart.vue @@ -377,4 +377,51 @@ const labels = computed(() => { color: #33ff33 !important; text-shadow: 0 0 5px #33ff33; } + +/* ========== Win98 主题 ========== */ +.wrapped-theme-win98 .overview-card { + background: #c0c0c0 !important; + border: 1px solid #808080 !important; + border-radius: 0 !important; + backdrop-filter: none; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000; +} + +.wrapped-theme-win98 .overview-progress-bg { + background: #ffffff !important; + border-radius: 0 !important; + border: 1px solid #808080; + box-shadow: + inset 1px 1px 0 #000000, + inset -1px -1px 0 #ffffff; +} + +.wrapped-theme-win98 .overview-progress-fill { + background: #000080 !important; + border-radius: 0 !important; +} + +.wrapped-theme-win98 .overview-grid-line { + stroke: rgba(0, 0, 0, 0.22); +} + +.wrapped-theme-win98 .overview-axis-line { + stroke: rgba(0, 0, 0, 0.35); +} + +.wrapped-theme-win98 .overview-data-polygon { + fill: rgba(0, 0, 128, 0.16); + stroke: #000080; +} + +.wrapped-theme-win98 .overview-data-node { + fill: #000080; + stroke: #ffffff; +} + +.wrapped-theme-win98 .overview-label { + fill: rgba(0, 0, 0, 0.8); +} diff --git a/frontend/components/wrapped/visualizations/MessageCharsChart.vue b/frontend/components/wrapped/visualizations/MessageCharsChart.vue index 159f4eb..a947267 100644 --- a/frontend/components/wrapped/visualizations/MessageCharsChart.vue +++ b/frontend/components/wrapped/visualizations/MessageCharsChart.vue @@ -1321,6 +1321,96 @@ const getLabelStyle = (code) => { text-shadow: 0 0 5px #ff3333; } +/* ========== Win98 主题 - 键盘外观 ========== */ +.wrapped-theme-win98 .keyboard-outer { + border-radius: 0; + background: #c0c0c0; + border: 1px solid #808080; + padding: 4px; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000; +} + +.wrapped-theme-win98 .keyboard-inner { + border-radius: 0; + background: #dfdfdf; + border: 1px solid #808080; + padding: 6px; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000; +} + +.wrapped-theme-win98 .keyboard-header { + border-bottom: 1px solid rgba(0, 0, 0, 0.18); + padding-bottom: 6px; + margin-bottom: 6px; +} + +.wrapped-theme-win98 .dot { + border-radius: 0; + width: 8px; + height: 8px; + box-shadow: none; +} + +.wrapped-theme-win98 .dot-red { background: #800000; } +.wrapped-theme-win98 .dot-yellow { background: #808000; } +.wrapped-theme-win98 .dot-green { background: #008000; } + +.wrapped-theme-win98 .keyboard-stats, +.wrapped-theme-win98 .keyboard-hint { + font-family: inherit; + color: rgba(0, 0, 0, 0.72); + text-shadow: none; +} + +.wrapped-theme-win98 .keyboard-body { + border-radius: 0; + background: #ffffff; + border: 1px solid #808080; + box-shadow: + inset 1px 1px 0 #000000, + inset -1px -1px 0 #ffffff; +} + +.wrapped-theme-win98 .kb-key::before { + border-radius: 0; + background: #808080; +} + +.wrapped-theme-win98 .kb-key-top { + border-radius: 0; + border: 1px solid #808080 !important; + background: #c0c0c0 !important; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000 !important; +} + +.wrapped-theme-win98 .kb-label, +.wrapped-theme-win98 .kb-sub { + font-family: inherit; + color: #000000 !important; + text-shadow: none !important; + filter: none !important; + opacity: 1 !important; +} + +.wrapped-theme-win98 .kb-space-bar { + border-radius: 0; + background: #000080; + box-shadow: none; + height: 2px; +} + +.wrapped-theme-win98 .keyboard-brand { + font-family: inherit; + color: rgba(0, 0, 0, 0.35); + text-shadow: none; +} + /* DOS 聊天气泡主题适配 */ .wrapped-theme-dos .bubble-left, .wrapped-theme-dos .bubble-right { @@ -1415,6 +1505,75 @@ const getLabelStyle = (code) => { color: #306230 !important; } +/* ========== Win98 主题 - 聊天气泡适配 ========== */ + +/* 聊天区域背景 */ +.wrapped-theme-win98 .rounded-2xl.border.bg-\[\#F5F5F5\] { + background: #c0c0c0 !important; + border: 1px solid #808080 !important; + border-radius: 0 !important; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000; +} + +/* 气泡 - 左侧 */ +.wrapped-theme-win98 .bubble-left { + background: #ffffff; + border: 1px solid #808080; + border-radius: 0; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000; +} +.wrapped-theme-win98 .bubble-left::before { + border-right-color: #ffffff; + filter: none; +} + +/* 气泡 - 右侧 */ +.wrapped-theme-win98 .bubble-right { + background: #dfdfdf; + border: 1px solid #808080; + border-radius: 0; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000; +} +.wrapped-theme-win98 .bubble-right::after { + border-left-color: #dfdfdf; + filter: none; +} + +/* 头像 */ +.wrapped-theme-win98 .avatar-box { + background: #c0c0c0; + border-color: #808080; + border-radius: 0; + box-shadow: + inset 1px 1px 0 #ffffff, + inset -1px -1px 0 #000000; +} +.wrapped-theme-win98 .avatar-box svg { + stroke: #000080; +} + +/* 文字样式(气泡内需要更“黑白”) */ +.wrapped-theme-win98 .bubble-left .wrapped-label, +.wrapped-theme-win98 .bubble-right .wrapped-label { + color: rgba(0, 0, 0, 0.65) !important; +} + +.wrapped-theme-win98 .bubble-left .wrapped-number, +.wrapped-theme-win98 .bubble-right .wrapped-number { + color: #000080 !important; +} + +.wrapped-theme-win98 .bubble-left .wrapped-body, +.wrapped-theme-win98 .bubble-right .wrapped-body { + color: rgba(0, 0, 0, 0.85) !important; +} + /* ========== DOS 主题 - 聊天气泡文字适配 ========== */ .wrapped-theme-dos .bubble-left .wrapped-label, diff --git a/frontend/components/wrapped/visualizations/WeekdayHourHeatmap.vue b/frontend/components/wrapped/visualizations/WeekdayHourHeatmap.vue index 2b611f9..a973126 100644 --- a/frontend/components/wrapped/visualizations/WeekdayHourHeatmap.vue +++ b/frontend/components/wrapped/visualizations/WeekdayHourHeatmap.vue @@ -157,4 +157,15 @@ const originFor = (weekdayIndex, hour) => { .wrapped-theme-dos .heatmap-legend-cell { border-radius: 0 !important; } + +/* ========== Win98 主题 ========== */ +.wrapped-theme-win98 .heatmap-cell { + border-radius: 0 !important; + border: 1px solid rgba(0, 0, 0, 0.12); +} + +.wrapped-theme-win98 .heatmap-legend-cell { + border-radius: 0 !important; + border: 1px solid rgba(0, 0, 0, 0.12); +} diff --git a/frontend/utils/wrapped/heatmap.js b/frontend/utils/wrapped/heatmap.js index b58e135..ed09a17 100644 --- a/frontend/utils/wrapped/heatmap.js +++ b/frontend/utils/wrapped/heatmap.js @@ -58,6 +58,13 @@ export const themedHeatColor = (value, max, theme) => { const light = 20 + 60 * t return `hsl(120 100% ${light.toFixed(1)}%)` } + case 'win98': { + // Win98-ish "system colors": gray -> blue highlight + if (t === 0) return '#dfdfdf' + if (t < 0.33) return '#c0c0c0' + if (t < 0.66) return '#808080' + return '#000080' + } default: // Modern (off) - use original heatColor return heatColor(value, max)