My one-page code portfolio.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

658 lines
27 KiB

<!DOCTYPE html>
<html>
<title>Sander Vocke: Codefolio</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" href="https://www.w3schools.com/w3css/4/w3.css">
<link rel="stylesheet" href="https://www.w3schools.com/lib/w3-theme-black.css">
<body>
<!-- Header -->
<header class="w3-container w3-theme w3-padding" id="myHeader">
<div class="w3-center">
<h4>Sander Vocke</h4>
<h1 class="w3-xxxlarge w3-animate-bottom">CODEFOLIO</h1>
</div>
</header>
<!-- MODALS (popup windows describing portfolio items -->
<div id="Transpara-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('Transpara-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/transpara.png" style="width:15cm"></img>
<h3>ScreenPoint Transpara</h3>
<p style="text-align:left">
I have spent about three years at !!LINK!! Screenpoint Medical in Nijmegen, The Netherlands.
ScreenPoint's sole product, Transpara, is an artificial intelligence tool capable of helping
radiologists make more accurate diagnoses reading mammograms for breast cancer.
</p>
<p style="text-align:left">
In a small team of developers I took on many hats. My activities included:
<ul>
<li>Writing and optimizing image processing code in C++.</li>
<li>Developing DICOM communications code in C++.</li>
<li>Improving ScreenPoint's DevOps infrastructure.</li>
<li>Developing Windows-based interactive medical image viewing applications.</li>
</ul>
</p>
<p style="text-align:left">
While I am not free to publish details about these projects, I would be happy to provide
some more details on request.
</p>
<h3>Keywords</h3>
<p><b>C++11, DICOM, Python, DevOps, Docker</b></p>
<h3>Available?</h3>
<p>No. This is proprietary software, property of ScreenPoint Medical.</p>
</div>
</div>
</div>
<div id="BBStudio-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('BBStudio-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/BBStudio-anim.gif" style="width:15cm"></img>
<h3>BBStudio</h3>
<p style="text-align:left">
This takes me back... BBStudio was a project I did alone back in high school for coursework. I was
interested in graphics, game programming and physics engines, so decided to "roll" my own -
literally, because to keep it manageble for myself I limited it to only spherical objects. My basic
knowledge of Newtonian physics was enough to get the ball rolling! And I learned a lot in the
process.
</p>
<p>
I added 3D graphics rendering with the <a href="http://www.ogre3d.org/">OGRE 3D engine</a> and a UI
that allowed the user to design and store small ballular physics experiments.
</p>
<p>
By far the coolest Eureka moment for me: I added the option to define a force toward a fixed point
in space, and found out that if applied in combination with initial motion, the spheres actually
started following stable elliptical orbits! That to me was awesome, since the physics engine itself
was not much more than an implementation of Newton's second law.
</p>
<h3>Keywords</h3>
<p><b>C++, graphics, physics, UI</b></p>
<h3>Available?</h3>
<p>No, but only because it's old and back then I was unaware of the concept "open source". I can send or
publish the code on request.</p>
</div>
</div>
</div>
<div id="Intergalactic-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('Intergalactic-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/intergalactic_1.jpg" style="width:15cm"></img>
<h3>Intergalactic</h3>
<p style="text-align:left">
Another high-school personal project. This was from even before BBStudio. As I'm sure was true for
some other teenagers, my interest in programming stemmed partly from the fantasy of creating my own
computer games.
</p>
<p>
Although the project proved too ambitious for my own attention span, Intergalactic was a pretty cool
3D game. It used the <a href="http://irrlicht.sourceforge.net/">Irrlicht 3D engine</a>. It had two
of my own spaceship designs and a castle floating in space (taken directly from a Quake map).
</p>
<p>
The player could fly around in third-person with mouse controls, control the throttle and shoot
lasers. You could crash into the castle and explode. Enemies could be spawned - unfortunately, the
most sophisticated AI I came up with was for them to fly in circles forever. The climax was being
able to "lock on" to an enemy and fire a missile, which would turn towards the target to hit it.
</p>
<h3>Keywords</h3>
<p><b>C++, graphics</b></p>
<h3>Available?</h3>
<p>No, but only because it's old and back then I was unaware of the concept "open source". I can send or
publish the code on request.</p>
</div>
</div>
</div>
<div id="Cuber-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('Cuber-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/Cuber-anim.gif" style="width:15cm"></img>
<h3>Cuber</h3>
<p style="text-align:left">
During my BSc period, I got increasingly interested in electronics and microcontrollers, and decided
to learn more about it by starting another personal project.
</p>
<p>
Cuber is a 8x8x8 LED cube. The first skill I honed with this project was soldering: getting all
those LEDs in place and reliably connected was hard! I went for an ambitious wiring scheme, where
one microcontroller (programmed in optimized assembly) was required to rapidly control 128 shift
registers and switch power to subsets of LEDs to create the illusion of continuous light. The other
controller provided a UI through an LCD screen and buttons, and accepted the serial control stream
from a PC.
</p>
<p>I designed the Cuber circuit board in Eagle and etched it myself. It even had a "simulator" on PC
which could consume the exact same serial control stream from a virtual serial port as the real
Cuber, and showed all the LED states in an OpenGL rendering window. This allowed me to focus on
creating cool animations and a 3D Snake game.
</p>
<h3>Keywords</h3>
<p><b>Microcontrollers, C, ASM, Circuit Design, Board Layout</b></p>
<h3>Available?</h3>
<p>No, but only because it's old and back then I was unaware of the concept "open source". I gave the
cube away, and can't even find my cool video shots of it in action - but I can send or publish the
code and board design on request.</p>
</div>
</div>
</div>
<div id="Brap-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('Brap-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/brap_1.jpg" style="width:15cm"></img>
<h3>Brap</h3>
<p style="text-align:left">
My girlfriend and I love to travel. We have built up a huge amount of photos and videos because of
this.
</p>
<p>
My brother and I got together and cooked up a plan. We would both build a world map with built-in
photo/video viewer. He would design the hardware and I would design the user interface. The project
never quite got off the ground, but we still use "Brap" to view our collection from our NAS.
</p>
<p>
Brap has a HTML5+CSS+Javascript web front-end, PHP+SQLite back-end and a suite of Python scripts for
database management. All that together makes for a pretty good web design learning project.
</p>
<h3>Keywords</h3>
<p><b>HTML, CSS, Javascript, PHP, SQL</b></p>
<h3>Available?</h3>
<p>No, I kept this on my private BitBucket pending the time I would deem it "ready". That being said, I
can send or publish the code on request.</p>
</div>
</div>
</div>
<div id="EVC-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('EVC-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/evc_1.jpg" style="width:15cm"></img>
<h3>Embedded Visual Control</h3>
<p style="text-align:left">
This coursework project during my MSc program is worth mentioning, because we took it pretty far.
</p>
<p>
With three other students, we designed and built a solar-powered rover which could track and follow
colored objects. Some of my personal contributions:<br>
- The design choice to use a 360 degree bubble lens, giving the rover omni-vision.<br>
- The effort to squeeze every drop of performance from the Raspberry Pi by implementing object
segmentation for GPU in OpenGL ES, which is not at all meant to be used for computer vision.<br>
- The deep-dive into the Pi's memory management abstraction layer to make it possible to do
zero-copy streaming from the rover's GPU output over to a control station over WiFi.<br>
- A Python simulator which we could use to develop the rover's driving behaviour.<br>
</p>
<h3>Keywords</h3>
<p><b>OpenGL ES, Computer Vision, Motor Control</b></p>
<h3>Available?</h3>
<p>The full suite: no, because it is written for a specific rover that no-one is likely to replicate.
However, here are links to a few small parts like the <a
href="https://github.com/SanderVocke/robosim">Pygame rover movement simulator</a>, <a
href="https://github.com/SanderVocke/EVCMotorDriver">motor driver</a> and a condensed example of
the <a href="https://github.com/SanderVocke/picamgpu_minimal">camera to GPU memory</a> on GitHub.
</p>
</div>
</div>
</div>
<div id="HalideIPU-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('HalideIPU-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/halideipu_2.jpg" style="width:20cm"></img>
<h3>Halide for IPU</h3>
<p style="text-align:left">
<a href="http://halide-lang.org">Halide</a> is an emerging domain-specific language for image
processing. It is seeing increasing adoption in the industry - most notably at Google and Adobe.
</p>
<p>
During my MSc thesis at Intel's Imaging and Camera Technologies Group (ICG), I extended Halide with
a code generation back-end and syntax extensions for Intel's imaging DSPs, which are found in Intel
IPU subsystems. In the process, I showed that high-performance code generation from Halide for such
targets is feasible.
</p>
<p>
The project has been, and still is a joy to work on. Halide's relatively low complexity (compared to
full-fledged back-end compilers such as LLVM) and high extensibility made for a great way to get
acquainted with compiler techniques, code generation and automatic optimization. It has also opened
my eyes to domain-specific languages as a solution for the problem of maintaining portable, fast
code for increasingly specialized and diverse computing platforms.
</p>
<p>
The paper I authored about the topic is set to appear in <a href="http://www.acm.org/taco/">ACM
Transactions on Architecture and Code Optimization</a>. Until it is published, an abridged early
version can be found at the <a href="http://repository.tue.nl/866731">TU/e university
repository</a>.
</p>
<h3>Keywords</h3>
<p><b>C++11, Halide, DSP, Imaging, Compiler</b></p>
<h3>Available?</h3>
<p>Unfortunately, no. The codebase is closed to protect Intel sensitive information.</p>
</div>
</div>
</div>
<div id="Qi-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('Qi-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/qi_1.jpg" style="width:15cm"></img>
<h3>Qi Wireless Charging</h3>
<p style="text-align:left">
I spent about a year at <a href="http://www.powerbyproxi.com">PowerByProxi</a> in Auckland, New
Zealand, working on a new generation of Qi wireless smartphone chargers.
</p>
<p>That involved getting previous products designed by PowerByProxi to comply to the existing Qi
standard, while at the same time expanding its capabilities to include multi-phone charging and free
placement.</p>
<p>Inventor on patents:<br>
<a href="https://patentscope.wipo.int/search/en/detail.jsf?docId=WO2015194969">Foreign object
detection in inductive power transfer field</a><br>
<a href="https://www.google.com/patents/US20170237296">System and method for power transfer</a></p>
<p>The most memorable moment in this pursuit was when I teamed up with a colleague specialized in power
transfer circuitry, who had an ambitious idea for controlling AC power flowing through the inductive
link. So far, the idea had only worked in circuit simulation, where all signals could be set
perfectly to control the phases and amplitudes in the system. After days of pushing, on New Year's
Day, we suddenly got the concept running on the real thing - just before I was set to leave for a
month-long holiday.</p>
<h3>Keywords</h3>
<p><b>Power Control, ARM, C</b></p>
</div>
</div>
</div>
<div id="Leash-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('Leash-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/leash_1.jpg" style="height:10cm"></img>
<h3>Leash Debugger</h3>
<p style="text-align:left">
During three months of internship at <a href="https://mindtribe.com/">Mindtribe Product
Engineering</a> in San Francisco, I created Leash Debugger (<a
href="https://github.com/Mindtribe/Leash-Debugger">GitHub</a>). Finally, an open-source project
in the list!
</p>
<p>It is a JTAG debugger for the Texas Instruments CC3200 development board, which can be used over WiFi
to debug a target remotely.</p>
<p>The solution is described in more detail <a
href="http://mindtribe.com/2015/12/leash-debugger-a-wifi-enabled-jtag-debug-adapter/">here</a>.
</p>
<h3>Keywords</h3>
<p><b>JTAG, C, ARM, WiFi</b></p>
</div>
</div>
</div>
<div id="Octiron-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('Octiron-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/octiron.jpg" style="height:10cm"></img>
<h3>Octiron</h3>
<p style="text-align:left">
I joined the <a href="https://soleus.nu">Soleus</a> association to tinker with my own VPS, Octiron.
Octiron runs a few web applications and serves as a test deployment server for my own web projects.
You may be reading this codefolio on Octiron!
</p>
<p>
Octiron runs Arch Linux with microk8s Kubernetes. I have deployed a small personal DevOps pipeline on
it, consisting of !!!LINK!!! Gitea for source code management and !!!LINK!!! Drone for automatic builds.
It's all secured via HTTPS with a LetsEncrypt certificate.
</p>
<p>
Feel free to visit e.g. <a href="https://gitea.octiron.soleus.nu">my Gitea</a> to have a look, although
you won't see much since my repositories are private; my public repositories are still on GitHub.
</p>
<h3>Keywords</h3>
<p><b>Kubernetes, DevOps, Gitea, Drone</b></p>
</div>
</div>
</div>
<div id="Fatclient-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('Fatclient-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/digikam-fatclient.png" style="height:10cm"></img>
<h3>Digikam-Fatclient</h3>
<p style="text-align:left">
My photo collection at home is quite large, and it is stored on a NAS device. The NAS can run
a webserver, but it is excruciatingly slow.
Despite this, I want the NAS to host my photos in a web application with modern features such as
searching and querying for photos by date, location or album.
</p>
<p style="text-align:left">
I also manage my photo collection using <a href="https://www.digikam.org/">digiKam</a>.
</p>
<p>
That is why I decided to make <a href="https://gitea.octiron.soleus.nu/sander/Digikam-FatClient">digiKam-fatClient</a>.
Instead of having a front-end and a back-end, it is a statically hosted web app that does all the fancy stuff
in the front-end.
</p>
<p>
To do that, it downloads the photo metadata database in its entirety to RAM and accesses it there using
<a href="https://github.com/kripken/sql.js/">SQL.js</a> (a Javascript/Webassembly build of SQLite).
The app can show the Digikam albums and filter photos, for example based on their geolocation.
</p>
<h3>Keywords</h3>
<p><b>Front-end, React, SQLite, Javascript</b></p>
</div>
</div>
</div>
<div id="Mudbase-Modal" class="w3-modal">
<div class="w3-modal-content">
<div class="w3-container">
<!-- Close button -->
<span onclick="document.getElementById('Mudbase-Modal').style.display='none'"
class="w3-button w3-display-topright">&times;</span>
<div style="height:0.5cm"></div>
<img src="img/mudbase.png" style="height:10cm"></img>
<h3>MuDBase</h3>
<p style="text-align:left">
Recently, Google announced that its music service Google Play Music is shutting down.
</p>
<p>
I loved this service and I am not sure what to do with my music preferences after it is gone.
While I could (and probably will) move to another streaming service, I don't want to be dependent
on such services for remembering what music I like.
I want to be able to make back-ups.
</p>
<p>
I also would like to keep a bit more metadata about songs I like so that I can, for example,
create playlists for jazz dancing more effectively.
</p>
<p>
This is where the idea for !!!LINK!!! MuDBase came from. MuDBase is going to remember my music tastes,
including playlists, but with additional metadata added (such as beats per minute for jazz songs).
Instead of using it to play music, it will only be for keeping track of music, providing scripts to
sync it up with my music library on streaming services.
</p>
<p>
This is an early-stage WIP, but a working prototype can be found on <a href="https://gitea.octiron.soleus.nu/sander/MuDBase">my Gitea</a>.
</p>
<h3>Keywords</h3>
<p><b></b></p>
</div>
</div>
</div>
<div class="w3-row-padding w3-center w3-margin-top">
<div class="w3-padding"></div>
<header class="w3-container">
<h2>Work- / Study-Related</h2>
</header>
<div class="w3-padding"></div>
<p style="text-align:center font-size:18">A small selection of projects I have created or worked on in the work
or study environment.</p>
<div class="w3-quarter" onclick="document.getElementById('Transpara-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>ScreenPoint Transpara</h3><br>
<img src="img/transpara.png" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">Full-stack development work on a medical analysis aid for breast cancer.</p>
<p><b>C++11, DICOM, Python, Dev-Ops, Docker</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('HalideIPU-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>Halide for Intel IPU</h3><br>
<img src="img/halideipu_1.jpg" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">Created a DSP compiler back-end for the emerging programming language Halide,
targeted towards Intel image processing accelerators.</p>
<p><b>C++11, Halide, DSP, Imaging, Compiler</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('Qi-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>Qi Wireless Charging</h3><br>
<img src="img/qi_1.jpg" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">Contributed to embedded software which controls inductive power transfer to
smartphones.</p>
<p><b>Power Control, ARM, C</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('Leash-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>Leash Debugger</h3><br>
<img src="img/leash_1.jpg" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">Created a JTAG microcontroller debug adapter which works over WiFi.</p>
<p><b>JTAG, C, ARM, WiFi</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('EVC-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>Embedded Visual Control</h3><br>
<img src="img/evc_1.jpg" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">A solar-powered rover with 360 degree vision and object tracking capability.
</p>
<p><b>OpenGL ES, Computer Vision, Motor Control</b></p>
</div>
</div>
<div class="w3-padding"></div>
<header class="w3-container">
<h2>Personal</h2>
</header>
<div class="w3-padding"></div>
<p style="text-align:center font-size:18">I am a tinkerer by nature. I have spent countless hours on hobby
projects of all shapes and sizes. Here are a few examples.</p>
<div class="w3-quarter" onclick="document.getElementById('Fatclient-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>Digikam-FatClient</h3><br>
<img src="img/digikam-fatclient.png" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">Fast-feeling photo exploration from a dead-slow NAS device.</p>
<p><b>Front-end, React, SQLite, JavaScript</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('Mudbase-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>MuDBase</h3><br>
<img src="img/mudbase.png" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">Making sure to never lose my favorite music.</p>
<p><b>Full-stack, React, Node.js, TypeScript</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('Octiron-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>Octiron</h3><br>
<img src="img/octiron.jpg" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">My own VPS running microk8s Kubernetes and a simple open-source DevOps pipeline.</p>
<p><b>Kubernetes, DevOps, Gitea, Drone</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('Brap-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>Brap</h3><br>
<img src="img/brap_2.jpg" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">Web- and Python-based management and viewing system for my personal photos
and videos.</p>
<p><b>HTML, CSS, Javascript, PHP, SQL</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('Cuber-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>Cuber</h3><br>
<img src="img/cuber_1.jpg" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">A 8x8x8 cube of dual-color LEDs, controlled by a custom board using two
ATMega microcontrollers.</p>
<p><b>Microcontrollers, C, ASM, Circuit Design, Board Layout</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('BBStudio-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>BBStudio</h3><br>
<img src="img/bbstudio_1.jpg" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">A simple physics engine with spheres as the only kind of object.</p>
<p><b>C++, graphics, physics, UI</b></p>
</div>
</div>
<div class="w3-quarter" onclick="document.getElementById('Intergalactic-Modal').style.display='block'"
style="cursor: pointer">
<div class="w3-card-2 w3-container w3-row" style="height: 450px">
<h3>Intergalactic</h3><br>
<img src="img/intergalactic_1.jpg" style="width:200px;height:200px;object-fit:contain"></img>
<p style="text-align:left">A 3D space shooter game.</p>
<p><b>C++, graphics</b></p>
</div>
</div>
<script>
// Expand/contract tiles
function tileExpandContract(id) {
var x = document.getElementById(id);
if (x.className.indexOf("w3-third") == -1) {
x.className = "w3-third";
x.style.width = "";
} else {
x.className = x.className.replace("w3-third", "");
x.style.width = "99%";
}
return x;
}
// Show/hide a container.
function showHide(id) {
var x = document.getElementById(id);
if ((x.className.indexOf("w3-show") == -1) && (x.className.indexOf("w3-hide") == -1)) {
x.className = x.className + " w3-show";
} else if (x.className.indexOf("w3-show") >= 0) {
x.className = x.className.replace("w3-show", "w3-hide");
} else {
x.className = x.className.replace("w3-hide", "w3-show");
}
return x;
}
// Read More: on click, expand the tile and show the body.
function readMore(tile_id, body_id) {
var tile = document.getElementById(tile_id);
var body = document.getElementById(body_id);
tileExpandContract(tile_id);
showHide(body_id);
}
</script>
</body>
</html>