Skip to content

Commit

Permalink
home: add carousel for banners
Browse files Browse the repository at this point in the history
  • Loading branch information
paulolieuthier committed Sep 18, 2021
1 parent bea5682 commit 27e46fa
Show file tree
Hide file tree
Showing 2 changed files with 136 additions and 22 deletions.
121 changes: 121 additions & 0 deletions theme/src/components/Carousel.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<template>
<div id="wrapper">
<div id="slides" ref="slides">
<slot />
</div>
<div id="pagination" ref="pagination" />
</div>
</template>

<script>
import { ref } from 'vue'
export default {
setup() {
return {
index: null,
timer: null,
slides: ref(null),
pagination: ref(null),
}
},
mounted() {
const slides = this.$refs.slides.children
if (slides.length) {
this.setupPagination()
this.changeSlide(0)
const options = { passive: true }
this.$refs.slides.addEventListener('mouseenter', this.stopTimer, options)
this.$refs.slides.addEventListener('mouseleave', this.restartTimer, options)
}
},
methods: {
setupPagination() {
const slides = this.$refs.slides.children.length
for (let i = 0; i < slides; ++i) {
const button = document.createElement('button')
button.addEventListener('click', () => this.changeSlide(i))
this.$refs.pagination.appendChild(button)
}
},
changeSlide(index) {
this.stopTimer()
this.$refs.slides.querySelector('.active')?.classList.remove('active')
const slides = this.$refs.slides.children
slides[index].classList.add('active')
this.startTimer(index)
},
startTimer(index) {
const nextSlideIndex = this.nextSlideIndex(index)
this.timer = setTimeout(() => {
this.index = nextSlideIndex
this.changeSlide(nextSlideIndex)
}, 4000)
},
nextSlideIndex(index) {
const slides = this.$refs.slides.children.length
return index < slides - 1 ? index + 1 : 0
},
stopTimer() {
if (this.timer)
clearTimeout(this.timer)
},
restartTimer() {
if (this.index !== null)
this.startTimer(this.index)
},
}
}
</script>
<style scoped lang="stylus">
#wrapper
height 100%
position relative
width 100%
#slides
display grid
height 100%
#slides > ::v-slotted(*)
display block
grid-column 1
grid-row 1
height 100%
width 100%
#slides > ::v-slotted(*)
opacity 0
#slides > ::v-slotted(*).active
animation fadein .5s linear 1 forwards
@keyframes fadein
0% { opacity: 0; }
100% { opacity: 1; }
#pagination
bottom 0
display block
position absolute
text-align center
width 100%
#pagination:deep(button)
border 0
border-radius 15px
box-shadow 0 0 5px #888
cursor pointer
height 15px
margin 10px 5px
opacity 0.9
width 15px
#pagination:deep(button:hover)
opacity 1
#pagination:deep(button:active)
transform scale(1.1)
</style>
37 changes: 15 additions & 22 deletions theme/src/components/Home.vue
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,9 @@
</Section>

<Section id="banners" class="fill gray borderless">
<div id="images">
<template v-for="banner in data.banners">
<a :href="banner.uri" class="image" :style="`background-image: url('${banner.image}')`" />
</template>
</div>
<Carousel>
<a v-for="banner in data.banners" class="banner" :href="banner.uri" :style="`background-image: url('${banner.image}')`" />
</Carousel>
</Section>

<Section id="intro" class="alternate spacing center">
Expand Down Expand Up @@ -171,6 +169,7 @@
import MenuHorizontal from './MenuHorizontal.vue'
import MenuCollapsible from './MenuCollapsible.vue'
import Section from './Section.vue'
import Carousel from './Carousel.vue'
import Button from './Button.vue'
import { ref } from 'vue'
Expand All @@ -179,6 +178,7 @@ import Querier from '../querier.js'
export default {
components: {
Section,
Carousel,
Button,
MenuHorizontal,
MenuCollapsible,
Expand All @@ -202,11 +202,13 @@ export default {
watch: {
loading(isLoading) {
if (!isLoading) {
// trigger scroll to correct section
// can't make it work without a timer
this.$nextTick(() => setTimeout(() => this.$refs[window.location.hash.slice(1)]?.scrollIntoView(), 400))
this.$nextTick(() => {
// trigger scroll to correct section
// can't make it work without a timer
setTimeout(() => this.$refs[window.location.hash.slice(1)]?.scrollIntoView(), 400)
window.addEventListener('scroll', this.updateMenu)
window.addEventListener('scroll', this.updateMenu)
})
}
}
},
Expand Down Expand Up @@ -302,7 +304,6 @@ Section#header
padding-left 20px
h1
/* font-size calc(13px + (25 - 13) * ((100vw - 360px) / (1920 - 360))) */
font-size @css{min(26px, max(16px, 2vw))}
margin 0
padding 0
Expand Down Expand Up @@ -343,19 +344,11 @@ Section#header
white-space normal
Section#banners
#images
display grid
height 40vh
width 100%
height 300px
.image
background-position center center
background-repeat no-repeat
background-size cover
grid-column 1
grid-row 1
height 100%
width 100%
.banner
background-position center center
background-size cover
Section#intro
#items
Expand Down

0 comments on commit 27e46fa

Please sign in to comment.