Carousel: Use the counter as a component

- Add animation when changing photos
- Reusable and scalable to more than XX photos
This commit is contained in:
2020-03-10 21:22:53 +01:00
parent a60a67a892
commit cc0d6c1dcd
5 changed files with 77 additions and 23 deletions

37
src/atoms/Counter.svelte Normal file
View File

@@ -0,0 +1,37 @@
<script>
import { onMount } from 'svelte'
// Props
export let currentIndex = 0
export let className = null
// Variables
$: actualIndex = currentIndex + 1
$: amount = String(actualIndex).length
$: index = (actualIndex < 10) ? String(actualIndex).padStart(2, '0') : String(actualIndex)
$: digits = index.split('')
let counter
const numbers = [...Array(10).keys()]
/*
** Run code when mounted
*/
onMount(() => {
// Set each digit column's height = its spans combined (in order to translate in tens of %)
counter.querySelectorAll('div').forEach(column => {
const spans = column.querySelectorAll('span')
column.style.height = spans[0].offsetHeight * spans.length + 'px'
})
})
</script>
<div class="counter {className}" bind:this={counter}>
{#each digits as digit}
<div class="counter__column" style="transform: translateY(-{digit}0%);">
{#each numbers as number}
<span>{number}</span>
{/each}
</div>
{/each}
</div>

View File

@@ -11,6 +11,7 @@
// Components
import IconArrow from '../atoms/IconArrow'
import Counter from '../atoms/Counter'
// Props
export let photos
@@ -42,6 +43,9 @@
} else if (direction === 'next') {
currentIndex++
currentIndex = (currentIndex >= photos.length) ? 0 : currentIndex
} else {
currentIndex = direction
console.log('Go to photo', direction, currentIndex)
}
// Send current photo to event
@@ -182,9 +186,7 @@
</div>
{#if viewer}
<div class="carousel__number">
{currentIndex < 10 ? 0 : ''}{photos.length - currentIndex}
</div>
<Counter {currentIndex} className="carousel__number" />
{/if}
</div>
@@ -207,25 +209,13 @@
<p class="carousel__date">{formatDate(currentPhoto.date, 'FULL')}</p>
{/if}
</div>
</div>
{#if !viewer}
<ol class="carousel__dots">
{#each photos as page, index}
<li class:active={page === currentPhoto} on:click={() => currentIndex = index}>
<li class:active={page === currentPhoto} on:click={() => goToPhoto(index)}>
<button aria-label="Go to photo #{index + 1}"></button>
</li>
{/each}
</ol>
{/if}
</div>
{#if viewer}
<ol class="carousel__dots">
{#each photos as page}
<li class:active={page === currentPhoto}>
<button></button>
</li>
{/each}
</ol>
{/if}
</div>

View File

@@ -0,0 +1,22 @@
// Counter
.counter {
display: inline-flex;
justify-content: center;
font-family: $font-serif-extra;
font-size: pxVW(672);
color: rgba($color-tertiary, 0.4);
text-align: center;
// pointer-events: none;
// user-select: none;
// Column
&__column {
display: flex;
flex-direction: column;
line-height: 0.85;
text-align: right;
margin: 0 -16px;
transition: transform 0.6s $ease-quart;
will-change: transform;
}
}

View File

@@ -6,7 +6,10 @@
max-width: 1280px;
padding: 0;
@include breakpoint (1600px) {
@include breakpoint (sm) {
max-width: 85%;
}
@include breakpoint (1680px) {
max-width: 1424px;
}
}
@@ -20,9 +23,6 @@
z-index: 2;
margin: 0 auto;
@include breakpoint (sm) {
max-width: 85%;
}
@include breakpoint (xl) {
max-width: 100%;
}
@@ -194,8 +194,12 @@
&__locations {
position: relative;
overflow: hidden;
min-height: 56px;
@include breakpoint (sm) {
min-height: 128px;
}
}
// Location
&__location {

View File

@@ -21,6 +21,7 @@
@import "atoms/toggle";
@import "atoms/link";
@import "atoms/switcher";
@import "atoms/counter";
// Molecules
@import "molecules/location";