Widget:Carousel: Difference between revisions
From Makerpedia
No edit summary |
No edit summary |
||
| (15 intermediate revisions by the same user not shown) | |||
| Line 1: | Line 1: | ||
<script> | <script> | ||
function addItem(url,image,title){ | |||
let item = µ('+div',µ('.carousel-container')[0]); | |||
item.className = 'carousel-item'; | |||
item.innerHTML = `<a href="${url}"> | |||
<img src="${image}" alt="Carousel Image"> | |||
</a> | |||
<div class="carousel-title">${title}</div>`; | |||
}; | |||
function loadCarouselData() { | function loadCarouselData() { | ||
// Make the API query to fetch pages for carousel | mw.loader.using(['mediawiki.api', 'jquery']).then(()=>{ | ||
var category = " | // Make the API query to fetch pages for carousel | ||
var category = "<!--{$category|escape:'url'}-->"; | |||
var carouselData = []; | var carouselData = []; | ||
| Line 53: | Line 63: | ||
// Store carousel item data in carouselData array | // Store carousel item data in carouselData array | ||
if (imgUrl) { | if (imgUrl) { | ||
carouselData.push({ pageUrl: pageUrl, imgUrl: imgUrl, title: page.title }); | console.log(page.title); | ||
addItem(pageUrl, imgUrl, page.title); | |||
//carouselData.push({ pageUrl: pageUrl, imgUrl: imgUrl, title: page.title }); | |||
} | } | ||
}); | }); | ||
| Line 59: | Line 71: | ||
// Store carousel item data | // Store carousel item data | ||
if (imgUrl) { | if (imgUrl) { | ||
carouselData.push({ pageUrl: pageUrl, imgUrl: imgUrl, title: page.title }); | //carouselData.push({ pageUrl: pageUrl, imgUrl: imgUrl, title: page.title }); | ||
addItem(pageUrl, imgUrl, page.title); | |||
} | } | ||
} | } | ||
| Line 67: | Line 80: | ||
Promise.all(requests).then(function () { | Promise.all(requests).then(function () { | ||
// Call the function to display carousel | // Call the function to display carousel | ||
displayCarousel(carouselData); | //displayCarousel(carouselData); | ||
//console.log(carouselData); | //console.log(carouselData); | ||
initializeCarousel(); | |||
}); | }); | ||
}); | }); | ||
}); | |||
} | } | ||
| Line 101: | Line 117: | ||
let totalItems = $carouselItems.length; | let totalItems = $carouselItems.length; | ||
$(".carousel-container .loadSpinner").hide(); | |||
$carouselItems.hide().eq(currentIndex).show(); | $carouselItems.hide().eq(currentIndex).show(); | ||
| Line 136: | Line 153: | ||
// Load the carousel data on page load | // Load the carousel data on page load | ||
document.addEventListener('DOMContentLoaded', function (event) { | document.addEventListener('DOMContentLoaded', function (event) { | ||
loadCarouselData | if(!window.widgets) window.widgets = []; | ||
window.widgets.push(loadCarouselData); | |||
}); | }); | ||
//$(document).ready(function () { | //$(document).ready(function () { | ||
| Line 143: | Line 161: | ||
</script> | </script> | ||
<style> | |||
/* CSS styling for carousel on the Homepage */ | |||
.carousel-heading { | |||
text-align: center; | |||
font-size: 20px; | |||
margin-bottom: 5px; | |||
margin-top: 23px; | |||
color: #003366; | |||
} | |||
.carousel-container { | |||
position: relative; | |||
display: block; | |||
width: 75%; | |||
margin: 0 auto; | |||
overflow: hidden; | |||
background-color: #eee; | |||
margin-bottom: 20px; | |||
box-shadow: 5px 5px 5px rgba(0,0,0,0.125) inset, -5px -5px 5px 0px rgba(255,255,255,0.5) inset; | |||
border-radius: 1em; | |||
height: 400px; | |||
} | |||
.carousel-item { | |||
display: flex; | |||
flex-direction: column; | |||
justify-content: center; | |||
align-items: center; | |||
width: 100%; | |||
height: 400px; | |||
box-sizing: border-box; | |||
text-align: center; | |||
} | |||
.carousel-title { | |||
margin-top: 10px; | |||
font-size: 18px; | |||
color: #333; | |||
} | |||
.carousel-item img { | |||
width: 400px; | |||
height: 300px; | |||
max-width: 400px; | |||
max-height: 300px; | |||
object-fit: cover; | |||
transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out; | |||
box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.3); | |||
} | |||
/* Carousel left and right button stylings */ | |||
.carousel-prev, .carousel-next { | |||
position: absolute; | |||
top: 50%; | |||
transform: translateY(-50%); | |||
background-color: var(--cc-white); | |||
color: #777; | |||
border: none; | |||
padding: 10px 15px; | |||
font-size: 20px; | |||
cursor: pointer; | |||
border-radius: 50%; | |||
width: 50px; | |||
height: 50px; | |||
display: flex; | |||
align-items: center; | |||
justify-content: center; | |||
z-index: 20; | |||
box-shadow: 2px 2px 2px rgba(0,0,0,.25),-2px -2px 2px 2px rgba(255,255,255,.25); | |||
} | |||
.carousel-next { | |||
right: 0px; | |||
border-radius: 50% 0 0 50%; | |||
} | |||
.carousel-prev { | |||
left: 0px; | |||
border-radius: 0 50% 50% 0; | |||
} | |||
.carousel-prev:hover, .carousel-next:hover { | |||
background-color: #002244; | |||
} | |||
</style> | |||
<div class="carousel-container"> | <div class="carousel-container"> | ||
<div class="loadSpinner"></div> | |||
<button class="carousel-prev"> ◀︎ </button> | <button class="carousel-prev"> ◀︎ </button> | ||
<button class="carousel-next"> ▶︎︎ </button> | <button class="carousel-next"> ▶︎︎ </button> | ||
</div> | </div> | ||
Latest revision as of 21:43, 20 March 2025
<script> function addItem(url,image,title){
let item = µ('+div',µ('.carousel-container')[0]);
item.className = 'carousel-item';
item.innerHTML = `<a href="${url}">
<img src="${image}" alt="Carousel Image">
</a>
${title}
`;
};
function loadCarouselData() {
mw.loader.using(['mediawiki.api', 'jquery']).then(()=>{
// Make the API query to fetch pages for carousel
var category = "";
var carouselData = [];
new mw.Api().get({
action: 'query',
list: 'categorymembers',
cmtitle: 'Category:' + category,
cmlimit: 50,
format: 'json'
}).done(function (data) {
var pages = data.query.categorymembers;
var requests = pages.map(function (page) {
return new mw.Api().get({
action: 'query',
prop: 'revisions',
rvprop: 'content',
titles: page.title,
format: 'json'
}).then(function (pageData) {
var pageId = Object.keys(pageData.query.pages)[0];
var content = pageData.query.pages[pageId].revisions[0]['*'];
var pageUrl = mw.util.getUrl(page.title);
var imgUrl = ;
// Try to find a direct image URL (img1=https://...). We do this because some images are from widgets.
var directMatch = content.match(/img1=(https:\/\/[^\s|}%]+)/);
if (directMatch) {
imgUrl = directMatch[1];
}
// If no direct URL, try to find a File:... entry. This is how Media Wiki embeds images.
var fileMatch = content.match(/\[\[File:([^|\]]+)/);
if (!imgUrl && fileMatch) {
var fileName = fileMatch[1].trim();
// Fetch full image URL from MediaWiki API
return new mw.Api().get({
action: 'query',
titles: 'File:' + fileName,
prop: 'imageinfo',
iiprop: 'url',
format: 'json'
}).then(function (imageData) {
var imagePageId = Object.keys(imageData.query.pages)[0];
if (imageData.query.pages[imagePageId].imageinfo) {
imgUrl = imageData.query.pages[imagePageId].imageinfo[0].url;
}
// Store carousel item data in carouselData array
if (imgUrl) {
console.log(page.title);
addItem(pageUrl, imgUrl, page.title);
//carouselData.push({ pageUrl: pageUrl, imgUrl: imgUrl, title: page.title });
}
});
} else {
// Store carousel item data
if (imgUrl) {
//carouselData.push({ pageUrl: pageUrl, imgUrl: imgUrl, title: page.title });
addItem(pageUrl, imgUrl, page.title);
}
}
});
});
Promise.all(requests).then(function () {
// Call the function to display carousel
//displayCarousel(carouselData);
//console.log(carouselData);
initializeCarousel();
});
});
});
}
// Creates the raw HTML to be injected into the Homepage, in the carousel container div. function displayCarousel(carouselData) {
var carouselHtml = ;
carouselData.forEach(function (item) {
carouselHtml += `
<a href="${item.pageUrl}">
<img src="${item.imgUrl}" alt="Carousel Image">
</a>
${item.title}
`; });
// Inject the HTML into the carousel container
var carouselContainer = $('.carousel-container');
carouselContainer.html(carouselHtml);
// Initialize the carousel behavior initializeCarousel();
}
function initializeCarousel() {
let currentIndex = 0;
let $carouselItems = $(".carousel-item");
let totalItems = $carouselItems.length;
$(".carousel-container .loadSpinner").hide();
$carouselItems.hide().eq(currentIndex).show();
let $prevButton = $(".carousel-prev");
let $nextButton = $(".carousel-next");
function nextSlide() {
currentIndex = (currentIndex + 1) % totalItems;
updateCarousel();
}
// Auto slide every 10 seconds
let autoSlide = setInterval(nextSlide, 10000);
function resetInterval() {
clearInterval(autoSlide);
autoSlide = setInterval(nextSlide, 10000);
}
$nextButton.click(function () {
nextSlide();
resetInterval();
});
$prevButton.click(function () {
currentIndex = (currentIndex - 1 + totalItems) % totalItems;
updateCarousel();
resetInterval();
});
function updateCarousel () {
$carouselItems.hide().eq(currentIndex).show();
}
}
// Load the carousel data on page load document.addEventListener('DOMContentLoaded', function (event) {
if(!window.widgets) window.widgets = []; window.widgets.push(loadCarouselData);
}); //$(document).ready(function () { // loadCarouselData(); //});
</script> <style>
/* CSS styling for carousel on the Homepage */
.carousel-heading {
text-align: center; font-size: 20px; margin-bottom: 5px; margin-top: 23px; color: #003366;
} .carousel-container {
position: relative; display: block; width: 75%; margin: 0 auto; overflow: hidden; background-color: #eee; margin-bottom: 20px; box-shadow: 5px 5px 5px rgba(0,0,0,0.125) inset, -5px -5px 5px 0px rgba(255,255,255,0.5) inset; border-radius: 1em; height: 400px;
}
.carousel-item {
display: flex; flex-direction: column; justify-content: center; align-items: center; width: 100%; height: 400px; box-sizing: border-box; text-align: center;
}
.carousel-title {
margin-top: 10px; font-size: 18px; color: #333;
}
.carousel-item img {
width: 400px; height: 300px; max-width: 400px; max-height: 300px; object-fit: cover; transition: transform 0.3s ease-in-out, box-shadow 0.3s ease-in-out; box-shadow: 0px 4px 15px rgba(0, 0, 0, 0.3);
}
/* Carousel left and right button stylings */ .carousel-prev, .carousel-next {
position: absolute; top: 50%; transform: translateY(-50%); background-color: var(--cc-white); color: #777; border: none; padding: 10px 15px; font-size: 20px; cursor: pointer; border-radius: 50%; width: 50px; height: 50px; display: flex; align-items: center; justify-content: center; z-index: 20; box-shadow: 2px 2px 2px rgba(0,0,0,.25),-2px -2px 2px 2px rgba(255,255,255,.25);
}
.carousel-next {
right: 0px; border-radius: 50% 0 0 50%;
}
.carousel-prev {
left: 0px; border-radius: 0 50% 50% 0;
}
.carousel-prev:hover, .carousel-next:hover {
background-color: #002244;
} </style>
<button class="carousel-prev"> ◀︎ </button> <button class="carousel-next"> ▶︎︎ </button>