Add entering transition on Shop and fix some styling
- Center intro title vertically - Cart item styling tweaks - Add cart button quantity label inside of button so it's clickable
This commit is contained in:
@@ -14,9 +14,8 @@
|
||||
<div class="button-cart">
|
||||
<ButtonCircle color="purple" on:click={openCart}>
|
||||
<Icon icon="bag" label="Cart icon" />
|
||||
</ButtonCircle>
|
||||
|
||||
{#if $cartAmount > 0}
|
||||
<span class="quantity" transition:scale={{ start: 0.6, duration: 400, easing: quartOut }}>{$cartAmount}</span>
|
||||
{/if}
|
||||
</ButtonCircle>
|
||||
</div>
|
||||
@@ -30,7 +30,10 @@
|
||||
</div>
|
||||
<div class="cart-item__right">
|
||||
<h3>Poster</h3>
|
||||
<p>{item.product.name} – {item.price_total}€</p>
|
||||
<p>
|
||||
{item.product.name}
|
||||
<br>– {item.price}€
|
||||
</p>
|
||||
|
||||
{#if item && item.quantity}
|
||||
<Select
|
||||
|
||||
@@ -140,7 +140,7 @@
|
||||
<div class="cart__content">
|
||||
{#if $cartAmount > 0}
|
||||
{#each $cartData.items as item, index}
|
||||
<CartItem {item} {index}
|
||||
<CartItem {item}
|
||||
on:updatedQuantity={changedQuantity}
|
||||
on:removed={removedItem}
|
||||
/>
|
||||
@@ -155,7 +155,7 @@
|
||||
{/if}
|
||||
|
||||
{#if !$cartData || $cartIsUpdating}
|
||||
<div class="cart__update">
|
||||
<div class="cart__update" transition:fade={{ duration: 400 }}>
|
||||
<p>Updating…</p>
|
||||
</div>
|
||||
{/if}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<script lang="ts">
|
||||
import { browser } from '$app/env'
|
||||
import { onMount } from 'svelte'
|
||||
import { shopLocations, cartOpen, cartNotifications } from '$utils/stores/shop'
|
||||
import anime from 'animejs'
|
||||
import type { AnimeTimelineInstance } from 'animejs'
|
||||
// Components
|
||||
import Metas from '$components/Metas.svelte'
|
||||
import SiteTitle from '$components/atoms/SiteTitle.svelte'
|
||||
@@ -31,7 +34,45 @@
|
||||
})
|
||||
|
||||
|
||||
onMount(async () => {
|
||||
/**
|
||||
* Transition: Anime timeline
|
||||
*/
|
||||
let timeline: AnimeTimelineInstance
|
||||
|
||||
if (browser) {
|
||||
requestAnimationFrame(() => {
|
||||
timeline = anime.timeline({
|
||||
duration: 1600,
|
||||
easing: 'easeOutQuart',
|
||||
autoplay: false,
|
||||
})
|
||||
|
||||
// Hero image
|
||||
timeline.add({
|
||||
targets: '.shop-page__background',
|
||||
scale: [1.06, 1],
|
||||
opacity: [0, 1],
|
||||
duration: 2400,
|
||||
}, 400)
|
||||
|
||||
// Intro top elements
|
||||
timeline.add({
|
||||
targets: '.shop-page__intro .top > *',
|
||||
translateY: [-100, 0],
|
||||
delay: anime.stagger(250),
|
||||
}, 400)
|
||||
|
||||
// Intro navbar
|
||||
timeline.add({
|
||||
targets: '.shop-page__nav .container > *',
|
||||
translateY: [100, 0],
|
||||
delay: anime.stagger(250),
|
||||
}, 700)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
onMount(() => {
|
||||
// Reveal the nav past the Intro
|
||||
navObserver = new IntersectionObserver(entries => {
|
||||
entries.forEach(entry => {
|
||||
@@ -43,6 +84,11 @@
|
||||
})
|
||||
navObserver.observe(introEl)
|
||||
|
||||
// Transition in
|
||||
requestAnimationFrame(() => {
|
||||
timeline.play()
|
||||
})
|
||||
|
||||
|
||||
// Destroy
|
||||
return () => {
|
||||
@@ -96,6 +142,7 @@
|
||||
</nav>
|
||||
|
||||
<Image
|
||||
class="shop-page__background"
|
||||
id={shop.page_heroimage.id}
|
||||
alt="photo"
|
||||
sizeKey="hero"
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
margin-left: auto;
|
||||
}
|
||||
|
||||
button {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
// Icon
|
||||
svg {
|
||||
color: #fff;
|
||||
@@ -20,18 +24,20 @@
|
||||
// Quantity label
|
||||
.quantity {
|
||||
position: absolute;
|
||||
z-index: 2;
|
||||
top: 50%;
|
||||
left: -12px;
|
||||
transform: translateY(-50%);
|
||||
left: 2px;
|
||||
transform: translate3d(-50%, -50%, 0);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: 22px;
|
||||
height: 22px;
|
||||
font-size: rem(11px);
|
||||
font-size: rem(12px);
|
||||
font-weight: 600;
|
||||
color: #fff;
|
||||
background-color: $color-secondary;
|
||||
border-radius: 100%;
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@
|
||||
&__right {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex: 1;
|
||||
|
||||
// Poster Title
|
||||
h3 {
|
||||
@@ -52,7 +53,7 @@
|
||||
}
|
||||
// Text
|
||||
p {
|
||||
max-width: 124px;
|
||||
max-width: 152px;
|
||||
margin: 8px 0 20px;
|
||||
font-size: rem(12px);
|
||||
line-height: 1.4;
|
||||
@@ -68,7 +69,7 @@
|
||||
align-items: center;
|
||||
height: 28px;
|
||||
margin-right: auto;
|
||||
padding: 0 12px;
|
||||
padding: 2px 12px 0;
|
||||
border: 1px solid rgba($color-lightgray, 0.3);
|
||||
border-radius: 100vh;
|
||||
cursor: pointer;
|
||||
|
||||
@@ -80,13 +80,14 @@
|
||||
|
||||
|
||||
@include bp (sm) {
|
||||
top: clamp(#{rem(40px)}, 16vw, #{rem(144px)});
|
||||
// top: clamp(#{rem(40px)}, 16vw, #{rem(144px)});
|
||||
top: 40%;
|
||||
left: 0;
|
||||
font-size: clamp(#{rem(40px)}, 8vw, #{rem(96px)});
|
||||
transform: none;
|
||||
}
|
||||
@include bp (md) {
|
||||
top: clamp(#{rem(40px)}, 10vw, #{rem(96px)});
|
||||
// top: clamp(#{rem(40px)}, 10vw, #{rem(96px)});
|
||||
font-size: clamp(#{rem(40px)}, 6vw, #{rem(96px)});
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user