style(frontend): yt 静态站移动端响应式适配(顶栏折叠/安全区/画布触摸平移缩放)
This commit is contained in:
parent
760cd517c2
commit
c4c95926d7
52
index.html
52
index.html
@ -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>
|
||||||
|
|||||||
11
login.html
11
login.html
@ -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>
|
||||||
|
|||||||
79
world.html
79
world.html
@ -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) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user