Add image carousel functionality with dynamic slideshow and navigation controls
This commit is contained in:
1 parent
cbd65c272f
commit
8c6e2994d7
2 files changed
+185
-2
No files matched your search
@@ -348,11 +348,11 @@
|
||||
var pre = code.parentNode;
|
||||
var raw = code.textContent;
|
||||
|
||||
// Split on [Tab Name] header lines
|
||||
// Split on "=== Tab Name" header lines (avoids Parsedown link-ref conflicts)
|
||||
var tabs = [];
|
||||
var current = null;
|
||||
raw.split('\n').forEach(function (line) {
|
||||
var m = line.match(/^\[(.+)\]\s*$/);
|
||||
var m = line.match(/^===\s+(.+?)\s*$/);
|
||||
if (m) {
|
||||
current = { name: m[1], lines: [] };
|
||||
tabs.push(current);
|
||||
@@ -414,6 +414,99 @@
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- Image carousel: transforms ```carousel fences into a slideshow -->
|
||||
<script>
|
||||
(function () {
|
||||
var blocks = document.querySelectorAll('pre > code.language-carousel');
|
||||
Array.prototype.forEach.call(blocks, function (code) {
|
||||
var pre = code.parentNode;
|
||||
|
||||
// Each non-empty line: "url" or "url | caption"
|
||||
var slides = [];
|
||||
code.textContent.split('\n').forEach(function (line) {
|
||||
line = line.trim();
|
||||
if (!line) return;
|
||||
var parts = line.split('|');
|
||||
slides.push({ url: parts[0].trim(), caption: (parts[1] || '').trim() });
|
||||
});
|
||||
if (!slides.length) return;
|
||||
|
||||
var car = document.createElement('div');
|
||||
car.className = 'carousel';
|
||||
|
||||
var track = document.createElement('div');
|
||||
track.className = 'carousel-track';
|
||||
car.appendChild(track);
|
||||
|
||||
var slideEls = [];
|
||||
var dotEls = [];
|
||||
var current = 0;
|
||||
|
||||
slides.forEach(function (s, i) {
|
||||
var slide = document.createElement('div');
|
||||
slide.className = 'carousel-slide' + (i === 0 ? ' is-active' : '');
|
||||
var img = document.createElement('img');
|
||||
img.src = s.url;
|
||||
img.alt = s.caption;
|
||||
img.loading = 'lazy';
|
||||
slide.appendChild(img);
|
||||
if (s.caption) {
|
||||
var cap = document.createElement('p');
|
||||
cap.className = 'carousel-caption';
|
||||
cap.textContent = s.caption;
|
||||
slide.appendChild(cap);
|
||||
}
|
||||
track.appendChild(slide);
|
||||
slideEls.push(slide);
|
||||
});
|
||||
|
||||
function goTo(idx) {
|
||||
slideEls[current].classList.remove('is-active');
|
||||
if (dotEls[current]) dotEls[current].classList.remove('is-active');
|
||||
current = (idx + slides.length) % slides.length;
|
||||
slideEls[current].classList.add('is-active');
|
||||
if (dotEls[current]) dotEls[current].classList.add('is-active');
|
||||
}
|
||||
|
||||
if (slides.length > 1) {
|
||||
var prev = document.createElement('button');
|
||||
prev.type = 'button'; prev.className = 'carousel-arrow carousel-prev';
|
||||
prev.innerHTML = '‹';
|
||||
prev.addEventListener('click', function () { goTo(current - 1); });
|
||||
car.appendChild(prev);
|
||||
|
||||
var next = document.createElement('button');
|
||||
next.type = 'button'; next.className = 'carousel-arrow carousel-next';
|
||||
next.innerHTML = '›';
|
||||
next.addEventListener('click', function () { goTo(current + 1); });
|
||||
car.appendChild(next);
|
||||
|
||||
var dots = document.createElement('div');
|
||||
dots.className = 'carousel-dots';
|
||||
slides.forEach(function (_, i) {
|
||||
var dot = document.createElement('button');
|
||||
dot.type = 'button';
|
||||
dot.className = 'carousel-dot' + (i === 0 ? ' is-active' : '');
|
||||
dot.addEventListener('click', function () { goTo(i); });
|
||||
dots.appendChild(dot);
|
||||
dotEls.push(dot);
|
||||
});
|
||||
car.appendChild(dots);
|
||||
|
||||
// Swipe support
|
||||
var startX = 0;
|
||||
track.addEventListener('touchstart', function (e) { startX = e.touches[0].clientX; }, { passive: true });
|
||||
track.addEventListener('touchend', function (e) {
|
||||
var dx = e.changedTouches[0].clientX - startX;
|
||||
if (Math.abs(dx) > 40) goTo(dx < 0 ? current + 1 : current - 1);
|
||||
}, { passive: true });
|
||||
}
|
||||
|
||||
pre.parentNode.replaceChild(car, pre);
|
||||
});
|
||||
})();
|
||||
</script>
|
||||
|
||||
<!-- Lightbox: click any article image to zoom -->
|
||||
<script>
|
||||
(function () {
|
||||
|
||||
Reference in new issue
Block a user