koptilnya.xyz/app.vue
Opti1337 250174211e
All checks were successful
Gitea Actions Demo / build-and-deploy (push) Successful in 25s
Styles
2024-04-18 21:28:18 +03:00

175 lines
3.3 KiB
Vue

<template>
<header>
<img ref="logoEl" class="logo" src="/logo-no-bg.png" alt="KPTL">
</header>
<div class="grid">
<div v-for="card in cards" ref="cardsELS" :key="card.title" class="card">
<p class="card__title">
{{ card.title }}
</p>
<img :src="card.img" alt="TeamSpeak" class="card__image">
<a class="button card__action" :href="card.href">
{{ card.action }}
</a>
</div>
</div>
</template>
<script setup>
import { onMounted, ref } from 'vue'
import { gsap } from 'gsap'
const cards = ref([
{
title: 'TeamSpeak',
action: 'Попиздеть',
img: '/ts.png',
href: 'https://invite.teamspeak.com/koptilnya.xyz/',
},
{
title: 'Dota 2',
action: 'Поиграть',
img: '/dota.png',
href: 'steam://run/570',
},
{
title: 'Gitea',
action: 'Поработать',
img: '/gitea.svg',
href: 'https://git.koptilnya.xyz',
},
{
title: 'YouTube',
action: 'Посмотреть',
img: '/youtube.png',
href: 'https://www.youtube.com/@kptl-team',
},
{
title: 'База знаний',
action: 'Почитать',
img: '/bookStack.png',
href: 'https://baza.koptilnya.xyz',
},
])
const cardsELS = ref([])
const logoEl = ref()
const DURATION = 0.3
const OVERLAP = 0.15
const CARD_OPTIONS = {
duration: DURATION,
ease: 'power1.out',
scale: 1.025,
yoyo: true,
repeat: 1,
opacity: 1,
}
onMounted(() => {
const cards = cardsELS.value
const groupsCount = Math.ceil((cards.length - 1) / 2)
const t = gsap.timeline()
if (cards[0])
t.to(cards[0], CARD_OPTIONS)
for (let i = 0; i < groupsCount; i++) {
if (cards[i * 2 + 1])
t.to(cards[i * 2 + 1], CARD_OPTIONS, `<${OVERLAP}`)
if (cards[i * 2 + 2])
t.to(cards[i * 2 + 2], CARD_OPTIONS, `<<${OVERLAP}`)
}
t.fromTo(
logoEl.value,
{ opacity: 0, y: 50 },
{ opacity: 1, y: 0, ease: 'power1.out', duration: DURATION },
`<`,
)
})
</script>
<style lang="scss">
@mixin mobile {
@media (max-width: 600px) {
@content;
}
}
header {
text-align: center;
padding-block: 16px;
margin-bottom: 16px;
}
.logo {
width: 64px;
opacity: 0;
}
.grid {
width: 800px;
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 16px;
@include mobile {
width: 100%;
grid-template-columns: 1fr;
}
}
.card {
display: grid;
grid-template-columns: 1fr auto;
align-items: center;
justify-items: flex-start;
border-radius: 16px;
padding: 16px;
gap: 16px;
background-image: linear-gradient(135deg, var(--chocolate-cosmos), var(--black));
&__title {
font-size: 24px;
font-weight: 700;
}
&__image {
width: 80px;
grid-row: span 2;
opacity: 0.7;
}
&__action {
grid-row: 2;
}
}
.button {
display: inline-block;
text-decoration: none;
border: none;
border-radius: 8px;
padding: 8px 12px;
cursor: pointer;
background-image: linear-gradient(135deg, var(--beaver) 0%, var(--beaver) 51%, var(--walnut-brown) 110%);
background-size: 200% auto;
background-color: var(--walnut-brown);
background-repeat: repeat;
color: var(--white-smoke);
font-weight: 500;
transition: .15s ease-out;
transition-property: color, background-position;
&:hover:not(:active) {
background-position: right center;
}
}
</style>