style(frontend): yt 静态站移动端响应式适配(顶栏折叠/安全区/画布触摸平移缩放)

This commit is contained in:
yuthonyun 2026-07-24 19:02:40 +08:00
parent 760cd517c2
commit c4c95926d7
3 changed files with 133 additions and 9 deletions

View File

@ -2,7 +2,7 @@
<html lang="zh-CN"> <html lang="zh-CN">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<title>宇森 · Yusen活的文明系统模拟</title> <title>宇森 · Yusen活的文明系统模拟</title>
<link rel="preconnect" href="https://fonts.googleapis.com" crossorigin /> <link rel="preconnect" href="https://fonts.googleapis.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=ZCOOL+QingKe+HuangYou&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" /> <link href="https://fonts.googleapis.com/css2?family=Press+Start+2P&family=ZCOOL+QingKe+HuangYou&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet" media="print" onload="this.media='all'" />
@ -299,6 +299,56 @@
.nav{overflow-x:auto;scrollbar-width:none;} .nav{overflow-x:auto;scrollbar-width:none;}
.nav::-webkit-scrollbar{display:none;} .nav::-webkit-scrollbar{display:none;}
} }
/* ===== 移动端适配(手机 / 平板竖屏) ===== */
@media (max-width:768px){
html,body{height:100%;}
body{height:100dvh;}
.app{height:100dvh;}
.topbar{height:auto;min-height:54px;flex-wrap:wrap;align-items:center;padding:8px 14px;gap:10px;}
.logo .cn{font-size:22px;letter-spacing:2px;}
.logo .en{display:none;}
.spacer{display:none;}
.user-box{margin-left:auto;font-size:13px;gap:8px;}
.user-box .auth-btn{padding:6px 13px;font-size:12px;}
.nav{order:3;flex:1 0 100%;width:100%;margin-left:0;gap:4px;padding-top:6px;border-top:1px solid var(--card-bd);}
.nav button{font-size:13px;padding:7px 9px;white-space:nowrap;}
.hero .copy{left:18px;right:18px;bottom:82px;}
.hero .copy h1{font-size:32px;letter-spacing:4px;}
.hero .copy .tag{font-size:16px;}
.hero .copy .desc{font-size:13.5px;max-width:100%;}
.hero .enter-wrap{bottom:28px;}
.hero .enter-btn{font-size:15px;padding:11px 30px;}
.panel{padding:18px 18px;}
.sec-title{font-size:26px;letter-spacing:2px;}
.bg-page-title{font-size:30px;}
.bg-page-body{font-size:15.5px;line-height:1.9;}
.grid{grid-template-columns:repeat(2,1fr);gap:12px;}
.card{min-height:120px;padding:15px 16px;}
.codex-search{width:140px;}
.reader-inner{padding:26px 18px 80px;}
.reader-inner h1{font-size:23px;}
#worlddata{padding:28px 16px 80px;}
#background{padding:30px 16px 80px;}
.story-toc{flex-basis:auto;}
.tier-row{grid-template-columns:72px 92px 1fr;gap:8px;}
}
@media (max-width:480px){
.topbar{padding:8px 10px;gap:8px;}
.logo .cn{font-size:20px;}
.nav button{font-size:12px;padding:6px 7px;}
.user-box .auth-btn{padding:6px 11px;}
.hero .copy{left:14px;right:14px;bottom:74px;}
.hero .copy h1{font-size:26px;letter-spacing:2px;}
.hero .copy .tag{font-size:14px;}
.grid{grid-template-columns:1fr;}
.panel{padding:14px 14px;}
.codex-search{width:118px;flex:1 1 100%;}
.codex-subrow{flex-wrap:wrap;}
.reader-inner{padding:22px 14px 70px;}
.tier-row{grid-template-columns:60px 76px 1fr;gap:6px;}
.codex-cats button,.codex-subs button{padding:7px 11px;font-size:13px;}
}
</style> </style>
</head> </head>
<body> <body>

View File

@ -2,7 +2,7 @@
<html lang="zh-CN"> <html lang="zh-CN">
<head> <head>
<meta charset="UTF-8" /> <meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover" />
<title>宇森 · 登录</title> <title>宇森 · 登录</title>
<style> <style>
:root{ :root{
@ -20,7 +20,7 @@
radial-gradient(1000px 620px at 82% -8%, rgba(139,92,246,.16), transparent 60%), radial-gradient(1000px 620px at 82% -8%, rgba(139,92,246,.16), transparent 60%),
radial-gradient(820px 560px at 8% 112%, rgba(76,201,240,.12), transparent 55%), radial-gradient(820px 560px at 8% 112%, rgba(76,201,240,.12), transparent 55%),
linear-gradient(160deg, var(--bg-0), var(--bg-1) 48%, var(--bg-2)); linear-gradient(160deg, var(--bg-0), var(--bg-1) 48%, var(--bg-2));
display:flex;align-items:center;justify-content:center;min-height:100vh;overflow:hidden;position:relative; display:flex;align-items:center;justify-content:center;min-height:100dvh;overflow:hidden;position:relative;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left);
} }
body::before,body::after{content:"";position:fixed;border-radius:50%;filter:blur(80px);z-index:0;pointer-events:none;} body::before,body::after{content:"";position:fixed;border-radius:50%;filter:blur(80px);z-index:0;pointer-events:none;}
body::before{width:380px;height:380px;background:rgba(139,92,246,.20);top:-110px;right:-70px;animation:f1 20s ease-in-out infinite;} body::before{width:380px;height:380px;background:rgba(139,92,246,.20);top:-110px;right:-70px;animation:f1 20s ease-in-out infinite;}
@ -61,6 +61,13 @@
.back a:hover{text-decoration:underline;} .back a:hover{text-decoration:underline;}
.hidden{display:none;} .hidden{display:none;}
@media (max-width:420px){
.brand .cn{font-size:34px;letter-spacing:5px;}
.card{padding:22px 18px 26px;}
.field input{padding:12px 13px;font-size:15px;}
.submit{padding:13px;font-size:15px;}
}
</style> </style>
</head> </head>
<body> <body>

View File

@ -2,7 +2,7 @@
<html lang="zh"> <html lang="zh">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
<title>宇森 - 微观场景</title> <title>宇森 - 微观场景</title>
<!-- Favicon精细像素风小星球v=20260723 强制浏览器绕开旧缓存重载 --> <!-- Favicon精细像素风小星球v=20260723 强制浏览器绕开旧缓存重载 -->
<link rel="icon" type="image/png" sizes="48x48" href="assets/ui/logo_planet_48.png?v=20260723"> <link rel="icon" type="image/png" sizes="48x48" href="assets/ui/logo_planet_48.png?v=20260723">
@ -10,16 +10,16 @@
<link rel="apple-touch-icon" href="assets/ui/logo_planet_256.png?v=20260723"> <link rel="apple-touch-icon" href="assets/ui/logo_planet_256.png?v=20260723">
<style> <style>
* { margin: 0; padding: 0; box-sizing: border-box; } * { margin: 0; padding: 0; box-sizing: border-box; }
body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sans-serif; color: #e0e0e0; } body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sans-serif; color: #e0e0e0; height: 100dvh; }
#gameCanvas { display: block; cursor: default; position: fixed; top: 0; left: 0; width: 100%; bottom: 72px; } #gameCanvas { display: block; cursor: default; position: fixed; top: 0; left: 0; width: 100%; bottom: 72px; }
#gameCanvas.dragging { cursor: grabbing; } #gameCanvas.dragging { cursor: grabbing; }
#gameCanvas.canDrag { cursor: grab; } #gameCanvas.canDrag { cursor: grab; }
#topBar { #topBar {
position: fixed; top: 0; left: 0; right: 0; height: 58px; position: fixed; top: 0; left: 0; right: 0; height: calc(58px + env(safe-area-inset-top));
background: #0a0e17; background: #0a0e17;
display: flex; align-items: center; padding: 0 18px; display: flex; align-items: center; padding: env(safe-area-inset-top) max(18px, env(safe-area-inset-left)) 0 max(18px, env(safe-area-inset-right));
border-bottom: 1px solid rgba(139,92,246,.35); border-bottom: 1px solid rgba(139,92,246,.35);
z-index: 100; z-index: 100;
pointer-events: none; pointer-events: none;
@ -66,8 +66,8 @@ body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sa
/* 主沙盘底部功能框架(预留区:放功能按钮 / 素材槽,比微观边框更高) */ /* 主沙盘底部功能框架(预留区:放功能按钮 / 素材槽,比微观边框更高) */
#bottomBar { #bottomBar {
position: fixed; left: 0; right: 0; bottom: 0; height: 72px; z-index: 120; position: fixed; left: 0; right: 0; bottom: 0; height: calc(72px + env(safe-area-inset-bottom)); z-index: 120;
display: flex; align-items: center; gap: 14px; padding: 0 18px; display: flex; align-items: center; gap: 14px; padding: 0 max(18px, env(safe-area-inset-left)) env(safe-area-inset-bottom) max(18px, env(safe-area-inset-right));
background-image: background-image:
url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='46'%20height='52'%20viewBox='0%200%2046%2052'%3E%3Cpolygon%20points='23,4%2041,15%2041,37%2023,48%205,37%205,15'%20fill='none'%20stroke='%234a6fa5'%20stroke-opacity='0.12'%20stroke-width='1.4'/%3E%3C/svg%3E"), url("data:image/svg+xml,%3Csvg%20xmlns='http://www.w3.org/2000/svg'%20width='46'%20height='52'%20viewBox='0%200%2046%2052'%3E%3Cpolygon%20points='23,4%2041,15%2041,37%2023,48%205,37%205,15'%20fill='none'%20stroke='%234a6fa5'%20stroke-opacity='0.12'%20stroke-width='1.4'/%3E%3C/svg%3E"),
linear-gradient(0deg, rgba(12,18,32,0.98), rgba(8,12,22,0.98)); linear-gradient(0deg, rgba(12,18,32,0.98), rgba(8,12,22,0.98));
@ -425,6 +425,22 @@ body { background: #0a0e17; overflow: hidden; font-family: 'Microsoft YaHei', sa
@keyframes authSpin{to{transform:rotate(360deg);}} @keyframes authSpin{to{transform:rotate(360deg);}}
/* #authBar 已融合进 #topBar .userArea */ /* #authBar 已融合进 #topBar .userArea */
/* ===== 移动端适配 ===== */
@media (max-width:768px){
#topBar .coords{display:none;}
#topBar .title{font-size:16px;}
#topBar .title .worldName{font-size:13px;margin-left:7px;padding-left:7px;}
#topBar .title img{width:28px;height:28px;}
#bottomBar{gap:8px;padding-left:max(10px,env(safe-area-inset-left));padding-right:max(10px,env(safe-area-inset-right));}
#bottomBar .bb-btn{padding:8px 11px;font-size:12px;}
#navControls{bottom:calc(96px + env(safe-area-inset-bottom));right:14px;
grid-template-columns:repeat(3,60px);grid-template-rows:repeat(3,60px);gap:6px;}
#navControls button{width:60px;height:60px;font-size:24px;border-radius:15px;}
}
@media (max-width:420px){
#topBar .title .worldName{display:none;}
#bottomBar .bb-btn{padding:7px 9px;font-size:11px;}
}
</style> </style>
</head> </head>
<body> <body>
@ -2923,6 +2939,57 @@ canvas.addEventListener('mouseleave', () => {
document.getElementById('coords').style.display = 'none'; document.getElementById('coords').style.display = 'none';
}); });
// ============ 移动端触摸支持(单指平移/点选 + 双指捏合缩放)============
(function setupTouch(){
if (!('ontouchstart' in window)) return; // 仅触摸设备启用,桌面不受影响
canvas.style.touchAction = 'none';
let mode = null; // 'pan' | 'pinch'
let panId = null;
let lastDist = 0;
const fire = (type, t) => canvas.dispatchEvent(new MouseEvent(type, {
clientX: t.clientX, clientY: t.clientY, button: 0, buttons: 1,
bubbles: true, cancelable: true
}));
canvas.addEventListener('touchstart', e => {
if (microViewOpen) return;
if (e.touches.length === 1) {
mode = 'pan'; panId = e.touches[0].identifier;
e.preventDefault();
fire('mousedown', e.touches[0]);
} else if (e.touches.length >= 2) {
if (mode === 'pan') { fire('mouseup', e.touches[0]); }
mode = 'pinch';
lastDist = Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY);
e.preventDefault();
}
}, { passive: false });
canvas.addEventListener('touchmove', e => {
if (microViewOpen) return;
if (mode === 'pan' && e.touches.length === 1) {
const t = e.touches[0];
if (t.identifier === panId) { e.preventDefault(); fire('mousemove', t); }
} else if (mode === 'pinch' && e.touches.length >= 2) {
e.preventDefault();
const d = Math.hypot(e.touches[0].clientX - e.touches[1].clientX, e.touches[0].clientY - e.touches[1].clientY);
if (lastDist > 0) {
camera.zoom = Math.max(MIN_ZOOM, Math.min(MAX_ZOOM, camera.zoom * (d / lastDist)));
}
lastDist = d;
}
}, { passive: false });
const endTouch = e => {
if (mode === 'pan') { fire('mouseup', e.changedTouches[0]); }
else if (mode === 'pinch' && e.touches.length === 1) {
// 从捏合退回单指:重置为平移起点,避免相机跳变
mode = 'pan'; panId = e.touches[0].identifier;
fire('mousedown', e.touches[0]);
}
if (e.touches.length === 0) mode = null;
};
canvas.addEventListener('touchend', endTouch);
canvas.addEventListener('touchcancel', endTouch);
})();
// ============ 建造模式:地形 & 板块交换 ============ // ============ 建造模式:地形 & 板块交换 ============
// 地形笔:点击地块刷地形 + 选定素材变体(仅大地层) // 地形笔:点击地块刷地形 + 选定素材变体(仅大地层)
function handleBuildClick(tile) { function handleBuildClick(tile) {