MediaWiki:Common.js: Unterschied zwischen den Versionen
Aus LNTwww
Lightbox: add zoom and download |
Remove JS navbar link, using native LangLinks Markierung: Manuelle Zurücksetzung |
||
| (4 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
| Zeile 10: | Zeile 10: | ||
var overlay = document.createElement('div'); | var overlay = document.createElement('div'); | ||
overlay.id = 'img-lightbox'; | overlay.id = 'img-lightbox'; | ||
overlay.style.cssText = 'display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.85);z-index:10000 | overlay.style.cssText = 'display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.85);z-index:10000;flex-direction:column;'; | ||
var | // Scrollable area that fills the screen | ||
var scrollArea = document.createElement('div'); | |||
scrollArea.style.cssText = 'flex:1;overflow:auto;display:flex;justify-content:center;align-items:center;padding:20px;'; | |||
var img = document.createElement('img'); | var img = document.createElement('img'); | ||
img.style.cssText = ' | img.style.cssText = 'border-radius:4px;box-shadow:0 4px 30px rgba(0,0,0,0.5);transition:max-width 0.2s,max-height 0.2s;'; | ||
scrollArea.appendChild(img); | |||
overlay.appendChild( | overlay.appendChild(scrollArea); | ||
// Toolbar | // Toolbar | ||
var toolbar = document.createElement('div'); | var toolbar = document.createElement('div'); | ||
toolbar.style.cssText = 'display:flex;gap:12px;padding:10px;align-items:center;'; | toolbar.style.cssText = 'display:flex;gap:12px;padding:10px;align-items:center;justify-content:center;flex-shrink:0;'; | ||
var btnStyle = 'background:rgba(255,255,255,0.15);color:white;border:none;padding:6px 14px;border-radius:4px;cursor:pointer;font-size:14px;'; | var btnStyle = 'background:rgba(255,255,255,0.15);color:white;border:none;padding:6px 14px;border-radius:4px;cursor:pointer;font-size:14px;'; | ||
| Zeile 34: | Zeile 35: | ||
zoomReset.innerHTML = '↺ Reset'; | zoomReset.innerHTML = '↺ Reset'; | ||
zoomReset.style.cssText = btnStyle; | zoomReset.style.cssText = btnStyle; | ||
var zoomLabel = document.createElement('span'); | |||
zoomLabel.style.cssText = 'color:rgba(255,255,255,0.6);font-size:13px;min-width:45px;text-align:center;'; | |||
var download = document.createElement('a'); | var download = document.createElement('a'); | ||
download.innerHTML = '⬇ Download'; | download.innerHTML = '⬇ Download'; | ||
| Zeile 42: | Zeile 45: | ||
closeBtn.style.cssText = btnStyle; | closeBtn.style.cssText = btnStyle; | ||
toolbar.appendChild(zoomOut); | |||
toolbar.appendChild(zoomLabel); | |||
toolbar.appendChild(zoomIn); | toolbar.appendChild(zoomIn); | ||
toolbar.appendChild(zoomReset); | toolbar.appendChild(zoomReset); | ||
toolbar.appendChild(download); | toolbar.appendChild(download); | ||
| Zeile 51: | Zeile 55: | ||
var scale = 1; | var scale = 1; | ||
var natW = 0, natH = 0; | |||
function setZoom(s) { | function setZoom(s) { | ||
scale = Math.max(0. | scale = Math.max(0.1, Math.min(s, 10)); | ||
img.style. | zoomLabel.textContent = Math.round(scale * 100) + '%'; | ||
// Set image size directly — no CSS transform, so it actually takes up space | |||
img.style.width = Math.round(natW * scale) + 'px'; | |||
img.style.height = 'auto'; | |||
img.style.maxWidth = 'none'; | |||
img.style.maxHeight = 'none'; | |||
// If image is smaller than viewport, center it; otherwise scroll | |||
if (img.offsetWidth < scrollArea.clientWidth && img.offsetHeight < scrollArea.clientHeight) { | |||
scrollArea.style.alignItems = 'center'; | |||
scrollArea.style.justifyContent = 'center'; | |||
} else { | } else { | ||
scrollArea.style.alignItems = 'flex-start'; | |||
scrollArea.style.justifyContent = 'flex-start'; | |||
} | } | ||
} | |||
function fitToScreen() { | |||
// Calculate scale that fits the image in the viewport | |||
var maxW = scrollArea.clientWidth - 40; | |||
var maxH = scrollArea.clientHeight - 40; | |||
scale = Math.min(1, maxW / natW, maxH / natH); | |||
setZoom(scale); | |||
} | } | ||
zoomIn.addEventListener('click', function(e) { e.stopPropagation(); setZoom(scale * 1.4); }); | zoomIn.addEventListener('click', function(e) { e.stopPropagation(); setZoom(scale * 1.4); }); | ||
zoomOut.addEventListener('click', function(e) { e.stopPropagation(); setZoom(scale / 1.4); }); | zoomOut.addEventListener('click', function(e) { e.stopPropagation(); setZoom(scale / 1.4); }); | ||
zoomReset.addEventListener('click', function(e) { e.stopPropagation(); | zoomReset.addEventListener('click', function(e) { e.stopPropagation(); fitToScreen(); }); | ||
closeBtn.addEventListener('click', function() { overlay.style.display = 'none'; }); | closeBtn.addEventListener('click', function() { overlay.style.display = 'none'; }); | ||
scrollArea.addEventListener('click', function(e) { | |||
if (e.target === scrollArea) overlay.style.display = 'none'; | |||
if (e.target === | |||
}); | }); | ||
// | // Scroll wheel zoom | ||
scrollArea.addEventListener('wheel', function(e) { | |||
e.preventDefault(); | e.preventDefault(); | ||
setZoom(scale * (e.deltaY < 0 ? 1.15 : 0.87)); | setZoom(scale * (e.deltaY < 0 ? 1.15 : 0.87)); | ||
| Zeile 88: | Zeile 104: | ||
if (e.key === '+' || e.key === '=') setZoom(scale * 1.3); | if (e.key === '+' || e.key === '=') setZoom(scale * 1.3); | ||
if (e.key === '-') setZoom(scale / 1.3); | if (e.key === '-') setZoom(scale / 1.3); | ||
if (e.key === '0') | if (e.key === '0') fitToScreen(); | ||
}); | }); | ||
| Zeile 109: | Zeile 125: | ||
} | } | ||
download.href = fullSrc; | download.href = fullSrc; | ||
download.download = fullSrc.split('/').pop(); | download.download = fullSrc.split('/').pop(); | ||
img. | // Load image to get natural dimensions, then fit | ||
img.onload = function() { | |||
natW = img.naturalWidth; | |||
natH = img.naturalHeight; | |||
fitToScreen(); | |||
}; | |||
img.src = fullSrc; | |||
overlay.style.display = 'flex'; | overlay.style.display = 'flex'; | ||
}); | }); | ||
})(); | })(); | ||
/* Fix collapse arrow: add "collapsed" class to links targeting closed panels */ | |||
document.addEventListener('DOMContentLoaded', function() { | |||
document.querySelectorAll('.panel-title > a[data-toggle="collapse"]').forEach(function(a) { | |||
var target = document.querySelector(a.getAttribute('href')); | |||
if (target && !target.classList.contains('show')) { | |||
a.classList.add('collapsed'); | |||
} | |||
}); | |||
}); | |||
Aktuelle Version vom 16. März 2026, 14:16 Uhr
/* Das folgende JavaScript wird für alle Benutzer geladen. */
$('body').scrollspy({
target: '.bs-docs-sidebar',
offset: 40
});
/* Simple image lightbox with zoom and download */
(function() {
var overlay = document.createElement('div');
overlay.id = 'img-lightbox';
overlay.style.cssText = 'display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.85);z-index:10000;flex-direction:column;';
// Scrollable area that fills the screen
var scrollArea = document.createElement('div');
scrollArea.style.cssText = 'flex:1;overflow:auto;display:flex;justify-content:center;align-items:center;padding:20px;';
var img = document.createElement('img');
img.style.cssText = 'border-radius:4px;box-shadow:0 4px 30px rgba(0,0,0,0.5);transition:max-width 0.2s,max-height 0.2s;';
scrollArea.appendChild(img);
overlay.appendChild(scrollArea);
// Toolbar
var toolbar = document.createElement('div');
toolbar.style.cssText = 'display:flex;gap:12px;padding:10px;align-items:center;justify-content:center;flex-shrink:0;';
var btnStyle = 'background:rgba(255,255,255,0.15);color:white;border:none;padding:6px 14px;border-radius:4px;cursor:pointer;font-size:14px;';
var zoomIn = document.createElement('button');
zoomIn.innerHTML = '🔍+ Zoom in';
zoomIn.style.cssText = btnStyle;
var zoomOut = document.createElement('button');
zoomOut.innerHTML = '🔍− Zoom out';
zoomOut.style.cssText = btnStyle;
var zoomReset = document.createElement('button');
zoomReset.innerHTML = '↺ Reset';
zoomReset.style.cssText = btnStyle;
var zoomLabel = document.createElement('span');
zoomLabel.style.cssText = 'color:rgba(255,255,255,0.6);font-size:13px;min-width:45px;text-align:center;';
var download = document.createElement('a');
download.innerHTML = '⬇ Download';
download.style.cssText = btnStyle + 'text-decoration:none;display:inline-block;';
download.download = '';
var closeBtn = document.createElement('button');
closeBtn.innerHTML = '✕ Close';
closeBtn.style.cssText = btnStyle;
toolbar.appendChild(zoomOut);
toolbar.appendChild(zoomLabel);
toolbar.appendChild(zoomIn);
toolbar.appendChild(zoomReset);
toolbar.appendChild(download);
toolbar.appendChild(closeBtn);
overlay.appendChild(toolbar);
document.body.appendChild(overlay);
var scale = 1;
var natW = 0, natH = 0;
function setZoom(s) {
scale = Math.max(0.1, Math.min(s, 10));
zoomLabel.textContent = Math.round(scale * 100) + '%';
// Set image size directly — no CSS transform, so it actually takes up space
img.style.width = Math.round(natW * scale) + 'px';
img.style.height = 'auto';
img.style.maxWidth = 'none';
img.style.maxHeight = 'none';
// If image is smaller than viewport, center it; otherwise scroll
if (img.offsetWidth < scrollArea.clientWidth && img.offsetHeight < scrollArea.clientHeight) {
scrollArea.style.alignItems = 'center';
scrollArea.style.justifyContent = 'center';
} else {
scrollArea.style.alignItems = 'flex-start';
scrollArea.style.justifyContent = 'flex-start';
}
}
function fitToScreen() {
// Calculate scale that fits the image in the viewport
var maxW = scrollArea.clientWidth - 40;
var maxH = scrollArea.clientHeight - 40;
scale = Math.min(1, maxW / natW, maxH / natH);
setZoom(scale);
}
zoomIn.addEventListener('click', function(e) { e.stopPropagation(); setZoom(scale * 1.4); });
zoomOut.addEventListener('click', function(e) { e.stopPropagation(); setZoom(scale / 1.4); });
zoomReset.addEventListener('click', function(e) { e.stopPropagation(); fitToScreen(); });
closeBtn.addEventListener('click', function() { overlay.style.display = 'none'; });
scrollArea.addEventListener('click', function(e) {
if (e.target === scrollArea) overlay.style.display = 'none';
});
// Scroll wheel zoom
scrollArea.addEventListener('wheel', function(e) {
e.preventDefault();
setZoom(scale * (e.deltaY < 0 ? 1.15 : 0.87));
}, { passive: false });
// Keyboard
document.addEventListener('keydown', function(e) {
if (overlay.style.display !== 'flex') return;
if (e.key === 'Escape') overlay.style.display = 'none';
if (e.key === '+' || e.key === '=') setZoom(scale * 1.3);
if (e.key === '-') setZoom(scale / 1.3);
if (e.key === '0') fitToScreen();
});
// Intercept image clicks
document.addEventListener('click', function(e) {
var link = e.target.closest('.image, a.mw-file-description');
if (!link) return;
var thumb = link.querySelector('img');
if (!thumb) return;
e.preventDefault();
e.stopPropagation();
var thumbSrc = thumb.getAttribute('src') || '';
var fullSrc;
if (thumbSrc.indexOf('/thumb/') !== -1) {
fullSrc = thumbSrc.replace('/thumb/', '/').replace(/\/[^\/]+$/, '');
} else {
fullSrc = thumbSrc;
}
download.href = fullSrc;
download.download = fullSrc.split('/').pop();
// Load image to get natural dimensions, then fit
img.onload = function() {
natW = img.naturalWidth;
natH = img.naturalHeight;
fitToScreen();
};
img.src = fullSrc;
overlay.style.display = 'flex';
});
})();
/* Fix collapse arrow: add "collapsed" class to links targeting closed panels */
document.addEventListener('DOMContentLoaded', function() {
document.querySelectorAll('.panel-title > a[data-toggle="collapse"]').forEach(function(a) {
var target = document.querySelector(a.getAttribute('href'));
if (target && !target.classList.contains('show')) {
a.classList.add('collapsed');
}
});
});