-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBaseLayout.astro
More file actions
208 lines (180 loc) · 5.26 KB
/
BaseLayout.astro
File metadata and controls
208 lines (180 loc) · 5.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
---
import "@styles/global.css";
import YatccTopbar from "@components/Yatcc/YatccTopbar.astro";
import Link from "@components/Link.astro";
import NavDropdown from "@components/NavDropdown.astro";
import ThemeManager from "@components/ThemeManager.astro";
import { getLangFromUrl } from "../i18n/utils";
import Button from "@/components/Button.astro";
import DarkLightButton from "@/components/DarkLightButton.astro";
import ChatPannel from "@/components/ChatPannel.astro";
import Footer from "@/components/Footer.astro";
const lang = getLangFromUrl(Astro.url);
interface Props {
transitionSpeed?: string;
}
---
<!doctype html>
<html lang={lang}>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width" />
<!-- <link rel="icon" type="image/svg+xml" href="/favicon.svg" />
<link rel="icon" href="/favicon.ico" /> -->
<link rel="icon" href="/favicon.png" />
<meta name="generator" content={Astro.generator} />
<title>YatCC AI</title>
<ThemeManager />
</head>
<body>
<div id="site-canvas" data-ai-open="false">
<div class="main-container">
<YatccTopbar />
<main class="page-content">
<slot />
</main>
<Footer />
</div>
<aside class="ai-panel">
<div class="panel-content">
<ChatPannel />
</div>
</aside>
<div id="ai-overlay" class="ai-overlay"></div>
</div>
</body>
</html>
<style>
/* 主内容区动画 */
.main-container {
display: flex;
flex-direction: column;
transition:
transform 0.5s cubic-bezier(0.32, 0.72, 0, 1),
border-radius 0.5s ease,
opacity 0.5s ease;
min-height: 100vh;
}
.page-content {
flex: 1;
display: flex;
flex-direction: column;
padding-top: var(--navbar-height);
}
/* 侧边栏:初始在右侧并透明 */
.ai-panel {
position: fixed;
top: 0;
right: 0;
width: 450px; /* Vercel 面板通常较宽 */
height: 100vh;
transform: translateX(100%);
transition: transform 0.5s cubic-bezier(0.32, 0.72, 0, 1);
z-index: 100;
box-shadow: 2px 2px 3px color-mix(in srgb, var(--bg-color), 10% white);
display: flex;
flex-direction: column;
}
/* --- 联动效果:关键逻辑 --- */
/* 1. 主内容区缩小并左移 */
.site-canvas[data-ai-open="true"] .main-container {
transform: scale(0.92) translateX(-80px);
border-radius: 1rem;
pointer-events: none;
user-select: none;
opacity: 0.6;
will-change: transform;
}
/* 2. 面板滑入 */
.site-canvas[data-ai-open="true"] .ai-panel {
transform: translateX(0);
}
.ai-overlay {
position: fixed;
inset: 0;
z-index: 90;
pointer-events: none;
}
.ai-trigger-wrapper {
position: fixed;
bottom: 2rem;
right: 2rem;
z-index: 80;
}
/* 移动端适配 */
@media (max-width: 640px) {
.ai-panel {
width: 100%;
}
.site-canvas[data-ai-open="true"] .main-container {
transform: scale(0.9) translateY(-20px);
will-change: transform;
}
}
</style>
<style>
/* 初始隐藏侧边栏 */
.ai-panel {
position: fixed;
top: 0;
right: 0;
width: 450px;
height: 100vh;
z-index: 1000; /* 确保足够高 */
transform: translateX(100%); /* 藏在右边 */
transition: transform 0.5s cubic-bezier(0.32, 0.72, 0, 1);
background: transparent;
border-radius: 1rem;
}
#site-canvas[data-is-open="true"] .ai-panel {
transform: translateX(0);
}
.ai-overlay {
position: fixed;
inset: 0;
z-index: 999;
opacity: 0;
pointer-events: none;
transition: opacity 0.5s;
}
#site-canvas[data-is-open="true"] .ai-overlay {
opacity: 1;
pointer-events: auto;
}
</style>
<script>
function setupSidePanel() {
const canvas = document.getElementById("site-canvas");
// 【核心修复】:不再用 getElementById,而是去类名容器里找 a 标签
const triggerBtns = document.querySelectorAll(".ai-trigger-container a");
const closeBtn = document.getElementById("close-ai");
const overlay = document.getElementById("ai-overlay");
const togglePanel = (e: any) => {
if (e) e.preventDefault(); // 阻止 a 标签默认跳转行为
const isOpen = canvas?.getAttribute("data-is-open") === "true";
// 注意:你 HTML 里定义的 ID 是 site-canvas,我们要修改它的属性
canvas?.setAttribute("data-is-open", isOpen ? "false" : "true");
// 锁定/解锁滚动
document.body.style.overflow = isOpen ? "" : "hidden";
console.log("Panel Toggle Status:", !isOpen); // 调试用:看控制台有没有输出
};
if (triggerBtns.length) {
triggerBtns.forEach((btn) => btn.addEventListener("click", togglePanel));
} else {
console.error("找不到触发按钮!请检查 Topbar 里的类名是否正确。");
}
closeBtn?.addEventListener("click", togglePanel);
overlay?.addEventListener("click", togglePanel);
document.addEventListener("keydown", (e) => {
if (
e.key === "Escape" &&
canvas?.getAttribute("data-is-open") === "true"
) {
togglePanel(e);
}
});
}
// 初始化并兼容 Astro 路由切换
setupSidePanel();
document.addEventListener("astro:after-swap", setupSidePanel);
</script>