实现翻转卡片功能,优化登录页面样式,添加移动端适配

This commit is contained in:
shuaiplus committed 2025-06-06 03:28:54 +08:00
1 parent bdeaf4850b
commit 518b098f9c
6 files changed
+275 -16

No files matched your search

+151 -3
View File
@@ -4,13 +4,161 @@ body {
margin: 0;
}
.login-container {
/* 翻转卡片样式 / Flip Card Styles */
.flip-card {
perspective: 1000px;
max-width: 400px;
width: 100%;
height: 500px; /* 固定高度,避免翻转时高度变化 */
}
.flip-card-inner {
position: relative;
width: 100%;
height: 100%;
text-align: center;
transition: transform 0.8s cubic-bezier(0.4, 0, 0.2, 1);
transform-style: preserve-3d;
transform-origin: center center; /* 设置旋转中心为卡片中心 */
}
.flip-card.flipped .flip-card-inner {
transform: rotateX(180deg);
}
.flip-card-front,
.flip-card-back {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
backface-visibility: hidden;
border-radius: 14px;
padding: 32px 24px 24px 24px;
box-shadow: 0 2px 16px rgba(60, 80, 100, 0.09);
background: #fff;
box-sizing: border-box;
display: flex;
flex-direction: column;
}
.flip-card-back {
transform: rotateX(180deg);
padding-top: 30px;
}
/* 帮助按钮样式 / Help Button Styles */
.help-btn {
position: absolute;
top: 16px;
right: 16px;
background: none;
border: 0px;
color: #666;
width: 40px;
height: 40px;
border-radius: 50%;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: all 0.3s ease;
z-index: 10;
}
.help-btn:hover {
background: #30a8f7;
border-color: #30a8f7;
color: #fff;
transform: scale(1.1);
}
.help-btn:active {
transform: scale(0.95);
}
.help-btn.back-btn {
background: #f8f9fa;
border-color: #dee2e6;
}
.help-btn.back-btn:hover {
background: #e9ecef;
border-color: #adb5bd;
color: #495057;
}
/* 使用说明内容样式 / Help Content Styles */
.help-content {
text-align: left;
margin-top: 20px;
padding: 0 20px;
}
.flip-card-back h2 {
font-size: 1.8rem;
font-weight: 600;
margin-bottom: 24px;
color: #30a8f7;
}
.flip-card-back p {
color: #666;
line-height: 1.6;
font-size: 1rem;
}
/* 移动端适配 / Mobile Adaptation */
@media (max-width: 768px) {
.flip-card {
width: 95%;
}
.flip-card-front,
.flip-card-back {
padding: 24px 16px 16px 16px;
}
.flip-card-back {
padding-top: 30px;
}
.flip-card-back h2 {
font-size: 1.5rem;
margin-bottom: 20px;
}
.help-content {
padding: 0 10px;
}
}
/* 触摸设备优化 / Touch Device Optimization */
@media (hover: none) and (pointer: coarse) {
.help-btn:hover {
transform: none;
}
.help-btn:active {
transform: scale(0.95);
}
}
.login-container {
/* 移除原有的样式,现在由flip-card处理 */
/* max-width: 400px;
margin: 60px auto 0 auto;
padding: 32px 24px 24px 24px;
background: #fff;
border-radius: 14px;
box-shadow: 0 2px 16px rgba(60, 80, 100, 0.09);
box-shadow: 0 2px 16px rgba(60, 80, 100, 0.09); */
display: flex;
flex-direction: row;
justify-content: space-around;
text-align: center;
}
@@ -394,4 +542,4 @@ body {
.send-message-btn:active .text {
fill: #fff;
transition: all 0.1s;
}
}
+6
View File
@@ -6,6 +6,12 @@ body {
background: #fff;
}
.login-page{
display: flex;
justify-content: center;
flex-direction: column;
}
.container {
display: flex;
height: 100vh;
+31 -7
View File
@@ -32,13 +32,37 @@
}
</style>
</head>
<body class="preload">
<div class="login-container" id="login-container">
<h1 id="login-title"></h1>
<form id="login-form">
<!-- 登录表单内容将由JavaScript动态生成 -->
<!-- Login form content will be dynamically generated by JavaScript -->
</form>
<body class="preload"> <div class="login-container" id="login-container">
<!-- 翻转卡片容器 -->
<div class="flip-card" id="flip-card">
<div class="flip-card-inner">
<!-- 卡片正面 - 登录表单 -->
<div class="flip-card-front">
<!-- 帮助按钮 -->
<button class="help-btn" id="help-btn" type="button" title="使用说明">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="12" cy="12" r="10" stroke="currentColor" stroke-width="2"/>
<path d="M9.09 9a3 3 0 0 1 5.83 1c0 2-3 3-3 3" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
<circle cx="12" cy="17" r="1" fill="currentColor"/>
</svg>
</button>
<h1 id="login-title"></h1>
<form id="login-form">
<!-- 登录表单内容将由JavaScript动态生成 -->
<!-- Login form content will be dynamically generated by JavaScript -->
</form>
</div>
<!-- 卡片背面 - 使用说明 --> <div class="flip-card-back">
<button class="help-btn back-btn" id="back-btn" type="button" title="返回登录">
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15 18L9 12L15 6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>
</button>
<h2>使用说明</h2>
</div>
</div>
</div>
</div>
</div><div class="container" id="chat-container" style="display:none;">
<div class="mobile-sidebar-mask" id="mobile-sidebar-mask"></div>
<div class="mobile-rightbar-mask" id="mobile-rightbar-mask"></div>
+6 -2
View File
@@ -76,7 +76,8 @@ import { renderUserList, // 渲染用户列表 / Render user list
setupTabs, // 设置页面标签切换 / Setup tab switching
autofillRoomPwd, // 自动填充房间密码 / Autofill room password
generateLoginForm, // 生成登录表单HTML / Generate login form HTML
initLoginForm // 初始化登录表单 / Initialize login form
initLoginForm, // 初始化登录表单 / Initialize login form
initFlipCard // 初始化翻转卡片功能 / Initialize flip card functionality
} from './ui.js';
// 设置全局配置参数
@@ -125,12 +126,15 @@ window.addEventListener('DOMContentLoaded', () => {
if (joinBtn) {
joinBtn.onclick = openLoginModal; // 点击打开登录窗口 / Click to open login modal
}
// 阻止用户输入用户名、房间名和密码时输入空格
// Prevent space input for username, room name, and password fields
preventSpaceInput($id('userName'));
preventSpaceInput($id('roomName'));
preventSpaceInput($id('password'));
// 初始化翻转卡片功能 / Initialize flip card functionality
initFlipCard();
// 初始化辅助功能和界面设置
// Initialize autofill, input placeholders, and menus
autofillRoomPwd(); setupInputPlaceholder();
+4 -3
View File
@@ -113,15 +113,16 @@ export function joinRoom(userName, roomName, password, modal = null, onResult) {
closed = true;
onResult(false)
}
},
onServerSecured: () => {
}, onServerSecured: () => {
setStatus('Secure connection to node');
if (modal) modal.remove();
else {
const loginContainer = $id('login-container');
if (loginContainer) loginContainer.style.display = 'none';
const chatContainer = $id('chat-container');
if (chatContainer) chatContainer.style.display = ''
if (chatContainer) chatContainer.style.display = '';
}
if (onResult && !closed) {
closed = true;
+77 -1
View File
@@ -557,6 +557,10 @@ export function initLoginForm() {
// Only initialize if login form is empty
loginFormContainer.innerHTML = generateLoginForm(false);
}
// 为登录页面添加class,用于手机适配
// Add class to login page for mobile adaptation
document.body.classList.add('login-page');
}
// Listen for language change events to refresh UI
@@ -577,4 +581,76 @@ window.addEventListener('regenerateLoginForm', () => {
if (loginFormContainer) {
loginFormContainer.innerHTML = generateLoginForm(false);
}
});
});
// 初始化翻转卡片功能
// Initialize flip card functionality
export function initFlipCard() {
const flipCard = document.getElementById('flip-card');
const helpBtn = document.getElementById('help-btn');
const backBtn = document.getElementById('back-btn');
if (!flipCard || !helpBtn || !backBtn) return;
// 检测是否为触摸设备 / Detect touch device
// 更准确的触摸设备检测方法
const isTouchDevice = window.matchMedia('(hover: none) and (pointer: coarse)').matches;
// 翻转到帮助页面 / Flip to help page
function flipToHelp() {
flipCard.classList.add('flipped');
}
// 翻转回登录页面 / Flip back to login page
function flipToLogin() {
flipCard.classList.remove('flipped');
}
if (isTouchDevice) {
// 移动端:点击切换 / Mobile: click to toggle
helpBtn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
flipToHelp();
});
backBtn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
flipToLogin();
});
} else {
// 桌面端:鼠标悬停切换 / Desktop: hover to toggle
let hoverTimeout;
helpBtn.addEventListener('mouseenter', () => {
clearTimeout(hoverTimeout);
hoverTimeout = setTimeout(() => {
flipToHelp();
}, 30); // 30ms延迟,避免误触
});
helpBtn.addEventListener('mouseleave', () => {
clearTimeout(hoverTimeout);
});
// 鼠标离开卡片时返回登录页面
flipCard.addEventListener('mouseleave', () => {
clearTimeout(hoverTimeout);
hoverTimeout = setTimeout(() => {
flipToLogin();
}, 30); // 30ms延迟,给用户时间查看内容
});
// 鼠标进入卡片时取消返回
flipCard.addEventListener('mouseenter', () => {
clearTimeout(hoverTimeout);
});
// 返回按钮点击事件(桌面端也可以点击)
backBtn.addEventListener('click', (e) => {
e.preventDefault();
e.stopPropagation();
flipToLogin();
});
}
}