Compare commits

...

26 Commits

Author SHA1 Message Date
Ward Truyen
ae0e261618 fix: icon missing url 2025-08-19 17:00:06 +02:00
Ward Truyen
dfc9abbb6d feat: icons are now links too 2025-08-19 16:59:06 +02:00
Ward Truyen
90f4daa2ad feat: Updated Introduction to match CV 2025-08-02 22:12:37 +02:00
Ward Truyen
747de6374f fix: typo in cv 2025-08-02 22:12:04 +02:00
Ward Truyen
fc9691b228 feat: Updated CV 2025-08-02 22:01:52 +02:00
Ward Truyen
30ce8a4282 fix: pulled footer out of main and improved carousel img alt text 2025-07-28 10:42:53 +02:00
Ward Truyen
829075fe4d feat: OG metatags setting picture size 2025-07-27 17:52:55 +02:00
Ward Truyen
3065719d7d fix: OG urls should not have www 2025-07-27 17:48:34 +02:00
Ward Truyen
9040f5ad53 fix: OG image not comming through again 2025-07-27 17:45:17 +02:00
Ward Truyen
9a1f0361bc fix: OG image not comming through 2025-07-27 15:34:29 +02:00
Ward Truyen
c79327a6f8 feat: added favicon link in head 2025-07-27 15:21:46 +02:00
Ward Truyen
2f6e9d4ea2 chore: improved visibility on low res mobile 2025-07-27 15:12:30 +02:00
Ward Truyen
b6472fadcd docs: Added short README.md 2025-07-27 14:17:44 +02:00
Ward Truyen
651dd34bf5 feat!: inserted new site 2025-07-27 14:10:59 +02:00
Ward Truyen
90cdef8909 feat!:moved old site to old folder 2025-07-27 14:10:26 +02:00
Ward Truyen
d0b6ee4a0f Chore: updated CV and small changes 2025-07-22 14:13:02 +02:00
Ward Truyen
c9e0d76cb4 Chore: Update Jan25 2025 2025-01-25 14:37:04 +01:00
Ward Truyen
437823c46f Chore: CV fix 2024-11-27 22:55:56 +01:00
Ward Truyen
75ba7aebf8 Chore: Cleanup 2024-11-27 22:33:05 +01:00
Ward Truyen
c4a265f2d2 Chore: update Nov 27 2024-11-27 21:56:57 +01:00
Ward Truyen
7f226c1a8b update 26 Nov 2024-11-27 20:51:51 +01:00
Ward Truyen
9558b09fc2 Chore: fixed resizing carrousel 2024-11-21 14:13:12 +01:00
Ward Truyen
0c6dbbc544 Chore: resize carrousel on small screens 2024-11-21 13:58:04 +01:00
Ward Truyen
36ba53eb2e Chore: improved background styling 2024-11-21 13:26:40 +01:00
Ward Truyen
5b5bb68f50 Chore: added photo carrousel 2024-11-21 12:10:28 +01:00
Ward Truyen
40482a1336 Updated CV + Screenshots 2024-11-21 11:48:58 +01:00
30 changed files with 891 additions and 256 deletions

10
README.md Normal file
View File

@@ -0,0 +1,10 @@
# Ward Truyen's CV website
Made using Bootstrap, Oneko's cat, and Zumari's Starback.
As required created with CSS, HTML and JavaScript.
## Thanks to
- My wife and son.
- Uncle Miel.
- The rest of the families.

6
src/css/bootstrap.min.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,122 +0,0 @@
/* Author: Ward Truyen
* Version: 1.0.0
*/
html,
body {
margin: 0px;
padding: 0px;
height: 100%;
display: flex;
flex-direction: column;
}
.theme-button {
float: right;
margin: 0.5em;
}
.card{
padding: 10px;
border: 1px solid darkblue;
background-color: #ffffffcc;
border-radius: 0.5em;
box-shadow: 3px 3px 3px #30303090;
margin: 1em 0.5em;
display: inline-block;
}
.card>h1{
font-size: 2em;
}
html {
background-image: linear-gradient(-30deg, #C0E0FF6F 70%, #FFE0C04F);
}
main {
margin: auto;
/* margin-top: 1em; */
min-width: 80%;
min-height: 40%;
overflow: auto;
padding-right: 8px;
}
main>div {
padding: 10px;
border: 1px solid darkblue;
background-color: #ffffffcc;
box-shadow: 3px 3px 3px #30303090;
margin-top: 1em;
margin-bottom: 1em;
}
main>div>h1 {
font-family: "Raleway", sans-serif;
font-size: 3em;
margin-top: 0px;
margin-bottom: 8px;
text-decoration: underline;
text-shadow: 0px 0px 4px white, 2px 2px 6px;
}
main>p,
main>div>p {
margin-left: 1em;
}
main>h2,
main>div>h2 {
margin-left: 0.2em;
}
main>h2{
margin-top: 1.5em;
}
main>div>h2 {
margin-top: 0.2em;
}
main>h3{
margin-left: 0.8em;
margin-top: 0.5em;
margin-bottom: 0.5em;
}
img {
display: block;
margin: 0 auto;
max-width: 100%;
}
ul.dashed {
list-style-type: '- ';
}
.text-red {
color: red;
}
html.theme-dark {
color-scheme: dark;
background-image: linear-gradient(-10deg, #1010206F 60%, #5050506F);
color: white;
}
.theme-dark>body>main>div {
border: 1px solid darkgray;
background-color: black;
box-shadow: 3px 3px 5px #101010C0;
}
.theme-dark>body>main>h1,
.theme-dark>body>main>div>h1 {
text-shadow: 0px 0px 3px blue, 2px 2px 6px;
}
@media(orientation: portrait) {
main {
margin-top: 0;
}
}

169
src/css/style.css Normal file
View File

@@ -0,0 +1,169 @@
.navbar {
background-color: #000b;
/* background: linear-gradient(0deg,rgba(35, 43, 62, 200) 0%, rgba(0, 0, 0, 200) 100%); */
border-bottom: 1px solid grey;
}
.divider {
height: 3rem;
background-color: rgba(0, 0, 0, .1);
border: solid rgba(0, 0, 0, .15);
border-width: 1px 0;
box-shadow: inset 0 .5em 1.5em rgba(0, 0, 0, .1), inset 0 .125em .5em rgba(0, 0, 0, .15);
}
.my-picture {
width: 8em;
aspect-ratio: 1;
border-radius: 5px;
float: right;
}
#icons>a {
display: inline;
width: unset;
}
.img-icon {
width: 4em;
aspect-ratio: 1;
margin: .5em .5em;
padding: 3px;
transition: all .2s;
border-radius: 5px;
}
.img-icon:hover {
width: 5em;
margin: 0;
border: 1px solid white;
box-shadow: 0 0 15px rgba(255, 255, 255, .8);
background-color: #FFFFFF88;
}
.card {
width: 40rem;
padding: 10px;
border: 1px solid black;
background-color: #aaaaaadd;
border-radius: 0.5em;
box-shadow: .5em .5em 1.5em rgba(0, 0, 0, .3);
margin: 1em 0.5em;
display: inline-block;
box-shadow: inset 0 0 3px black;
}
.card iframe {
width: 100%;
aspect-ratio: 16/9;
}
.card a {
color: #0000FF;
}
a {
color: #8888FF;
}
.carousel {
max-width: 80vh;
}
.carousel-control-next,
.carousel-control-prev {
filter: brightness(.5) drop-shadow(0px 0px 1px #FFFFFF);
}
.carousel-caption>h5 {
color: #aaaaffdd;
}
.carousel-indicators [data-bs-target] {
background-color: #aaaaffdd;
}
.attention {
font-size: 1.5em;
}
.rowlines-short li:not(:last-of-type)::after {
content: "";
width: 52%;
margin: 0 4rem;
border-bottom: 1px solid #66666688;
}
.rowlines li:not(:last-of-type)::after {
content: "";
width: 78%;
margin: 0 4rem;
border-bottom: 1px solid #66666688;
}
.rowlines-short li,
.rowlines li {
transition: all .2s;
}
.rowlines li:hover {
/* background-color: #8888; */
box-shadow: inset 0 0 3px white;
text-decoration: underline;
}
.rowlines-short li:hover {
text-decoration: underline;
}
canvas {
-webkit-transform: translate3d(0, 0, 0);
-moz-transform: translate3d(0, 0, 0);
transform: translate3d(0, 0, 0);
z-index: -2;
}
body {
overflow-x: hidden;
}
#canvas {
position: fixed;
top: 0px;
height: 100%;
width: 100%;
}
.note {
background: #00000032;
border: 2px solid #888888;
border-radius: 0.5em;
box-shadow: .5em .5em 1.5em rgba(0, 0, 0, .3);
padding: 1em;
margin: 1em auto;
width: 50%;
}
@media (max-width: 800px) {
.note {
width: 80%;
}
.card {
width: 32rem;
}
.attention {
font-size: 1.3em;
}
ul {
padding-left: 1rem;
}
}
@media(max-width: 600px) {
body {
font-size: 80%;
}
}

Binary file not shown.

Binary file not shown.

BIN
src/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
src/img/arch.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
src/img/docker.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

BIN
src/img/gitea.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

BIN
src/img/lua.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
src/img/me.jpg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
src/img/mountain2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

BIN
src/img/neovim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 93 KiB

BIN
src/img/nginx.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

BIN
src/img/oneko.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 78 KiB

After

Width:  |  Height:  |  Size: 107 KiB

BIN
src/img/tds2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
src/img/tds3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
src/img/tds4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

BIN
src/img/traefik.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

BIN
src/img/tux.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
src/img/windows.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.9 KiB

BIN
src/img/wterminal.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -1,96 +1,339 @@
<!DOCTYPE html> <!DOCTYPE html>
<html> <html lang="en">
<head> <head>
<title>Ward Truyen home</title> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/main.css" /> <title>Ward Truyen's CV</title>
</head> <link rel="shortcut icon" href="favicon.ico" />
<body> <meta name="description" content="Op zoek naar een Java developer job.">
<main>
<div> <!-- Facebook Meta Tags -->
<button class="theme-button" title="Dark theme on/off" onclick="toggleTheme();">&#9728;</button> <meta property="og:url" content="https://ward.truyen.network/">
<h1>Ward Truyen</h1> <meta property="og:type" content="website">
<h2>Wie ben ik:</h2> <meta property="og:title" content="Ward Truyen's CV">
<p>Ik ben een computerliefhebber op zoek naar een job in de ICT, als programmeur. </p> <meta property="og:description" content="Op zoek naar een Java developer job.">
<meta property="og:image" content="https://ward.truyen.network/img/me.jpg">
<p>Sinds de jaren '90, van Dos naar Windows en later Linux ben ik in de ICT wereld actief. <meta property="og:image:width" content="400">
<br>Daarbij heb ik vele mensen geholpen met hun computer problemen, of als trainer mensen geholpen naar junior <meta property="og:image:height" content="400">
Java developer.
<br>Meestal ben ik bezig in de talen Java en Java-/Type-Script alsook bijhorende frameworks en tools: <!-- Twitter Meta Tags -->
<ul> <meta name="twitter:card" content="summary_large_image">
<li>Java, Maven/Gradle, Spring, Hibernate/SQL, Lombok, JUnit, enz. voor Back-end</li> <meta property="twitter:domain" content="ward.truyen.network">
<li>HTML, CSS, JavaScript, Typescript &amp; Angular enz. voor Front-end</li> <meta property="twitter:url" content="https://ward.truyen.network/">
<li>Git en vele andere tools en scripts om de server en code te beheren en in productie te zetten.</li> <meta name="twitter:title" content="Ward Truyen's CV">
</ul> <meta name="twitter:description" content="Op zoek naar een Java developer job.">
</p> <meta name="twitter:image" content="https://ward.truyen.network/img/me.jpg">
<p>Ook Agile en Scrum zijn gekende termen, evenals OOP, TDD, UML enz.</p>
<p>Uiteraard kan ik blindelings typen, en thuis gebruik ik <a href="https://neovim.io/" <link rel="stylesheet" href="css/bootstrap.min.css" />
target="_blank">neo<b>vim</b> als IDE</a>. <link rel="stylesheet" href="css/style.css">
<br>Ik ken mijn weg op een server, desktop, laptop, tablet en op smartphone. </head>
</p>
<p>Voor meer informatie <a href="docs/CV_WardTruyen_2024.pdf">bekijk mijn cv</a>.</p> <body class="text-bg-dark bg-dark">
</div> <header>
<h2>Zelf gemaakt 2024:</h2> <nav class="navbar navbar-expand-md fixed-top navbar-dark">
<h3>Deze website</h3> <div class="container-fluid">
<p>Deze <a href="https://nl.wikipedia.org/wiki/Server" <a class="navbar-brand" href="#">Ward Truyen</a>
title="Een server is een computer dat diensten verleent aan clients" target="_blank">server</a> heb ik kunnen <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown"
opzetten met aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<a href="https://archlinux.org/" title="Besturingssysteem Arch Linux" target="_blank">Arch Linux</a> als <a <span class="navbar-toggler-icon"></span>
href="https://nl.wikipedia.org/wiki/Besturingssysteem" title"Besturingssysteem" target="_blank">OS</a>. </button>
<br>Daarop staat <a href="https://doc.traefik.io/traefik/" title="Reverse proxy en load balancer" <div class="collapse navbar-collapse" id="navbarNavDropdown">
target="_blank">Traefik</a> als <a href="https://en.wikipedia.org/wiki/Reverse_proxy" <ul class="navbar-nav ms-auto mb-2 mb-lg-0">
title="1 domein en server met meerdere subdomeinen en/of servers en services" target="_blank">reverse <li class="nav-item">
proxy</a> en de vele <a href="https://nl.wikipedia.org/wiki/Subdomein" <a class="nav-link" href="#skills">Vaardigheden</a>
title="Een subdomein is een domein dat deel uitmaakt van een groter domein" target="_blank">subdomeinen</a> </li>
zijn <li class="nav-item">
m.b.v. <a href="https://www.docker.com/" title="Container applicatie" target="_blank">Docker</a> beheerd. <a class="nav-link" href="#werk">Werkervaring</a>
</p> </li>
<h3>Familie website</h3> <li class="nav-item">
<p>Op <a href="https://tds.truyen.network" target="_blank">tds.truyen.network</a> staat mijn gezin data beheer site. <a class="nav-link" href="#studies">Studies</a>
Deze is gemaakt met als backend Java, Spring en REST, als frontend is er Angular.</p> <img src="img/tds1.png" </li>
alt="tds.truyen.network"> <li class="nav-item">
<p>Op <a href="https://sf.truyen.network" target="_blank">sf.truyen.network</a> staat een kopie van diezelfde site, <a class="nav-link" href="#portfolio">Portfolio</a>
waar u op kan inloggen en inspecteren (login gegevens staan in mijn CV).<br> Mocht er hier iets fout lopen, stuur </li>
me a.u.b. een e-mail of bel me, en ik los het ASAP op.</p> </ul>
<h3>WTerminal</h3> </div>
<p>Op <a href="https://wterminal.truyen.network" target="_blank">wterminal.truyen.network</a> kan u mijn </div>
browser-addon of website-tooltje WTerminal vinden.</p> </nav>
<h2>Zelf gemaakt vroeger:</h2> </header>
<div class="card">
<h1>Ronny</h1> <main>
<p>Gemaakt in VB.net 2004-2006<br>Direct draw rendering</p> <h1 class="visually-hidden">Ward Truyen's CV</h1>
<iframe src="https://www.youtube.com/embed/m7tgDUc2jXs"> <section id="intro">
</iframe> <div class="p-2 my-5">
</div> <div class="note">
<div class="card"> <h2 class="d-inline">Introductie</h2>
<h1>Minesweeper</h1> <img class="my-picture d-none d-md-block" src="img/me.jpg" alt="[my picture]" />
<p>Gemaakt in C/C++ 2006-2013<br>OpenGL rendering</p> <p>Ik ben een gepassioneed informaticus. Ik heb een hulpvaardig karakter en ben zeer technisch geinformeerd.
<iframe src="https://www.youtube.com/embed/Rejp6cVRxfc"> Bijleren doe ik graag en kan genieten van structuur en orde in mijn werk. Ik ben geduldig
</iframe> en kan met volle concentratie problemen aanpakken en daarbij streven naar afwerking.
</div> Je kan me vinden voor een aangename babbel of een luisterend oor.</p>
<div> <a href="docs/cv-wardtruyen-2025-Java.pdf" class="btn btn-primary" download>Download mijn CV</a>
<h2>Links naar de verschillende domeinen op deze server:</h2> </div>
<ul class="dashed"> </div>
<li>website <a href="https://truyen.network" target="_blank">truyen.network</a> centrale website</li> </section>
<li>gitea service op <a href="https://git.truyen.network" target="_blank">git.truyen.network</a> om git
repositories te beheren</li> <div id="skills" class="divider"></div>
<li>website <a href="https://tds.truyen.network" target="_blank">tds.truyen.network</a> voor gezin data beheer
</li> <section>
<li>voorbeeld-website <a href="https://sf.truyen.network" target="_blank">sf.truyen.network</a> voor gezin data <div class="px-4 py-4">
beheer</li> <h2>Vaardigheden</h2>
<li>website <a href="https://willem.truyen.network" target="_blank">willem.truyen.network</a> bevat spelletjes <div class="row">
voor Willem</li> <div class="col-4">
<li>website <a href="https://wterminal.truyen.network" target="_blank">wterminal.truyen.network</a> voor <h4>Back-end</h4>
WTerminal, zelf gemaakte browser-addon project</li> <ul>
</ul> <li>Java EE</li>
<p class="text-red">Deze server wordt nog verder uitgebreid, stay tuned.</p> <li>Spring &amp; REST</li>
<p>Laatste update: 17 Oktober 2024</p> <li>SQL &amp; Hibernate</li>
</div> <li>Lombok</li>
</main> <li>Maven &amp; Gradle</li>
<li>JSP</li>
<script src="js/theme.js"></script> <li>JUnit</li>
</body> <li>Multithreading &amp; Concurrency</li>
</ul>
</html> </div>
<div class="col-4">
<h4>Front-end</h4>
<ul>
<li>JavaScript</li>
<li>TypeScript</li>
<li>Angular</li>
<li>HTML &amp; CSS</li>
<li>NPM</li>
<li>JQuery</li>
<li>Bootstrap</li>
<li>async &amp; wait</li>
</ul>
</div>
<div class="col-4">
<h4>Tools</h4>
<ul>
<li>Git</li>
<li>Scrutm &amp; Agile</li>
<li>VS code &amp; IntelliJ &amp; vim</li>
<li>Docker &amp; Virtualisatie</li>
<li>CI/CD</li>
<li>Powershell &amp; bash</li>
<li>Terminal &amp; SSH</li>
</ul>
</div>
</div>
<div class="row justify-content-center" id="icons">
<a target="_blank" href="https://en.wikipedia.org/wiki/Linux">
<img class="img-icon" src="img/tux.png" alt="Linux" title="Tux, the linux mascot" /></a>
<a target="_blank" href="https://archlinux.org">
<img class="img-icon" src="img/arch.png" alt="Arch linux" title="Arch linux" /></a>
<a target="_blank" href="https://www.microsoft.com/nl-be/windows">
<img class="img-icon" src="img/windows.png" alt="Windows" title="MS Windows" /></a>
<a target="_blank" href="https://traefik.io">
<img class="img-icon" src="img/traefik.png" alt="Traefik" title="Traefik: a reverse proxy" /></a>
<a target="_blank" href="https://www.docker.com">
<img class="img-icon" src="img/docker.png" alt="Docker" title="Docker" /></a>
<a target="_blank" href="https://www.lua.org">
<img class="img-icon" src="img/lua.png" alt="Lua" title="Lua script" /></a>
<a target="_blank" href="https://neovim.io">
<img class="img-icon" src="img/neovim.png" alt="Neovim" title="Neovim editor" /></a>
<a target="_blank" href="https://nginx.org">
<img class="img-icon" src="img/nginx.png" alt="Nginx" title="Nginx a reverse proxy" /></a>
</div>
</div>
</section>
<div id="werk" class="divider"></div>
<section>
<div class="px-4 py-4">
<h2>Werkervaring</h2>
<ul class="rowlines">
<li class="row attention">
<span class="col-5">Opleiding Java Enterprise</span>
<span class="col-4">/</span>
<span class="col-3">2025 - Nu</span>
</li>
<li class="row text-secondary">
<span class="col-5">Tijdelijke Interim jobs</span>
<span class="col-4">Verscheidene werkplaatsen</span>
<span class="col-3">2025 - Nu</span>
</li>
<li class="row">
<span class="col-5">Zelfstudie Angular en docker</span>
<span class="col-4">/</span>
<span class="col-3">2023 - 2025</span>
</li>
<li class="row">
<span class="col-5">Allround ICT-er</span>
<span class="col-4">Nelissen computers</span>
<span class="col-3">2022 - 2022</span>
</li>
<li class="row attention">
<span class="col-5">ICT Trainer Java</span>
<span class="col-4">Multimedi</span>
<span class="col-3">2018 - 2021</span>
</li>
<li class="row">
<span class="col-5">Zelfstudie Java en Linux</span>
<span class="col-4">/</span>
<span class="col-3">2016 - 2017</span>
</li>
<li class="row">
<span class="col-5">Helpdesk technische dienst</span>
<span class="col-4">KUL</span>
<span class="col-3">2015 - 2016</span>
</li>
<li class="row">
<span class="col-5">Vrijwillig programmeur</span>
<span class="col-4">KUL</span>
<span class="col-3">2013 - 2014</span>
</li>
<li class="row text-secondary">
<span class="col-5">Tijdelijke Interim jobs</span>
<span class="col-4">Verscheidene werkplaatsen</span>
<span class="col-3">2007 - 2013</span>
</li>
<li class="row attention">
<span class="col-5">Programmeur C++</span>
<span class="col-4">Zetes</span>
<span class="col-3">2007 - 2007</span>
</li>
<li class="row">
<span class="col-5">Computer dokter</span>
<span class="col-4">Compudoc</span>
<span class="col-3">2006 - 2007</span>
</li>
</ul>
</div>
</section>
<div id="studies" class="divider"></div>
<section>
<div class="px-4 py-4">
<h2>Studies</h2>
<ul class="rowlines-short">
<li class="row">
<span class="col-6">Multimedi Java Enterprise ontwikkelaar</span>
<span class="col-6">2025 - nu</span>
</li>
<li class="row">
<span class="col-6">Multimedi Systeembeheer</span>
<span class="col-6">2017 - 2018</span>
</li>
<li class="row">
<span class="col-6">Cevora Java Enterprise ontwikkelaar</span>
<span class="col-6">2008 - 2009</span>
</li>
<li class="row">
<span class="col-6">A2: Elektrische installatietechnieken</span>
<span class="col-6">1998 - 2004</span>
</li>
</ul>
</div>
</section>
<div id="portfolio" class="divider"></div>
<section>
<div class="px-4 py-4">
<h2>Portfolio</h2>
<h4>Huidig project:</h4>
<a target="_blank" href="https://tds.truyen.network">TDS Family website</a>
<p>Full stack Java &amp; Angular website.</p>
<div id="carouselExampleIndicators" class="carousel carousel-dark slide carousel-fade mx-auto">
<div class="carousel-indicators">
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="0" class="active"
aria-current="true" aria-label="Slide 1"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="1"
aria-label="Slide 2"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="2"
aria-label="Slide 3"></button>
<button type="button" data-bs-target="#carouselExampleIndicators" data-bs-slide-to="3"
aria-label="Slide 4"></button>
</div>
<div class="carousel-inner">
<div class="carousel-item active">
<img src="img/tds1.png" class="d-block w-100" alt="Screenshot TDS Familiy site 1">
<div class="carousel-caption d-none d-md-block">
<h5>1</h5>
</div>
</div>
<div class="carousel-item">
<img src="img/tds2.png" class="d-block w-100" alt="Screenshot TDS Familiy site 2">
<div class="carousel-caption d-none d-md-block">
<h5>2</h5>
</div>
</div>
<div class="carousel-item">
<img src="img/tds3.png" class="d-block w-100" alt="Screenshot TDS Familiy site 3">
<div class="carousel-caption d-none d-md-block">
<h5>3</h5>
</div>
</div>
<div class="carousel-item">
<img src="img/tds4.png" class="d-block w-100" alt="Screenshot TDS Familiy site 4">
<div class="carousel-caption d-none d-md-block">
<h5>4</h5>
</div>
</div>
</div>
<button class="carousel-control-prev" type="button" data-bs-target="#carouselExampleIndicators"
data-bs-slide="prev">
<span class="carousel-control-prev-icon" aria-hidden="true"></span>
<span class="visually-hidden">Previous</span>
</button>
<button class="carousel-control-next" type="button" data-bs-target="#carouselExampleIndicators"
data-bs-slide="next">
<span class="carousel-control-next-icon" aria-hidden="true"></span>
<span class="visually-hidden">Next</span>
</button>
</div>
<h4>Websites:</h4>
<ul>
<li><a target="_blank" href="https://ward.truyen.network">Ward(this one)</a></li>
<li><a target="_blank" href="https://willem.truyen.network">Willem games</a></li>
<li><a target="_blank" href="https://git.truyen.network">Gitea</a></li>
<!-- <li><a target="_blank" href="https://wterminal.truyen.network">WTerminal</a></li> -->
</ul>
<br>
<h4>Oudere projecten:</h4>
<div class="row">
<div class="card">
<a target="_blank" href="https://wterminal.truyen.network">
<h3>WTerminal</h3>
</a>
<p>JavaScript 2023-2024<br>
Kan gebruikt worden in websites en als browser-addon</p>
<h5>Screenshot:</h5>
<img style="width: 100%" src="img/wterminal.png" />
</div>
<div class="card">
<h3>Ronny</h3>
<p>VB.net 2004-2006<br>Game met Direct draw rendering</p>
<h5>Youtube video:</h5>
<iframe src="https://www.youtube.com/embed/m7tgDUc2jXs">
</iframe>
</div>
<div class="card">
<h3>Minesweeper</h3>
<p>C/C++ 2006-2013<br>Game met OpenGL rendering</p>
<h5>Youtube video:</h5>
<iframe src="https://www.youtube.com/embed/Rejp6cVRxfc">
</iframe>
</div>
</div>
</section>
</main>
<footer class="text-end">
<p class="text-secondary my-0 me-1">Life is a long lesson in humility.</p>
</footer>
<script src="js/bootstrap.min.js"></script>
<script src="js/starback.js"></script>
<canvas id="canvas"></canvas>
<script src="js/main.js"> </script>
<script src="js/oneko.js"> </script>
</body>
</html>

7
src/js/bootstrap.min.js vendored Normal file

File diff suppressed because one or more lines are too long

49
src/js/main.js Normal file
View File

@@ -0,0 +1,49 @@
const starback = new Starback("#canvas", {
width: document.body.clientWidth,
height: document.body.clientHeight,
type: 'dot',
quantity: 100,
direction: 225,
backgroundColor: ['#0e1118', '#232b3e'],
randomOpacity: true,
});
const mountain = new Image();
mountain.src = 'img/mountain2.png';
mountain.onload = () => {
starback.addToFront((ctx) => {
ctx.drawImage(
mountain,
0,
0,
mountain.width,
mountain.height,
0,
canvas.height - mountain.height,
canvas.width,
mountain.height
);
});
}
function resizeCanvas() {
const canvas = document.getElementById("canvas");
canvas.setAttribute("width", window.innerWidth);
canvas.setAttribute("height", window.innerHeight);
}
function onLoadDoc() {
resizeCanvas();
const elements = document.getElementsByClassName("nav-link");
for (const el of elements) {
el.onclick = onNavLinkClick;
}
}
function onNavLinkClick() {
const collapse = document.getElementsByClassName('navbar-collapse');
if (collapse[0] != null)
collapse[0].classList.remove('show');
}
window.addEventListener("resize", resizeCanvas);
window.addEventListener("load", onLoadDoc);

310
src/js/oneko.js Normal file
View File

@@ -0,0 +1,310 @@
// oneko.js: https://github.com/adryd325/oneko.js
var onekoEnabled = true;
(function oneko() {
const isMobile = /iPhone|iPad|iPod|Android/i.test(navigator.userAgent);
const isReducedMotion =
window.matchMedia(`(prefers-reduced-motion: reduce)`) === true ||
window.matchMedia(`(prefers-reduced-motion: reduce)`).matches === true;
if (isReducedMotion || isMobile)
{
console.log("disabling cat");
onekoEnabled = false;
return;
}
const nekoEl = document.createElement("div");
let nekoPosX = window.innerWidth + 32;
let nekoPosY = window.innerHeight + 32;
let mousePosX = 0;
let mousePosY = 0;
let frameCount = 0;
let idleTime = 0;
let idleAnimation = null;
let idleAnimationFrame = 0;
const nekoSpeed = 10;
const spriteSets = {
idle: [[-3, -3]],
alert: [[-7, -3]],
scratchSelf: [
[-5, 0],
[-6, 0],
[-7, 0],
],
scratchWallN: [
[0, 0],
[0, -1],
],
scratchWallS: [
[-7, -1],
[-6, -2],
],
scratchWallE: [
[-2, -2],
[-2, -3],
],
scratchWallW: [
[-4, 0],
[-4, -1],
],
tired: [[-3, -2]],
sleeping: [
[-2, 0],
[-2, -1],
],
N: [
[-1, -2],
[-1, -3],
],
NE: [
[0, -2],
[0, -3],
],
E: [
[-3, 0],
[-3, -1],
],
SE: [
[-5, -1],
[-5, -2],
],
S: [
[-6, -3],
[-7, -2],
],
SW: [
[-5, -3],
[-6, -1],
],
W: [
[-4, -2],
[-4, -3],
],
NW: [
[-1, 0],
[-1, -1],
],
};
function init() {
nekoEl.id = "oneko";
nekoEl.ariaHidden = true;
nekoEl.style.width = "32px";
nekoEl.style.height = "32px";
nekoEl.style.position = "fixed";
nekoEl.style.pointerEvents = "none"; // no petting :(
nekoEl.style.imageRendering = "pixelated";
nekoEl.style.left = `${nekoPosX - 16}px`;
nekoEl.style.top = `${nekoPosY - 16}px`;
nekoEl.style.zIndex = 999999;
let nekoFile = "/img/oneko.gif"
const curScript = document.currentScript
if (curScript && curScript.dataset.cat) {
nekoFile = curScript.dataset.cat
}
nekoEl.style.backgroundImage = `url(${nekoFile})`;
document.body.appendChild(nekoEl);
document.addEventListener("mousemove", function(event) {
mousePosX = event.clientX;
mousePosY = event.clientY;
});
window.requestAnimationFrame(onAnimationFrame);
}
let lastFrameTimestamp;
function onAnimationFrame(timestamp) {
// Stops execution if the neko element is removed from DOM
if (!nekoEl.isConnected) {
return;
}
if (!lastFrameTimestamp) {
lastFrameTimestamp = timestamp;
}
if (timestamp - lastFrameTimestamp > 100) {
lastFrameTimestamp = timestamp
frame()
}
window.requestAnimationFrame(onAnimationFrame);
}
function setSprite(name, frame) {
const sprite = spriteSets[name][frame % spriteSets[name].length];
nekoEl.style.backgroundPosition = `${sprite[0] * 32}px ${sprite[1] * 32}px`;
}
function resetIdleAnimation() {
idleAnimation = null;
idleAnimationFrame = 0;
}
function idle() {
idleTime += 1;
// every ~ 20 seconds
if (
idleTime > 10 &&
Math.floor(Math.random() * 200) == 0 &&
idleAnimation == null
) {
let avalibleIdleAnimations = ["sleeping", "scratchSelf"];
let scratchDist = 64;
if (nekoPosX < scratchDist) {
avalibleIdleAnimations.push("scratchWallW");
}
if (nekoPosY < scratchDist) {
avalibleIdleAnimations.push("scratchWallN");
}
if (nekoPosX > window.innerWidth - scratchDist) {
avalibleIdleAnimations.push("scratchWallE");
}
if (nekoPosY > window.innerHeight - scratchDist) {
avalibleIdleAnimations.push("scratchWallS");
}
idleAnimation =
avalibleIdleAnimations[
Math.floor(Math.random() * avalibleIdleAnimations.length)
];
}
switch (idleAnimation) {
case "sleeping":
if (idleAnimationFrame < 8) {
setSprite("tired", 0);
break;
}
setSprite("sleeping", Math.floor(idleAnimationFrame / 4));
if (idleAnimationFrame > 192) {
resetIdleAnimation();
}
break;
case "scratchWallN":
case "scratchWallS":
case "scratchWallE":
case "scratchWallW":
case "scratchSelf":
setSprite(idleAnimation, idleAnimationFrame);
if (idleAnimationFrame > 9) {
resetIdleAnimation();
}
break;
default:
setSprite("idle", 0);
return;
}
idleAnimationFrame += 1;
}
function explodeHearts() {
const parent = nekoEl.parentElement;
const rect = nekoEl.getBoundingClientRect();
const scrollLeft = window.scrollX || document.documentElement.scrollLeft;
const scrollTop = window.scrollY || document.documentElement.scrollTop;
const centerX = rect.left + rect.width / 2 + scrollLeft;
const centerY = rect.top + rect.height / 2 + scrollTop;
for (let i = 0; i < 10; i++) {
const heart = document.createElement('div');
heart.className = 'heart';
heart.textContent = '❤';
const offsetX = (Math.random() - 0.5) * 50;
const offsetY = (Math.random() - 0.5) * 50;
heart.style.left = `${centerX + offsetX - 16}px`;
heart.style.top = `${centerY + offsetY - 16}px`;
heart.style.transform = `translate(-50%, -50%) rotate(${Math.random() * 360}deg)`;
parent.appendChild(heart);
setTimeout(() => {
parent.removeChild(heart);
}, 1000);
}
}
const style = document.createElement('style');
style.innerHTML = `
@keyframes heartBurst {
0% { transform: scale(0); opacity: 1; }
100% { transform: scale(1); opacity: 0; }
}
.heart {
position: absolute;
font-size: 2em;
animation: heartBurst 1s ease-out;
animation-fill-mode: forwards;
color: #ab9df2;
user-select: none;
}
`;
document.head.appendChild(style);
nekoEl.addEventListener('click', explodeHearts);
let previousOnekoEnabled = onekoEnabled;
function frame() {
if(previousOnekoEnabled != onekoEnabled)
{
nekoEl.style.display = onekoEnabled ? "block" : "none";
if(onekoEnabled)
document.getElementById("toggle-cat").classList.remove("sleepy");
else
document.getElementById("toggle-cat").classList.add("sleepy");
previousOnekoEnabled = onekoEnabled;
}
if (!onekoEnabled || mousePosX == 0 || mousePosY == 0)
return;
frameCount += 1;
const diffX = nekoPosX - mousePosX;
const diffY = nekoPosY - mousePosY;
const distance = Math.sqrt(diffX ** 2 + diffY ** 2);
if (distance < nekoSpeed || distance < 48) {
idle();
return;
}
idleAnimation = null;
idleAnimationFrame = 0;
if (idleTime > 1) {
setSprite("alert", 0);
// count down after being alerted before moving
idleTime = Math.min(idleTime, 7);
idleTime -= 1;
return;
}
let direction;
direction = diffY / distance > 0.5 ? "N" : "";
direction += diffY / distance < -0.5 ? "S" : "";
direction += diffX / distance > 0.5 ? "W" : "";
direction += diffX / distance < -0.5 ? "E" : "";
setSprite(direction, frameCount);
nekoPosX -= (diffX / distance) * nekoSpeed;
nekoPosY -= (diffY / distance) * nekoSpeed;
nekoPosX = Math.min(Math.max(16, nekoPosX), window.innerWidth - 16);
nekoPosY = Math.min(Math.max(16, nekoPosY), window.innerHeight - 16);
nekoEl.style.left = `${nekoPosX - 16}px`;
nekoEl.style.top = `${nekoPosY - 16}px`;
}
init();
})();

1
src/js/starback.js Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,38 +0,0 @@
function toggleTheme() {
const theme = "theme-dark";//localStorage.getItem('theme');
const root = document.querySelector(":root");
root.classList.toggle(theme);
if (root.classList.contains(theme)) {
localStorage.setItem('theme', theme);
} else {
localStorage.setItem('theme', "theme-light");
}
}
function setTheme(themeName) {
console.log("setting them: " + themeName);
const root = document.querySelector(":root");
root.classList.add(themeName);
localStorage.setItem('theme', themeName);
}
function detectTheme() {
const theme = localStorage.getItem('theme');
if (theme === 'theme-dark' || theme === 'theme-light') {
setTheme(theme);
return;
}
if (window.matchMedia('(prefers-color-scheme: dark)').matches) {
setTheme('theme-dark');
return;
}
if (window.matchMedia('(prefers-color-scheme: light)').matches) {
setTheme('theme-light');
return;
}
setTheme('theme-light');
}
detectTheme();