Files
housesof/src/components/molecules/Location.svelte
Félix Péault cdabe6935b 🔥 Huge style refactoring by using SvelteKit built-in style tag
It's been tricky but got there finally! Hello `:global`
- Avoid using one global CSS file containing everything
- Import the component SCSS file in a script tag from the component file to allow style scoping and including it only when used
2022-06-22 23:26:00 +02:00

110 lines
3.0 KiB
Svelte

<style lang="scss">
@import "../../style/molecules/location";
</style>
<script lang="ts">
import { getContext } from 'svelte'
import { spring } from 'svelte/motion'
import dayjs from 'dayjs'
import { lerp } from '$utils/functions'
// Components
import Image from '$components/atoms/Image.svelte'
import Badge from '$components/atoms/Badge.svelte'
export let location: any
export let latestPhoto: any
const { settings: { limit_new }}: any = getContext('global')
let locationEl: HTMLElement
let photoIndex = 0
// Location date limit
let isNew = false
let dateUpdated: dayjs.Dayjs
const dateNowOffset = dayjs().subtract(limit_new, 'day')
$: if (latestPhoto) {
dateUpdated = dayjs(latestPhoto.date_created)
isNew = dateUpdated.isAfter(dateNowOffset)
}
/**
* Moving cursor over
*/
const offset = spring({ x: 0, y: 0 }, {
stiffness: 0.075,
damping: 0.9
})
const handleMouseMove = ({ clientX }: MouseEvent) => {
const { width, left } = locationEl.getBoundingClientRect()
const moveProgress = (clientX - left) / width // 0 to 1
// Move horizontally
offset.update(_ => ({
x: lerp(-56, 56, moveProgress),
y: 0
}))
// Change photo index from mouse position percentage
photoIndex = Math.round(lerp(0, Number(import.meta.env.VITE_PREVIEW_COUNT) - 1, moveProgress))
}
// Leaving mouseover
const handleMouseLeave = () => {
offset.update($c => ({
x: $c.x,
y: 40
}))
}
</script>
<div class="location" bind:this={locationEl}
style="--offset-x: {$offset.x}px; --offset-y: {$offset.y}px; --rotate: {$offset.x * 0.125}deg"
>
<a href="/{location.country.slug}/{location.slug}"
on:mousemove={handleMouseMove}
on:mouseleave={handleMouseLeave}
sveltekit:noscroll
tabindex="0"
>
<Image
class="flag"
id={location.country.flag.id}
sizeKey="square-small"
width={32} height={32}
alt="Flag of {location.country.name}"
/>
<div class="text">
<dl>
<dt class="location__name">
{location.name}
</dt>
<dd class="location__country text-label">
{location.country.name}
</dd>
</dl>
{#if isNew}
<Badge text="New" />
{/if}
</div>
</a>
{#if location.photos.length}
<div class="location__photos">
{#each location.photos as { image }, index}
{#if image}
<Image
class={`location__photo ${index === photoIndex ? 'is-visible' : ''}`}
id={image.id}
sizeKey="photo-thumbnail"
width={340} height={226}
alt={image.title}
/>
{/if}
{/each}
</div>
{/if}
</div>