add a nice progress bar

This commit is contained in:
2024-02-21 10:20:24 +01:00
parent 0646463a6a
commit 7d31449543
3 changed files with 51 additions and 12 deletions
+32 -5
View File
@@ -7,6 +7,7 @@
--width: 800px; --width: 800px;
--height: 600px; --height: 600px;
--scale: 1.0; --scale: 1.0;
--slide-duration: 10s;
} }
@font-face { @font-face {
@@ -159,16 +160,21 @@ button.slide-button.next {
} }
.slide .description { .slide .description {
position: relative; position: relative;
padding: 1rem 8rem; padding: 0.5rem 8rem 1rem;
height: calc(var(--height) / 4); height: calc(var(--height) / 4);
background-color: white; background-color: white;
overflow: auto; overflow: auto;
display: flex;
flex-direction: column;
justify-content: center;
} }
.slide .description h1, .slide .description h1,
.slide .description p { .slide .description p {
margin: 0.5rem 0; margin: 0 0 0.5rem 0;
}
.slide .description p:last-child {
margin-bottom: 0;
} }
.slide .description h1 { .slide .description h1 {
@@ -180,6 +186,27 @@ button.slide-button.next {
margin-top: 0; margin-top: 0;
} }
.slide .description p:last-of-type { .slide .description code {
margin-bottom: 0; background-color: var(--medium-grey);
padding: 0.15rem 0.5rem;
color: white;
}
.progressBar {
position: fixed;
height: .333rem;
width: 0%;
background-color: #ccc;
mix-blend-mode: multiply;
/* opacity: 0.5; */
bottom: 0px;
transition: width;
transition-duration: 0s;
transition-timing-function: linear;
}
.progressBar.playing {
width: 100%;
transition-duration: var(--slide-duration);
} }
+1 -1
View File
@@ -53,7 +53,7 @@
<script src="js/Slider.js"></script> <script src="js/Slider.js"></script>
<script> <script>
var slider = new Slider("#slider", "#slide-template", slides, 8000); var slider = new Slider("#slider", "#slide-template", slides, 10000);
</script> </script>
</body> </body>
+18 -6
View File
@@ -5,6 +5,7 @@ class Slider {
data; data;
element; element;
progressBar;
template; template;
slides = []; slides = [];
activeSlide = 0; activeSlide = 0;
@@ -66,18 +67,26 @@ class Slider {
this.slides.push(slideNode); this.slides.push(slideNode);
} }
// append progress bar
let progressBar = document.createElement("div");
progressBar.classList.add("progressBar");
this.progressBar = this.element.appendChild(progressBar);
document.querySelector(":root").style.setProperty("--slide-duration", this.slideDuration / 1000 + "s");
// observe scroll position // observe scroll position
this.element.onscroll = e => this.onScroll(e); this.element.onscroll = e => this.onScroll(e);
// start auto play // start auto play
this.start(); this.startTimeout();
} }
onScroll(e) { onScroll(e) {
let newSlide = Math.round(e.target.scrollLeft / 800); let newSlide = Math.round(e.target.scrollLeft / 800);
if(this.activeSlide != newSlide) { if (this.activeSlide != newSlide) {
this.handleVideoPlayback(this.activeSlide, newSlide); this.handleVideoPlayback(this.activeSlide, newSlide);
this.activeSlide = newSlide; this.activeSlide = newSlide;
this.startTimeout();
} }
} }
@@ -88,7 +97,6 @@ class Slider {
this.handleVideoPlayback(this.activeSlide, targetSlide); this.handleVideoPlayback(this.activeSlide, targetSlide);
this.start();
} }
handleVideoPlayback(oldSlideIndex, newSlideIndex) { handleVideoPlayback(oldSlideIndex, newSlideIndex) {
@@ -112,13 +120,17 @@ class Slider {
this.element.scrollTo(targetSlide * 800, 0); this.element.scrollTo(targetSlide * 800, 0);
this.handleVideoPlayback(this.activeSlide, targetSlide); this.handleVideoPlayback(this.activeSlide, targetSlide);
this.start();
} }
start(timeout = this.slideDuration) { startTimeout(timeout = this.slideDuration) {
clearTimeout(this.slideTimeout); clearTimeout(this.slideTimeout);
this.slideTimeout = setTimeout(() => { this.next(); }, timeout); this.slideTimeout = setTimeout(() => { this.next(); }, timeout);
// restart progress animation
// https://css-tricks.com/restart-css-animation/
this.progressBar.classList.remove("playing");
void this.progressBar.offsetWidth;
this.progressBar.classList.add("playing");
} }
getType(slideIndex) { getType(slideIndex) {