refactor: beta card adjustments & light mode

This commit is contained in:
tglide
2023-04-24 14:48:01 +01:00
committed by Christy Jacob
parent 1467d4f6dd
commit fbd62e03fe
5 changed files with 190 additions and 85 deletions
+137 -21
View File
@@ -1,19 +1,26 @@
<script lang="ts">
import { Confetti } from 'svelte-confetti';
import Card from './Card.svelte';
import { fade } from 'svelte/transition';
let triggerConfettiKey = 1;
const confettiColors = [
'hsl(var(--color-primary-100))',
'hsl(var(--color-primary-200))',
'hsl(var(--color-primary-300))'
'hsl(var(--color-primary-300))',
'#F05088',
'#FF86BB',
'#FFFFFF80'
];
let cardActive = false;
let cardIsFlipped = false;
</script>
<div class="wrapper">
<div class="card">
<h3 class="heading-level-3">
Join the celebration
Welcome to the Cloud Club
<button class="confetti-btn" on:click={() => triggerConfettiKey++}>
🎉
{#each Array(triggerConfettiKey) as _, i (i)}
@@ -28,7 +35,10 @@
</button>
</h3>
<div class="u-flex u-margin-block-start-40 u-cross-center u-gap-24">
<img src="/images/cloud-beta-hoodies.png" alt="Cloud Beta hoodies" />
<div class="hoodie-container">
<img src="/images/hoodie-1.png" alt="Cloud Beta hoodies" />
<img src="/images/hoodie-2.png" alt="Cloud Beta hoodies" />
</div>
<div>
<div class="u-flex u-cross-center u-gap-8">
<h4 class="eyebrow-heading-1">Cloud is live in public</h4>
@@ -64,17 +74,38 @@
</div>
</div>
<div class="cbc-wrapper">
<!-- <div class="confetti-wrapper">
<Confetti
x={[-2, 2]}
y={[-2.25, 1.25]}
amount={50}
size="10"
delay={[0, 5000]}
colorArray={confettiColors}
fallDistance="50px" />
</div> -->
<Card />
{#if !cardActive}
<div transition:fade>
<Confetti
x={[-1.75, 1.85]}
y={[-1.875, 1]}
amount={100}
size="10"
infinite
delay={[2000, 7000]}
colorArray={confettiColors}
fallDistance="50px" />
</div>
{/if}
<Card bind:active={cardActive} bind:isFlipped={cardIsFlipped} />
</div>
{#if cardActive}
<div
class="overlay"
on:click={() => (cardActive = false)}
on:keydown={() => {
/* no-op */
}}
transition:fade />
{/if}
<div class="controls" class:invisible={!cardActive}>
<button
class="button is-text"
on:click={() => (cardIsFlipped = !cardIsFlipped)}
aria-label="Rotate card">
<span class="icon-refresh" aria-hidden="true" />
<span class="text">Spin</span>
</button>
</div>
</div>
@@ -85,7 +116,19 @@
flex-direction: column;
}
:global(.theme-dark) .wrapper {
--glow: hsl(var(--color-primary-100));
--beta-bg: hsl(var(--color-neutral-120));
--beta-fg: hsl(var(--color-neutral-0));
--sep-clr: hsl(var(--color-neutral-150));
}
.wrapper {
--glow: transparent;
--beta-bg: rgba(240, 46, 101, 0.16);
--beta-fg: rgba(240, 46, 101, 0.8);
--sep-clr: hsl(var(--color-neutral-10));
display: grid;
place-items: center;
justify-content: center;
@@ -107,7 +150,8 @@
}
.beta-tag {
background-color: hsl(var(--color-neutral-120));
background-color: var(--beta-bg);
color: var(--beta-fg);
padding-inline: 0.75rem; // 12px
padding-block: 0.25rem; // 4px
border-radius: 0.375rem; // 6px
@@ -117,11 +161,59 @@
font-size: 1rem;
}
.hoodie-container {
background-image: url('/images/hoodies-bg.png');
background-size: contain;
background-repeat: no-repeat;
position: relative;
width: 9.9375rem; // 159px
height: 7.375rem; // 118px
flex-shrink: 0;
transition: 300ms ease;
img {
display: block;
position: absolute;
object-fit: contain;
width: 5.8125rem; // 93px
height: 5.8125rem; // 93px
transition: 300ms ease;
&:first-child {
top: 1rem;
left: 0.1875rem;
}
&:last-child {
top: 0.5625rem; // 9px
right: 0.1875rem; // 3px
}
}
&:hover {
box-shadow: 0 0 30px var(--glow);
img:first-child {
scale: 1.5;
rotate: -5deg;
translate: -1rem 1rem;
}
img:last-child {
scale: 1.5;
rotate: 5deg;
translate: 1rem -1rem;
}
}
}
.card-footer {
display: flex;
justify-content: flex-end;
border-top: 1px solid hsl(var(--color-neutral-150));
border-top: 1px solid var(--sep-clr);
margin-block-start: 2rem;
padding-block-start: 2rem;
@@ -136,11 +228,6 @@
align-items: center;
}
.confetti-wrapper {
position: relative;
// z-index: 9999;
}
@keyframes shake {
0% {
translate: 0;
@@ -179,4 +266,33 @@
align-items: center;
gap: 0.5rem;
}
.controls {
display: flex;
align-items: center;
gap: 0.5rem;
position: absolute;
top: 80%;
left: 50%;
translate: -50% -50%;
transition: opacity 250ms ease;
&.invisible {
opacity: 0;
}
}
.overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background-color: hsl(var(--p-body-bg-color));
backdrop-filter: blur(80px);
opacity: 0.5;
}
</style>
+53 -64
View File
@@ -22,12 +22,14 @@
import { spring } from 'svelte/motion';
let cardEl: HTMLDivElement | undefined;
let active = false;
export let active = false;
export let isFlipped = false;
let interacting = false;
const springR = { stiffness: 0.066, damping: 0.25 };
const springD = { stiffness: 0.033, damping: 0.45 };
const THICKNESS = 6;
const THICKNESS = 3;
let springRotate = spring({ x: 0, y: 0 }, springR);
let springGlare = spring({ x: 50, y: 50, o: 0.25 }, springR);
@@ -39,8 +41,6 @@
let centerProximity = spring(0, springR);
let springRotateZ = spring(-15, springD);
let isBackwards = false;
// Events
const interact = (e: MouseEvent | TouchEvent) => {
if (!active) return;
@@ -61,7 +61,7 @@
};
const center = {
x: percent.x - 50,
y: (percent.y - 50) * (isBackwards ? -1 : 1)
y: (percent.y - 50) * (isFlipped ? -1 : 1)
};
springBackground.stiffness = springR.stiffness;
@@ -153,6 +153,7 @@
springTranslate.set({ x: 0, y: 0 });
springRotateDelta.set({ x: 0, y: 0 });
springRotate.set({ x: 0, y: 0 });
springGlare.set({ x: 50, y: 50, o: 0 });
$centerProximity = 0;
springRotateZ.set(-15);
};
@@ -161,23 +162,19 @@
active = !active;
};
const handleBlur = () => {
active = false;
};
const windowKeyDown = (e: KeyboardEvent) => {
if (!active) return;
// If user presses q, rotate card
if (e.key === 'q') {
isBackwards = !isBackwards;
isFlipped = !isFlipped;
}
};
$: if (!active) {
isBackwards = false;
isFlipped = false;
} else {
springRotateDelta.update((old) => ({
x: isBackwards ? 180 : 360,
x: isFlipped ? 180 : 360,
y: old.y
}));
}
@@ -273,7 +270,9 @@
on:pointermove={interact}
on:mouseout={interactEnd}
on:click={handleClick}
on:blur={handleBlur}>
on:blur={() => {
/* noop */
}}>
<div class="card__back">
<img
src="/images/back.png"
@@ -310,20 +309,24 @@
--hyp: 0;
}
:global(.theme-dark) .cb-card {
--shadow-clr: transparent;
}
.cb-card {
--radius: 12px;
--back: white;
--glow: var(--primary);
--radius: 16px;
--shadow-clr: hsl(var(--color-neutral-30));
z-index: calc(var(--s) * 100);
transform: translate3d(0, 0, 0.1px);
-webkit-transform: translate3d(0, 0, 0.1px);
will-change: transform, visibility;
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
}
.cb-card.interacting {
z-index: calc(var(--s) * 120);
&.interacting {
z-index: calc(var(--s) * 120);
}
}
.cb-card.active .card__translater,
@@ -352,17 +355,30 @@
transform-style: preserve-3d;
-webkit-transform: rotateY(var(--rx)) rotateX(var(--ry)) rotateZ(var(--rz));
-webkit-transform-style: preserve-3d;
box-shadow: 0px 10px 20px -5px #14141f;
box-shadow: 0px 10px 20px -5px var(--shadow-clr);
border-radius: var(--radius);
outline: none;
transition: box-shadow 0.4s ease, outline 0.2s ease;
}
button.card__rotator {
appearance: none;
-webkit-appearance: none;
border: none;
background: top;
padding: 0;
:global(*) {
width: 100%;
display: grid;
grid-area: 1/1;
border-radius: var(--radius);
image-rendering: optimizeQuality;
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
}
img {
outline: 1px solid transparent;
height: auto;
}
}
.card__thick {
@@ -373,44 +389,14 @@
transform: translateZ(calc(var(--i) * 1px));
}
.cb-card.active .card__rotator {
box-shadow: 0 0 10px 0px var(--glow), 0 0 10px 0px var(--glow), 0 0 30px 0px var(--glow);
}
.card__rotator:focus {
box-shadow: 0 0 10px 0px var(--glow), 0 0 10px 0px var(--glow), 0 0 30px 0px var(--glow);
}
.cb-card.active .card__rotator:focus {
box-shadow: 0px 10px 30px 3px #14141f;
}
.card__rotator :global(*) {
width: 100%;
display: grid;
grid-area: 1/1;
border-radius: var(--radius);
image-rendering: optimizeQuality;
transform-style: preserve-3d;
-webkit-transform-style: preserve-3d;
}
.card__rotator img {
outline: 1px solid transparent;
height: auto;
}
.card__back {
background-color: var(--back);
transform: rotateY(180deg) translateZ(0px);
-webkit-transform: rotateY(180deg) translateZ(0px);
backface-visibility: hidden;
}
.card__front,
.card__front * {
backface-visibility: hidden;
&::before {
--resolved-angle: calc(calc(var(--angle) * -1) + 60deg);
}
}
.card__front {
@@ -418,18 +404,20 @@
transition: opacity 0.33s ease-out;
transform: translateZ(calc(var(--thickness) * 1px));
position: relative;
}
.card__front::before {
--resolved-angle: calc(var(--angle) + 65deg);
}
.card__back::before {
--resolved-angle: calc(calc(var(--angle) * -1) + 60deg);
backface-visibility: hidden;
* {
backface-visibility: hidden;
}
&::before {
--resolved-angle: calc(var(--angle) + 65deg);
}
}
.card__front::before,
.card__back::before {
/* Conic gradient */
content: '';
position: absolute;
top: 0;
@@ -449,6 +437,7 @@
}
.card__glare {
border-radius: calc(var(--radius) + 3px);
transform: translateZ(1px);
z-index: 4;
background: radial-gradient(
@@ -458,6 +447,6 @@
rgba(0, 0, 0, 0.5) 90%
);
mix-blend-mode: overlay;
opacity: calc(var(--o) * 0.25);
opacity: calc(var(--o) * 0.5);
}
</style>
Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB