Преглед изворни кода

style(业务代码): 横屏布局优化及 promo-screen 覆盖范围修正

- index.html:promo-screen 从 #game-area 移至 #game-col,覆盖 canvas+工具栏完整区域
- tools.css:
  - 横屏 sidebar 改为透明背景、去除阴影、justify-content:center 居中聚拢
  - 横屏 logo/logo-txt 尺寸调大(85%/80%),gap 收紧,CTA 加底部留白上移
  - promo-coloring/promo-slogon 改用 width 固定尺寸防止图片加载前布局塌缩
  - 新增横屏 promo 尺寸覆盖规则(95%/90% 宽度,适配横向空间)
  - #game-col 加 position:relative 作为 promo-screen 定位父容器
guoziyun пре 3 недеља
родитељ
комит
8a9cd7f929
2 измењених фајлова са 152 додато и 121 уклоњено
  1. 136 105
      assets/css/tools.css
  2. 16 16
      index.html

+ 136 - 105
assets/css/tools.css

@@ -7,7 +7,8 @@ html,
 body {
   width: 100%;
   height: 100%;
-  background: #fff9f2;
+  background: linear-gradient(160deg, #fff9f2 0%, #ffeedd 100%);
+  transition: none;
   -webkit-tap-highlight-color: transparent; /*消除移动端的灰色背景闪烁*/
   -webkit-touch-callout: none; /*系统默认菜单被禁用*/
   -webkit-user-select: none; /*webkit浏览器*/
@@ -35,74 +36,84 @@ textarea {
   width: 100%;
 }
 
-/* ── 根布局 ─────────────────────────────────────────── */
-/* 竖屏:game-area 全屏,sidebar fixed 叠在上方(logo 顶/CTA 底) */
-/* 横屏:game-area 左 58%,sidebar 右 42% 固定栏 */
+/* ── 根布局:全 Flex,无 fixed/absolute 主结构 ──────────── */
+/* 竖屏:body flex column                                    */
+/*   sidebar → display:contents,子项直接排入 body            */
+/*   logo-bar(order:1) → game-col(order:2) → cta(order:10)  */
+/* 横屏:body flex row,game-col 左(flex:1) + sidebar 右     */
 
 body {
+  display: flex;
+  flex-direction: column;
   position: relative;
   overflow: hidden;
 }
 
+/* ── 游戏列:canvas 区 + 工具栏 ── */
+#game-col {
+  order: 2; /* 竖屏:位于 logo(1) 与 cta(10) 之间 */
+  flex: 1;
+  min-height: 0; /* 防止 flex 子项无法收缩 */
+  display: flex;
+  flex-direction: column;
+  position: relative; /* promo-screen absolute 定位的父容器 */
+}
+
+/* 纯填色区域,flex:1 铺满 game-col 剩余空间 */
 #game-area {
-  position: fixed;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  z-index: 0;
-  /* 与宣传屏背景一致,canvas 透明区及消失后风格统一 */
-  background: linear-gradient(160deg, #fff9f2 0%, #ffeedd 100%);
+  flex: 1;
+  min-height: 0;
+  position: relative;
 }
 
+/* canvas 绝对填满 game-area;syncCanvasSize() 同步像素尺寸 */
 #canvas {
   position: absolute;
-  top: 0;
-  left: 0;
+  inset: 0;
   width: 100%;
   height: 100%;
   z-index: 1;
 }
 
-/* ── 竖屏:sidebar 覆盖 canvas,logo 顶对齐,CTA 底对齐 ── */
+/* ── 竖屏:sidebar 用 display:contents,子项直接排入 body ── */
 #sidebar {
-  position: fixed;
-  top: 0;
-  left: 0;
-  width: 100%;
-  height: 100%;
-  pointer-events: none;
-  z-index: 100;
-  display: flex;
-  flex-direction: column;
-  justify-content: space-between;
-  align-items: center;
-  padding-bottom: 16px;
-  box-sizing: border-box;
+  display: contents;
+}
+
+.sidebar-flex-spacer {
+  order: 5;
+  display: none; /* 竖屏不需要 */
 }
 
-/* ── 横屏:左右分栏 ─────────────────────────────────── */
+/* ── 横屏:body flex row,sidebar 作为右侧固定栏 ─────────── */
 @media (orientation: landscape) {
-  #game-area {
-    width: 58%;
-    height: 100%;
+  body {
+    flex-direction: row;
+  }
+
+  #game-col {
+    order: 1;
+    flex: 1;
+    min-width: 0;
   }
 
   #sidebar {
-    left: 58%;
-    top: 0;
-    width: 42%;
-    height: 100%;
-    background: linear-gradient(175deg, #fff0e6 0%, #ffdbb4 100%);
     display: flex;
+    order: 2;
     flex-direction: column;
     align-items: center;
     justify-content: center;
-    gap: 28px;
-    padding: 24px 20px;
+    gap: clamp(12px, 2.5vh, 24px);
+    width: clamp(140px, 36%, 260px);
+    background: transparent;
+    padding: clamp(12px, 2vh, 20px) clamp(10px, 2vw, 16px);
     box-sizing: border-box;
+    box-shadow: none;
     pointer-events: auto;
-    box-shadow: -2px 0 16px rgba(0, 0, 0, 0.1);
+  }
+
+  .sidebar-flex-spacer {
+    display: none;
   }
 }
 
@@ -111,24 +122,14 @@ body {
 }
 
 #toolbar-bottom {
-  position: absolute;
-  bottom: 0;
-  left: 0;
-  width: 100%;
+  /* 在 game-col flex column 中正常流,不与 canvas 重叠 */
+  flex-shrink: 0;
   text-align: center;
   z-index: 2;
   pointer-events: none;
   transition:
     transform 1s ease-in-out,
     opacity 1s ease-in-out;
-  padding-bottom: 72px; /* 竖屏:为底部 CTA 留空 */
-  box-sizing: border-box;
-}
-
-@media (orientation: landscape) {
-  #toolbar-bottom {
-    padding-bottom: 8px; /* 横屏:CTA 在右侧栏,不需要留底部空间 */
-  }
 }
 
 .hidden-toolbar-bottom {
@@ -365,57 +366,63 @@ body {
   pointer-events: none;
 }
 
-/* ── Logo 栏 ────────────────────────────────────────── */
-/* 竖屏:sidebar 顶部,图标+文字横向排列 */
-/* 横屏:右侧栏,图标+文字纵向排列,更大 */
+/* ── Logo 栏 ────────────────────────────────────────────── */
+/* 竖屏(display:contents 子项):横排,order:1 置顶,z:200 浮于 promo */
+/* 横屏(sidebar 内 flex 子项) :竖排,充满宽度                        */
 #app-logo-bar {
-  width: 100%;
+  order: 1; /* 竖屏:body 第一行 */
+  flex: 0 0 18dvh; /* ← 竖屏固定占屏高 18% */
   display: flex;
-  flex-direction: row; /* 竖屏:横向 */
+  flex-direction: row; /* 竖屏:图标+文字横排 */
   align-items: center;
   justify-content: center;
-  gap: 10px;
-  padding: 14px 16px 0;
+  gap: clamp(8px, 3vw, 18px);
+  padding: 0 20px;
   box-sizing: border-box;
   pointer-events: none;
-  flex-shrink: 0;
-}
-
-#app-logo-bar.visible {
-  opacity: 1;
+  position: relative;
+  z-index: 200;
 }
 
 #app-logo {
-  height: 52px;
+  height: 12dvh; /* ≈ 55% of 20dvh bar */
   width: auto;
   display: block;
   flex-shrink: 0;
+  object-fit: contain;
 }
 
 #app-logo-txt {
-  height: 40px;
+  height: 12dvh;
   width: auto;
   max-width: 55%;
   display: block;
+  object-fit: contain;
 }
 
 @media (orientation: landscape) {
   #app-logo-bar {
-    flex-direction: column; /* 横屏:纵向 */
-    gap: 10px;
+    flex: 0 0 auto;
+    order: 1;
+    flex-direction: column;
+    gap: clamp(4px, 1vh, 8px);
     padding: 0;
-    width: 100%;
+    width: 80%;
+    position: static;
+    z-index: auto;
   }
 
   #app-logo {
-    height: clamp(64px, 17vh, 110px);
-    max-width: 70%;
+    width: 85%;
+    height: auto;
+    max-width: none;
     object-fit: contain;
   }
 
   #app-logo-txt {
-    height: clamp(28px, 8vh, 48px);
-    max-width: 88%;
+    width: 70%;
+    height: auto;
+    max-width: none;
     object-fit: contain;
   }
 }
@@ -437,27 +444,37 @@ body {
   pointer-events: none;
 }
 
-/* ── CTA 按钮容器 ────────────────────────────────────── */
-/* 竖屏:sidebar flex 末尾(space-between 自动贴底) */
-/* 横屏:sidebar flex 内静态排列 */
+/* ── CTA 按钮容器 ────────────────────────────────────────── */
+/* 竖屏(display:contents 子项):order:10 置底,z:200 浮于 promo  */
+/* 横屏(sidebar 内 flex 子项) :在 spacer 之后贴底              */
 #cta-btn-wrapper {
-  width: 100%;
+  order: 10; /* 竖屏:body 最末行 */
+  flex: 0 0 14dvh; /* ← 竖屏固定占屏高 14%(含按钮+上下间距) */
   display: flex;
+  align-items: center;
   justify-content: center;
   pointer-events: none;
-  flex-shrink: 0;
+  padding: 0 16px;
+  box-sizing: border-box;
+  position: relative;
+  z-index: 200; /* 竖屏:浮于 promo-screen 之上 */
 }
 
 @media (orientation: landscape) {
   #cta-btn-wrapper {
-    width: 100%;
+    flex: 0 0 auto;
+    order: 10;
+    width: 90%;
+    padding: 0 0 clamp(20px, 5vh, 44px);
+    position: static;
+    z-index: auto;
   }
 
   #cta-btn {
     width: 100%;
     max-width: none;
-    height: 52px;
-    font-size: 16px;
+    height: clamp(42px, 10vh, 54px);
+    font-size: clamp(13px, 3.5vh, 17px);
   }
 }
 
@@ -533,10 +550,9 @@ body {
   animation: cta-highlight-pulse 0.8s ease-in-out infinite;
 }
 
-/* ── 宣传界面 ──────────────────────────────────────── */
-/* 竖屏/横屏均在 game-area 内 absolute 展开:
-   竖屏:game-area=全屏,promo 覆盖全屏;sidebar logo/CTA 在 z:100 叠在上方
-   横屏:game-area=左58%,promo 填满左侧 */
+/* ── 宣传界面 ──────────────────────────────────────────── */
+/* 在 game-area 内 position:absolute 展开,填满整个填色区域   */
+/* logo-bar(z:200) 和 cta-wrapper(z:200) 叠在其上             */
 #promo-screen {
   position: absolute;
   inset: 0;
@@ -544,30 +560,25 @@ body {
   flex-direction: column;
   align-items: center;
   justify-content: center;
-  gap: 20px;
-  background: linear-gradient(160deg, #fff9f2 0%, #ffeedd 100%);
+  gap: clamp(4px, 1vh, 8px);
+  /* 背景由 body 提供,此处透明 */
+  background: transparent;
   z-index: 10;
-  /* 竖屏:顶部让出 logo(~80px),底部让出 CTA(~72px) */
-  padding: 80px 2vw 72px;
+  /* padding-top 把重心下移,远离顶部 logo;overflow:hidden 防止 scale 动画溢出 */
+  padding: clamp(24px, 12vh, 64px) 4vw clamp(8px, 2vh, 20px);
   box-sizing: border-box;
+  overflow: hidden;
 }
 
 #promo-screen.visible {
   display: flex;
 }
 
-@media (orientation: landscape) {
-  #promo-screen {
-    /* 横屏:logo/CTA 在右侧栏,无需额外留白 */
-    padding: 16px 12px;
-    gap: 16px;
-  }
-}
-
 /* coloring-pages:从小(远)到大(近) */
 #promo-coloring {
-  max-width: 96%;
-  max-height: 52vh;
+  width: 96vw;
+  max-width: 96vw;
+  max-height: 56vh;
   object-fit: contain;
   opacity: 0;
   transform: scale(0.12);
@@ -580,18 +591,38 @@ body {
   opacity: 1;
 }
 
-/* slogan:从大(近)到小(正常,比 coloring-pages 晚 0.25s */
+/* slogan:从大(近)到正常,比 coloring-pages 晚 0.25s,加强弹跳感 */
 #promo-slogon {
-  max-width: 95%;
-  max-height: 20vh;
+  width: 90vw;
+  max-width: 90vw;
+  max-height: 22vh;
   object-fit: contain;
   opacity: 0;
-  transform: scale(1.9);
+  transform: scale(4);
   transition:
-    transform 0.65s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0.3s,
-    opacity 0.35s ease 0.3s;
+    transform 0.75s cubic-bezier(0.175, 0.885, 0.32, 1.6) 0.3s,
+    opacity 0.25s ease 0.3s;
 }
 #promo-slogon.animate-in {
   transform: scale(1);
   opacity: 1;
 }
+
+/* ── 横屏:promo 占游戏区宽度 90% ── */
+@media (orientation: landscape) {
+  #promo-screen {
+    padding: clamp(12px, 10vh, 36px) 5% clamp(4px, 2vh, 12px);
+  }
+
+  #promo-coloring {
+    width: 95%;
+    max-width: 95%;
+    max-height: 54vh;
+  }
+
+  #promo-slogon {
+    width: 90%;
+    max-width: 90%;
+    max-height: 44vh;
+  }
+}

+ 16 - 16
index.html

@@ -23,11 +23,19 @@
     <!-- 广告标识(各平台合规要求) -->
     <div id="ad-badge">Ad</div>
 
-    <!-- 填色区域(左侧 / 竖屏全屏);promo 也在此覆盖 -->
-    <div id="game-area">
-      <canvas id="canvas"></canvas>
+    <!-- 游戏列:flex column,上方是纯 canvas 区,下方是工具栏 -->
+    <div id="game-col">
+      <!-- 宣传界面:在 game-col 内 absolute 展开,覆盖 canvas+toolbar 整体区域 -->
+      <div id="promo-screen">
+        <img id="promo-coloring" alt="" />
+        <img id="promo-slogon" alt="" />
+      </div>
+
+      <div id="game-area">
+        <canvas id="canvas"></canvas>
+      </div>
 
-      <!-- 进度条 + 调色板,绝对定位在底部 -->
+      <!-- 进度条 + 调色板,在 canvas 下方独立行,不与 canvas 重叠 -->
       <div id="toolbar-bottom">
         <div id="progress-toolbar">
           <div id="progress-wrapper" class="progress-wrapper">
@@ -39,25 +47,17 @@
         </div>
         <div id="color-btns"></div>
       </div>
-
-      <!-- 宣传界面:canvas 消失后填充此区域
-           竖屏=覆盖全屏;横屏=覆盖左侧 58% -->
-      <div id="promo-screen">
-        <img id="promo-coloring" alt="" />
-        <img id="promo-slogon" alt="" />
-      </div>
     </div>
 
-    <!-- 竖屏:fixed 叠加(logo 顶 / CTA 底)
-         横屏:右侧固定栏 -->
+    <!-- 竖屏:display:contents,子元素直接参与 body flex 排列
+         横屏:flex column 右侧栏 -->
     <div id="sidebar">
       <div id="app-logo-bar">
-        <!-- logo.png = 图标,logo-txt.png = 文字;竖屏横排,横屏竖排 -->
         <img id="app-logo" alt="" />
         <img id="app-logo-txt" alt="" />
       </div>
-
-      <!-- CTA 按钮 -->
+      <!-- 横屏时撑开 logo 与 CTA 之间的空白 -->
+      <div class="sidebar-flex-spacer"></div>
       <div id="cta-btn-wrapper">
         <button id="cta-btn">PLAY NOW</button>
       </div>