* { padding: 0; margin: 0; } html, body { width: 100%; height: 100%; background: linear-gradient(160deg, #fff9f2 0%, #ffeedd 100%); transition: none; -webkit-tap-highlight-color: transparent; /*消除移动端的灰色背景闪烁*/ -webkit-touch-callout: none; /*系统默认菜单被禁用*/ -webkit-user-select: none; /*webkit浏览器*/ -khtml-user-select: none; /*早期浏览器*/ -moz-user-select: none; /*火狐*/ -ms-user-select: none; /*IE10*/ user-select: none; } input, textarea { -webkit-user-select: auto; /*webkit浏览器*/ margin: 0px; padding: 0px; outline: none; } #container { display: flex; flex-direction: column; position: absolute; left: 0; top: 0; height: 100% !important; width: 100%; } /* ── 根布局:全 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 { flex: 1; min-height: 0; position: relative; } /* canvas 绝对填满 game-area;syncCanvasSize() 同步像素尺寸 */ #canvas { position: absolute; inset: 0; width: 100%; height: 100%; z-index: 1; } /* ── 竖屏:sidebar 用 display:contents,子项直接排入 body ── */ #sidebar { display: contents; } .sidebar-flex-spacer { order: 5; display: none; /* 竖屏不需要 */ } /* ── 横屏:body flex row,sidebar 作为右侧固定栏 ─────────── */ @media (orientation: landscape) { body { flex-direction: row; } #game-col { order: 1; flex: 1; min-width: 0; } #sidebar { display: flex; order: 2; flex-direction: column; align-items: center; justify-content: flex-start; gap: 0; width: clamp(140px, 36%, 260px); height: 100%; background: transparent; padding: clamp(8px, 1.5vh, 16px) clamp(10px, 2vw, 16px); box-sizing: border-box; box-shadow: none; pointer-events: auto; overflow: hidden; } /* spacer 布局改用比例 flex,无需 spacer */ .sidebar-flex-spacer { display: none; } } #progress-toolbar { height: 20px; } #toolbar-bottom { /* 在 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; } .hidden-toolbar-bottom { transform: translateY(100%); /* 移出屏幕下方 */ opacity: 0; /* 完全透明 */ } .hidden-toolbar-right { transform: translateX(150%); /* 移出屏幕右方 */ opacity: 0; /* 完全透明 */ } #color-btns { display: flex; flex-direction: row; justify-content: flex-start; padding: 0px 10px 10px 10px; overflow-x: scroll; height: 60px; align-items: center; gap: 10px; user-select: none; /* 隐藏滚动条但保留滚动功能 */ scrollbar-width: none; -ms-overflow-style: none; } #color-btns::-webkit-scrollbar { display: none; } .color-btn-container { position: relative; min-width: 48px; width: 48px; height: 48px; } .color-btn-container-selected { transform: scale(1.2); } /* SVG 充满容器 */ .color-btn-progress-ring { width: 100%; height: 100%; } /* 进度条轨道 */ .color-btn-progress-ring-track { transition: none; } /* 动态进度条 */ .color-btn-progress-ring-value { transition: stroke-dashoffset 0.5s ease-in-out; transform: rotate(-90deg); transform-origin: 50% 50%; } .color-btn { position: absolute; min-width: 40px; width: 40px; height: 40px; line-height: 40px; text-align: center; border-radius: 50%; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15); top: 50%; left: 50%; transform: translate(-50%, -50%); z-index: 2; box-sizing: border-box; cursor: pointer; pointer-events: auto; /*允许button接收事件*/ transition: all 0.2s; } #progress-wrapper { box-sizing: border-box; display: flex; align-items: center; flex-direction: row; width: 100%; padding-left: 10px; padding-right: 10px; gap: 10px; } #progress-bar { box-sizing: border-box; flex-grow: 1; overflow: hidden; text-align: left; background-color: lightgray; border-radius: 2px; height: 4px; } #progress { transition: width 0.5s ease-in-out; width: 0%; height: 4px; background-color: rgb(7, 206, 7); } #percent { font-size: 12px; color: rgb(7, 206, 7); line-height: 12px; font-weight: 500; font-family: Arial, Helvetica, sans-serif; } /* 各种工具buuton */ .btn-img { width: 100%; height: 100%; } .btn-img-mask { position: absolute; width: 100%; height: 100%; top: 0%; border-radius: 50%; opacity: 0; background: black; } /* 有兼容性问题, 干脆不用了,直接js代码里监听各种事件来做吧*/ @media (hover: hover) and (pointer: fine) { .btn-img-mask:hover { opacity: 0.5; } } /* 移动端,解决按钮按下去再没复原的问题 */ .btn-img-mask:active { opacity: 0.5; } .btn { z-index: 120; width: 40px; height: 40px; border-radius: 50%; box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.16); } /*adapt firefox*/ @-moz-document url-prefix() { .star-rating input:checked ~ label::before { font-size: 36px; line-height: 21px; } } /*全部完成的撒花动画wrapper*/ .finish-ani-wrapper { position: absolute; pointer-events: none; width: 95vw; height: 95vh; z-index: 90; top: 0%; } /*撒花动画的花片样式*/ .finish-ani-div { position: absolute; width: 10px; height: 10px; top: 0%; opacity: 1; z-index: 90; transition: top 3s, left 3s, opacity 3s; } /*爆破动画canvas*/ .finish-ani-canvas { position: fixed; pointer-events: none; bottom: 0px; z-index: 300; } .toast { position: fixed; bottom: 20px; left: 50%; transform: translateX(-50%); background: rgba(0, 0, 0, 0.8); color: white; padding: 12px 24px; border-radius: 4px; animation: fadeInOut 2.5s; z-index: 9999; } .toast-hidden { display: none; } @keyframes fadeInOut { 0% { opacity: 0; bottom: -20px; } 20% { opacity: 1; bottom: 20px; } 80% { opacity: 1; bottom: 20px; } 100% { opacity: 0; bottom: -20px; } } /* ── Canvas 缩小消失动画 ────────────────────────────── */ #canvas.canvas-shrink-out { transition: transform 0.55s ease-in, opacity 0.55s ease-in; transform: scale(0.05); opacity: 0; pointer-events: none; } /* ── Logo 栏 ────────────────────────────────────────────── */ /* 竖屏(display:contents 子项):横排,order:1 置顶,z:200 浮于 promo */ /* 横屏(sidebar 内 flex 子项) :竖排,充满宽度 */ #app-logo-bar { order: 1; /* 竖屏:body 第一行 */ flex: 0 0 18dvh; /* ← 竖屏固定占屏高 18% */ display: flex; flex-direction: row; /* 竖屏:图标+文字横排 */ align-items: center; justify-content: center; gap: clamp(8px, 3vw, 18px); padding: 0 20px; box-sizing: border-box; pointer-events: none; position: relative; z-index: 200; } #app-logo { height: 12dvh; /* ≈ 55% of 20dvh bar */ width: auto; display: block; flex-shrink: 0; object-fit: contain; } #app-logo-txt { height: 12dvh; width: auto; max-width: 55%; display: block; object-fit: contain; } @media (orientation: landscape) { #app-logo-bar { /* sidebar 高度的 70%(logo图 4 + logo文字 3) */ flex: 7 7 0; min-height: 0; order: 1; flex-direction: column; gap: clamp(4px, 1.5vh, 10px); padding: 0; width: 80%; position: static; z-index: auto; } #app-logo { /* 占 logo-bar 的 ~57%(4/7),用 max-height 限高 */ width: 82%; height: auto; max-width: none; max-height: 55%; object-fit: contain; flex-shrink: 1; } #app-logo-txt { /* 占 logo-bar 的 ~43%(3/7) */ width: 68%; height: auto; max-width: none; max-height: 40%; object-fit: contain; flex-shrink: 1; } } /* ── 广告标识 ────────────────────────────────────────── */ #ad-badge { position: fixed; top: 6px; right: 8px; z-index: 300; background: rgba(0, 0, 0, 0.35); color: #fff; font-size: 10px; font-family: Arial, Helvetica, sans-serif; font-weight: 600; letter-spacing: 0.5px; padding: 2px 6px; border-radius: 4px; pointer-events: none; } /* ── CTA 按钮容器 ────────────────────────────────────────── */ /* 竖屏(display:contents 子项):order:10 置底,z:200 浮于 promo */ /* 横屏(sidebar 内 flex 子项) :在 spacer 之后贴底 */ #cta-btn-wrapper { order: 10; /* 竖屏:body 最末行 */ flex: 0 0 14dvh; /* ← 竖屏固定占屏高 14%(含按钮+上下间距) */ display: flex; align-items: center; justify-content: center; pointer-events: none; padding: 0 16px; box-sizing: border-box; position: relative; z-index: 200; /* 竖屏:浮于 promo-screen 之上 */ } @media (orientation: landscape) { #cta-btn-wrapper { /* sidebar 高度的 30% */ flex: 3 3 0; min-height: 0; order: 10; width: 90%; padding: 0; position: static; z-index: auto; } #cta-btn { width: 100%; max-width: none; height: clamp(42px, 10vh, 54px); font-size: clamp(13px, 3.5vh, 17px); } } #cta-btn { pointer-events: auto; width: min(300px, 80vw); height: 44px; border: none; border-radius: 22px; background: linear-gradient(135deg, #ff5f1f 0%, #ffb300 100%); color: #fff; font-size: 18px; font-weight: 800; letter-spacing: 3px; font-family: Arial, Helvetica, sans-serif; cursor: pointer; /* 立体感阴影 */ box-shadow: 0 4px 10px rgba(255, 95, 31, 0.45), 0 2px 0 rgba(255, 255, 255, 0.25) inset, 0 -3px 0 rgba(0, 0, 0, 0.18) inset; /* 按压效果 */ transition: transform 0.1s ease, box-shadow 0.1s ease; /* 脉冲光晕动画 */ animation: cta-pulse 2s ease-in-out infinite; } #cta-btn:active { transform: scale(0.96) translateY(2px); box-shadow: 0 2px 8px rgba(255, 95, 31, 0.4), 0 1px 0 rgba(255, 255, 255, 0.2) inset; } @keyframes cta-pulse { 0%, 100% { box-shadow: 0 4px 10px rgba(255, 95, 31, 0.45), 0 2px 0 rgba(255, 255, 255, 0.25) inset, 0 -3px 0 rgba(0, 0, 0, 0.18) inset; } 50% { box-shadow: 0 4px 16px rgba(255, 95, 31, 0.7), 0 2px 0 rgba(255, 255, 255, 0.25) inset, 0 -3px 0 rgba(0, 0, 0, 0.18) inset; } } /* 填色完成后的强化 CTA 状态 */ @keyframes cta-highlight-pulse { 0%, 100% { transform: scale(1.08); box-shadow: 0 6px 24px rgba(255, 95, 31, 0.8), 0 2px 0 rgba(255, 255, 255, 0.3) inset, 0 -3px 0 rgba(0, 0, 0, 0.2) inset; } 50% { transform: scale(1.14); box-shadow: 0 8px 32px rgba(255, 95, 31, 1), 0 2px 0 rgba(255, 255, 255, 0.3) inset, 0 -3px 0 rgba(0, 0, 0, 0.2) inset; } } #cta-btn.cta-highlight { animation: cta-highlight-pulse 0.8s ease-in-out infinite; } /* ── 宣传界面 ──────────────────────────────────────────── */ /* 在 game-area 内 position:absolute 展开,填满整个填色区域 */ /* logo-bar(z:200) 和 cta-wrapper(z:200) 叠在其上 */ #promo-screen { position: absolute; inset: 0; display: none; flex-direction: column; align-items: center; justify-content: center; gap: clamp(4px, 1vh, 8px); /* 背景由 body 提供,此处透明 */ background: transparent; z-index: 10; /* 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; } /* coloring-pages:从小(远)到大(近) */ #promo-coloring { width: 96vw; max-width: 96vw; max-height: 56vh; object-fit: contain; opacity: 0; transform: scale(0.12); transition: transform 0.7s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0.05s, opacity 0.4s ease 0.05s; } #promo-coloring.animate-in { transform: scale(1); opacity: 1; } /* slogan:从超大(近)到正常,比 coloring-pages 晚 0.25s,加强弹跳感 */ #promo-slogon { width: 90vw; max-width: 90vw; max-height: 22vh; object-fit: contain; opacity: 0; transform: scale(4); transition: 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; } }