Widget:SlidingGallerySewing: Difference between revisions
No edit summary |
No edit summary Tag: Reverted |
||
| Line 113: | Line 113: | ||
</div> | </div> | ||
</div> | </div> | ||
<style> | |||
/* Override the animation block to let JavaScript control the width and loop */ | |||
.wrapper { | |||
width: max-content !important; | |||
animation: none !important; | |||
} | |||
</style> | |||
<script> | |||
(function() { | |||
// Find the scrolling row | |||
var track = document.querySelector('.wrapper'); | |||
if (!track) return; | |||
// 1. Grab all your unique items | |||
var originalItems = Array.prototype.slice.call(track.getElementsByClassName('gallery-item')); | |||
if (originalItems.length === 0) return; | |||
// 2. Automatically compute widths (Item width: 160px + Gap: 20px = 180px) | |||
var itemWidth = originalItems[0].offsetWidth || 160; | |||
var gapValue = 20; | |||
var fullStepWidth = itemWidth + gapValue; | |||
var totalOriginalWidth = originalItems.length * fullStepWidth; | |||
// 3. Smart Looper: Clone just enough items to fill the viewable viewport width (742px) | |||
var clonesNeeded = Math.ceil(742 / fullStepWidth) + 1; | |||
for (var i = 0; i < clonesNeeded; i++) { | |||
var cloneIndex = i % originalItems.length; | |||
var clonedNode = originalItems[cloneIndex].cloneNode(true); | |||
track.appendChild(clonedNode); | |||
} | |||
// 4. Dynamically generate and inject the looping keyframes cleanly into the browser head | |||
var styleSheet = document.createElement("style"); | |||
styleSheet.type = "text/css"; | |||
styleSheet.innerText = | |||
"@keyframes dynamicCredits {" + | |||
" 0% { transform: translateX(0); }" + | |||
" 100% { transform: translateX(-" + totalOriginalWidth + "px); }" + | |||
"}\n" + | |||
".wrapper { animation: 45s dynamicCredits linear infinite !important; }"; | |||
document.head.appendChild(styleSheet); | |||
})(); | |||
</script> | |||
Revision as of 22:44, 15 October 2026
<style> /* Layout containers matching your original specifications */ .gallery-outer { position: relative; height: 100%; margin: 20px 0; } .gallery-bg { position: relative; margin: 0 -1em; padding: 0; background-color: transparent; border: 1px none #ddd; height: 100%; } .gallery-viewport { position: relative; margin: 0 auto; width: 742px; height: 300px; overflow: hidden; }
/* Sliding engine (Pure CSS - Starts automatically) */ .wrapper {
position: absolute; top: 0; left: 0; display: flex; gap: 20px; width: 300px; /* Generous width for the moving track */ animation: 45s credits linear infinite;
}
/* ⏸️ PAUSE ANIMATION ON HOVER */ .wrapper:hover {
animation-play-state: paused;
}
.gallery-item {
display: inline-block; text-align: center; width: 160px; flex-shrink: 0;
}
.gallery-item img {
width: 120px; height: 180px; object-fit: contain; transition: transform 0.3s ease;
}
/* 🔍 ENLARGE IMAGE ON HOVER */ .gallery-item img:hover {
transform: scale(1.15); cursor: pointer;
}
.gallery-caption {
font-size: 0.85em; color: #333; margin-top: 8px; line-height: 1.3;
}
@keyframes credits {
0% { transform: translateX(0); }
100% { transform: translateX(-1620px); } /* Perfect loop reset point based on total item widths */
} </style>
<style> /* Override the animation block to let JavaScript control the width and loop */ .wrapper {
width: max-content !important; animation: none !important;
} </style>
<script> (function() {
// Find the scrolling row
var track = document.querySelector('.wrapper');
if (!track) return;
// 1. Grab all your unique items
var originalItems = Array.prototype.slice.call(track.getElementsByClassName('gallery-item'));
if (originalItems.length === 0) return;
// 2. Automatically compute widths (Item width: 160px + Gap: 20px = 180px) var itemWidth = originalItems[0].offsetWidth || 160; var gapValue = 20; var fullStepWidth = itemWidth + gapValue; var totalOriginalWidth = originalItems.length * fullStepWidth;
// 3. Smart Looper: Clone just enough items to fill the viewable viewport width (742px) var clonesNeeded = Math.ceil(742 / fullStepWidth) + 1;
for (var i = 0; i < clonesNeeded; i++) {
var cloneIndex = i % originalItems.length;
var clonedNode = originalItems[cloneIndex].cloneNode(true);
track.appendChild(clonedNode);
}
// 4. Dynamically generate and inject the looping keyframes cleanly into the browser head
var styleSheet = document.createElement("style");
styleSheet.type = "text/css";
styleSheet.innerText =
"@keyframes dynamicCredits {" +
" 0% { transform: translateX(0); }" +
" 100% { transform: translateX(-" + totalOriginalWidth + "px); }" +
"}\n" +
".wrapper { animation: 45s dynamicCredits linear infinite !important; }";
document.head.appendChild(styleSheet);
})(); </script>