Add hover effect on Location

This commit is contained in:
2021-09-30 23:30:13 +02:00
parent 624f02d84d
commit 7777d26907
6 changed files with 313 additions and 126 deletions

View File

@@ -1,4 +1,8 @@
<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'
@@ -6,18 +10,67 @@
export let location: any
export let index: number
const { name, slug, country, last_updated } = location
const { settings: { limit_new }}: any = getContext('global')
const { name, slug, country, date_updated } = location
// Location date limit
const dateNowOffset = dayjs().subtract(limit_new, 'day')
const dateLocationUpdated = dayjs(date_updated)
const isNew = dateLocationUpdated.isAfter(dateNowOffset)
let locationEl: HTMLElement
let photoIndex = 0
const offset = spring({ x: 0, y: 0 }, {
stiffness: 0.075,
damping: 0.9
})
// Moving cursor over
const handleMouseMove = ({ clientX }: MouseEvent) => {
const { width, left } = locationEl.getBoundingClientRect()
const moveProgress = (clientX - left) / width // 0 to 1
// Move horizontally
offset.update($c => ({
x: lerp(-56, 56, moveProgress),
y: 0
}))
// Change photo index from mouse position percentage
photoIndex = Math.round(lerp(0, 3, moveProgress))
}
// Leaving mouseover
const handleMouseLeave = (event: MouseEvent) => {
offset.update($c => ({
x: $c.x,
y: 40
}))
}
</script>
<div class="location" role="listitem">
<a href="/{country.slug}/{slug}" rel="prefetch" sveltekit-noscroll>
<div class="location" role="listitem" bind:this={locationEl}
style="--offset-x: {$offset.x}px; --offset-y: {$offset.y}px; --rotate: {$offset.x * 0.15}deg"
>
<a href="/{country.slug}/{slug}"
on:mousemove={handleMouseMove}
on:mouseleave={handleMouseLeave}
sveltekit-noscroll
>
<Image id={country.flag.id} alt="Flag of {country.name}" width={32} height={32} />
<h3 class="location__name">
{name}
</h3>
<span class="text-label location__country">{country.name}</span>
{#if index < 2}
<dl>
<dt class="location__name">
{name}
</dt>
<dd class="location__country text-label">
{country.name}
</dd>
</dl>
{#if isNew}
<Badge text="New" />
{/if}
</a>
<div class="location__photos">
<span>{photoIndex}</span>
</div>
</div>