Files
u-desktop/web/overlay.html

328 lines
9.8 KiB
HTML

<!-- v4 -->
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<style>
* { margin: 0; padding: 0; }
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
font-family: "Microsoft YaHei", sans-serif;
color: #fff;
}
/* ===== 公共卡片样式 ===== */
.card {
background: rgba(0, 0, 0, 0.25);
backdrop-filter: blur(24px);
-webkit-backdrop-filter: blur(24px);
border-radius: 20px;
padding: 24px 28px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3), inset 0 0 0 1px rgba(255,255,255,0.08);
z-index: 10;
}
.time {
font-size: 72px;
font-weight: 200;
text-shadow: 0 2px 20px rgba(0,0,0,0.5);
letter-spacing: -2px;
line-height: 1;
font-variant-numeric: tabular-nums;
font-family: "Segoe UI", "Microsoft YaHei", sans-serif;
}
.date {
font-size: 14px;
color: rgba(255,255,255,0.7);
margin-bottom: 6px;
text-shadow: 0 1px 6px rgba(0,0,0,0.5);
letter-spacing: 0.5px;
}
.current-weather {
font-size: 16px;
font-weight: 500;
color: rgba(255,255,255,0.95);
text-shadow: 0 1px 4px rgba(0,0,0,0.5);
margin-bottom: 14px;
}
.forecast-title {
font-size: 11px;
font-weight: 500;
color: rgba(255,255,255,0.45);
letter-spacing: 1px;
margin-bottom: 8px;
}
.weather-forecast {
display: flex;
gap: 6px;
overflow-x: auto;
padding-bottom: 6px;
justify-content: flex-end;
}
.forecast-item {
background: rgba(255,255,255,0.06);
border-radius: 10px;
padding: 10px 12px;
text-align: center;
min-width: 58px;
font-size: 12px;
color: rgba(255,255,255,0.85);
border: 1px solid rgba(255,255,255,0.04);
}
.forecast-icon { font-size: 20px; margin: 4px 0; }
.forecast-time { opacity: 0.6; font-size: 10px; }
.forecast-temp { font-weight: 600; margin-top: 2px; font-size: 13px; }
.daily-forecast {
display: flex;
gap: 6px;
overflow-x: auto;
padding-bottom: 6px;
justify-content: flex-end;
}
.daily-item {
background: rgba(255,255,255,0.04);
border-radius: 8px;
padding: 8px 10px;
text-align: center;
min-width: 54px;
font-size: 12px;
color: rgba(255,255,255,0.85);
border: 1px solid rgba(255,255,255,0.03);
}
.daily-icon { font-size: 20px; margin: 3px 0; }
.zodiac-text {
font-size: 14px;
color: rgba(255,255,255,0.9);
line-height: 1.6;
text-shadow: 0 1px 4px rgba(0,0,0,0.5);
}
.divider {
height: 1px;
background: linear-gradient(90deg, transparent, rgba(255,255,255,0.15), transparent);
margin: 16px 0;
}
#author {
position: fixed;
bottom: 60px;
right: 30px;
font-size: 16px;
color: rgba(255,255,255,0.5);
letter-spacing: 1px;
z-index: 10;
pointer-events: none;
}
.weather-forecast::-webkit-scrollbar,
.daily-forecast::-webkit-scrollbar { display: none; }
/* ===== SINGLE 布局(现有) ===== */
body.layout-single #layout-single { display: block; }
body.layout-single #layout-multi { display: none; }
body.layout-single #info {
position: fixed;
top: 40px;
right: 40px;
text-align: left;
min-width: 320px;
}
body.layout-single #info .date {
text-align: left;
}
/* ===== MULTI 布局(独立卡片) ===== */
body.layout-multi #layout-single { display: none; }
body.layout-multi #layout-multi { display: block; }
body.layout-multi #card-time {
position: fixed;
top: 40px;
right: 40px;
text-align: left;
min-width: 280px;
}
body.layout-multi #card-weather {
position: fixed;
bottom: 80px;
right: 40px;
text-align: right;
min-width: 420px;
}
body.layout-multi #card-zodiac {
position: fixed;
bottom: 80px;
left: 40px;
min-width: 200px;
}
</style>
</head>
<body class="layout-{{LAYOUT}}">
{{BACKGROUND}}
<!-- ===== SINGLE 布局 ===== -->
<div id="layout-single">
<div id="info" class="card">
<div class="date" id="date">1月1日 周一</div>
<div class="time" id="time">00:00</div>
<div class="divider"></div>
<div>
<div class="current-weather" id="currentWeather">加载中...</div>
<div class="forecast-title">24小时预报</div>
<div class="weather-forecast" id="hourlyForecast"></div>
<div class="forecast-title" style="margin-top:12px">7日预报</div>
<div class="daily-forecast" id="dailyForecast"></div>
</div>
<div class="divider"></div>
<div class="zodiac-text" id="zodiac">加载中...</div>
</div>
</div>
<!-- ===== MULTI 布局 ===== -->
<div id="layout-multi">
<div id="card-time" class="card">
<div class="date" id="date2">1月1日 周一</div>
<div class="time" id="time2">00:00</div>
</div>
<div id="card-weather" class="card">
<div class="current-weather" id="currentWeather2">加载中...</div>
<div class="forecast-title">24小时预报</div>
<div class="weather-forecast" id="hourlyForecast2"></div>
<div class="forecast-title" style="margin-top:12px">7日预报</div>
<div class="daily-forecast" id="dailyForecast2"></div>
</div>
<div id="card-zodiac" class="card">
<div class="zodiac-text" id="zodiac2">加载中...</div>
</div>
</div>
<div id="author">绝尘</div>
<script>
var lastTimeStr='', lastDateStr='', lastZodiac='';
var zodiacData = {
'白羊座':{icon:'♈',date:'3.21-4.19',fortune:'今日运势旺盛,适合开展新计划。'},
'金牛座':{icon:'♉',date:'4.20-5.20',fortune:'财运不错,但需注意健康。'},
'双子座':{icon:'♊',date:'5.21-6.21',fortune:'人际关系活跃,社交运势佳。'},
'巨蟹座':{icon:'♋',date:'6.22-7.22',fortune:'情绪敏感,适合独处思考。'},
'狮子座':{icon:'♌',date:'7.23-8.22',fortune:'自信爆棚,工作表现突出。'},
'处女座':{icon:'♍',date:'8.23-9.22',fortune:'细节决定成败,专注当下。'},
'天秤座':{icon:'♎',date:'9.23-10.23',fortune:'感情运佳,单身者有机会。'},
'天蝎座':{icon:'♏',date:'10.24-11.22',fortune:'直觉敏锐,适合做决策。'},
'射手座':{icon:'♐',date:'11.23-12.21',fortune:'冒险精神旺盛,出行注意安全。'},
'摩羯座':{icon:'♑',date:'12.22-1.19',fortune:'事业运佳,工作效率高。'},
'水瓶座':{icon:'♒',date:'1.20-2.18',fortune:'创新思维活跃,灵感不断。'},
'双鱼座':{icon:'♓',date:'2.19-3.20',fortune:'艺术灵感丰富,适合创作。'}
};
function getUserZodiac(){ return window.userZodiac||'射手座'; }
function setEl(id,html){
var e=document.getElementById(id);
if(e) e.innerHTML=html;
}
function setText(id,txt){
var e=document.getElementById(id);
if(e) e.textContent=txt;
}
function updateZodiacDisplay(){
var name=getUserZodiac();
if(name===lastZodiac) return;
lastZodiac=name;
var z=zodiacData[name]||{icon:'✨',date:'',fortune:'运势平稳,保持平常心。'};
var html=z.icon+' '+name+'运势 <span style="opacity:0.4;font-size:12px">'+z.date+'</span><br><span style="opacity:0.6;font-size:12px">'+z.fortune+'</span>';
setEl('zodiac',html);
setEl('zodiac2',html);
}
var holidays=[
{m:1,d:1,name:'元旦'},
{m:2,d:14,name:'情人节'},
{m:3,d:8,name:'妇女节'},
{m:4,d:5,name:'清明节'},
{m:5,d:1,name:'劳动节'},
{m:5,d:4,name:'青年节'},
{m:6,d:1,name:'儿童节'},
{m:7,d:1,name:'建党节'},
{m:8,d:1,name:'建军节'},
{m:9,d:10,name:'教师节'},
{m:10,d:1,name:'国庆节'},
{m:10,d:31,name:'万圣节'},
{m:12,d:25,name:'圣诞节'}
];
function getNextHoliday(now){
var y=now.getFullYear(), results=[];
for(var i=0;i<holidays.length;i++){
var h=holidays[i];
var target=new Date(y,h.m-1,h.d);
var diff=Math.ceil((target-now)/(1000*60*60*24));
if(diff>0&&diff<=60) results.push({diff:diff,name:h.name});
if(diff<0){target=new Date(y+1,h.m-1,h.d);diff=Math.ceil((target-now)/(1000*60*60*24));if(diff>0&&diff<=60)results.push({diff:diff,name:h.name});}
}
results.sort(function(a,b){return a.diff-b.diff;});
return results.length>0?'距'+results[0].name+'还有'+results[0].diff+'天':'';
}
function updateTime(){
var now=new Date();
var hh=String(now.getHours()).padStart(2,'0');
var mm=String(now.getMinutes()).padStart(2,'0');
var ss=String(now.getSeconds()).padStart(2,'0');
var month=now.getMonth()+1;
var day=now.getDate();
var week=['周日','周一','周二','周三','周四','周五','周六'][now.getDay()];
var timeStr=hh+':'+mm+':'+ss;
var dateStr=month+'月'+day+'日 '+week;
if(timeStr!==lastTimeStr){
setText('time',timeStr); setText('time2',timeStr); lastTimeStr=timeStr;
}
if(dateStr!==lastDateStr){
var holiday=getNextHoliday(now);
var displayStr=holiday?dateStr+' <span style="opacity:0.5;font-size:12px">「'+holiday+'」</span>':dateStr;
setEl('date',displayStr); setEl('date2',displayStr); lastDateStr=dateStr;
}
updateZodiacDisplay();
}
window.updateWeatherFromGo=function(data){
if(typeof data==='string') data=JSON.parse(data);
function renderWeather(curId,hourlyId,dailyId){
if(data.current) setText(curId,data.current);
var fel=document.getElementById(hourlyId);
if(fel){
if(data.hourly&&data.hourly.length>0){
fel.innerHTML=data.hourly.map(function(item){
return '<div class="forecast-item"><div class="forecast-time">'+item.time+'</div><div class="forecast-icon">'+item.icon+'</div><div class="forecast-temp">'+item.temp+'</div></div>';
}).join('');
} else { fel.innerHTML='<div style="font-size:11px;opacity:0.4">暂无数据</div>'; }
}
var del=document.getElementById(dailyId);
if(del){
if(data.daily&&data.daily.length>0){
del.innerHTML=data.daily.map(function(item){
return '<div class="daily-item"><div style="opacity:0.6;font-size:10px">'+item.date+'</div><div class="daily-icon">'+item.icon+'</div><div class="forecast-temp">'+item.tempMin+'°~'+item.tempMax+'°</div></div>';
}).join('');
} else { del.innerHTML='<div style="font-size:11px;opacity:0.4">暂无数据</div>'; }
}
}
renderWeather('currentWeather','hourlyForecast','dailyForecast');
renderWeather('currentWeather2','hourlyForecast2','dailyForecast2');
};
updateTime();
setInterval(updateTime,1000);
</script>
</body>
</html>