190 lines
5.9 KiB
HTML
190 lines
5.9 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>图片资源展示</title>
|
|
<style>
|
|
* { margin: 0; padding: 0; box-sizing: border-box; }
|
|
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #fff; }
|
|
|
|
.header {
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
padding: 16px 20px;
|
|
font-size: 18px;
|
|
font-weight: 500;
|
|
border-bottom: 1px solid #eee;
|
|
}
|
|
|
|
.content { padding: 30px; }
|
|
|
|
.group-label {
|
|
text-align: center;
|
|
margin-bottom: 20px;
|
|
font-size: 16px;
|
|
color: #333;
|
|
}
|
|
.group-label .countdown {
|
|
color: #1890ff;
|
|
font-weight: 500;
|
|
}
|
|
|
|
.image-grid {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
gap: 30px;
|
|
}
|
|
|
|
.image-item {
|
|
width: 140px; height: 140px;
|
|
background: #e8e8e8;
|
|
flex-shrink: 0;
|
|
}
|
|
.image-item img {
|
|
width: 100%; height: 100%;
|
|
object-fit: cover;
|
|
display: block;
|
|
}
|
|
|
|
.empty {
|
|
text-align: center;
|
|
color: #999;
|
|
padding: 80px 0;
|
|
}
|
|
|
|
.indicator {
|
|
display: flex;
|
|
justify-content: center;
|
|
gap: 8px;
|
|
margin-top: 20px;
|
|
}
|
|
.indicator .dot {
|
|
width: 8px; height: 8px;
|
|
border-radius: 50%;
|
|
background: #ddd;
|
|
}
|
|
.indicator .dot.active {
|
|
background: #1890ff;
|
|
}
|
|
</style>
|
|
</head>
|
|
<body>
|
|
<div class="header">
|
|
首页
|
|
</div>
|
|
<div class="content">
|
|
<div id="groupLabel" class="group-label" style="display:none;">
|
|
<span id="groupName"></span>
|
|
<span id="countdown" class="countdown"></span>
|
|
</div>
|
|
<div class="image-grid" id="imageGrid"></div>
|
|
<div class="empty" id="empty">暂无图片</div>
|
|
<div class="indicator" id="indicator"></div>
|
|
</div>
|
|
|
|
<script>
|
|
let ws;
|
|
let countdownTimer = null;
|
|
let remaining = 0;
|
|
|
|
function connectWS() {
|
|
const protocol = location.protocol === 'https:' ? 'wss:' : 'ws:';
|
|
ws = new WebSocket(protocol + '//' + location.host);
|
|
|
|
ws.onmessage = function(e) {
|
|
try {
|
|
const data = JSON.parse(e.data);
|
|
if (data.type === 'state') renderState(data);
|
|
} catch(err) {}
|
|
};
|
|
|
|
ws.onclose = function() {
|
|
setTimeout(connectWS, 3000);
|
|
};
|
|
}
|
|
|
|
function renderState(state) {
|
|
const grid = document.getElementById('imageGrid');
|
|
const empty = document.getElementById('empty');
|
|
const groupLabel = document.getElementById('groupLabel');
|
|
const indicator = document.getElementById('indicator');
|
|
|
|
if (!state.playing || state.images.length === 0) {
|
|
grid.innerHTML = '';
|
|
empty.style.display = 'block';
|
|
groupLabel.style.display = 'none';
|
|
indicator.innerHTML = '';
|
|
if (countdownTimer) { clearInterval(countdownTimer); countdownTimer = null; }
|
|
return;
|
|
}
|
|
|
|
empty.style.display = 'none';
|
|
groupLabel.style.display = 'block';
|
|
document.getElementById('groupName').textContent = state.group_name + ' ';
|
|
|
|
remaining = state.remaining;
|
|
updateCountdownDisplay();
|
|
if (countdownTimer) clearInterval(countdownTimer);
|
|
if (remaining > 0) {
|
|
countdownTimer = setInterval(function() {
|
|
remaining--;
|
|
if (remaining <= 0) {
|
|
clearInterval(countdownTimer);
|
|
countdownTimer = null;
|
|
}
|
|
updateCountdownDisplay();
|
|
}, 1000);
|
|
}
|
|
|
|
grid.innerHTML = '';
|
|
state.images.forEach(function(img) {
|
|
var div = document.createElement('div');
|
|
div.className = 'image-item';
|
|
var imgEl = document.createElement('img');
|
|
imgEl.src = '/uploads/' + img.filename;
|
|
imgEl.loading = 'lazy';
|
|
var pressTimer;
|
|
imgEl.addEventListener('touchstart', function() {
|
|
pressTimer = setTimeout(function() {
|
|
saveImage('/uploads/' + img.filename, img.original_name);
|
|
}, 1000);
|
|
});
|
|
imgEl.addEventListener('touchend', function() { clearTimeout(pressTimer); });
|
|
imgEl.addEventListener('touchmove', function() { clearTimeout(pressTimer); });
|
|
div.appendChild(imgEl);
|
|
grid.appendChild(div);
|
|
});
|
|
|
|
indicator.innerHTML = '';
|
|
for (var i = 0; i < state.total; i++) {
|
|
var dot = document.createElement('div');
|
|
dot.className = 'dot' + (i === state.current_index ? ' active' : '');
|
|
indicator.appendChild(dot);
|
|
}
|
|
}
|
|
|
|
function updateCountdownDisplay() {
|
|
var el = document.getElementById('countdown');
|
|
if (remaining < 0) {
|
|
el.textContent = '持续展示';
|
|
} else if (remaining > 0) {
|
|
el.textContent = remaining + '秒';
|
|
} else {
|
|
el.textContent = '';
|
|
}
|
|
}
|
|
|
|
function saveImage(url, name) {
|
|
var a = document.createElement('a');
|
|
a.href = url;
|
|
a.download = name || 'image.jpg';
|
|
a.click();
|
|
}
|
|
|
|
connectWS();
|
|
</script>
|
|
</body>
|
|
</html>
|