|
208 | 208 |
|
209 | 209 | /* 隐藏滚动条 */ |
210 | 210 | -ms-overflow-style: none; scrollbar-width: none; |
| 211 | + |
| 212 | + /* Initial state hidden to prevent flicker */ |
| 213 | + opacity: 0; transition: opacity 0.3s ease; |
211 | 214 | } |
| 215 | + /* 临时禁用平滑滚动的类 */ |
| 216 | + .scroll-track.no-smooth { scroll-behavior: auto !important; } |
| 217 | + /* 布局稳定后显示 */ |
| 218 | + .scroll-track.ready { opacity: 1; } |
| 219 | + |
212 | 220 | .scroll-track::-webkit-scrollbar { display: none; } |
213 | 221 |
|
214 | 222 | /* 左右对齐方式不同 - 统一改为居中,因为现在是独立的侧边栏区域 */ |
|
736 | 744 | // 场景列表容器 - 动态加载 |
737 | 745 | let SCENES = []; |
738 | 746 |
|
739 | | - const WALLPAPERS = [ |
| 747 | + let WALLPAPERS = [ |
740 | 748 | 'assets/killian-prevost-caillou-final.jpg', |
741 | 749 | 'assets/jacek-pilarski-citadel.webp', |
742 | 750 | 'assets/yucong-tang-yucong-tang-2e.webp', |
|
765 | 773 | wallIndex: 0, |
766 | 774 | bgFlip: false, |
767 | 775 | isScrolling: false, |
768 | | - viewMode: 'scene' |
| 776 | + viewMode: 'scene', |
| 777 | + currentBgUrl: '' |
769 | 778 | }; |
770 | 779 |
|
771 | 780 | const els = { |
|
859 | 868 | */ |
860 | 869 |
|
861 | 870 | async function init() { |
| 871 | + // Try to load wallpapers from sessionStorage first |
| 872 | + try { |
| 873 | + const storedWallpapers = sessionStorage.getItem('preview_wallpapers'); |
| 874 | + if (storedWallpapers) { |
| 875 | + const parsed = JSON.parse(storedWallpapers); |
| 876 | + if (Array.isArray(parsed) && parsed.length > 0) { |
| 877 | + WALLPAPERS = parsed; |
| 878 | + } |
| 879 | + } |
| 880 | + } catch (e) { |
| 881 | + console.error("Failed to load wallpapers from session", e); |
| 882 | + } |
| 883 | + |
862 | 884 | // Load Scenes |
863 | 885 | try { |
864 | 886 | await loadScenes(); |
|
873 | 895 | // 如果 URL 提供了壁纸 src |
874 | 896 | if (params.src) { |
875 | 897 | // 检查壁纸是否已存在于列表中 |
876 | | - const existingIndex = WALLPAPERS.indexOf(params.src); |
| 898 | + // Normalize URLs for comparison (handle absolute/relative) |
| 899 | + const normalize = (url) => { |
| 900 | + try { |
| 901 | + return new URL(url, window.location.href).href; |
| 902 | + } catch(e) { return url; } |
| 903 | + }; |
| 904 | + const targetSrc = normalize(params.src); |
| 905 | + |
| 906 | + let existingIndex = WALLPAPERS.findIndex(w => normalize(w) === targetSrc); |
| 907 | + |
| 908 | + // Fallback: simple string inclusion if normalization fails to match |
| 909 | + if (existingIndex === -1) { |
| 910 | + existingIndex = WALLPAPERS.findIndex(w => w.includes(params.src) || params.src.includes(w)); |
| 911 | + } |
| 912 | + |
877 | 913 | if (existingIndex !== -1) { |
878 | 914 | initialWallIndex = existingIndex; |
879 | 915 | } else { |
|
937 | 973 | // 5. 初始对齐 |
938 | 974 | // 延时执行以确保布局渲染完毕 |
939 | 975 | setTimeout(() => { |
940 | | - scrollToCard(els.sceneTrack, 0); |
941 | | - scrollToCard(els.wallTrack, initialWallIndex); |
| 976 | + // 临时禁用 CSS 平滑滚动 |
| 977 | + els.sceneTrack.classList.add('no-smooth'); |
| 978 | + els.wallTrack.classList.add('no-smooth'); |
| 979 | + |
| 980 | + // 强制瞬间跳转 |
| 981 | + scrollToCard(els.sceneTrack, 0, 'auto'); |
| 982 | + scrollToCard(els.wallTrack, initialWallIndex, 'auto'); |
| 983 | + |
| 984 | + // 恢复平滑滚动 (下一帧恢复,确保跳转已执行) |
| 985 | + requestAnimationFrame(() => { |
| 986 | + setTimeout(() => { |
| 987 | + els.sceneTrack.classList.remove('no-smooth'); |
| 988 | + els.wallTrack.classList.remove('no-smooth'); |
| 989 | + |
| 990 | + // Show tracks after position is stabilized |
| 991 | + els.sceneTrack.classList.add('ready'); |
| 992 | + els.wallTrack.classList.add('ready'); |
| 993 | + }, 50); |
| 994 | + }); |
942 | 995 | }, 100); |
943 | 996 |
|
944 | 997 | // 6. Render iOS UI |
|
1103 | 1156 | } |
1104 | 1157 |
|
1105 | 1158 | // 辅助:平滑滚动到指定卡片 |
1106 | | - function scrollToCard(container, index) { |
| 1159 | + function scrollToCard(container, index, behavior = 'smooth') { |
1107 | 1160 | const card = container.children[index]; |
1108 | 1161 | if (!card) return; |
1109 | 1162 | // 计算让卡片居中的滚动位置 |
1110 | 1163 | const scrollPos = card.offsetTop - (container.clientHeight / 2) + (card.offsetHeight / 2); |
1111 | 1164 | container.scrollTo({ |
1112 | 1165 | top: scrollPos, |
1113 | | - behavior: 'smooth' |
| 1166 | + behavior: behavior |
1114 | 1167 | }); |
1115 | 1168 | } |
1116 | 1169 |
|
|
1244 | 1297 | }); |
1245 | 1298 | }; |
1246 | 1299 |
|
1247 | | - // Trigger load |
| 1300 | + // 触发 load |
1248 | 1301 | els.base.src = s.src; |
| 1302 | + |
| 1303 | + // 更新背景 (如果是 Scene 模式,背景随场景变) |
| 1304 | + updateAmbientBackground(); |
1249 | 1305 | } |
1250 | 1306 |
|
1251 | 1307 | function updateWallpaper(idx) { |
|
1260 | 1316 | // 3. Raw Image |
1261 | 1317 | if(els.rawImg) els.rawImg.src = url; |
1262 | 1318 |
|
| 1319 | + // 更新背景 (如果是 UI/Raw 模式,背景随壁纸变) |
| 1320 | + updateAmbientBackground(); |
| 1321 | + } |
| 1322 | + |
| 1323 | + // 统一背景更新逻辑 |
| 1324 | + function updateAmbientBackground() { |
| 1325 | + let bgUrl = ''; |
| 1326 | + |
| 1327 | + if (state.viewMode === 'scene') { |
| 1328 | + // Scene 模式:背景使用场景图 |
| 1329 | + if (SCENES[state.sceneIndex]) { |
| 1330 | + bgUrl = SCENES[state.sceneIndex].src; |
| 1331 | + } |
| 1332 | + } else { |
| 1333 | + // 其他模式:背景使用壁纸 |
| 1334 | + bgUrl = WALLPAPERS[state.wallIndex]; |
| 1335 | + } |
| 1336 | + |
| 1337 | + if (!bgUrl || state.currentBgUrl === bgUrl) return; |
| 1338 | + state.currentBgUrl = bgUrl; |
| 1339 | + |
1263 | 1340 | // 环境光背景切换 (Cross-fade) |
1264 | 1341 | state.bgFlip = !state.bgFlip; |
1265 | 1342 | const activeBg = state.bgFlip ? els.bg2 : els.bg1; |
1266 | 1343 | const inactiveBg = state.bgFlip ? els.bg1 : els.bg2; |
1267 | 1344 |
|
1268 | | - activeBg.style.backgroundImage = `url(${url})`; |
| 1345 | + activeBg.style.backgroundImage = `url(${bgUrl})`; |
1269 | 1346 | activeBg.classList.add('active'); |
1270 | 1347 | inactiveBg.classList.remove('active'); |
1271 | 1348 | } |
|
1290 | 1367 | } |
1291 | 1368 | }); |
1292 | 1369 |
|
| 1370 | + // 切换模式时,检查是否需要更新背景 |
| 1371 | + updateAmbientBackground(); |
| 1372 | + |
1293 | 1373 | // Ensure current wallpaper is loaded for the new mode |
1294 | 1374 | // (Usually handled by updateWallpaper, but strictly enforcing here for safety) |
1295 | 1375 | const url = WALLPAPERS[state.wallIndex]; |
|
0 commit comments