Compare commits

...

28 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
Ward Truyen
282b5b4380 chore: layout update Ronny+Minesweeper 2024-10-17 14:23:41 +02:00
Ward Truyen
0ba7fd1a8d chore: cv + layout update 2024-10-17 12:50:35 +02:00
30 changed files with 891 additions and 192 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,82 +0,0 @@
/* Author: Ward Truyen
* Version: 1.0.0
*/
html,
body {
margin: 0px;
padding: 0px;
height: 100%;
display: flex;
flex-direction: column;
}
html {
background-image: linear-gradient(-30deg, #C0E0FF6F 70%, #FFE0C04F);
}
main {
margin: auto;
margin-top: 1em;
min-width: 80%;
padding: 10px;
min-height: 40%;
overflow: auto;
/* colors */
border: 1px solid darkblue;
background-color: white;
box-shadow: 3px 3px 3px #30303090;
}
main>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 {
margin-left: 1em;
}
main>h2 {
margin-left: 0.2em;
}
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 {
border: 1px solid darkgray;
background-color: black;
box-shadow: 3px 3px 5px #101010C0;
}
.theme-dark>body>main>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,72 +1,339 @@
<!DOCTYPE html>
<html>
<head>
<title>Ward Truyen home</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="css/main.css" />
</head>
<body>
<main>
<button style="float: right; font-size:large;" title="Dark theme on/off" onclick="toggleTheme();">&#9728;</button>
<h1>Ward Truyen</h1>
<h2>Wie ben ik:</h2>
<p>Ik ben een computer expert op zoek naar een job in de ICT, als programmeur. </p>
<p>Sinds de jaren '90, van Dos naar Windows en later Linux ben ik in ICT mijn structuur en vernieuwing, alsook
plezier aan het vinden.
<br>Meestal ben ik bezig in de talen Java en Java-/Type-Script alsook bijhorende frameworks en tools:
<ul>
<li>Java, Maven/Gradle, Spring, Hibernate/SQL, Lombok, JUnit, enz. voor Back-end</li>
<li>HTML, CSS, JavaScript, Typescript &amp; Angular enz. voor Front-end</li>
<li>Git en vele andere tools en scripts om de server en code te beheren en in productie te zetten.</li>
</ul>
</p>
<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/">neo<b>vim</b> als IDE</a>.
<p>Deze <a href="https://nl.wikipedia.org/wiki/Server"
title="Een server is een computer dat diensten verleent aan clients" target="_blank">server</a> heb ik kunnen
opzetten met
<a href="https://archlinux.org/" title="Besturingssysteem Arch Linux" target="_blank">Arch Linux</a> als <a
href="https://nl.wikipedia.org/wiki/Besturingssysteem" title"Besturingssysteem" target="_blank">OS</a>, <a
href="https://doc.traefik.io/traefik/" title="reverse proxy en load balancer" target="_blank">Traefik</a> als <a
href="https://en.wikipedia.org/wiki/Reverse_proxy"
title="1 domein en server met meerdere subdomeinen en/of servers en services" target="_blank">reverse proxy</a>
en de vele <a href="https://nl.wikipedia.org/wiki/Subdomein"
title="Een subdomein is een domein dat deel uitmaakt van een groter domein" target="_blank">subdomeinen</a> zijn
m.b.v. <a href="https://www.docker.com/" title="Container applicatie" target="_blank">Docker</a> beheerd.
<br>Ik ken mijn weg op een server, desktop, laptop, tablet en op smartphone.
</p>
<p>Voor meer informatie <a href="docs/CV_WardTruyen_2024.pdf">bekijk mijn cv</a>.</p>
<h2>Zelf gemaakt:</h2>
<p>Op <a href="https://tds.truyen.network" target="_blank">tds.truyen.network</a> staat mijn gezin data beheer site.
Deze is gemaakt met als backend Java, Spring en REST, als frontend is er Angular.</p> <img src="img/tds1.png"
alt="tds.truyen.network">
<p>Op <a href="https://sf.truyen.network" target="_blank">sf.truyen.network</a> staat een kopie van diezelfde site,
waar u op kan inloggen en inspecteren (login gegevens staan in mijn CV).<br> Mocht er hier iets fout lopen, stuur
me a.u.b. een e-mail of bel me, en ik los het ASAP op.</p>
<p>Op <a href="https://wterminal.truyen.network" target="_blank">wterminal.truyen.network</a> kan u mijn
browser-addon of website-tooltje WTerminal vinden.</p>
<h2>Links naar de verschillende domeinen op deze server:</h2>
<ul class="dashed">
<li>website <a href="https://truyen.network" target="_blank">truyen.network</a> centrale website</li>
<li>gitea service op <a href="https://git.truyen.network" target="_blank">git.truyen.network</a> om git
repositories te beheren</li>
<li>website <a href="https://tds.truyen.network" target="_blank">tds.truyen.network</a> voor gezin data beheer
</li>
<li>voorbeeld-website <a href="https://sf.truyen.network" target="_blank">sf.truyen.network</a> voor gezin data
beheer</li>
<li>website <a href="https://willem.truyen.network" target="_blank">willem.truyen.network</a> bevat spelletjes
voor Willem</li>
<li>website <a href="https://wterminal.truyen.network" target="_blank">wterminal.truyen.network</a> voor
WTerminal, zelf gemaakte browser-addon project</li>
</ul>
<p class="text-red">Deze server wordt nog verder uitgebreid, stay tuned.</p>
<p>Laatste update: 3 Oktober 2024</p>
</main>
<script src="js/theme.js"></script>
</body>
</html>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Ward Truyen's CV</title>
<link rel="shortcut icon" href="favicon.ico" />
<meta name="description" content="Op zoek naar een Java developer job.">
<!-- Facebook Meta Tags -->
<meta property="og:url" content="https://ward.truyen.network/">
<meta property="og:type" content="website">
<meta property="og:title" content="Ward Truyen's CV">
<meta property="og:description" content="Op zoek naar een Java developer job.">
<meta property="og:image" content="https://ward.truyen.network/img/me.jpg">
<meta property="og:image:width" content="400">
<meta property="og:image:height" content="400">
<!-- Twitter Meta Tags -->
<meta name="twitter:card" content="summary_large_image">
<meta property="twitter:domain" content="ward.truyen.network">
<meta property="twitter:url" content="https://ward.truyen.network/">
<meta name="twitter:title" content="Ward Truyen's CV">
<meta name="twitter:description" content="Op zoek naar een Java developer job.">
<meta name="twitter:image" content="https://ward.truyen.network/img/me.jpg">
<link rel="stylesheet" href="css/bootstrap.min.css" />
<link rel="stylesheet" href="css/style.css">
</head>
<body class="text-bg-dark bg-dark">
<header>
<nav class="navbar navbar-expand-md fixed-top navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="#">Ward Truyen</a>
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNavDropdown"
aria-controls="navbarNavDropdown" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavDropdown">
<ul class="navbar-nav ms-auto mb-2 mb-lg-0">
<li class="nav-item">
<a class="nav-link" href="#skills">Vaardigheden</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#werk">Werkervaring</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#studies">Studies</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#portfolio">Portfolio</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<main>
<h1 class="visually-hidden">Ward Truyen's CV</h1>
<section id="intro">
<div class="p-2 my-5">
<div class="note">
<h2 class="d-inline">Introductie</h2>
<img class="my-picture d-none d-md-block" src="img/me.jpg" alt="[my picture]" />
<p>Ik ben een gepassioneed informaticus. Ik heb een hulpvaardig karakter en ben zeer technisch geinformeerd.
Bijleren doe ik graag en kan genieten van structuur en orde in mijn werk. Ik ben geduldig
en kan met volle concentratie problemen aanpakken en daarbij streven naar afwerking.
Je kan me vinden voor een aangename babbel of een luisterend oor.</p>
<a href="docs/cv-wardtruyen-2025-Java.pdf" class="btn btn-primary" download>Download mijn CV</a>
</div>
</div>
</section>
<div id="skills" class="divider"></div>
<section>
<div class="px-4 py-4">
<h2>Vaardigheden</h2>
<div class="row">
<div class="col-4">
<h4>Back-end</h4>
<ul>
<li>Java EE</li>
<li>Spring &amp; REST</li>
<li>SQL &amp; Hibernate</li>
<li>Lombok</li>
<li>Maven &amp; Gradle</li>
<li>JSP</li>
<li>JUnit</li>
<li>Multithreading &amp; Concurrency</li>
</ul>
</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();