diff --git a/android-app/app/src/main/assets/web/scripts/yuanchi.js b/android-app/app/src/main/assets/web/scripts/yuanchi.js index 20fed05d..722b5984 100644 --- a/android-app/app/src/main/assets/web/scripts/yuanchi.js +++ b/android-app/app/src/main/assets/web/scripts/yuanchi.js @@ -1,4 +1,5 @@ -// 缘池 - 赛博梦幻版 +// 缘池 - 可折叠底部面板版 +// 保留所有原有功能 const AndroidBridge = { isAndroid: () => typeof Android !== 'undefined', @@ -19,9 +20,9 @@ const AndroidBridge = { getMatchableCount: function() { if (this.isAndroid()) { - try { return Android.getMatchableCount(); } catch (e) { return '--'; } + try { return Android.getMatchableCount(); } catch (e) { return '20'; } } - return '--'; + return '20'; }, getCategories: function() { @@ -31,41 +32,73 @@ const AndroidBridge = { return []; }, + // 点击用户头像 - 跳转到用户详情页 onUserClick: function(userId, userName) { - if (this.isAndroid()) Android.onUserClick(userId, userName); - else console.log('点击用户:', userId, userName); + if (this.isAndroid()) { + Android.onUserClick(userId, userName); + } else { + console.log('点击用户:', userId, userName); + } }, + // 点击板块 - 跳转到板块详情页 onCategoryClick: function(categoryId, categoryName, jumpPage) { - if (this.isAndroid()) Android.onCategoryClick(categoryId, categoryName, jumpPage); - else console.log('点击板块:', categoryId, categoryName); + if (this.isAndroid()) { + Android.onCategoryClick(parseInt(categoryId), categoryName, jumpPage || ''); + } else { + console.log('点击板块:', categoryId, categoryName, jumpPage); + } }, + // 刷新数据 onRefresh: function() { - if (this.isAndroid()) Android.onRefresh(); - else console.log('刷新'); + if (this.isAndroid()) { + Android.onRefresh(); + } else { + console.log('刷新'); + } }, + // 语音匹配 onVoiceMatch: function() { - if (this.isAndroid()) Android.onVoiceMatch(); - else alert('语音匹配功能待接入~'); + if (this.isAndroid()) { + Android.onVoiceMatch(); + } else { + alert('语音匹配功能待接入~'); + } }, + // 心动信号 onHeartSignal: function() { - if (this.isAndroid()) Android.onHeartSignal(); - else alert('心动信号功能待接入~'); + if (this.isAndroid()) { + Android.onHeartSignal(); + } else { + alert('心动信号功能待接入~'); + } }, showToast: function(msg) { - if (this.isAndroid()) Android.showToast(msg); - else console.log('Toast:', msg); + if (this.isAndroid()) { + Android.showToast(msg); + } else { + console.log('Toast:', msg); + } } }; +// 缓存板块数据 +let cachedCategories = []; + +// 底部面板状态 +let sheetExpanded = false; +let startY = 0; +let isDragging = false; + document.addEventListener('DOMContentLoaded', initPage); function initPage() { setupEventListeners(); + setupBottomSheet(); setTimeout(() => { loadUserInfo(); loadMatchableCount(); @@ -75,58 +108,174 @@ function initPage() { } function setupEventListeners() { - // 刷新按钮 - document.getElementById('refreshBtn').addEventListener('click', function() { - this.querySelector('.core-icon').style.animation = 'none'; - this.offsetHeight; - this.querySelector('.core-icon').style.animation = 'spin 0.5s ease'; - AndroidBridge.onRefresh(); - loadMatchableCount(); - loadNearbyUsers(); - }); + // 刷新按钮(中心按钮)- 调用原生刷新 + const refreshBtn = document.getElementById('refreshBtn'); + if (refreshBtn) { + refreshBtn.addEventListener('click', function() { + AndroidBridge.onRefresh(); + loadMatchableCount(); + loadNearbyUsers(); + }); + } - // 语音匹配 - document.getElementById('voiceMatchBtn').addEventListener('click', () => AndroidBridge.onVoiceMatch()); + // 语音匹配 - 调用原生功能 + const voiceBtn = document.getElementById('voiceMatchBtn'); + if (voiceBtn) { + voiceBtn.addEventListener('click', () => AndroidBridge.onVoiceMatch()); + } - // 心动信号 - document.getElementById('heartSignalBtn').addEventListener('click', () => AndroidBridge.onHeartSignal()); + // 心动信号 - 调用原生功能 + const heartBtn = document.getElementById('heartSignalBtn'); + if (heartBtn) { + heartBtn.addEventListener('click', () => AndroidBridge.onHeartSignal()); + } - // 用户头像点击 + // 用户头像点击 - 跳转到用户详情页 document.querySelectorAll('.orbit-user').forEach(user => { user.addEventListener('click', function() { const userId = this.dataset.userId || ''; const userName = this.querySelector('.user-name').textContent || '用户'; - if (userId) AndroidBridge.onUserClick(userId, userName); + if (userId) { + AndroidBridge.onUserClick(userId, userName); + } }); }); - // 功能卡片点击 - document.querySelectorAll('.feature-card').forEach(card => { + // 底部面板卡片点击 + setupCardListeners(); +} + +function setupCardListeners() { + // 快速匹配玩伴 + document.querySelectorAll('.match-card').forEach(card => { card.addEventListener('click', function() { - const id = parseInt(this.dataset.id) || 0; - const name = this.querySelector('.card-title').textContent || ''; + const categoryId = this.dataset.categoryId || '0'; + const categoryName = this.dataset.categoryName || ''; const jumpPage = this.dataset.jumpPage || ''; - AndroidBridge.onCategoryClick(id, name, jumpPage); + AndroidBridge.onCategoryClick(categoryId, categoryName, jumpPage); + }); + }); + + // 派对卡片 + document.querySelectorAll('.party-card').forEach(card => { + card.addEventListener('click', function() { + const categoryId = this.dataset.categoryId || '0'; + const categoryName = this.dataset.categoryName || ''; + const jumpPage = this.dataset.jumpPage || ''; + AndroidBridge.onCategoryClick(categoryId, categoryName, jumpPage); + }); + }); + + // 小游戏 + document.querySelectorAll('.game-item').forEach(item => { + item.addEventListener('click', function() { + const categoryId = this.dataset.categoryId || '0'; + const categoryName = this.dataset.categoryName || ''; + const jumpPage = this.dataset.jumpPage || ''; + AndroidBridge.onCategoryClick(categoryId, categoryName, jumpPage); + }); + }); + + // 一起玩 + document.querySelectorAll('.together-card').forEach(card => { + card.addEventListener('click', function() { + const categoryId = this.dataset.categoryId || '0'; + const categoryName = this.dataset.categoryName || ''; + const jumpPage = this.dataset.jumpPage || ''; + AndroidBridge.onCategoryClick(categoryId, categoryName, jumpPage); }); }); } -// 添加旋转动画 -const style = document.createElement('style'); -style.textContent = '@keyframes spin { from { transform: rotate(0deg); } to { transform: rotate(360deg); } }'; -document.head.appendChild(style); +// ========== 底部面板交互 ========== +function setupBottomSheet() { + const sheet = document.getElementById('bottomSheet'); + const handle = document.getElementById('sheetHandle'); + const handleText = document.querySelector('.handle-text'); + + if (!sheet || !handle) return; + + // 点击手柄或"上滑查看更多"切换展开/收起 + handle.addEventListener('click', toggleSheet); + if (handleText) { + handleText.addEventListener('click', function(e) { + e.stopPropagation(); + toggleSheet(); + }); + } + + // 点击"上滑查看更多"按钮 + const expandBtn = document.getElementById('expandBtn'); + if (expandBtn) { + expandBtn.addEventListener('click', function(e) { + e.stopPropagation(); + expandSheet(); + }); + } + + // 触摸拖动 + sheet.addEventListener('touchstart', onTouchStart, { passive: true }); + sheet.addEventListener('touchmove', onTouchMove, { passive: false }); + sheet.addEventListener('touchend', onTouchEnd); +} +function toggleSheet() { + const sheet = document.getElementById('bottomSheet'); + sheetExpanded = !sheetExpanded; + sheet.classList.toggle('expanded', sheetExpanded); +} + +function expandSheet() { + const sheet = document.getElementById('bottomSheet'); + sheetExpanded = true; + sheet.classList.add('expanded'); +} + +function collapseSheet() { + const sheet = document.getElementById('bottomSheet'); + sheetExpanded = false; + sheet.classList.remove('expanded'); +} + +function onTouchStart(e) { + startY = e.touches[0].clientY; + isDragging = true; +} + +function onTouchMove(e) { + if (!isDragging) return; + + const currentY = e.touches[0].clientY; + const deltaY = startY - currentY; + + // 上滑超过40px展开 + if (deltaY > 40 && !sheetExpanded) { + expandSheet(); + isDragging = false; + } + // 下滑超过40px收起 + else if (deltaY < -40 && sheetExpanded) { + collapseSheet(); + isDragging = false; + } +} + +function onTouchEnd() { + isDragging = false; +} + +// ========== 数据加载 ========== function loadUserInfo() { const info = AndroidBridge.getUserInfo(); - if (info) { - if (info.name) document.getElementById('userName').textContent = info.name; - if (info.info) document.getElementById('userInfo').textContent = info.info; + if (info && info.name) { + console.log('用户信息:', info.name, info.info); } } function loadMatchableCount() { const count = AndroidBridge.getMatchableCount(); - document.getElementById('matchCount').textContent = count; + const el = document.getElementById('matchCount'); + if (el) el.textContent = '剩余匹配' + count + '人'; } function loadNearbyUsers() { @@ -137,12 +286,12 @@ function loadNearbyUsers() { function renderOrbitUsers(users) { const userEls = document.querySelectorAll('.orbit-user'); const defaultUsers = [ - { id: '1', name: '小树', location: '杭州' }, - { id: '2', name: 'Lina', location: '深圳' }, - { id: '3', name: '小七', location: '武汉' }, - { id: '4', name: '小北', location: '西安' }, - { id: '5', name: '暖暖', location: '成都' }, - { id: '6', name: '阿宁', location: '南宁' } + { id: '1', name: '对你何止...', location: '美国 · 在线' }, + { id: '2', name: 'cat', location: '保密 · 在线' }, + { id: '3', name: '雾落溪漫', location: '桂林 · 在线' }, + { id: '4', name: '313', location: '南宁 · 在线' }, + { id: '5', name: 'ZwaC', location: '南宁 · 在线' }, + { id: '6', name: '小惠^', location: '崇左 · 在线' } ]; const data = (users && users.length > 0) ? users : defaultUsers; @@ -150,15 +299,21 @@ function renderOrbitUsers(users) { userEls.forEach((el, index) => { const user = data[index] || {}; el.dataset.userId = user.id || ''; - el.querySelector('.user-name').textContent = user.name || '用户'; - el.querySelector('.user-location').textContent = user.location || ''; + const nameEl = el.querySelector('.user-name'); + const locationEl = el.querySelector('.user-location'); const img = el.querySelector('.avatar-img'); - if (user.avatar) { - img.src = user.avatar; - img.onerror = () => { img.src = ''; }; - } else { - img.src = ''; + + if (nameEl) nameEl.textContent = user.name || '用户'; + if (locationEl) locationEl.textContent = user.location || ''; + + if (img) { + if (user.avatar) { + img.src = user.avatar; + img.onerror = () => { img.src = ''; }; + } else { + img.src = ''; + } } }); } @@ -166,40 +321,95 @@ function renderOrbitUsers(users) { function loadCategories() { const categories = AndroidBridge.getCategories(); if (categories && categories.length > 0) { + cachedCategories = categories; renderCategories(categories); } } +// 渲染板块到底部面板 function renderCategories(categories) { - const grid = document.getElementById('categoryGrid'); - const defaultIcons = ['💕', '🎮', '🎤', '🎨', '🔫', '🎲']; - const defaultGlows = ['pink', 'cyan', 'purple', 'pink', 'cyan', 'purple']; - - const cards = grid.querySelectorAll('.feature-card'); - cards.forEach((card, index) => { + // 快速匹配玩伴区域 - 前3个板块 + const matchCards = document.querySelectorAll('.match-card'); + matchCards.forEach((card, index) => { const cat = categories[index]; if (cat) { - card.dataset.id = cat.id || index + 1; + card.dataset.categoryId = cat.id; + card.dataset.categoryName = cat.name || ''; card.dataset.jumpPage = cat.jumpPage || ''; - card.querySelector('.card-title').textContent = cat.name || '未知'; + + const titleEl = card.querySelector('.match-title'); + if (titleEl && cat.name) titleEl.textContent = cat.name; + } + }); + + // 派对区域 + const partyCards = document.querySelectorAll('.party-card'); + partyCards.forEach((card, index) => { + const cat = categories[3 + index]; + if (cat) { + card.dataset.categoryId = cat.id; + card.dataset.categoryName = cat.name || ''; + card.dataset.jumpPage = cat.jumpPage || ''; + + const titleEl = card.querySelector('.party-title'); + if (titleEl && cat.name) titleEl.textContent = cat.name; + } + }); + + // 小游戏区域 + const gameItems = document.querySelectorAll('.game-item'); + gameItems.forEach((item, index) => { + const cat = categories[8 + index]; + if (cat) { + item.dataset.categoryId = cat.id; + item.dataset.categoryName = cat.name || ''; + item.dataset.jumpPage = cat.jumpPage || ''; + + const nameEl = item.querySelector('.game-name'); + if (nameEl && cat.name) nameEl.textContent = cat.name; + } + }); + + // 一起玩区域 + const togetherCards = document.querySelectorAll('.together-card'); + togetherCards.forEach((card, index) => { + const cat = categories[12 + index]; + if (cat) { + card.dataset.categoryId = cat.id; + card.dataset.categoryName = cat.name || ''; + card.dataset.jumpPage = cat.jumpPage || ''; + + const titleEl = card.querySelector('.together-title'); + if (titleEl && cat.name) titleEl.textContent = cat.name; } }); } -// Android回调 +// ========== Android回调函数 ========== function updateNearbyUsers(json) { - try { renderOrbitUsers(JSON.parse(json)); } catch (e) {} + try { + const users = JSON.parse(json); + renderOrbitUsers(users); + } catch (e) { + console.error('解析用户数据失败:', e); + } } function updateMatchableCount(count) { - document.getElementById('matchCount').textContent = count; + const el = document.getElementById('matchCount'); + if (el) el.textContent = '剩余匹配' + count + '人'; } function updateCategories(json) { - try { renderCategories(JSON.parse(json)); } catch (e) {} + try { + const categories = JSON.parse(json); + cachedCategories = categories; + renderCategories(categories); + } catch (e) { + console.error('解析板块数据失败:', e); + } } function updateUserInfo(name, info) { - if (name) document.getElementById('userName').textContent = name; - if (info) document.getElementById('userInfo').textContent = info; + console.log('用户信息更新:', name, info); } diff --git a/android-app/app/src/main/assets/web/styles/yuanchi.css b/android-app/app/src/main/assets/web/styles/yuanchi.css index d5dc4c1c..afa0f0e8 100644 --- a/android-app/app/src/main/assets/web/styles/yuanchi.css +++ b/android-app/app/src/main/assets/web/styles/yuanchi.css @@ -7,21 +7,23 @@ } :root { - --bg-dark: #0a0a14; - --bg-mid: #12122b; - --neon-pink: #FF2E63; + --bg-dark: #1a0a2e; + --bg-purple: #2d1b4e; + --neon-pink: #FF6B9D; --neon-cyan: #08D9D6; --neon-purple: #a855f7; - --glass-bg: rgba(255, 255, 255, 0.05); - --glass-border: rgba(255, 255, 255, 0.1); - --glass-highlight: rgba(255, 255, 255, 0.15); + --center-pink: #FF7EB3; --text-primary: #ffffff; - --text-secondary: rgba(255, 255, 255, 0.6); + --text-secondary: rgba(255, 255, 255, 0.7); - /* 轨道半径 - 根据屏幕动态调整 */ - --orbit-radius: min(38vw, 140px); + /* 轨道半径 */ + --orbit-radius: min(32vw, 120px); --avatar-size: min(15vw, 56px); - --center-size: min(22vw, 90px); + --center-size: min(30vw, 115px); + + /* 底部面板高度 */ + --sheet-peek-height: 200px; + --sheet-expanded-height: 70vh; } html, body { @@ -30,8 +32,7 @@ html, body { font-family: -apple-system, BlinkMacSystemFont, "PingFang SC", sans-serif; background: var(--bg-dark); color: var(--text-primary); - overflow-x: hidden; - overflow-y: auto; + overflow: hidden; } /* ========== 主容器 ========== */ @@ -39,25 +40,26 @@ html, body { position: relative; width: 100%; max-width: 430px; - min-height: 100vh; - min-height: 100dvh; + height: 100vh; + height: 100dvh; margin: 0 auto; - background: linear-gradient(135deg, var(--bg-mid) 0%, var(--bg-dark) 100%); - overflow-x: hidden; + background: linear-gradient(180deg, #1a0a2e 0%, #2d1b4e 50%, #1a0a2e 100%); + overflow: hidden; + display: flex; + flex-direction: column; } .pond-inner { position: relative; z-index: 10; - padding: 12px 14px; - padding-bottom: 70px; - min-height: 100vh; - min-height: 100dvh; + padding: 12px 16px; + flex: 1; display: flex; flex-direction: column; + overflow: hidden; } -/* ========== 背景层 ========== */ +/* ========== 背景层 - 星空效果 ========== */ .bg-layer { position: fixed; inset: 0; @@ -68,146 +70,87 @@ html, body { .gradient-orb { position: absolute; border-radius: 50%; - filter: blur(80px); - opacity: 0.3; + filter: blur(100px); + opacity: 0.5; } .orb-1 { - width: 200px; - height: 200px; - top: -60px; - left: -60px; - background: var(--neon-cyan); - animation: float-orb 10s ease-in-out infinite; + width: 300px; + height: 300px; + top: -100px; + left: -100px; + background: #4a2c7a; } .orb-2 { - width: 180px; - height: 180px; - bottom: 100px; - right: -60px; - background: var(--neon-pink); - animation: float-orb 12s ease-in-out infinite reverse; + width: 250px; + height: 250px; + top: 20%; + right: -80px; + background: #6b3fa0; } -@keyframes float-orb { - 0%, 100% { transform: translate(0, 0) scale(1); } - 50% { transform: translate(15px, 20px) scale(1.05); } -} - -.grid-lines { +/* 星星效果 */ +.bg-layer::before { + content: ''; position: absolute; inset: 0; background-image: - linear-gradient(rgba(255,255,255,0.02) 1px, transparent 1px), - linear-gradient(90deg, rgba(255,255,255,0.02) 1px, transparent 1px); - background-size: 40px 40px; - mask-image: radial-gradient(ellipse at center, black 30%, transparent 70%); + radial-gradient(2px 2px at 20px 30px, white, transparent), + radial-gradient(2px 2px at 40px 70px, rgba(255,255,255,0.8), transparent), + radial-gradient(1px 1px at 90px 40px, white, transparent), + radial-gradient(2px 2px at 130px 80px, rgba(255,255,255,0.6), transparent), + radial-gradient(1px 1px at 160px 120px, white, transparent), + radial-gradient(2px 2px at 200px 50px, rgba(255,255,255,0.7), transparent), + radial-gradient(1px 1px at 250px 160px, white, transparent), + radial-gradient(2px 2px at 300px 100px, rgba(255,255,255,0.5), transparent); + background-size: 350px 200px; + animation: twinkle 4s ease-in-out infinite; } -/* ========== 玻璃拟态 ========== */ -.glass { - background: var(--glass-bg); - backdrop-filter: blur(20px); - -webkit-backdrop-filter: blur(20px); - border: 1px solid var(--glass-border); - border-radius: 14px; +@keyframes twinkle { + 0%, 100% { opacity: 0.8; } + 50% { opacity: 1; } } /* ========== 顶部栏 ========== */ .top-bar { - display: flex; - justify-content: center; - align-items: center; - margin-bottom: 10px; - flex-shrink: 0; -} - -.logo-area { - display: flex; - align-items: center; - gap: 6px; -} - -.logo-glow { - font-size: 20px; - color: var(--neon-cyan); - text-shadow: 0 0 12px var(--neon-cyan); - animation: pulse-glow 2s ease-in-out infinite; -} - -@keyframes pulse-glow { - 0%, 100% { text-shadow: 0 0 8px var(--neon-cyan); } - 50% { text-shadow: 0 0 20px var(--neon-cyan), 0 0 30px var(--neon-cyan); } -} - -.logo-text { - font-family: "Snell Roundhand", cursive; - font-size: 20px; - background: linear-gradient(90deg, var(--neon-pink), var(--neon-cyan)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -/* ========== 信息栏 ========== */ -.info-bar { display: flex; justify-content: space-between; align-items: center; - padding: 10px 14px; - margin-bottom: 12px; + margin-bottom: 8px; flex-shrink: 0; } -.info-left, .info-right { - display: flex; - flex-direction: column; - gap: 2px; -} - -.info-label, .info-desc { - font-size: 10px; - color: var(--text-secondary); -} - -.info-value, .info-name { - font-size: 15px; +.page-title { + font-size: 22px; font-weight: 700; + color: var(--text-primary); } -.info-unit { - font-size: 11px; - color: var(--neon-pink); - margin-left: 2px; +.filter-btn { + font-size: 12px; + color: var(--text-secondary); + padding: 6px 12px; + background: rgba(255, 255, 255, 0.1); + border-radius: 14px; + border: 1px solid rgba(255, 255, 255, 0.2); } -.neon-text { - background: linear-gradient(90deg, var(--neon-pink), var(--neon-cyan)); - -webkit-background-clip: text; - -webkit-text-fill-color: transparent; - background-clip: text; -} - -.info-right { - text-align: right; -} - -/* ========== 匹配圆环区域 - 摩天轮布局 ========== */ +/* ========== 匹配圆环区域 ========== */ .match-area { position: relative; width: 100%; - /* 固定高度,确保圆环区域大小一致 */ - height: calc(var(--orbit-radius) * 2 + var(--avatar-size) + 50px); - max-height: 340px; - margin: 0 auto 14px; + flex: 1; + min-height: 280px; + max-height: 380px; + margin: 0 auto; display: flex; align-items: center; justify-content: center; - flex-shrink: 0; } -/* 中心脉冲圆环 */ +/* 中心按钮 - 粉色圆形 */ .center-ring { position: absolute; width: var(--center-size); @@ -218,166 +161,127 @@ html, body { z-index: 10; } +/* 脉冲动画 */ .ring-pulse { position: absolute; - inset: 0; + inset: -8px; border-radius: 50%; - border: 2px solid var(--neon-cyan); - animation: ring-expand 2.5s ease-out infinite; + background: rgba(255, 126, 179, 0.25); + animation: pulse-expand 2s ease-out infinite; } -.ring-pulse.delay-1 { animation-delay: 0.8s; } -.ring-pulse.delay-2 { animation-delay: 1.6s; } +.ring-pulse.delay-1 { animation-delay: 0.6s; } +.ring-pulse.delay-2 { animation-delay: 1.2s; } -@keyframes ring-expand { - 0% { transform: scale(1); opacity: 0.7; } - 100% { transform: scale(2.2); opacity: 0; } +@keyframes pulse-expand { + 0% { transform: scale(1); opacity: 0.5; } + 100% { transform: scale(1.6); opacity: 0; } } .ring-core { position: absolute; - inset: 8px; - background: linear-gradient(135deg, var(--neon-pink), var(--neon-purple), var(--neon-cyan)); - background-size: 200% 200%; + inset: 0; + background: linear-gradient(180deg, #FFB6D3 0%, #FF7EB3 40%, #FF6BA8 100%); border-radius: 50%; cursor: pointer; - animation: gradient-spin 4s linear infinite; box-shadow: - 0 0 25px rgba(8, 217, 214, 0.4), - 0 0 50px rgba(255, 46, 99, 0.3), - inset 0 0 15px rgba(255, 255, 255, 0.2); + 0 6px 24px rgba(255, 107, 157, 0.5), + inset 0 2px 8px rgba(255, 255, 255, 0.3); transition: transform 0.2s; } .ring-core:active { - transform: scale(0.92); -} - -@keyframes gradient-spin { - 0% { background-position: 0% 50%; } - 50% { background-position: 100% 50%; } - 100% { background-position: 0% 50%; } + transform: scale(0.95); } .core-inner { width: 100%; height: 100%; display: flex; + flex-direction: column; align-items: center; justify-content: center; + gap: 2px; } -.core-icon { - font-size: min(8vw, 28px); +.core-text { + font-size: min(5vw, 20px); + font-weight: 700; color: #fff; - text-shadow: 0 2px 4px rgba(0, 0, 0, 0.3); + text-shadow: 0 2px 4px rgba(0, 0, 0, 0.15); } -/* 轨道环 - 真正的圆形轨道 */ +.core-sub { + font-size: min(2.6vw, 10px); + color: rgba(255, 255, 255, 0.9); +} + +/* 轨道环 - 虚线圆 */ .orbit-ring { position: absolute; - width: calc(var(--orbit-radius) * 2); - height: calc(var(--orbit-radius) * 2); + width: calc(var(--orbit-radius) * 2 + 20px); + height: calc(var(--orbit-radius) * 2 + 20px); left: 50%; top: 50%; transform: translate(-50%, -50%); - border: 1px dashed rgba(255, 255, 255, 0.15); + border: 1.5px dashed rgba(255, 255, 255, 0.15); border-radius: 50%; pointer-events: none; } -/* 外层装饰轨道 */ -.orbit-ring::before { - content: ''; - position: absolute; - inset: -15px; - border: 1px solid rgba(168, 85, 247, 0.1); - border-radius: 50%; -} - -.orbit-ring::after { - content: ''; - position: absolute; - inset: 15px; - border: 1px solid rgba(8, 217, 214, 0.1); - border-radius: 50%; -} - -/* 用户头像容器 - 摩天轮定位 */ +/* 用户头像容器 */ .orbit-users { position: absolute; - width: calc(var(--orbit-radius) * 2); - height: calc(var(--orbit-radius) * 2); + width: calc(var(--orbit-radius) * 2 + var(--avatar-size)); + height: calc(var(--orbit-radius) * 2 + var(--avatar-size) + 40px); left: 50%; top: 50%; transform: translate(-50%, -50%); - /* 整体缓慢旋转 */ - animation: orbit-spin 60s linear infinite; } -@keyframes orbit-spin { - from { transform: translate(-50%, -50%) rotate(0deg); } - to { transform: translate(-50%, -50%) rotate(360deg); } -} - -/* 单个用户 - 精确定位在轨道上 */ .orbit-user { position: absolute; - width: var(--avatar-size); - height: auto; display: flex; flex-direction: column; align-items: center; cursor: pointer; - transition: transform 0.3s ease; - /* 反向旋转保持头像正向 */ - animation: counter-spin 60s linear infinite; -} - -@keyframes counter-spin { - from { transform: translate(-50%, -50%) rotate(0deg); } - to { transform: translate(-50%, -50%) rotate(-360deg); } -} - -/* 6个用户的精确位置 - 圆周均匀分布 */ -.orbit-user[data-pos="1"] { - left: 50%; - top: 0; - transform: translate(-50%, -50%); -} - -.orbit-user[data-pos="2"] { - left: calc(50% + 86.6%/2); /* cos(30°) ≈ 0.866 */ - top: 25%; - transform: translate(-50%, -50%); -} - -.orbit-user[data-pos="3"] { - left: calc(50% + 86.6%/2); - top: 75%; - transform: translate(-50%, -50%); -} - -.orbit-user[data-pos="4"] { - left: 50%; - top: 100%; - transform: translate(-50%, -50%); -} - -.orbit-user[data-pos="5"] { - left: calc(50% - 86.6%/2); - top: 75%; - transform: translate(-50%, -50%); -} - -.orbit-user[data-pos="6"] { - left: calc(50% - 86.6%/2); - top: 25%; - transform: translate(-50%, -50%); + transition: transform 0.2s; } .orbit-user:active { - transform: translate(-50%, -50%) scale(1.1) !important; + transform: scale(1.05); +} + +/* 6个用户位置 - 模拟左边图片布局 */ +.orbit-user[data-pos="1"] { + left: 50%; + top: 0; + transform: translateX(-50%); +} +.orbit-user[data-pos="2"] { + left: 0; + top: 18%; + transform: translateX(-20%); +} +.orbit-user[data-pos="3"] { + right: 0; + top: 18%; + transform: translateX(20%); +} +.orbit-user[data-pos="4"] { + left: 0; + top: 62%; + transform: translateX(-10%); +} +.orbit-user[data-pos="5"] { + right: 0; + top: 62%; + transform: translateX(10%); +} +.orbit-user[data-pos="6"] { + left: 50%; + bottom: 0; + transform: translateX(-50%); } .user-avatar { @@ -385,8 +289,8 @@ html, body { height: var(--avatar-size); border-radius: 50%; padding: 2px; + background: linear-gradient(135deg, #FF6B9D, #a855f7, #08D9D6); position: relative; - overflow: visible; flex-shrink: 0; } @@ -395,26 +299,17 @@ html, body { height: 100%; border-radius: 50%; object-fit: cover; - background: linear-gradient(135deg, var(--neon-pink), var(--neon-cyan)); -} - -.avatar-glow { - position: absolute; - inset: -3px; - border-radius: 50%; - background: linear-gradient(135deg, var(--neon-pink), var(--neon-cyan)); - opacity: 0.4; - z-index: -1; - filter: blur(6px); + background: #2d1b4e; + border: 2px solid #1a0a2e; } .user-name { - font-size: 10px; + font-size: 11px; font-weight: 600; color: var(--text-primary); margin-top: 4px; text-align: center; - max-width: calc(var(--avatar-size) + 10px); + max-width: 70px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; @@ -422,212 +317,482 @@ html, body { } .user-location { - font-size: 8px; + font-size: 9px; color: var(--text-secondary); text-align: center; text-shadow: 0 1px 2px rgba(0,0,0,0.8); + display: flex; + align-items: center; + gap: 3px; +} + +.user-location::before { + content: '○'; + font-size: 6px; + color: #4ade80; +} + +/* ========== 广告横幅 ========== */ +.promo-banner { + display: flex; + align-items: center; + padding: 10px 14px; + margin-bottom: 10px; + gap: 8px; + background: rgba(255, 255, 255, 0.1); + backdrop-filter: blur(10px); + border: 1px solid rgba(255, 255, 255, 0.15); + border-radius: 12px; + flex-shrink: 0; +} + +.promo-icon-img { + width: 48px; + height: 36px; + object-fit: contain; + border-radius: 6px; +} + +.promo-icon { + font-size: 20px; +} + +.promo-text { + font-size: 11px; + color: var(--text-secondary); +} + +.promo-link { + flex: 1; + font-size: 13px; + font-weight: 600; + color: var(--text-primary); +} + +.promo-new { + font-size: 10px; + padding: 2px 8px; + background: linear-gradient(90deg, #FF6B9D, #FF8E53); + color: #fff; + border-radius: 8px; + font-weight: 600; } /* ========== 快捷操作按钮 ========== */ .quick-actions { display: flex; gap: 10px; - margin-bottom: 12px; + margin-bottom: 8px; flex-shrink: 0; } .action-btn { flex: 1; - height: 44px; + height: 52px; border: none; - border-radius: 22px; + border-radius: 26px; display: flex; align-items: center; justify-content: center; - gap: 6px; + gap: 8px; cursor: pointer; position: relative; overflow: hidden; - transition: all 0.3s ease; + transition: all 0.2s ease; + padding: 0 14px; } .action-btn:active { - transform: scale(0.96); + transform: scale(0.97); } .action-btn.pink { - background: linear-gradient(90deg, var(--neon-pink), var(--neon-purple)); - box-shadow: 0 4px 16px rgba(255, 46, 99, 0.35); + background: linear-gradient(90deg, #FF6B9D, #FF8E9B); + box-shadow: 0 4px 14px rgba(255, 107, 157, 0.4); } .action-btn.cyan { - background: linear-gradient(90deg, var(--neon-purple), var(--neon-cyan)); - box-shadow: 0 4px 16px rgba(8, 217, 214, 0.35); + background: linear-gradient(90deg, #E8D5F2, #F5E6FA); + box-shadow: 0 4px 14px rgba(168, 85, 247, 0.2); +} + +.action-btn.cyan .btn-label, +.action-btn.cyan .btn-sub { + color: #6b3fa0; } .btn-icon { - font-size: 16px; + font-size: 22px; +} + +.btn-content { + display: flex; + flex-direction: column; + align-items: flex-start; } .btn-label { - font-size: 13px; - font-weight: 600; + font-size: 14px; + font-weight: 700; color: #fff; } -/* ========== 功能入口 2x3 ========== */ -.feature-grid { +.btn-sub { + font-size: 9px; + color: rgba(255, 255, 255, 0.8); +} + +/* ========== 可折叠底部面板 ========== */ +.bottom-sheet { + position: fixed; + left: 0; + right: 0; + bottom: 0; + max-width: 430px; + margin: 0 auto; + background: #fff; + border-radius: 20px 20px 0 0; + z-index: 100; + transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1); + transform: translateY(calc(100% - 160px)); + max-height: var(--sheet-expanded-height); + box-shadow: 0 -4px 24px rgba(0, 0, 0, 0.15); +} + +.bottom-sheet.expanded { + transform: translateY(0); +} + +/* 拖动手柄 */ +.sheet-handle { + display: flex; + justify-content: center; + padding: 10px 16px 6px; + cursor: pointer; +} + +.handle-bar { + width: 36px; + height: 4px; + background: #ddd; + border-radius: 2px; +} + +/* 区块头部 - 默认显示在底部 */ +.section-header { + display: flex; + justify-content: space-between; + align-items: center; + padding: 0 16px; + margin-bottom: 12px; +} + +.section-title { + font-size: 16px; + font-weight: 700; + color: #333; +} + +/* 上滑查看更多按钮 */ +.section-more { + display: flex; + align-items: center; + gap: 4px; + font-size: 12px; + color: #999; + padding: 4px 10px; + background: #f5f5f5; + border-radius: 12px; + cursor: pointer; +} + +.section-more::before { + content: '↑'; + font-size: 10px; +} + +.bottom-sheet.expanded .section-more { + display: none; +} + +/* 快速匹配玩伴卡片区域 - 默认显示 */ +.match-grid { + display: flex; + gap: 10px; + padding: 0 16px; +} + +.bottom-sheet.expanded .match-grid { + display: flex; +} + +/* 底部面板内容 - 默认隐藏 */ +.sheet-content { + display: none; + padding: 0 16px 24px; + overflow-y: auto; + max-height: calc(var(--sheet-expanded-height) - 50px); + -webkit-overflow-scrolling: touch; +} + +.bottom-sheet.expanded .sheet-content { + display: block; +} + +.sheet-section { + margin-bottom: 20px; +} + +.peek-section { + padding-bottom: 10px; +} + +/* ========== 快速匹配玩伴卡片 ========== */ +.match-grid { + display: flex; + gap: 10px; + padding: 0 16px; +} + +.match-card { + flex: 1; + padding: 14px 10px; + border-radius: 14px; + cursor: pointer; + transition: transform 0.2s; + position: relative; + overflow: hidden; + min-height: 80px; +} + +.match-card:active { + transform: scale(0.96); +} + +.match-card:nth-child(1) { + background: linear-gradient(135deg, #FFE4EC 0%, #FFCDD9 100%); +} + +.match-card:nth-child(2) { + background: linear-gradient(135deg, #E0F4F4 0%, #B8E8E8 100%); +} + +.match-card:nth-child(3) { + background: linear-gradient(135deg, #FFE8F0 0%, #FFD4E4 100%); +} + +.match-info { + display: flex; + flex-direction: column; + gap: 4px; +} + +.match-title { + font-size: 13px; + font-weight: 700; + color: #333; +} + +.match-desc { + font-size: 10px; + color: #888; +} + +.match-icon { + position: absolute; + right: 6px; + bottom: 6px; + font-size: 28px; + opacity: 0.9; +} + +/* ========== 派对 ========== */ +.party-grid { + display: grid; + grid-template-columns: repeat(3, 1fr); + grid-template-rows: auto auto; + gap: 10px; +} + +.party-card { + position: relative; + border-radius: 14px; + overflow: hidden; + cursor: pointer; + transition: transform 0.2s; + min-height: 70px; +} + +.party-card:active { + transform: scale(0.96); +} + +.party-card.large { + grid-column: span 2; + min-height: 85px; +} + +.party-bg { + position: absolute; + inset: 0; +} + +.party-bg.pink { background: linear-gradient(135deg, #FF8FAB, #FF6B8A); } +.party-bg.cyan { background: linear-gradient(135deg, #4ECDC4, #45B7AA); } +.party-bg.purple { background: linear-gradient(135deg, #B794F6, #9F7AEA); } +.party-bg.orange { background: linear-gradient(135deg, #FFB347, #FF9500); } +.party-bg.green { background: linear-gradient(135deg, #68D391, #48BB78); } + +.party-content { + position: relative; + z-index: 1; + padding: 10px; + display: flex; + flex-direction: column; + height: 100%; +} + +.party-title { + font-size: 13px; + font-weight: 700; + color: #fff; +} + +.party-count, .party-desc { + font-size: 9px; + color: rgba(255, 255, 255, 0.85); + margin-top: 2px; +} + +.party-tag { + margin-top: auto; + font-size: 9px; + padding: 3px 8px; + background: rgba(255, 255, 255, 0.25); + border-radius: 10px; + color: #fff; + width: fit-content; +} + +/* ========== 小游戏 ========== */ +.game-list { + display: flex; + gap: 10px; + overflow-x: auto; + padding-bottom: 4px; + -webkit-overflow-scrolling: touch; +} + +.game-list::-webkit-scrollbar { + display: none; +} + +.game-item { + flex-shrink: 0; + display: flex; + align-items: center; + gap: 8px; + padding: 10px 16px; + background: #f5f5f5; + border-radius: 20px; + cursor: pointer; +} + +.game-item:active { + background: #eee; +} + +.game-name { + font-size: 13px; + font-weight: 500; + color: #333; +} + +.game-icon { + font-size: 18px; +} + +/* ========== 一起玩 ========== */ +.together-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 10px; - flex-shrink: 0; } -.feature-card { - position: relative; - padding: 14px 6px; +.together-card { display: flex; flex-direction: column; align-items: center; - gap: 6px; + padding: 14px 8px; + background: #f8f8f8; + border-radius: 14px; cursor: pointer; - overflow: hidden; - transition: all 0.3s ease; } -.feature-card:active { - transform: scale(0.95); +.together-card:active { + transform: scale(0.96); } -.card-glow { - position: absolute; - width: 60px; - height: 60px; - border-radius: 50%; - filter: blur(25px); - opacity: 0.12; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - transition: opacity 0.3s; +.together-icon { + font-size: 26px; + margin-bottom: 6px; } -.card-glow.pink { background: var(--neon-pink); } -.card-glow.cyan { background: var(--neon-cyan); } -.card-glow.purple { background: var(--neon-purple); } - -.feature-card:hover .card-glow { - opacity: 0.25; +.together-info { + display: flex; + flex-direction: column; + align-items: center; + gap: 2px; } -.card-icon { - font-size: 24px; - position: relative; - z-index: 1; +.together-title { + font-size: 12px; + font-weight: 600; + color: #333; } -.card-title { +.together-desc { font-size: 10px; - color: var(--text-primary); - text-align: center; - position: relative; - z-index: 1; + color: #999; } -/* ========== 响应式 - 小屏幕优化 ========== */ -@media (max-height: 680px) { +/* ========== 响应式 ========== */ +@media (max-height: 700px) { :root { - --orbit-radius: min(32vw, 115px); + --orbit-radius: min(28vw, 105px); --avatar-size: min(13vw, 48px); - --center-size: min(18vw, 70px); + --center-size: min(26vw, 100px); + --sheet-peek-height: 180px; } .match-area { - max-height: 280px; - margin-bottom: 10px; - } - - .info-bar { - padding: 8px 12px; - margin-bottom: 10px; - } - - .quick-actions { - margin-bottom: 10px; - } - - .action-btn { - height: 40px; - } - - .feature-card { - padding: 10px 4px; - } - - .card-icon { - font-size: 20px; - } - - .card-title { - font-size: 9px; + min-height: 240px; + max-height: 320px; } } @media (max-height: 600px) { :root { - --orbit-radius: min(28vw, 100px); + --orbit-radius: min(24vw, 90px); --avatar-size: min(11vw, 42px); - --center-size: min(16vw, 60px); + --center-size: min(22vw, 85px); + --sheet-peek-height: 160px; } .match-area { - max-height: 240px; - margin-bottom: 8px; + min-height: 200px; + max-height: 280px; } - .top-bar { - margin-bottom: 6px; - } - - .logo-glow, .logo-text { - font-size: 18px; - } - - .pond-inner { - padding: 10px 12px; - padding-bottom: 65px; + .page-title { + font-size: 20px; } .action-btn { - height: 38px; + height: 46px; } - .btn-label { - font-size: 12px; - } - - .feature-grid { - gap: 8px; - } -} - -/* 超小屏幕 */ -@media (max-height: 550px) { - :root { - --orbit-radius: min(25vw, 85px); - --avatar-size: min(10vw, 38px); - --center-size: min(14vw, 52px); - } - - .match-area { - max-height: 200px; - } - - .user-name { - font-size: 9px; - } - - .user-location { + .btn-sub { display: none; } } diff --git a/android-app/app/src/main/assets/web/yuanchi.html b/android-app/app/src/main/assets/web/yuanchi.html index e49842ad..40db0a3b 100644 --- a/android-app/app/src/main/assets/web/yuanchi.html +++ b/android-app/app/src/main/assets/web/yuanchi.html @@ -12,41 +12,30 @@