测试代码~简化版灯箱样式
作者: 柏哥 日期: 5小时前
复制代码,创建CSS和JS文件,引用就可以了~
/* BaigeLightbox - 简化版灯箱样式 */
.baige-lightbox-overlay {
display: none;
position: fixed;
top: 0; left: 0; right: 0; bottom: 0;
background: rgba(0,0,0,.85);
z-index: 99999;
flex-direction: column;
align-items: center;
justify-content: center;
touch-action: none;
-webkit-user-select: none;
user-select: none;
}
.baige-lightbox-img {
display: block;
max-width: 90vw;
max-height: 85vh;
border-radius: 4px;
box-shadow: 0 4px 20px rgba(0,0,0,.4);
transition: opacity .3s;
user-select: none;
-webkit-user-drag: none;
transform-origin: center center;
cursor: grab;
touch-action: none;
}
.baige-lightbox-img:active { cursor: grabbing; }
.baige-lightbox-title {
display: none;
color: #fff;
text-align: center;
font-size: 14px;
margin-top: 10px;
max-width: 90vw;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.baige-lightbox-counter {
display: none;
color: rgba(255,255,255,.7);
font-size: 14px;
margin-top: 6px;
}
.baige-lightbox-btn {
position: absolute;
background: rgba(255,255,255,.15);
border: none;
border-radius: 50%;
width: 44px;
height: 44px;
color: #fff;
cursor: pointer;
display: flex;
align-items: center;
justify-content: center;
transition: background .2s;
z-index: 100001;
padding: 0;
}
.baige-lightbox-btn:hover { background: rgba(255,255,255,.3); }
.baige-lightbox-close {
left: 50%;
bottom: 18px;
transform: translateX(-50%);
top: auto;
}
.baige-lightbox-prev { left: 12px; top: 50%; transform: translateY(-50%); }
.baige-lightbox-next { right: 12px; top: 50%; transform: translateY(-50%); }
@media (max-width: 768px) {
.baige-lightbox-prev,
.baige-lightbox-next { width: 38px; height: 38px; }
.baige-lightbox-close { width: 40px; height: 40px; }
}
/* BaigeLightbox - 简化版灯箱,PC 双击/滚轮,手机双指缩放+拖拽 */
!function() {
"use strict";
var groups = {}, current = null;
var overlay, img, titleEl, counterEl, closeBtn, prevBtn, nextBtn;
var origOverflow = "";
var scale = 1, minScale = 0.2, maxScale = 5, tx = 0, ty = 0;
var dragging = false, startX, startY;
var lastTouchDist = 0, isPinching = false;
function mkEl(tag, cls) {
var el = document.createElement(tag);
if (cls) el.className = cls;
return el;
}
function create() {
if (overlay) return;
overlay = mkEl("div", "baige-lightbox-overlay");
img = new Image();
img.className = "baige-lightbox-img";
titleEl = mkEl("div", "baige-lightbox-title");
counterEl = mkEl("div", "baige-lightbox-counter");
closeBtn = mkEl("button", "baige-lightbox-btn baige-lightbox-close");
closeBtn.innerHTML = '<svg viewBox="0 0 24 24" width="20" height="20"><path d="M18 6L6 18M6 6l12 12" stroke="currentColor" stroke-width="2" stroke-linecap="round" fill="none"/></svg>';
prevBtn = mkEl("button", "baige-lightbox-btn baige-lightbox-prev");
prevBtn.innerHTML = '<svg viewBox="0 0 24 24" width="28" height="28"><path d="M15 18l-6-6 6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>';
nextBtn = mkEl("button", "baige-lightbox-btn baige-lightbox-next");
nextBtn.innerHTML = '<svg viewBox="0 0 24 24" width="28" height="28"><path d="M9 18l6-6-6-6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/></svg>';
overlay.appendChild(img);
overlay.appendChild(titleEl);
overlay.appendChild(counterEl);
overlay.appendChild(closeBtn);
overlay.appendChild(prevBtn);
overlay.appendChild(nextBtn);
document.body.appendChild(overlay);
closeBtn.onclick = function(e) { e.stopPropagation(); close(); };
prevBtn.onclick = function(e) { e.stopPropagation(); go(-1); };
nextBtn.onclick = function(e) { e.stopPropagation(); go(1); };
overlay.onclick = function(e) { if (e.target === overlay) close(); };
// PC 滚轮缩放
overlay.addEventListener("wheel", function(e) {
if (!current) return;
e.preventDefault();
scale = clamp(scale * (e.deltaY > 0 ? 0.9 : 1.1));
applyTransform();
}, { passive: false });
// PC 双击最大化 / 还原
overlay.addEventListener("dblclick", function(e) {
if (!current) return;
e.preventDefault();
pcToggleZoom();
});
// PC 拖拽
overlay.addEventListener("mousedown", function(e) {
if (!current || scale <= 1.05 || e.button !== 0 || e.target.closest('.baige-lightbox-btn')) return;
dragging = true;
startX = e.clientX - tx;
startY = e.clientY - ty;
e.preventDefault();
});
document.addEventListener("mousemove", function(e) {
if (!dragging) return;
tx = e.clientX - startX;
ty = e.clientY - startY;
applyTransform();
});
document.addEventListener("mouseup", function() { dragging = false; });
// 手机双指缩放 + 单指拖拽
overlay.addEventListener("touchstart", onTouchStart, { passive: false });
overlay.addEventListener("touchmove", onTouchMove, { passive: false });
overlay.addEventListener("touchend", onTouchEnd, { passive: false });
document.addEventListener("keydown", onKey);
}
function clamp(s) { return Math.min(maxScale, Math.max(minScale, s)); }
function applyTransform() {
img.style.transform = "translate(" + tx + "px," + ty + "px) scale(" + scale + ")";
}
// PC 双击:按原始尺寸显示
function pcToggleZoom() {
if (scale > 1.05) {
scale = 1; tx = 0; ty = 0;
} else {
var nw = img.naturalWidth || img.width;
var nh = img.naturalHeight || img.height;
var vw = window.innerWidth * 0.9;
var vh = window.innerHeight * 0.85;
scale = Math.min(nw / vw, nh / vh, maxScale);
if (scale < 1) scale = 1;
tx = 0; ty = 0;
}
applyTransform();
}
function getTouchDist(touches) {
var dx = touches[0].clientX - touches[1].clientX;
var dy = touches[0].clientY - touches[1].clientY;
return Math.sqrt(dx * dx + dy * dy);
}
function onTouchStart(e) {
if (!current) return;
if (e.touches.length === 2) {
isPinching = true;
lastTouchDist = getTouchDist(e.touches);
e.preventDefault();
} else if (e.touches.length === 1) {
var t = e.touches[0];
startX = t.clientX - tx;
startY = t.clientY - ty;
}
}
function onTouchMove(e) {
if (!current) return;
if (e.touches.length === 2) {
e.preventDefault();
var dist = getTouchDist(e.touches);
scale = clamp(scale * (dist / lastTouchDist));
applyTransform();
lastTouchDist = dist;
} else if (e.touches.length === 1 && scale > 1.05) {
e.preventDefault();
var t = e.touches[0];
tx = t.clientX - startX;
ty = t.clientY - startY;
applyTransform();
}
}
function onTouchEnd(e) {
if (!current) return;
if (isPinching && e.touches.length < 2) {
isPinching = false;
return;
}
}
function open(src, group, idx) {
if (!overlay) create();
origOverflow = document.body.style.overflow;
document.body.style.overflow = "hidden";
overlay.style.display = "flex";
img.style.opacity = "0";
img.style.transform = "translate(0px,0px) scale(1)";
scale = 1; tx = 0; ty = 0;
var list = groups[group] && groups[group].length ? groups[group] : [{ src: src, caption: "" }];
current = { group: group, idx: idx || 0, list: list };
img.onload = function() {
img.style.opacity = "1";
showCaption();
updateNav();
};
img.src = src;
if (list.length > 1) {
counterEl.style.display = "block";
counterEl.textContent = (current.idx + 1) + " / " + list.length;
} else {
counterEl.style.display = "none";
}
}
function showCaption() {
if (!current || !current.list) return;
var item = current.list[current.idx];
titleEl.textContent = item.caption || "";
titleEl.style.display = item.caption ? "block" : "none";
}
function updateNav() {
if (!current || !current.list) {
prevBtn.style.display = "none";
nextBtn.style.display = "none";
return;
}
prevBtn.style.display = current.idx > 0 ? "flex" : "none";
nextBtn.style.display = current.idx < current.list.length - 1 ? "flex" : "none";
}
function go(dir) {
if (!current || !current.list) return;
var n = current.idx + dir;
if (n < 0 || n >= current.list.length) return;
current.idx = n;
// 切换动画:先淡出并横向移动
img.style.transition = "opacity .25s ease, transform .25s ease";
img.style.opacity = "0";
img.style.transform = "translate(" + (dir * -60) + "px, 0px) scale(1)";
setTimeout(function() {
scale = 1; tx = 0; ty = 0;
var nextSrc = current.list[n].src;
img.onload = function() {
// 从另一侧滑入并淡入
img.style.transform = "translate(" + (dir * 60) + "px, 0px) scale(1)";
setTimeout(function() {
img.style.transform = "translate(0px, 0px) scale(1)";
img.style.opacity = "1";
showCaption();
updateNav();
counterEl.textContent = (n + 1) + " / " + current.list.length;
// 动画完成后恢复默认 transition
setTimeout(function() { img.style.transition = "opacity .3s"; }, 260);
}, 30);
};
// 先清空再赋值,确保 onload 触发
img.src = "";
setTimeout(function() { img.src = nextSrc; }, 10);
}, 260);
}
function close() {
if (!overlay) return;
overlay.style.display = "none";
img.src = "";
document.body.style.overflow = origOverflow;
current = null;
}
function onKey(e) {
if (!current) return;
if (e.keyCode === 27) close();
if (e.keyCode === 37) go(-1);
if (e.keyCode === 39) go(1);
if (e.keyCode === 48 || e.keyCode === 96) { scale = 1; tx = 0; ty = 0; applyTransform(); }
if (e.keyCode === 107 || e.keyCode === 187) { scale = clamp(scale * 1.2); applyTransform(); }
if (e.keyCode === 109 || e.keyCode === 189) { scale = clamp(scale * 0.8); applyTransform(); }
}
function register() {
document.querySelectorAll("[data-fancybox]").forEach(function(el) {
var src = el.getAttribute("href");
if (!src) return;
var group = el.getAttribute("data-fancybox") || "";
var caption = el.getAttribute("data-caption") || el.getAttribute("title") || "";
if (group === "gallery") group = "";
var item = { src: src, caption: caption };
if (!groups[group]) groups[group] = [];
groups[group].push(item);
el.addEventListener("click", function(e) {
e.preventDefault();
var idx = groups[group].indexOf(item);
open(src, group, idx);
});
});
}
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", register);
} else {
register();
}
}();
评论: 0 | 查看: 26
上一篇
没有了