/** * WelcomePage 屏幕适配方案 - postcss-px-to-viewport * * 设计稿基准: 375px × 812px (iPhone X/11/12/13/14) * 适配策略: vw/vh 单位,通过 postcss-px-to-viewport 自动转换 * * 核心思路: * - CSS 中的 px 自动转换为 vw * - 使用百分比和 vw/vh 实现流式响应式布局 * - 无需媒体查询,自动适配所有屏幕尺寸 */ /* ======================================== 外层容器 - 全屏布局 ======================================== */ .welcome-page { position: relative; width: 100%; /* 让欢迎页本身也跟随视口高度自适应,而不是依赖父级固定高度 */ min-height: 100dvh; min-height: calc(var(--vh, 1vh) * 100); overflow: hidden; background-color: #E8E8E8; /* iOS 安全区域适配 */ padding-top: env(safe-area-inset-top); padding-left: env(safe-area-inset-left); padding-right: env(safe-area-inset-right); padding-bottom: env(safe-area-inset-bottom); } /* ======================================== 背景层 - 全屏覆盖,消除空白 ======================================== */ .welcome-bg { position: absolute; top: 0; left: 0; width: 100%; height: 100%; background-size: cover; background-position: center; background-repeat: no-repeat; background-image: url('https://lyrria-pro.oss-cn-beijing.aliyuncs.com/chatbot-bg.svg'); z-index: 0; } /* ======================================== 内容容器 - 基于 vw/vh 响应式适配 ======================================== */ .welcome-content { position: relative; /* 宽度跟随父级,在大屏上也保持全宽自适应 */ width: 100%; /* 使用动态视口高度(dvh),降级方案使用 JavaScript 设置的 CSS 变量 */ min-height: 100dvh; /* 现代浏览器:动态视口高度 */ min-height: calc(var(--vh, 1vh) * 100); /* 降级方案:JavaScript 计算的视口高度 */ margin: 0 auto; z-index: 1; } /* ======================================== Lumi 图片 - 基于 vh 的响应式布局 设计稿: 375 × 812, 元素尺寸: width: 520px, height: 520px, top: 186.38px, left: -133px 规则: - 高度跟随视口高度 (vh) 等比缩放 - 宽度 auto,由图片本身比例决定 ======================================== */ .welcome-lumi { position: absolute; /* 纵向位置:按高度 812px 等比缩放 */ top: 22.95vh; /* 186.38 / 812 × 100 = 22.95vh */ /* 高度:按设计稿 520px 高度等比缩放 */ height: 64.04vh; /* 520 / 812 × 100 = 64.04vh */ /* 宽度自动,由图片比例决定,不直接跟随 vw 缩放 */ width: 100%; /* 横向位置:仍按设计稿等比缩放,宽度封顶 600px 时不再继续偏移 */ /* left: calc(-133PX * min(100vw, 600PX) / 375PX); */ object-fit: contain; } /* ======================================== Hello 文字 - 基于 vh 的响应式布局 设计稿: 812px 高度基准, width: 245px, height: 113px ======================================== */ .welcome-hello { position: absolute; top: 17vh; /* 138 / 812 × 100 = 17vh */ /* 横向位置与宽度: - 视口宽度 ≤ 600px 时:按 375 设计稿等比缩放 - 视口宽度 > 600px 时:按 600px 视口封顶,不再继续放大 */ left: calc(45PX * min(100vw, 600PX) / 375PX); width: calc(245PX * min(100vw, 600PX) / 375PX); height: 13.92vh; /* 113 / 812 × 100 = 13.92vh */ /* 文字渐变色 */ background: linear-gradient(97.3deg, rgba(245, 243, 240, 0.8) 2.21%, rgba(245, 243, 240, 0.3) 150.89%); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; opacity: 1; /* 文字样式 - 使用系统字体 */ display: flex; align-items: center; justify-content: center; font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Arial, sans-serif; font-weight: 500; font-style: normal; /* 字体大小:同时考虑宽度和高度,取二者中较小的值 */ /* 宽度方向:96PX * min(100vw, 600PX) / 375PX (≤600 等比缩放,>600 封顶) */ /* 高度方向:96PX * 100vh / 812PX (按设计稿高度 812px 等比缩放) */ /* 最终:min(宽度方案, 高度方案),防止某一维度过大导致文字过大或被遮挡 */ font-size: min( calc(96PX * min(100vw, 600PX) / 375PX), calc(96PX * 100vh / 812PX) ); line-height: 1; /* 使用数值而非百分比,更稳定 */ letter-spacing: 0; text-align: center; text-transform: capitalize; /* 交互 */ cursor: pointer; transition: opacity 0.2s ease, transform 0.2s ease; user-select: none; -webkit-tap-highlight-color: transparent; touch-action: manipulation; } .welcome-hello:hover { opacity: 0.9; } .welcome-hello:active { opacity: 0.8; } /* ======================================== 性能优化 ======================================== */ .welcome-lumi, .welcome-hello { /* 启用硬件加速 */ transform: translateZ(0); will-change: transform; /* 图片优化 */ image-rendering: -webkit-optimize-contrast; image-rendering: crisp-edges; /* 防止图片拖拽 */ -webkit-user-drag: none; } /* ======================================== 视频播放器容器 ======================================== */ .player-container { position: fixed; top: 0; left: 0; width: 100%; height: 100%; z-index: 10; transition: opacity 0.3s ease-in; } .player-container.player-visible { opacity: 1; visibility: visible; pointer-events: auto; } .player-container.player-hidden { opacity: 0; visibility: hidden; pointer-events: none; } /* Video.js 容器样式 */ .video-js { position: absolute; top: 0; left: 0; width: 100% !important; height: 100% !important; padding-top: 0 !important; background: transparent; z-index: 1; } /* Video.js 技术层(实际video元素) */ .video-js .vjs-tech { position: absolute; top: 0; left: 0; width: 100%; height: 100%; object-fit: contain; z-index: 2; } /* 隐藏 Video.js 控制栏 */ .video-js .vjs-control-bar { display: none !important; opacity: 0 !important; visibility: hidden !important; } .video-js:hover .vjs-control-bar, .video-js.vjs-user-active .vjs-control-bar, .video-js.vjs-user-inactive .vjs-control-bar, .video-js.vjs-paused .vjs-control-bar { display: none !important; opacity: 0 !important; visibility: hidden !important; } /* 隐藏原生浏览器控制栏 */ .video-js video::-webkit-media-controls { display: none !important; -webkit-appearance: none !important; opacity: 0 !important; visibility: hidden !important; } .video-js video::-webkit-media-controls-enclosure { display: none !important; -webkit-appearance: none !important; opacity: 0 !important; visibility: hidden !important; } .video-js video::-webkit-media-controls-panel, .video-js video::-webkit-media-controls-play-button, .video-js video::-webkit-media-controls-timeline, .video-js video::-webkit-media-controls-current-time-display, .video-js video::-webkit-media-controls-time-remaining-display, .video-js video::-webkit-media-controls-mute-button, .video-js video::-webkit-media-controls-volume-slider, .video-js video::-webkit-media-controls-fullscreen-button { display: none !important; } /* 移动端 iOS Safari - 隐藏播放开始按钮和叠加层 */ video::-webkit-media-controls-start-playback-button, video::-webkit-media-controls-overlay-enclosure, video::-webkit-media-controls-overlay-play-button { display: none !important; -webkit-appearance: none !important; opacity: 0 !important; } /* 移动端强制隐藏所有原生控件 */ .player-container video, .video-js video { -webkit-appearance: none !important; appearance: none !important; } /* 移除Video.js的聚焦轮廓 */ .video-js *:focus { outline: none; } /* 隐藏大播放按钮 */ .video-js .vjs-big-play-button { display: none !important; opacity: 0 !important; visibility: hidden !important; pointer-events: none !important; } /* 隐藏加载动画 */ .video-js .vjs-loading-spinner { display: none !important; opacity: 0 !important; visibility: hidden !important; pointer-events: none !important; } /* 视频元素本身需要可见和可交互(用于播放) */ .video-js, .video-js .vjs-tech, .video-js video { pointer-events: auto !important; cursor: default; } /* Video.js 响应式处理 */ .vjs-fluid { padding-top: 0 !important; } .vjs-16-9 { padding-top: 0 !important; } /* 确保video元素填充满容器 */ .video-js video { width: 100% !important; height: 100% !important; object-fit: contain; z-index: 2; display: block !important; } /* 禁用文本选择和拖拽 */ .player-container, .video-js { user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; -webkit-touch-callout: none; } /* ======================================== 加载动画遮罩 ======================================== */ .video-loading-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0, 0, 0, 0.7); display: flex; justify-content: center; align-items: center; z-index: 10000; backdrop-filter: blur(4px); } .video-loading-content { display: flex; flex-direction: column; align-items: center; gap: 24px; /* 0.24rem = 24px (基于 1rem = 100px) */ } .video-loading-spinner { position: relative; width: 80px; /* 0.8rem = 80px */ height: 80px; /* 0.8rem = 80px */ } .spinner-ring { position: absolute; top: 0; left: 0; width: 100%; height: 100%; border: 3px solid transparent; border-top-color: #fff; border-radius: 50%; animation: spin 1s linear infinite; } .spinner-ring-1 { border-top-color: rgba(255, 255, 255, 0.9); animation-duration: 1s; } .spinner-ring-2 { width: 70%; height: 70%; top: 15%; left: 15%; border-top-color: rgba(255, 255, 255, 0.7); animation-duration: 1.5s; animation-direction: reverse; } .spinner-ring-3 { width: 40%; height: 40%; top: 30%; left: 30%; border-top-color: rgba(255, 255, 255, 0.5); animation-duration: 2s; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } .video-loading-text { color: #fff; font-size: 16px; /* 0.16rem = 16px */ font-weight: 500; text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); animation: pulse 1.5s ease-in-out infinite; } @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.6; } } /* ======================================== 协议文字 - 基于 vh 的响应式布局 设计稿: 812px 高度基准,top: 700px ======================================== */ .agreement-container { position: absolute; left: 0; right: 0; /* 改为使用 bottom + 安全区,避免被浏览器底栏遮挡 */ bottom: calc(env(safe-area-inset-bottom, 0px) + 24PX); display: flex; justify-content: center; align-items: center; /* 协议区域左右留白在大屏上保持固定,不跟随宽度无限放大 */ padding: 0 20PX; z-index: 2; } .agreement-login-tip { position: absolute; left: 0; right: 0; bottom: calc(env(safe-area-inset-bottom, 0px) + 56PX); /* 在协议文字上方留出间距 */ text-align: center; font-size: 12PX; /* 与 .agreement-text 一致 */ line-height: 1.5; color: rgba(245, 243, 240, 1); /* 白色文字,与协议文字一致 */ text-decoration: underline; user-select: none; cursor: pointer; transition: opacity 0.2s ease; -webkit-tap-highlight-color: transparent; z-index: 2; } .agreement-login-tip:active, .agreement-login-tip:hover { opacity: 0.8; } .agreement-content { display: flex; align-items: center; /* 间距固定,不随视口宽度变化 */ gap: 8PX; } .agreement-checkbox { width: 16PX; height: 16PX; min-width: 16PX; border-radius: 50%; /* 边框宽度固定为 1.5PX,使用大写 PX 避免被 postcss-px-to-viewport 转换 */ border: 1.5PX solid rgba(245, 243, 240, 1); background: transparent; cursor: pointer; transition: all 0.2s ease; position: relative; } .agreement-checkbox.checked { background: rgba(191, 157, 248, 1); border-color: rgba(191, 157, 248, 1); } .agreement-checkbox.checked::after { content: ''; position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); width: 6PX; height: 6PX; background: white; border-radius: 50%; } .agreement-text { /* 协议文字在大屏上保持固定字号,避免过大 */ font-size: 12PX; line-height: 1.5; color: rgba(245, 243, 240, 1); user-select: none; } .agreement-link { color: rgba(191, 157, 248, 1); text-decoration: none; cursor: pointer; transition: opacity 0.2s ease; } .agreement-link:hover, .agreement-link:active { opacity: 0.8; }