feat!: inserted new site
							
								
								
									
										6
									
								
								src/css/bootstrap.min.css
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										150
									
								
								src/css/style.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,150 @@
 | 
			
		||||
.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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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.6em;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.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 5rem;
 | 
			
		||||
  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;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										
											BIN
										
									
								
								src/docs/cv-wardtruyen-2025-Java.pdf
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								src/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 15 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/arch.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 41 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/docker.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 2.8 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/gitea.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 41 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/lua.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 81 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/me.jpg
									
									
									
									
									
										Executable file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 45 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/mountain2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/neovim.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 93 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/nginx.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 4.7 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/oneko.gif
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/tds1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 107 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/tds2.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 96 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/tds3.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 96 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/tds4.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 101 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/traefik.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 45 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/tux.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 47 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/windows.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 3.9 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								src/img/wterminal.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 19 KiB  | 
							
								
								
									
										329
									
								
								src/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						@@ -0,0 +1,329 @@
 | 
			
		||||
<!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>
 | 
			
		||||
 | 
			
		||||
  <meta name="description" content="Op zoek naar een Java developer job.">
 | 
			
		||||
 | 
			
		||||
  <!-- Facebook Meta Tags -->
 | 
			
		||||
  <meta property="og:url" content="https://www.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="/img/me.jpg">
 | 
			
		||||
 | 
			
		||||
  <!-- 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://www.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="/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 computer liefhebber met een gedreven, hulpvaardig karakter en een zeer technisch geinformeerde
 | 
			
		||||
            achtergrond. Bijleren doe ik graag. Werk met structuur en orde. Ik ben geduldig,
 | 
			
		||||
            zal met volle concentratie problemen aanpakken en 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 & REST</li>
 | 
			
		||||
              <li>SQL & Hibernate</li>
 | 
			
		||||
              <li>Lombok</li>
 | 
			
		||||
              <li>Maven & Gradle</li>
 | 
			
		||||
              <li>JSP</li>
 | 
			
		||||
              <li>JUnit</li>
 | 
			
		||||
              <li>Multithreading & Concurrency</li>
 | 
			
		||||
            </ul>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col-4">
 | 
			
		||||
            <h4>Front-end</h4>
 | 
			
		||||
            <ul>
 | 
			
		||||
              <li>JavaScript</li>
 | 
			
		||||
              <li>TypeScript</li>
 | 
			
		||||
              <li>Angular</li>
 | 
			
		||||
              <li>HTML & CSS</li>
 | 
			
		||||
              <li>NPM</li>
 | 
			
		||||
              <li>JQuery</li>
 | 
			
		||||
              <li>Bootstrap</li>
 | 
			
		||||
              <li>async & wait</li>
 | 
			
		||||
            </ul>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div class="col-4">
 | 
			
		||||
            <h4>Tools</h4>
 | 
			
		||||
            <ul>
 | 
			
		||||
              <li>Git</li>
 | 
			
		||||
              <li>Scrutm & Agile</li>
 | 
			
		||||
              <li>VS code & IntelliJ & vim</li>
 | 
			
		||||
              <li>Docker & Virtualisatie</li>
 | 
			
		||||
              <li>CI/CD</li>
 | 
			
		||||
              <li>Powershell & bash</li>
 | 
			
		||||
              <li>Terminal & SSH</li>
 | 
			
		||||
            </ul>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="row justify-content-center">
 | 
			
		||||
          <img class="img-icon" src="img/tux.png" alt="Linux" title="Tux, the linux mascot" />
 | 
			
		||||
          <img class="img-icon" src="img/arch.png" alt="Arch linux" title="Arch linux" />
 | 
			
		||||
          <img class="img-icon" src="img/windows.png" alt="Windows" title="MS Windows" />
 | 
			
		||||
          <img class="img-icon" src="img/traefik.png" alt="Traefik" title="Traefik: a reverse proxy" />
 | 
			
		||||
          <img class="img-icon" src="img/docker.png" alt="Docker" title="Docker" />
 | 
			
		||||
          <img class="img-icon" src="img/lua.png" alt="Lua" title="Lua script" />
 | 
			
		||||
          <img class="img-icon" src="img/neovim.png" alt="Neovim" title="Neovim editor" />
 | 
			
		||||
          <img class="img-icon" src="img/nginx.png" alt="Nginx" title="Nginx a reverse proxy" />
 | 
			
		||||
        </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 & 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 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 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 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 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">
 | 
			
		||||
            </img>
 | 
			
		||||
          </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>
 | 
			
		||||
    <footer class="text-end">
 | 
			
		||||
      <p class="text-secondary my-0 me-1">Life is a long lesson in humility.</p>
 | 
			
		||||
    </footer>
 | 
			
		||||
  </main>
 | 
			
		||||
 | 
			
		||||
  <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
									
								
							
							
						
						
							
								
								
									
										49
									
								
								src/js/main.js
									
									
									
									
									
										Normal 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
									
								
							
							
						
						@@ -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();
 | 
			
		||||
})();
 | 
			
		||||