revert
This commit is contained in:
parent
248868b1bd
commit
372984e55b
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 @@
|
||||
{}
|
@ -7,7 +7,7 @@ pipeline:
|
||||
username: xeovalyte
|
||||
password:
|
||||
from_secret: docker_password
|
||||
repo: gitea.xeovalyte.dev/xeovalyte/portfolio
|
||||
repo: gitea.xeovalyte.dev/xeovalyte/website
|
||||
tags:
|
||||
- latest
|
||||
registry: gitea.xeovalyte.dev
|
||||
|
44
assets/css/tailwind.css
Normal file
44
assets/css/tailwind.css
Normal file
@ -0,0 +1,44 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
|
||||
@layer base {
|
||||
h1 {
|
||||
@apply text-4xl;
|
||||
}
|
||||
h2 {
|
||||
@apply text-3xl;
|
||||
}
|
||||
h3 {
|
||||
@apply text-2xl;
|
||||
}
|
||||
h4 {
|
||||
@apply text-xl;
|
||||
}
|
||||
}
|
||||
|
||||
@layer utilities {
|
||||
.perspective {
|
||||
perspective: 100px;
|
||||
}
|
||||
|
||||
.preserve-3d {
|
||||
transform-style: preserve-3d;
|
||||
}
|
||||
|
||||
.distance-1 {
|
||||
transform: translateZ(-50px) scale(1.5);
|
||||
}
|
||||
|
||||
.distance-2 {
|
||||
transform: translateZ(-100px) scale(2);
|
||||
}
|
||||
|
||||
.distance-3 {
|
||||
transform: translateZ(-150px) scale(2.5);
|
||||
}
|
||||
|
||||
.-distance-1 {
|
||||
transform: translateZ(50px) scale(0.5);
|
||||
}
|
||||
}
|
41
components/About.vue
Normal file
41
components/About.vue
Normal file
@ -0,0 +1,41 @@
|
||||
<template>
|
||||
<section class="flex h-screen snap-center items-center justify-center">
|
||||
<div
|
||||
class="my-40 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>
|
40
components/Heading.vue
Normal file
40
components/Heading.vue
Normal file
@ -0,0 +1,40 @@
|
||||
<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="text-7xl 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
|
||||
size="2em"
|
||||
name="ph:arrow-fat-line-down"
|
||||
class="absolute bottom-20 basis-full animate-bounce hover:cursor-pointer"
|
||||
/>
|
||||
</div>
|
||||
</section>
|
||||
</template>
|
85
components/Skills.vue
Normal file
85
components/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>
|
@ -7,27 +7,7 @@ export default defineNuxtConfig({
|
||||
"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: [
|
||||
|
4831
package-lock.json
generated
4831
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -8,11 +8,10 @@
|
||||
"postinstall": "nuxt prepare"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxtjs/plausible": "^0.2.0",
|
||||
"@nuxtjs/tailwindcss": "^6.2.0",
|
||||
"@vueuse/core": "^9.8.2",
|
||||
"@vueuse/nuxt": "^9.8.2",
|
||||
"nuxt": "3.1.2",
|
||||
"nuxt": "3.0.0",
|
||||
"nuxt-icon": "^0.1.8",
|
||||
"prettier": "^2.8.3",
|
||||
"prettier-plugin-tailwindcss": "^0.2.2"
|
||||
@ -21,6 +20,7 @@
|
||||
"@nuxtjs/i18n": "^8.0.0-beta.9",
|
||||
"@nuxtjs/robots": "^3.0.0",
|
||||
"locomotive-scroll": "^4.1.4",
|
||||
"motion": "^10.15.5",
|
||||
"nuxt-icons": "^3.1.0"
|
||||
}
|
||||
}
|
||||
|
9
pages/index.vue
Normal file
9
pages/index.vue
Normal file
@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<div class="h-screen snap-y snap-mandatory overflow-y-auto bg-dark-200">
|
||||
<Heading />
|
||||
<About />
|
||||
<Skills />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup></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)
|
||||
})
|
||||
})
|
||||
})
|
Loading…
Reference in New Issue
Block a user