tools.css 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597
  1. * {
  2. padding: 0;
  3. margin: 0;
  4. }
  5. html,
  6. body {
  7. width: 100%;
  8. height: 100%;
  9. background: #fff9f2;
  10. -webkit-tap-highlight-color: transparent; /*消除移动端的灰色背景闪烁*/
  11. -webkit-touch-callout: none; /*系统默认菜单被禁用*/
  12. -webkit-user-select: none; /*webkit浏览器*/
  13. -khtml-user-select: none; /*早期浏览器*/
  14. -moz-user-select: none; /*火狐*/
  15. -ms-user-select: none; /*IE10*/
  16. user-select: none;
  17. }
  18. input,
  19. textarea {
  20. -webkit-user-select: auto; /*webkit浏览器*/
  21. margin: 0px;
  22. padding: 0px;
  23. outline: none;
  24. }
  25. #container {
  26. display: flex;
  27. flex-direction: column;
  28. position: absolute;
  29. left: 0;
  30. top: 0;
  31. height: 100% !important;
  32. width: 100%;
  33. }
  34. /* ── 根布局 ─────────────────────────────────────────── */
  35. /* 竖屏:game-area 全屏,sidebar fixed 叠在上方(logo 顶/CTA 底) */
  36. /* 横屏:game-area 左 58%,sidebar 右 42% 固定栏 */
  37. body {
  38. position: relative;
  39. overflow: hidden;
  40. }
  41. #game-area {
  42. position: fixed;
  43. top: 0;
  44. left: 0;
  45. width: 100%;
  46. height: 100%;
  47. z-index: 0;
  48. /* 与宣传屏背景一致,canvas 透明区及消失后风格统一 */
  49. background: linear-gradient(160deg, #fff9f2 0%, #ffeedd 100%);
  50. }
  51. #canvas {
  52. position: absolute;
  53. top: 0;
  54. left: 0;
  55. width: 100%;
  56. height: 100%;
  57. z-index: 1;
  58. }
  59. /* ── 竖屏:sidebar 覆盖 canvas,logo 顶对齐,CTA 底对齐 ── */
  60. #sidebar {
  61. position: fixed;
  62. top: 0;
  63. left: 0;
  64. width: 100%;
  65. height: 100%;
  66. pointer-events: none;
  67. z-index: 100;
  68. display: flex;
  69. flex-direction: column;
  70. justify-content: space-between;
  71. align-items: center;
  72. padding-bottom: 16px;
  73. box-sizing: border-box;
  74. }
  75. /* ── 横屏:左右分栏 ─────────────────────────────────── */
  76. @media (orientation: landscape) {
  77. #game-area {
  78. width: 58%;
  79. height: 100%;
  80. }
  81. #sidebar {
  82. left: 58%;
  83. top: 0;
  84. width: 42%;
  85. height: 100%;
  86. background: linear-gradient(175deg, #fff0e6 0%, #ffdbb4 100%);
  87. display: flex;
  88. flex-direction: column;
  89. align-items: center;
  90. justify-content: center;
  91. gap: 28px;
  92. padding: 24px 20px;
  93. box-sizing: border-box;
  94. pointer-events: auto;
  95. box-shadow: -2px 0 16px rgba(0, 0, 0, 0.1);
  96. }
  97. }
  98. #progress-toolbar {
  99. height: 20px;
  100. }
  101. #toolbar-bottom {
  102. position: absolute;
  103. bottom: 0;
  104. left: 0;
  105. width: 100%;
  106. text-align: center;
  107. z-index: 2;
  108. pointer-events: none;
  109. transition:
  110. transform 1s ease-in-out,
  111. opacity 1s ease-in-out;
  112. padding-bottom: 72px; /* 竖屏:为底部 CTA 留空 */
  113. box-sizing: border-box;
  114. }
  115. @media (orientation: landscape) {
  116. #toolbar-bottom {
  117. padding-bottom: 8px; /* 横屏:CTA 在右侧栏,不需要留底部空间 */
  118. }
  119. }
  120. .hidden-toolbar-bottom {
  121. transform: translateY(100%); /* 移出屏幕下方 */
  122. opacity: 0; /* 完全透明 */
  123. }
  124. .hidden-toolbar-right {
  125. transform: translateX(150%); /* 移出屏幕右方 */
  126. opacity: 0; /* 完全透明 */
  127. }
  128. #color-btns {
  129. display: flex;
  130. flex-direction: row;
  131. justify-content: flex-start;
  132. padding: 0px 10px 10px 10px;
  133. overflow-x: scroll;
  134. height: 60px;
  135. align-items: center;
  136. gap: 10px;
  137. user-select: none;
  138. /* 隐藏滚动条但保留滚动功能 */
  139. scrollbar-width: none;
  140. -ms-overflow-style: none;
  141. }
  142. #color-btns::-webkit-scrollbar {
  143. display: none;
  144. }
  145. .color-btn-container {
  146. position: relative;
  147. min-width: 48px;
  148. width: 48px;
  149. height: 48px;
  150. }
  151. .color-btn-container-selected {
  152. transform: scale(1.2);
  153. }
  154. /* SVG 充满容器 */
  155. .color-btn-progress-ring {
  156. width: 100%;
  157. height: 100%;
  158. }
  159. /* 进度条轨道 */
  160. .color-btn-progress-ring-track {
  161. transition: none;
  162. }
  163. /* 动态进度条 */
  164. .color-btn-progress-ring-value {
  165. transition: stroke-dashoffset 0.5s ease-in-out;
  166. transform: rotate(-90deg);
  167. transform-origin: 50% 50%;
  168. }
  169. .color-btn {
  170. position: absolute;
  171. min-width: 40px;
  172. width: 40px;
  173. height: 40px;
  174. line-height: 40px;
  175. text-align: center;
  176. border-radius: 50%;
  177. box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
  178. top: 50%;
  179. left: 50%;
  180. transform: translate(-50%, -50%);
  181. z-index: 2;
  182. box-sizing: border-box;
  183. cursor: pointer;
  184. pointer-events: auto; /*允许button接收事件*/
  185. transition: all 0.2s;
  186. }
  187. #progress-wrapper {
  188. box-sizing: border-box;
  189. display: flex;
  190. align-items: center;
  191. flex-direction: row;
  192. width: 100%;
  193. padding-left: 10px;
  194. padding-right: 10px;
  195. gap: 10px;
  196. }
  197. #progress-bar {
  198. box-sizing: border-box;
  199. flex-grow: 1;
  200. overflow: hidden;
  201. text-align: left;
  202. background-color: lightgray;
  203. border-radius: 2px;
  204. height: 4px;
  205. }
  206. #progress {
  207. transition: width 0.5s ease-in-out;
  208. width: 0%;
  209. height: 4px;
  210. background-color: rgb(7, 206, 7);
  211. }
  212. #percent {
  213. font-size: 12px;
  214. color: rgb(7, 206, 7);
  215. line-height: 12px;
  216. font-weight: 500;
  217. font-family: Arial, Helvetica, sans-serif;
  218. }
  219. /* 各种工具buuton */
  220. .btn-img {
  221. width: 100%;
  222. height: 100%;
  223. }
  224. .btn-img-mask {
  225. position: absolute;
  226. width: 100%;
  227. height: 100%;
  228. top: 0%;
  229. border-radius: 50%;
  230. opacity: 0;
  231. background: black;
  232. }
  233. /* 有兼容性问题, 干脆不用了,直接js代码里监听各种事件来做吧*/
  234. @media (hover: hover) and (pointer: fine) {
  235. .btn-img-mask:hover {
  236. opacity: 0.5;
  237. }
  238. }
  239. /* 移动端,解决按钮按下去再没复原的问题 */
  240. .btn-img-mask:active {
  241. opacity: 0.5;
  242. }
  243. .btn {
  244. z-index: 120;
  245. width: 40px;
  246. height: 40px;
  247. border-radius: 50%;
  248. box-shadow: 0 0 4px 0 rgba(0, 0, 0, 0.16);
  249. }
  250. /*adapt firefox*/
  251. @-moz-document url-prefix() {
  252. .star-rating input:checked ~ label::before {
  253. font-size: 36px;
  254. line-height: 21px;
  255. }
  256. }
  257. /*全部完成的撒花动画wrapper*/
  258. .finish-ani-wrapper {
  259. position: absolute;
  260. pointer-events: none;
  261. width: 95vw;
  262. height: 95vh;
  263. z-index: 90;
  264. top: 0%;
  265. }
  266. /*撒花动画的花片样式*/
  267. .finish-ani-div {
  268. position: absolute;
  269. width: 10px;
  270. height: 10px;
  271. top: 0%;
  272. opacity: 1;
  273. z-index: 90;
  274. transition:
  275. top 3s,
  276. left 3s,
  277. opacity 3s;
  278. }
  279. /*爆破动画canvas*/
  280. .finish-ani-canvas {
  281. position: fixed;
  282. pointer-events: none;
  283. bottom: 0px;
  284. z-index: 300;
  285. }
  286. .toast {
  287. position: fixed;
  288. bottom: 20px;
  289. left: 50%;
  290. transform: translateX(-50%);
  291. background: rgba(0, 0, 0, 0.8);
  292. color: white;
  293. padding: 12px 24px;
  294. border-radius: 4px;
  295. animation: fadeInOut 2.5s;
  296. z-index: 9999;
  297. }
  298. .toast-hidden {
  299. display: none;
  300. }
  301. @keyframes fadeInOut {
  302. 0% {
  303. opacity: 0;
  304. bottom: -20px;
  305. }
  306. 20% {
  307. opacity: 1;
  308. bottom: 20px;
  309. }
  310. 80% {
  311. opacity: 1;
  312. bottom: 20px;
  313. }
  314. 100% {
  315. opacity: 0;
  316. bottom: -20px;
  317. }
  318. }
  319. /* ── Canvas 缩小消失动画 ────────────────────────────── */
  320. #canvas.canvas-shrink-out {
  321. transition:
  322. transform 0.55s ease-in,
  323. opacity 0.55s ease-in;
  324. transform: scale(0.05);
  325. opacity: 0;
  326. pointer-events: none;
  327. }
  328. /* ── Logo 栏 ────────────────────────────────────────── */
  329. /* 竖屏:sidebar 顶部,图标+文字横向排列 */
  330. /* 横屏:右侧栏,图标+文字纵向排列,更大 */
  331. #app-logo-bar {
  332. width: 100%;
  333. display: flex;
  334. flex-direction: row; /* 竖屏:横向 */
  335. align-items: center;
  336. justify-content: center;
  337. gap: 10px;
  338. padding: 14px 16px 0;
  339. box-sizing: border-box;
  340. pointer-events: none;
  341. flex-shrink: 0;
  342. }
  343. #app-logo-bar.visible {
  344. opacity: 1;
  345. }
  346. #app-logo {
  347. height: 52px;
  348. width: auto;
  349. display: block;
  350. flex-shrink: 0;
  351. }
  352. #app-logo-txt {
  353. height: 40px;
  354. width: auto;
  355. max-width: 55%;
  356. display: block;
  357. }
  358. @media (orientation: landscape) {
  359. #app-logo-bar {
  360. flex-direction: column; /* 横屏:纵向 */
  361. gap: 10px;
  362. padding: 0;
  363. width: 100%;
  364. }
  365. #app-logo {
  366. height: clamp(64px, 17vh, 110px);
  367. max-width: 70%;
  368. object-fit: contain;
  369. }
  370. #app-logo-txt {
  371. height: clamp(28px, 8vh, 48px);
  372. max-width: 88%;
  373. object-fit: contain;
  374. }
  375. }
  376. /* ── 广告标识 ────────────────────────────────────────── */
  377. #ad-badge {
  378. position: fixed;
  379. top: 6px;
  380. right: 8px;
  381. z-index: 300;
  382. background: rgba(0, 0, 0, 0.35);
  383. color: #fff;
  384. font-size: 10px;
  385. font-family: Arial, Helvetica, sans-serif;
  386. font-weight: 600;
  387. letter-spacing: 0.5px;
  388. padding: 2px 6px;
  389. border-radius: 4px;
  390. pointer-events: none;
  391. }
  392. /* ── CTA 按钮容器 ────────────────────────────────────── */
  393. /* 竖屏:sidebar flex 末尾(space-between 自动贴底) */
  394. /* 横屏:sidebar flex 内静态排列 */
  395. #cta-btn-wrapper {
  396. width: 100%;
  397. display: flex;
  398. justify-content: center;
  399. pointer-events: none;
  400. flex-shrink: 0;
  401. }
  402. @media (orientation: landscape) {
  403. #cta-btn-wrapper {
  404. width: 100%;
  405. }
  406. #cta-btn {
  407. width: 100%;
  408. max-width: none;
  409. height: 52px;
  410. font-size: 16px;
  411. }
  412. }
  413. #cta-btn {
  414. pointer-events: auto;
  415. width: min(300px, 80vw);
  416. height: 44px;
  417. border: none;
  418. border-radius: 22px;
  419. background: linear-gradient(135deg, #ff5f1f 0%, #ffb300 100%);
  420. color: #fff;
  421. font-size: 18px;
  422. font-weight: 800;
  423. letter-spacing: 3px;
  424. font-family: Arial, Helvetica, sans-serif;
  425. cursor: pointer;
  426. /* 立体感阴影 */
  427. box-shadow:
  428. 0 4px 10px rgba(255, 95, 31, 0.45),
  429. 0 2px 0 rgba(255, 255, 255, 0.25) inset,
  430. 0 -3px 0 rgba(0, 0, 0, 0.18) inset;
  431. /* 按压效果 */
  432. transition:
  433. transform 0.1s ease,
  434. box-shadow 0.1s ease;
  435. /* 脉冲光晕动画 */
  436. animation: cta-pulse 2s ease-in-out infinite;
  437. }
  438. #cta-btn:active {
  439. transform: scale(0.96) translateY(2px);
  440. box-shadow:
  441. 0 2px 8px rgba(255, 95, 31, 0.4),
  442. 0 1px 0 rgba(255, 255, 255, 0.2) inset;
  443. }
  444. @keyframes cta-pulse {
  445. 0%,
  446. 100% {
  447. box-shadow:
  448. 0 4px 10px rgba(255, 95, 31, 0.45),
  449. 0 2px 0 rgba(255, 255, 255, 0.25) inset,
  450. 0 -3px 0 rgba(0, 0, 0, 0.18) inset;
  451. }
  452. 50% {
  453. box-shadow:
  454. 0 4px 16px rgba(255, 95, 31, 0.7),
  455. 0 2px 0 rgba(255, 255, 255, 0.25) inset,
  456. 0 -3px 0 rgba(0, 0, 0, 0.18) inset;
  457. }
  458. }
  459. /* 填色完成后的强化 CTA 状态 */
  460. @keyframes cta-highlight-pulse {
  461. 0%,
  462. 100% {
  463. transform: scale(1.08);
  464. box-shadow:
  465. 0 6px 24px rgba(255, 95, 31, 0.8),
  466. 0 2px 0 rgba(255, 255, 255, 0.3) inset,
  467. 0 -3px 0 rgba(0, 0, 0, 0.2) inset;
  468. }
  469. 50% {
  470. transform: scale(1.14);
  471. box-shadow:
  472. 0 8px 32px rgba(255, 95, 31, 1),
  473. 0 2px 0 rgba(255, 255, 255, 0.3) inset,
  474. 0 -3px 0 rgba(0, 0, 0, 0.2) inset;
  475. }
  476. }
  477. #cta-btn.cta-highlight {
  478. animation: cta-highlight-pulse 0.8s ease-in-out infinite;
  479. }
  480. /* ── 宣传界面 ──────────────────────────────────────── */
  481. /* 竖屏/横屏均在 game-area 内 absolute 展开:
  482. 竖屏:game-area=全屏,promo 覆盖全屏;sidebar logo/CTA 在 z:100 叠在上方
  483. 横屏:game-area=左58%,promo 填满左侧 */
  484. #promo-screen {
  485. position: absolute;
  486. inset: 0;
  487. display: none;
  488. flex-direction: column;
  489. align-items: center;
  490. justify-content: center;
  491. gap: 20px;
  492. background: linear-gradient(160deg, #fff9f2 0%, #ffeedd 100%);
  493. z-index: 10;
  494. /* 竖屏:顶部让出 logo(~80px),底部让出 CTA(~72px) */
  495. padding: 80px 2vw 72px;
  496. box-sizing: border-box;
  497. }
  498. #promo-screen.visible {
  499. display: flex;
  500. }
  501. @media (orientation: landscape) {
  502. #promo-screen {
  503. /* 横屏:logo/CTA 在右侧栏,无需额外留白 */
  504. padding: 16px 12px;
  505. gap: 16px;
  506. }
  507. }
  508. /* coloring-pages:从小(远)到大(近) */
  509. #promo-coloring {
  510. max-width: 96%;
  511. max-height: 52vh;
  512. object-fit: contain;
  513. opacity: 0;
  514. transform: scale(0.12);
  515. transition:
  516. transform 0.7s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0.05s,
  517. opacity 0.4s ease 0.05s;
  518. }
  519. #promo-coloring.animate-in {
  520. transform: scale(1);
  521. opacity: 1;
  522. }
  523. /* slogan:从大(近)到小(正常),比 coloring-pages 晚 0.25s */
  524. #promo-slogon {
  525. max-width: 95%;
  526. max-height: 20vh;
  527. object-fit: contain;
  528. opacity: 0;
  529. transform: scale(1.9);
  530. transition:
  531. transform 0.65s cubic-bezier(0.175, 0.885, 0.32, 1.275) 0.3s,
  532. opacity 0.35s ease 0.3s;
  533. }
  534. #promo-slogon.animate-in {
  535. transform: scale(1);
  536. opacity: 1;
  537. }