Compare commits
37 Commits
ad72f51063
...
temp
Author | SHA1 | Date | |
---|---|---|---|
282a5e774e | |||
1a7727cd7d | |||
63cab3af76 | |||
aa0dfd15c9 | |||
a18f197141 | |||
63cc1858eb | |||
69c446da5a | |||
abab04eb1d | |||
7f4a81be3f | |||
3ab21267c6 | |||
fe0a8febc2 | |||
22e1fc2eb8 | |||
43123a3e5b | |||
c18b1b0fb6 | |||
b314df57fb | |||
85059ab1bf | |||
8bbc4cd77c | |||
5382c4394b | |||
58a1236c71 | |||
b1788a6102 | |||
574c5d8fb8 | |||
012dd7c52a | |||
3e47016cd9 | |||
cd620f686e | |||
d6e81e47f4 | |||
e1ed3d53db | |||
57a50a5810 | |||
aa795fb090 | |||
5c674e1541 | |||
3cef2f4107 | |||
ee8e51f62b | |||
0340ce23e7 | |||
372984e55b | |||
248868b1bd | |||
93dc92b56e | |||
6a116f40bb | |||
eb6f590dbd |
40
.gitea/workflows/ci.yml
Normal file
40
.gitea/workflows/ci.yml
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
name: Build and Deploy
|
||||||
|
on: [push]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Use Nodejs
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run build
|
||||||
|
|
||||||
|
|
||||||
|
Deploy:
|
||||||
|
runs-on: ubuntu-docker
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Use Nodejs
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 18
|
||||||
|
- run: npm install
|
||||||
|
- run: npm run build
|
||||||
|
|
||||||
|
- uses: docker/setup-qemu-action@v2
|
||||||
|
- uses: docker/setup-buildx-action@v2
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
- uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
registry: gitea.xeovalyte.dev
|
||||||
|
username: ${{ secrets.USERNAME }}
|
||||||
|
password: ${{ secrets.PASSWORD }}
|
||||||
|
- run: docker buildx build -t gitea.xeovalyte.dev/xeovalyte/portfolio --platform=linux/amd64,linux/arm64 .
|
||||||
|
- run: docker inspect gitea.xeovalyte.dev/xeovalyte/portfolio
|
||||||
|
- run: docker push gitea.xeovalyte.dev/xeovalyte/portfolio
|
1
.prettierigonore
Normal file
1
.prettierigonore
Normal file
@@ -0,0 +1 @@
|
|||||||
|
.nuxt
|
1
.prettierrc.json
Normal file
1
.prettierrc.json
Normal file
@@ -0,0 +1 @@
|
|||||||
|
{}
|
@@ -1,13 +0,0 @@
|
|||||||
pipeline:
|
|
||||||
publish:
|
|
||||||
image: plugins/docker
|
|
||||||
secrets:
|
|
||||||
- docker_password
|
|
||||||
settings:
|
|
||||||
username: xeovalyte
|
|
||||||
password:
|
|
||||||
from_secret: docker_password
|
|
||||||
repo: gitea.xeovalyte.dev/xeovalyte/website
|
|
||||||
tags:
|
|
||||||
- latest
|
|
||||||
registry: gitea.xeovalyte.dev
|
|
@@ -2,11 +2,8 @@ FROM node:18
|
|||||||
|
|
||||||
WORKDIR /usr/src/app
|
WORKDIR /usr/src/app
|
||||||
|
|
||||||
COPY . .
|
COPY .output .
|
||||||
|
|
||||||
RUN npm install
|
|
||||||
RUN npm run build
|
|
||||||
|
|
||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
|
|
||||||
CMD [ "node", ".output/server/index.mjs" ]
|
CMD [ "node", "server/index.mjs" ]
|
||||||
|
2
app.vue
2
app.vue
@@ -1,5 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<div>
|
||||||
<NuxtWelcome />
|
<NuxtPage />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@@ -1,3 +1,18 @@
|
|||||||
@tailwind base;
|
@tailwind base;
|
||||||
@tailwind components;
|
@tailwind components;
|
||||||
@tailwind utilities;
|
@tailwind utilities;
|
||||||
|
|
||||||
|
@layer base {
|
||||||
|
h1 {
|
||||||
|
@apply text-4xl;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
@apply text-3xl;
|
||||||
|
}
|
||||||
|
h3 {
|
||||||
|
@apply text-2xl;
|
||||||
|
}
|
||||||
|
h4 {
|
||||||
|
@apply text-xl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
21
assets/icons/logo.svg
Normal file
21
assets/icons/logo.svg
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="48"
|
||||||
|
height="48"
|
||||||
|
viewBox="0 0 12.7 12.7"
|
||||||
|
version="1.1"
|
||||||
|
id="svg5"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<g
|
||||||
|
id="layer1">
|
||||||
|
<path
|
||||||
|
id="rect753"
|
||||||
|
style="fill:#0080ff;fill-opacity:1;stroke-width:0.367356"
|
||||||
|
d="M 0.8196733,1.5362707 5.1211071,5.8377046 4.3020509,6.657378 -2e-7,2.355327 V 4.81373 L 3.0725407,7.8862709 0.8196733,10.139138 H 3.2774591 L 4.3014337,9.1151643 5.1211071,9.9342203 6.35,11.163729 7.578893,9.9342203 8.3985664,9.1151643 9.4225412,10.139138 H 11.880326 L 9.6274592,7.8862709 12.7,4.81373 V 2.355327 L 8.3979491,6.657378 7.578893,5.8377046 11.880326,1.5362707 H 9.4225412 L 6.35,4.6088116 3.2774591,1.5362707 Z M 6.35,7.0665975 7.1696734,7.8856537 6.35,8.7053271 5.5303266,7.8856537 Z" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 958 B |
17
components/layout/Leftbar.vue
Normal file
17
components/layout/Leftbar.vue
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
<template>
|
||||||
|
<div class="fixed hidden lg:block left-3 top-1/2 text-primary-500 space-y-1 z-50">
|
||||||
|
<div @click="scrollToElement('heading')" class="py-2 hover:cursor-pointer">
|
||||||
|
<div class="h-1 rounded-full bg-primary-500 transition-all duration-300 hover:cursor-pointer" :class="route.hash === '#heading' ? 'w-16' : 'w-8'" />
|
||||||
|
</div>
|
||||||
|
<div @click="scrollToElement('about')" class="py-2 hover:cursor-pointer">
|
||||||
|
<div class="h-1 rounded-full bg-primary-500 transition-all duration-300 hover:cursor-pointer" :class="route.hash === '#about' ? 'w-16' : 'w-8'" />
|
||||||
|
</div>
|
||||||
|
<div @click="scrollToElement('skills')" class="py-2 hover:cursor-pointer">
|
||||||
|
<div class="h-1 rounded-full bg-primary-500 transition-all duration-300 hover:cursor-pointer" :class="route.hash === '#skills' ? 'w-16' : 'w-8'" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const route = useRoute()
|
||||||
|
</script>
|
41
components/slides/About.vue
Normal file
41
components/slides/About.vue
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
<template>
|
||||||
|
<section class="flex h-screen snap-center items-center justify-center">
|
||||||
|
<div
|
||||||
|
class="my-40 mx-3 flex w-full max-w-xl flex-wrap items-center justify-center gap-5 whitespace-pre-wrap text-lg text-primary-500"
|
||||||
|
>
|
||||||
|
<h2
|
||||||
|
v-animate="{ preset: 'slide-right', duration: 500 }"
|
||||||
|
class="mb-10 text-center text-3xl font-bold"
|
||||||
|
>
|
||||||
|
{{ t("title") }}
|
||||||
|
</h2>
|
||||||
|
<div v-animate="{ preset: 'slide-right', delay: 400, duration: 500 }">
|
||||||
|
{{ t("message") }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const { t } = useI18n({ useScope: "local" });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<i18n lang="yaml">
|
||||||
|
en:
|
||||||
|
message: |
|
||||||
|
Hi,
|
||||||
|
My name is Timo Boomers (16) also known as Xeovalyte. I live in the Netherlands and I have always found electronics and computers interesting.
|
||||||
|
|
||||||
|
When I was 12 I started programming. I now program Websites, Discord bots and Arduino.
|
||||||
|
|
||||||
|
title: "About"
|
||||||
|
|
||||||
|
nl:
|
||||||
|
message: |
|
||||||
|
Hallo,
|
||||||
|
Mijn naam is Timo Boomers (16) ook wel bekend als Xeovalyte. Ik heb electronica en computers altijd interresant gevonden en ben toen gaan programmeren.
|
||||||
|
|
||||||
|
Toen ik 12 was begon ik met programmeren. Ondertussen programmeer ik Websites, Discord bots en Arduino.
|
||||||
|
|
||||||
|
title: "Over mij"
|
||||||
|
</i18n>
|
44
components/slides/Heading.vue
Normal file
44
components/slides/Heading.vue
Normal file
@@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<section
|
||||||
|
class="relative flex h-screen snap-center items-center justify-center"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
class="flex flex-wrap items-center justify-center gap-5 text-center text-primary-500"
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
v-animate="{ preset: 'slide-left', delay: 300 }"
|
||||||
|
src="../../assets/icons/logo.svg"
|
||||||
|
alt="Logo Xeovalyte"
|
||||||
|
width="150"
|
||||||
|
/>
|
||||||
|
<div class="space-y-2">
|
||||||
|
<h1
|
||||||
|
v-animate="{ preset: 'slide-up', delay: 450 }"
|
||||||
|
class="sm:text-7xl text-6xl font-bold"
|
||||||
|
>
|
||||||
|
Xeovalyte
|
||||||
|
</h1>
|
||||||
|
<div
|
||||||
|
v-animate="{ preset: 'slide-right', delay: 600 }"
|
||||||
|
class="h-1 w-full rounded-full bg-primary-500"
|
||||||
|
/>
|
||||||
|
<h3
|
||||||
|
v-animate="{ preset: 'slide-down', delay: 750 }"
|
||||||
|
class="text-4xl font-bold"
|
||||||
|
>
|
||||||
|
Timo Boomers
|
||||||
|
</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
@click="scrollToElement('about')"
|
||||||
|
size="2em"
|
||||||
|
name="ph:arrow-fat-line-down"
|
||||||
|
class="absolute bottom-20 basis-full animate-bounce hover:cursor-pointer"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
</script>
|
85
components/slides/Skills.vue
Normal file
85
components/slides/Skills.vue
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<section class="flex h-screen snap-center items-center justify-center">
|
||||||
|
<div
|
||||||
|
class="my-40 mx-5 flex w-full max-w-3xl flex-col text-primary-500"
|
||||||
|
v-animate="{ stagger: true, preset: 'slide-left', duration: 500 }"
|
||||||
|
>
|
||||||
|
<h2 class="mb-10 text-center text-3xl font-bold">
|
||||||
|
{{ t("skills.skills") }}
|
||||||
|
</h2>
|
||||||
|
<h2 class="text-lg font-bold">Arduino</h2>
|
||||||
|
<div class="mb-5 grid grid-cols-5 items-center gap-x-4">
|
||||||
|
<div
|
||||||
|
class="col-span-5 h-4 w-full rounded-full bg-dark-600 sm:col-span-4"
|
||||||
|
>
|
||||||
|
<div class="h-4 w-3/5 rounded-full bg-primary-100" />
|
||||||
|
</div>
|
||||||
|
<h2 class="hidden text-lg font-bold sm:inline-block">
|
||||||
|
{{ t("skills.intermediate") }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<h2 class="text-lg font-bold">Docker</h2>
|
||||||
|
<div class="mb-5 grid grid-cols-5 items-center gap-x-4">
|
||||||
|
<div
|
||||||
|
class="col-span-5 h-4 w-full rounded-full bg-dark-600 sm:col-span-4"
|
||||||
|
>
|
||||||
|
<div class="h-4 w-4/5 rounded-full bg-primary-100" />
|
||||||
|
</div>
|
||||||
|
<h2 class="hidden text-lg font-bold sm:inline-block">
|
||||||
|
{{ t("skills.advanced") }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<h2 class="text-lg font-bold">Javascript</h2>
|
||||||
|
<div class="mb-5 grid grid-cols-5 items-center gap-x-4">
|
||||||
|
<div
|
||||||
|
class="col-span-5 h-4 w-full rounded-full bg-dark-600 sm:col-span-4"
|
||||||
|
>
|
||||||
|
<div class="h-4 w-2/3 rounded-full bg-primary-100" />
|
||||||
|
</div>
|
||||||
|
<h2 class="hidden text-lg font-bold sm:inline-block">
|
||||||
|
{{ t("skills.intermediate") }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<h2 class="text-lg font-bold">Linux</h2>
|
||||||
|
<div class="mb-5 grid grid-cols-5 items-center gap-x-4">
|
||||||
|
<div
|
||||||
|
class="col-span-5 h-4 w-full rounded-full bg-dark-600 sm:col-span-4"
|
||||||
|
>
|
||||||
|
<div class="h-4 w-4/5 rounded-full bg-primary-100" />
|
||||||
|
</div>
|
||||||
|
<h2 class="hidden text-lg font-bold sm:inline-block">
|
||||||
|
{{ t("skills.advanced") }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
<h2 class="text-lg font-bold">Nuxt</h2>
|
||||||
|
<div class="mb-5 grid grid-cols-5 items-center gap-x-4">
|
||||||
|
<div
|
||||||
|
class="col-span-5 h-4 w-full rounded-full bg-dark-600 sm:col-span-4"
|
||||||
|
>
|
||||||
|
<div class="h-4 w-3/5 rounded-full bg-primary-100" />
|
||||||
|
</div>
|
||||||
|
<h2 class="hidden text-lg font-bold sm:inline-block">
|
||||||
|
{{ t("skills.intermediate") }}
|
||||||
|
</h2>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const { t } = useI18n({ useScope: "local" });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<i18n lang="yaml">
|
||||||
|
en:
|
||||||
|
skills:
|
||||||
|
skills: "Skills"
|
||||||
|
intermediate: "Intermediate"
|
||||||
|
advanced: "Advanced"
|
||||||
|
|
||||||
|
nl:
|
||||||
|
skills:
|
||||||
|
skills: "Vaardigheden"
|
||||||
|
intermediate: "Gemiddeld"
|
||||||
|
advanced: "Geavanceerd"
|
||||||
|
</i18n>
|
4
composables/scrollToElement.js
Normal file
4
composables/scrollToElement.js
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
export default function (hash) {
|
||||||
|
const element = document.getElementById(hash)
|
||||||
|
element.scrollIntoView({ behavior: 'smooth' })
|
||||||
|
}
|
@@ -1,9 +1,44 @@
|
|||||||
// https://v3.nuxtjs.org/api/configuration/nuxt.config
|
// https://v3.nuxtjs.org/api/configuration/nuxt.config
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
modules: [
|
modules: [
|
||||||
'@nuxtjs/tailwindcss',
|
"@nuxtjs/tailwindcss",
|
||||||
'@vueuse/nuxt',
|
"@vueuse/nuxt",
|
||||||
'nuxt-icon',
|
"nuxt-icon",
|
||||||
'@nuxtjs/robots'
|
"nuxt-icons",
|
||||||
|
"@nuxtjs/robots",
|
||||||
|
"@nuxtjs/i18n",
|
||||||
|
"@nuxtjs/plausible",
|
||||||
|
],
|
||||||
|
plausible: {
|
||||||
|
domain: 'xeovalyte.com',
|
||||||
|
apiHost: 'https://plausible.xeovalyte.dev'
|
||||||
|
},
|
||||||
|
app: {
|
||||||
|
head: {
|
||||||
|
title: 'Xeovalyte | Timo Boomers Portfolio',
|
||||||
|
link: [
|
||||||
|
{
|
||||||
|
"rel": "icon",
|
||||||
|
"href": "/favicon.ico",
|
||||||
|
"type": "image/png"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
meta: [
|
||||||
|
{ name: 'description', content: 'This is the official portfolio of Xeovalyte or Timo Boomers'}
|
||||||
]
|
]
|
||||||
})
|
}
|
||||||
|
},
|
||||||
|
i18n: {
|
||||||
|
baseUrl: 'https://xeovalyte.com',
|
||||||
|
locales: [
|
||||||
|
{ code: 'en', iso: 'en-US', isCatchallLocale: true },
|
||||||
|
{ code: 'nl', iso: 'nl-NL'},
|
||||||
|
],
|
||||||
|
defaultLocale: 'en',
|
||||||
|
detectBrowserLanguage: {
|
||||||
|
useCookie: true,
|
||||||
|
cookieKey: 'i18n_redirected',
|
||||||
|
redirectOn: 'root',
|
||||||
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
|
4925
package-lock.json
generated
4925
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
18
package.json
18
package.json
@@ -8,13 +8,19 @@
|
|||||||
"postinstall": "nuxt prepare"
|
"postinstall": "nuxt prepare"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@nuxtjs/tailwindcss": "^6.2.0",
|
"@nuxtjs/tailwindcss": "^6.3.1",
|
||||||
"@vueuse/core": "^9.8.2",
|
"@vueuse/core": "^9.12.0",
|
||||||
"@vueuse/nuxt": "^9.8.2",
|
"@vueuse/nuxt": "^9.12.0",
|
||||||
"nuxt": "3.0.0",
|
"nuxt": "3.2.0",
|
||||||
"nuxt-icon": "^0.1.8"
|
"nuxt-icon": "^0.2.11",
|
||||||
|
"prettier": "^2.8.4",
|
||||||
|
"prettier-plugin-tailwindcss": "^0.2.2"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nuxtjs/robots": "^3.0.0"
|
"@nuxtjs/i18n": "^8.0.0-beta.9",
|
||||||
|
"@nuxtjs/plausible": "^0.2.0",
|
||||||
|
"@nuxtjs/robots": "^3.0.0",
|
||||||
|
"locomotive-scroll": "^4.1.4",
|
||||||
|
"nuxt-icons": "^3.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
pages/index.vue
Normal file
29
pages/index.vue
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<template>
|
||||||
|
<LayoutLeftbar />
|
||||||
|
<div id="observe" class="h-screen snap-y snap-mandatory overflow-y-auto overflow-x-hidden bg-dark-200">
|
||||||
|
<SlidesHeading id="heading" />
|
||||||
|
<SlidesAbout id="about" />
|
||||||
|
<SlidesSkills id="skills" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
const router = useRouter()
|
||||||
|
|
||||||
|
const callback = (entries, observer) => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
router.replace({ hash: '#' + entry.target.id})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
let targets = document.querySelectorAll('section')
|
||||||
|
const observer = new IntersectionObserver(callback, { root: document.querySelector('#observe'), threshold: 0.9 })
|
||||||
|
|
||||||
|
targets.forEach(target => {
|
||||||
|
observer.observe(target)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
</script>
|
101
plugins/motion.js
Normal file
101
plugins/motion.js
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
export default defineNuxtPlugin((NuxtApp) => {
|
||||||
|
|
||||||
|
NuxtApp.vueApp.directive('animate', (el, binding) => {
|
||||||
|
el.classList.add('animate')
|
||||||
|
|
||||||
|
el.setAttribute('data-animate-duration', binding.value.duration || 250 )
|
||||||
|
el.setAttribute('data-animate-delay', binding.value.delay || 200 )
|
||||||
|
el.setAttribute('data-animate-preset', binding.value.preset || 'fade' )
|
||||||
|
el.setAttribute('data-animate-stagger', binding.value.stagger || false )
|
||||||
|
el.setAttribute('data-animate-stagger-delay', binding.value.staggerDelay || 100 )
|
||||||
|
})
|
||||||
|
|
||||||
|
NuxtApp.hook('page:finish', () => {
|
||||||
|
const applyClasses = (el, type) => {
|
||||||
|
const initialClasses = JSON.parse(el.getAttribute('data-animate-initial'))
|
||||||
|
const animateClasses = JSON.parse(el.getAttribute('data-animate-animate'))
|
||||||
|
|
||||||
|
if (type === 'initial') {
|
||||||
|
Object.keys(initialClasses).forEach(x => {
|
||||||
|
el.style[x] = initialClasses[x]
|
||||||
|
})
|
||||||
|
|
||||||
|
el.style['transition-property'] = 'none'
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type === 'animate') {
|
||||||
|
Object.keys(animateClasses).forEach(x => {
|
||||||
|
el.style[x] = animateClasses[x]
|
||||||
|
})
|
||||||
|
|
||||||
|
el.style['transition-property'] = 'all'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const callback = (entries) => {
|
||||||
|
entries.forEach(entry => {
|
||||||
|
if (entry.isIntersecting) {
|
||||||
|
applyClasses(entry.target, 'animate')
|
||||||
|
} else {
|
||||||
|
applyClasses(entry.target, 'initial')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure staggering animations
|
||||||
|
let targets = document.querySelectorAll('.animate')
|
||||||
|
targets.forEach((target) => {
|
||||||
|
if (target.getAttribute('data-animate-stagger') === 'true') {
|
||||||
|
target.classList.remove('animate')
|
||||||
|
|
||||||
|
const collection = target.children
|
||||||
|
Object.values(collection).forEach((child, index) => {
|
||||||
|
child.setAttribute('data-animate-preset', target.getAttribute('data-animate-preset') )
|
||||||
|
child.setAttribute('data-animate-duration', target.getAttribute('data-animate-duration') )
|
||||||
|
|
||||||
|
child.style.transitionDelay = Number(target.getAttribute('data-animate-delay')) + index * Number(target.getAttribute('data-animate-stagger-delay')) + 'ms'
|
||||||
|
child.classList.add('animate')
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
target.style.transitionDelay = target.getAttribute('data-animate-delay') + 'ms'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// Configure presets
|
||||||
|
const observer = new IntersectionObserver(callback)
|
||||||
|
targets = document.querySelectorAll('.animate')
|
||||||
|
|
||||||
|
targets.forEach(target => {
|
||||||
|
const preset = target.getAttribute('data-animate-preset')
|
||||||
|
|
||||||
|
if (preset === 'fade') {
|
||||||
|
target.setAttribute('data-animate-initial', JSON.stringify({ opacity: 0 }))
|
||||||
|
target.setAttribute('data-animate-animate', JSON.stringify({ opacity: 100 }))
|
||||||
|
|
||||||
|
} else if (preset === 'slide-left') {
|
||||||
|
target.setAttribute('data-animate-initial', JSON.stringify({ opacity: 0, transform: 'translateX(-6em)', filter: 'blur(5px)' }))
|
||||||
|
target.setAttribute('data-animate-animate', JSON.stringify({ opacity: 100, transform: 'translateX(0)', filter: 'blur(0)' }))
|
||||||
|
|
||||||
|
} else if (preset === 'slide-right') {
|
||||||
|
target.setAttribute('data-animate-initial', JSON.stringify({ opacity: 0, transform: 'translateX(6em)', filter: 'blur(5px)' }))
|
||||||
|
target.setAttribute('data-animate-animate', JSON.stringify({ opacity: 100, transform: 'translateX(0)', filter: 'blur(0px)' }))
|
||||||
|
|
||||||
|
} else if (preset === 'slide-up') {
|
||||||
|
target.setAttribute('data-animate-initial', JSON.stringify({ opacity: 0, transform: 'translateY(-2em)', filter: 'blur(5px)' }))
|
||||||
|
target.setAttribute('data-animate-animate', JSON.stringify({ opacity: 100, transform: 'translateY(0)', filter: 'blur(0px)' }))
|
||||||
|
|
||||||
|
} else if (preset === 'slide-down') {
|
||||||
|
target.setAttribute('data-animate-initial', JSON.stringify({ opacity: 0, transform: 'translateY(2em)', filter: 'blur(5px)' }))
|
||||||
|
target.setAttribute('data-animate-animate', JSON.stringify({ opacity: 100, transform: 'translateY(0)', filter: 'blur(0px)' }))
|
||||||
|
}
|
||||||
|
|
||||||
|
applyClasses(target, 'initial')
|
||||||
|
|
||||||
|
target.classList.add('transition-all')
|
||||||
|
target.style['transition-duration'] = target.getAttribute('data-animate-duration') + 'ms'
|
||||||
|
|
||||||
|
observer.observe(target)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
BIN
public/favicon.ico
Normal file
BIN
public/favicon.ico
Normal file
Binary file not shown.
After Width: | Height: | Size: 91 KiB |
@@ -2,7 +2,32 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
content: [],
|
content: [],
|
||||||
theme: {
|
theme: {
|
||||||
extend: {},
|
extend: {
|
||||||
|
colors: {
|
||||||
|
dark: {
|
||||||
|
100: "#131920",
|
||||||
|
200: "#11171d",
|
||||||
|
300: "#0f141a",
|
||||||
|
400: "#0d1216",
|
||||||
|
500: "#0b0f13",
|
||||||
|
600: "#0a0d10",
|
||||||
|
700: "#080a0d",
|
||||||
|
800: "#06080a",
|
||||||
|
900: "#040506",
|
||||||
|
},
|
||||||
|
primary: {
|
||||||
|
100: "#66b2ff",
|
||||||
|
200: "#4da6ff",
|
||||||
|
300: "#39f",
|
||||||
|
400: "#1a8cff",
|
||||||
|
500: "#0080ff",
|
||||||
|
600: "#0073e6",
|
||||||
|
700: "#06c",
|
||||||
|
800: "#0059b3",
|
||||||
|
900: "#004c99",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
plugins: [],
|
plugins: [],
|
||||||
}
|
};
|
||||||
|
@@ -1,4 +1,5 @@
|
|||||||
{
|
{
|
||||||
// https://v3.nuxtjs.org/concepts/typescript
|
// https://v3.nuxtjs.org/concepts/typescript
|
||||||
"extends": "./.nuxt/tsconfig.json"
|
"extends": "./.nuxt/tsconfig.json",
|
||||||
|
"allowJs": true
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user