Skip to content

Commit 3f789bd

Browse files
committed
feat(backgrounds): adds grid hover background
1 parent f9dfd72 commit 3f789bd

File tree

6 files changed

+170
-54
lines changed

6 files changed

+170
-54
lines changed

src/components/AppComponent.vue

+5-12
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { Transition } from 'vue';
33
import { RouterView } from 'vue-router';
44
55
import { NavbarComponent } from '~/components/common';
6+
import GridBackground from '~/components/common/background/GridBackground.vue';
67
import PageLoading from '~/components/common/loading/PageLoading.vue';
78
import { useAuthSettingsStoreRefs } from '~/stores/settings/auth.store';
89
@@ -15,6 +16,7 @@ const { isAuthenticated } = useAuthSettingsStoreRefs();
1516
</header>
1617
<main>
1718
<RouterView v-slot="{ Component, route }">
19+
<GridBackground v-if="!Component" :size="20" />
1820
<Transition name="scale" mode="out-in">
1921
<component :is="Component ?? PageLoading" :key="route.path" />
2022
</Transition>
@@ -23,8 +25,10 @@ const { isAuthenticated } = useAuthSettingsStoreRefs();
2325
</template>
2426

2527
<style lang="scss" scoped>
26-
@use 'src/styles/mixin' as mixin;
28+
@use '~/styles/mixin' as mixin;
2729
@use '~/styles/z-index' as layers;
30+
@use '~/styles/transition' as transition;
31+
@include transition.scale;
2832
2933
$header-height: 2.75rem;
3034
@@ -49,15 +53,4 @@ main {
4953
min-height: calc(100% - #{$header-height});
5054
padding: 0 2rem;
5155
}
52-
53-
.scale-enter-active,
54-
.scale-leave-active {
55-
transition: all 0.25s ease;
56-
}
57-
58-
.scale-enter-from,
59-
.scale-leave-to {
60-
transform: scale(0.95);
61-
opacity: 0;
62-
}
6356
</style>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<script setup lang="ts">
2+
import { computed, defineProps, onBeforeUnmount, onMounted, ref, Transition } from 'vue';
3+
4+
const props = withDefaults(defineProps<{ size: number }>(), { size: 16 });
5+
6+
const container = ref<Element>();
7+
8+
const viewportWidth = ref(container.value?.clientWidth ?? window.innerWidth);
9+
const viewportHeight = ref(container.value?.clientHeight ?? window.innerHeight);
10+
const numberOfSquares = computed(() =>
11+
Math.ceil((viewportWidth.value * viewportHeight.value) / (props.size * props.size)),
12+
);
13+
14+
const handleResize = () => {
15+
if (!container.value) return;
16+
viewportWidth.value = container.value?.clientWidth;
17+
viewportHeight.value = container.value?.clientHeight;
18+
};
19+
20+
onMounted(() => window.addEventListener('resize', handleResize));
21+
onBeforeUnmount(() => window.removeEventListener('resize', handleResize));
22+
</script>
23+
24+
<template>
25+
<div
26+
ref="container"
27+
class="background-container"
28+
:style="`--grid-size: ${ props.size }px`"
29+
>
30+
<Transition name="fade" mode="in-out">
31+
<div v-if="container" class="grid-container">
32+
<div
33+
v-for="(_, i) in Array(numberOfSquares).fill(1)"
34+
:key="`row-${ i }`"
35+
class="grid-item"
36+
></div>
37+
</div>
38+
</Transition>
39+
</div>
40+
</template>
41+
42+
<style scoped lang="scss">
43+
@use '~/styles/transition' as transition;
44+
@include transition.fade;
45+
46+
.background-container {
47+
--grid-size: 16px;
48+
49+
position: absolute;
50+
top: 0;
51+
left: 0;
52+
width: 100%;
53+
height: 100%;
54+
overflow: hidden;
55+
56+
.grid-container {
57+
display: grid;
58+
grid-template-rows: repeat(auto-fill, minmax(var(--grid-size), 1fr));
59+
grid-template-columns: repeat(auto-fill, minmax(var(--grid-size), 1fr));
60+
transform: skewX(-20deg) skewY(10deg) scale(2);
61+
}
62+
63+
.grid-item {
64+
width: var(--grid-size);
65+
height: var(--grid-size);
66+
border-top: 0.1px solid var(--bg-blur-black);
67+
border-left: 0.1px solid var(--bg-blur-black);
68+
transition: background-color 0.25s var(--n-bezier);
69+
will-change: background-color;
70+
71+
&:hover {
72+
background-color: var(--bg-blur-black-hover);
73+
transition: none;
74+
}
75+
}
76+
}
77+
</style>

src/components/views/login/LoginComponent.vue

+44-33
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<script lang="ts" setup>
22
import { NButton, NCard, NCheckbox, NFlex, NH4, NText } from 'naive-ui';
33
4-
import { onMounted, ref, watch } from 'vue';
4+
import { onMounted, ref, Transition, watch } from 'vue';
55
66
import { useRoute, useRouter } from 'vue-router';
77
8+
import GridBackground from '~/components/common/background/GridBackground.vue';
89
import { TraktService } from '~/services/trakt.service';
910
import { useAuthSettingsStoreRefs } from '~/stores/settings/auth.store';
1011
import { useI18n } from '~/utils';
@@ -21,11 +22,13 @@ const onRedirect = (authenticated = isAuthenticated.value) => {
2122
return router.push((route.query.redirect as string) ?? '/');
2223
};
2324
25+
const show = ref(false);
2426
onMounted(() => {
2527
onRedirect();
2628
watch(isAuthenticated, authenticated => {
2729
onRedirect(authenticated);
2830
});
31+
show.value = !isAuthenticated.value;
2932
});
3033
3134
const signUp = ref(false);
@@ -45,42 +48,50 @@ const onSignIn = async () => {
4548

4649
<template>
4750
<NFlex vertical justify="space-around" align="center">
48-
<NCard class="card" :title="i18n('title')" hoverable>
49-
<template #cover>
50-
<div class="spacer" />
51-
<img
52-
alt="Vue logo"
53-
class="logo"
54-
src="/assets/logo.svg"
55-
width="125"
56-
height="125"
57-
/>
58-
</template>
59-
60-
<NFlex vertical>
61-
<NH4 class="title" prefix="bar">{{ i18n('sub_title') }}</NH4>
62-
63-
<NButton class="button" @click="onSignIn">{{ i18n('sign_in') }}</NButton>
64-
65-
<NFlex class="checkboxes" vertical>
66-
<NCheckbox v-model:checked="signUp">
67-
{{ i18n('checkbox__sign_up_for') }}
68-
<NText type="info">{{ i18n('checkbox__new_account') }}</NText>
69-
!
70-
</NCheckbox>
71-
<NCheckbox v-model:checked="useSession">
72-
{{ i18n('checkbox__use') }}
73-
<NText type="info">{{ i18n('checkbox__active_user') }}</NText>
74-
{{ i18n('checkbox__session') }}
75-
</NCheckbox>
76-
</NFlex>
77-
</NFlex>
78-
</NCard>
51+
<GridBackground :size="20" />
52+
53+
<Transition name="scale" mode="in-out">
54+
<div v-if="show">
55+
<NCard class="card" :title="i18n('title')" hoverable>
56+
<template #cover>
57+
<div class="spacer" />
58+
<img
59+
alt="Vue logo"
60+
class="logo"
61+
src="/assets/logo.svg"
62+
width="125"
63+
height="125"
64+
/>
65+
</template>
66+
67+
<NFlex vertical>
68+
<NH4 class="title" prefix="bar">{{ i18n('sub_title') }}</NH4>
69+
70+
<NButton class="button" @click="onSignIn">{{ i18n('sign_in') }}</NButton>
71+
72+
<NFlex class="checkboxes" vertical>
73+
<NCheckbox v-model:checked="signUp">
74+
{{ i18n('checkbox__sign_up_for') }}
75+
<NText type="info">{{ i18n('checkbox__new_account') }}</NText>
76+
!
77+
</NCheckbox>
78+
<NCheckbox v-model:checked="useSession">
79+
{{ i18n('checkbox__use') }}
80+
<NText type="info">{{ i18n('checkbox__active_user') }}</NText>
81+
{{ i18n('checkbox__session') }}
82+
</NCheckbox>
83+
</NFlex>
84+
</NFlex>
85+
</NCard>
86+
</div>
87+
</Transition>
7988
</NFlex>
8089
</template>
8190

8291
<style lang="scss" scoped>
83-
@use 'src/styles/mixin' as mixin;
92+
@use '~/styles/mixin' as mixin;
93+
@use '~/styles/transition' as transition;
94+
@include transition.scale(0.9);
8495
8596
.card {
8697
@include mixin.hover-background;

src/styles/base.css

+3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@
2525
--trakt-red: #ed1c24;
2626
--trakt-red-dark: #ba080f;
2727

28+
/* Transforms */
29+
--n-bezier: cubic-bezier(.4, 0, .2, 1);
30+
2831
/* semantic color variables for this project */
2932
--section-gap: 160px;
3033
--color-background: var(--vt-c-black);

src/styles/mixin.scss

+10-9
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,21 @@
22
$from: var(--bg-blur-black),
33
$to: var(--bg-blur-black-hover),
44
$blur: var(--bg-blur),
5-
$transition: var(--n-bezier)
5+
$transition: 0.5s var(--n-bezier)
66
) {
7-
background-color: $from;
7+
background: $from;
88
backdrop-filter: blur($blur);
99
transition:
10-
color 0.3s $transition,
11-
background 0.3s $transition,
12-
backdrop-filter 0.3s $transition,
13-
box-shadow 0.3s $transition,
14-
border-color 0.3s $transition;
15-
will-change: color, background, backdrop-filter, box-shadow,
10+
color $transition,
11+
background $transition,
12+
background-color $transition,
13+
backdrop-filter $transition,
14+
box-shadow $transition,
15+
border-color $transition;
16+
will-change: color, background, background-color, backdrop-filter, box-shadow,
1617
border-color;
1718

1819
&:hover {
19-
background-color: $to;
20+
background: $to;
2021
}
2122
}

src/styles/transition.scss

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
@mixin fade(
2+
$from: 0,
3+
$transition: 0.2s ease
4+
) {
5+
.fade-enter-active,
6+
.fade-leave-active {
7+
transition: opacity $transition;
8+
}
9+
10+
.fade-enter-from,
11+
.fade-leave-to {
12+
opacity: $from;
13+
}
14+
}
15+
16+
@mixin scale(
17+
$scale: 0.95,
18+
$opacity: 0,
19+
$transition: 0.25s ease
20+
) {
21+
.scale-enter-active,
22+
.scale-leave-active {
23+
transition: all $transition;
24+
}
25+
26+
.scale-enter-from,
27+
.scale-leave-to {
28+
transform: scale($scale);
29+
opacity: $opacity;
30+
}
31+
}

0 commit comments

Comments
 (0)