Skip to content

Commit 7bbbecc

Browse files
committed
add about page
1 parent 03c0848 commit 7bbbecc

File tree

14 files changed

+364
-4
lines changed

14 files changed

+364
-4
lines changed

assets/css/styles.css

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@
99
/* Tailwind's utility classes - generated based on config file */
1010
@import "node_modules/tailwindcss/utilities";
1111

12+
.background {
13+
position: fixed;
14+
top: 0;
15+
left: 0;
16+
z-index: -1
17+
}
18+
1219
figcaption {
1320
margin-top: 0.5em !important;
1421
}

assets/js/vapourwave.js

Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
import * as THREE from 'three';
2+
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js';
3+
import { RenderPass } from "three/examples/jsm/postprocessing/RenderPass.js";
4+
import { EffectComposer } from "three/examples/jsm/postprocessing/EffectComposer.js";
5+
import { GammaCorrectionShader } from "three/examples/jsm/shaders/GammaCorrectionShader.js";
6+
import { ShaderPass } from "three/examples/jsm/postprocessing/ShaderPass.js";
7+
import { RGBShiftShader } from "three/examples/jsm/shaders/RGBShiftShader.js";
8+
9+
// toggle-dark-mode
10+
async function main() {
11+
const canvas = document.querySelector('canvas.webgl');
12+
13+
// Scene
14+
const scene = new THREE.Scene();
15+
16+
// Fog
17+
const fog = new THREE.Fog("#1f2937", 1, 2.5);
18+
scene.fog = fog;
19+
20+
// Objects
21+
const planeSize = { w: 24, h: 48 };
22+
const planeSizeUnits = { w: 1, h: 2 };
23+
24+
// TODO: generate noise map
25+
// const noiseData = new Uint8Array(planeSize.w * planeSize.h);
26+
// for (let i = 0; i < noiseData.length; i++) {
27+
// const v = Math.floor(Math.random() * 255);
28+
// noiseData[i] = v;
29+
// }
30+
// const noiseTexture = new THREE.DataTexture({
31+
// data: noiseData,
32+
// width: planeSize.w,
33+
// height: planeSize.h,
34+
// format: THREE.LuminanceFormat
35+
// });
36+
// noiseTexture.needsUpdate = true;
37+
38+
const textureLoader = new THREE.TextureLoader();
39+
const noiseTexture = await textureLoader.loadAsync('/displacement.png');
40+
41+
const geometry = new THREE.PlaneGeometry(planeSizeUnits.w, planeSizeUnits.h, planeSize.w, planeSize.h);
42+
let uniforms = {
43+
segU: { value: planeSize.w },
44+
segV: { value: planeSize.h },
45+
isWire: { value: false },
46+
wireWidthFactor: { value: 2 },
47+
wireColor: { value: new THREE.Color(0xcccccc) },
48+
dmap: { value: noiseTexture },
49+
scroll: { value: 0.0 }
50+
}
51+
const material = new THREE.MeshStandardMaterial({
52+
metalness: 1,
53+
roughness: 0.3,
54+
onBeforeCompile: shader => {
55+
shader.uniforms.segU = uniforms.segU;
56+
shader.uniforms.segV = uniforms.segV;
57+
shader.uniforms.wireColor = uniforms.wireColor;
58+
shader.uniforms.isWire = uniforms.isWire;
59+
shader.uniforms.wireWidthFactor = uniforms.wireWidthFactor;
60+
shader.uniforms.dmap = uniforms.dmap;
61+
shader.uniforms.scroll = uniforms.scroll;
62+
shader.fragmentShader = `
63+
uniform float segU;
64+
uniform float segV;
65+
uniform vec3 wireColor;
66+
uniform float isWire;
67+
uniform float wireWidthFactor;
68+
69+
${shader.fragmentShader}
70+
`.replace(
71+
`#include <dithering_fragment>`,
72+
`
73+
#include <dithering_fragment>
74+
75+
// http://madebyevan.com/shaders/grid/
76+
vec2 coord = vUv * vec2(segU, segV);
77+
78+
vec2 grid = abs(fract(coord - 0.5) - 0.5) / fwidth(coord);
79+
float line = min(grid.x, grid.y) / wireWidthFactor;
80+
line = 1.0 - min(line, 1.0);
81+
82+
if (isWire > 0.5 && line < 0.5) discard;
83+
if (isWire > 0.5) gl_FragColor = vec4(0);
84+
float fade = 1.0 - vUv.y;
85+
gl_FragColor = mix(gl_FragColor, vec4(wireColor, 1.0), line * fade * fade);
86+
`
87+
);
88+
console.log(shader.fragmentShader);
89+
90+
shader.vertexShader = `
91+
uniform sampler2D dmap;
92+
uniform float scroll;
93+
${shader.vertexShader}
94+
`.replace(
95+
`#include <begin_vertex>`,
96+
`
97+
#include <begin_vertex>
98+
// offset the plane textures in the same increments as scrolling moves the plane
99+
// but also shift the sampling position by 1 square after every increment
100+
float offset = floor(scroll * ${planeSize.h / planeSizeUnits.h}.0) / ${planeSize.h}.0;
101+
transformed.z += texture(dmap, vec2(uv.x, fract(uv.y + offset))).r * 0.4;
102+
`
103+
);
104+
console.log(shader.vertexShader)
105+
},
106+
});
107+
material.defines = { 'USE_UV': '' };
108+
109+
const plane = new THREE.Mesh(geometry, material);
110+
111+
// Here we position our plane flat in front of the camera
112+
plane.rotation.x = -Math.PI * 0.5;
113+
plane.position.y = 0.0;
114+
plane.position.z = 0.0;
115+
scene.add(plane);
116+
117+
// Light
118+
// Ambient Light
119+
const ambientLight = new THREE.AmbientLight("#ffffff", 10);
120+
scene.add(ambientLight);
121+
122+
// Right Spotlight aiming to the left
123+
const spotlight = new THREE.SpotLight("#5bcffa", 20, 25, Math.PI * 0.1, 0.25);
124+
spotlight.position.set(0.5, 0.75, 2.2);
125+
// Target the spotlight to a specific point to the left of the scene
126+
spotlight.target.position.x = -0.25;
127+
spotlight.target.position.y = 0.25;
128+
spotlight.target.position.z = 0.25;
129+
scene.add(spotlight);
130+
scene.add(spotlight.target);
131+
132+
// Left Spotlight aiming to the right
133+
const spotlight2 = new THREE.SpotLight("#f5abb9", 20, 25, Math.PI * 0.1, 0.25);
134+
spotlight2.position.set(-0.5, 0.75, 2.2);
135+
// Target the spotlight to a specific point to the right side of the scene
136+
spotlight2.target.position.x = 0.25;
137+
spotlight2.target.position.y = 0.25;
138+
spotlight2.target.position.z = 0.25;
139+
scene.add(spotlight2);
140+
scene.add(spotlight2.target);
141+
142+
// Sizes
143+
const sizes = {
144+
width: window.innerWidth,
145+
height: window.innerHeight,
146+
};
147+
148+
// Camera
149+
const camera = new THREE.PerspectiveCamera(
150+
// field of view
151+
75,
152+
// aspect ratio
153+
sizes.width / sizes.height,
154+
// near plane: it's low since we want our mesh to be visible even from very close
155+
0.01,
156+
// far plane: how far we're rendering
157+
20
158+
);
159+
160+
// Position the camera a bit higher on the y axis and a bit further back from the center
161+
camera.position.x = 0;
162+
camera.position.y = 0.1;
163+
camera.position.z = 1.1;
164+
165+
// Controls
166+
// These are custom controls I like using for dev: we can drag/rotate the scene easily
167+
const controls = new OrbitControls(camera, canvas);
168+
controls.enableDamping = true;
169+
170+
// Renderer
171+
const renderer = new THREE.WebGLRenderer({
172+
canvas: canvas
173+
});
174+
renderer.setSize(sizes.width, sizes.height);
175+
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
176+
renderer.setClearColor(0x1f2937, 0);
177+
178+
// Post Processing
179+
const effectComposer = new EffectComposer(renderer);
180+
effectComposer.setSize(sizes.width, sizes.height);
181+
effectComposer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
182+
183+
const renderPass = new RenderPass(scene, camera);
184+
effectComposer.addPass(renderPass);
185+
186+
const rgbShiftPass = new ShaderPass(RGBShiftShader);
187+
rgbShiftPass.uniforms["amount"].value = 0.0015;
188+
189+
effectComposer.addPass(rgbShiftPass);
190+
191+
const gammaCorrectionPass = new ShaderPass(GammaCorrectionShader);
192+
effectComposer.addPass(gammaCorrectionPass);
193+
194+
// Event listener to handle screen resize
195+
window.addEventListener('resize', () => {
196+
// Update sizes
197+
sizes.width = window.innerWidth;
198+
sizes.height = window.innerHeight;
199+
200+
// Update camera's aspect ratio and projection matrix
201+
camera.aspect = sizes.width / sizes.height;
202+
camera.updateProjectionMatrix();
203+
204+
// Update renderer
205+
renderer.setSize(sizes.width, sizes.height);
206+
// Note: We set the pixel ratio of the renderer to at most 2
207+
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
208+
effectComposer.render();
209+
});
210+
211+
// const animate = () => {
212+
// effectComposer.render();
213+
// };
214+
// renderer.setAnimationLoop(animate);
215+
216+
const setupColours = () => {
217+
const darkMode = document.documentElement.classList.contains('dark');
218+
fog.color = new THREE.Color(darkMode ? 0x1f2937 : 0xffffff);
219+
uniforms.wireColor.value = new THREE.Color(darkMode ? 0x9e9e9e : 0xffffff);
220+
material.roughness = darkMode ? 0.30 : 0.75;
221+
const article = document.querySelector('article');
222+
if (article) {
223+
article.style.color = darkMode ? '#ffffff' : '#000000';
224+
article.style.textShadow = `0 0 0.5em ${darkMode ? '#000000' : '#ffffff'}`;
225+
}
226+
};
227+
228+
setupColours();
229+
effectComposer.render();
230+
231+
const darkmodeToggle = document.querySelector('.toggle-dark-mode');
232+
if (darkmodeToggle) {
233+
darkmodeToggle.addEventListener('click', () => {
234+
setupColours();
235+
effectComposer.render();
236+
});
237+
}
238+
239+
document.body.onscroll = () => {
240+
uniforms.scroll.value = (
241+
(document.documentElement.scrollTop || document.body.scrollTop) / (
242+
(document.documentElement.scrollHeight || document.body.scrollHeight)
243+
- document.documentElement.clientHeight
244+
)
245+
);
246+
// move the plane forward by 1 unit when scrolled all the way down
247+
const squaresPerUnit = planeSize.h / planeSizeUnits.h;
248+
plane.position.z = ((uniforms.scroll.value * squaresPerUnit) % 1.0) / squaresPerUnit;
249+
effectComposer.render();
250+
};
251+
}
252+
253+
main();

content/about.md

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,61 @@ title: About Me
44
date: 2021-07-15
55
description:
66
keywords: ["about", "contact"]
7-
type: about
7+
params:
8+
build_js: ["vapourwave"]
89
---
910

10-
I'm Sam. :3
11+
{{<raw>}}
12+
<canvas class="background webgl"></canvas>
13+
{{</raw>}}
14+
15+
### I'm Sam. :3
16+
Welcome to my blog.
17+
18+
<br/><br/><br/><br/><br/><br/>↓<br/><br/><br/><br/><br/><br/>
19+
20+
### I'm a software developer and hardware enthusiast.
21+
I love solving problems, strategy games, and making cool things.
22+
23+
<br/><br/><br/><br/><br/><br/>↓<br/><br/><br/><br/><br/><br/>
24+
25+
### Most of my experience is in mobile & web development
26+
Professionally I have around 3 years of work experience - mainly in react native development.
27+
Outside of work I love learning and making stuff to make my life easier.
28+
29+
<br/><br/><br/><br/><br/><br/>↓<br/><br/><br/><br/><br/><br/>
30+
31+
## Here's some stuff that I have made:
32+
33+
<br/><br/><br/><br/><br/><br/>↓<br/><br/><br/><br/><br/><br/>
34+
35+
{{< vidfig title="Factorio: Auto Resource Redux" src="/showcase-auto-resource.mp4" href="https://github.com/udf/factorio-auto-resource-redux" >}}
36+
A mod for [Factorio](https://factorio.com) that overhauls the gameplay to be more RTS like and combat focused (has over a hundred downloads). Built in Lua.
37+
{{< /vidfig >}}
38+
39+
<br/><br/><br/><br/><br/><br/>↓<br/><br/><br/><br/><br/><br/>
40+
41+
{{< vidfig title="Telegram: Tag Bot" src="/showcase-tagbot.mp4" href="https://github.com/udf/the-tag-bot" >}}
42+
A personalised media search engine for [Telegram](https://telegram.org). Built using Elasticsearch and Python. Hosted on Oracle Cloud.
43+
{{< /vidfig >}}
44+
45+
<br/><br/><br/><br/><br/><br/>↓<br/><br/><br/><br/><br/><br/>
46+
47+
{{< vidfig title="WeThinkCode_ 3D: Cherry" src="/showcase-wolf-3d-cherry.mp4" href="https://github.com/udf/wolf3d-cherry" >}}
48+
A recreation of the WeThinkCode_ campus in a custom raycasting engine. Built in C++ and [shown off at rAge 2019.](https://twitter.com/WTC_Students/status/1177162021302874113)
49+
{{< /vidfig >}}
50+
51+
{{<raw>}}
52+
<blockquote class="twitter-tweet"><p lang="en" dir="ltr"><a href="https://twitter.com/wethinkcode?ref_src=twsrc%5Etfw">@WeThinkCode</a> students getting ready for <a href="https://twitter.com/rAgeExpo?ref_src=twsrc%5Etfw">@rAgeExpo</a> tomorrow! It&#39;s all happening <a href="https://twitter.com/Ticketprodome?ref_src=twsrc%5Etfw">@Ticketprodome</a> in Johannesburg! We will be showcasing our project all weekend. See you there! 🎮🖥️ <a href="https://t.co/TfTO45bs3k">pic.twitter.com/TfTO45bs3k</a></p>&mdash; WeThinkCode_ Students (@WTC_Students) <a href="https://twitter.com/WTC_Students/status/1177162021302874113?ref_src=twsrc%5Etfw">September 26, 2019</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
53+
{{</raw>}}
54+
55+
<br/><br/><br/><br/><br/><br/>↓<br/><br/><br/><br/><br/><br/>
56+
57+
58+
{{< vidfig title="This page!" src="/showcase-about-illusion.mp4" href="https://github.com/udf/udf.github.io/blob/master/assets/js/vapourwave.js" >}}
59+
The animated background on this page was made with Three.js! It works by utilising some clever maths to create the illusion of an infinitely scrolling digital landscape.
60+
{{< /vidfig >}}
61+
62+
<br/><br/><br/><br/><br/><br/>↓<br/><br/><br/><br/><br/><br/>
1163

1264
Contact: tabhooked <@> gmail <dot> com

layouts/_default/baseof.html

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<!DOCTYPE html>
2+
<html lang="{{ .Lang }}" itemscope itemtype="http://schema.org/WebPage">
3+
<head>
4+
{{- partial "head.html" . -}}
5+
{{ range .Params.build_js }}
6+
{{- $js := resources.Get (printf "js/%s.js" .) | js.Build (dict "sourcemap" "inline" "minify" true "target" "es2015") -}}
7+
<script src="{{ $js.RelPermalink }}" defer></script>
8+
{{ end }}
9+
10+
</head>
11+
<body class="dark:bg-gray-800 dark:text-white relative flex flex-col min-h-screen">
12+
{{- partial "header.html" . -}}
13+
<main class="flex-1">
14+
{{- block "main" . }}{{- end }}
15+
</main>
16+
{{- partial "footer.html" . -}}
17+
</body>
18+
</html>

layouts/shortcodes/raw.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{{.Inner}}

layouts/shortcodes/vidfig.html

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<figure>
2+
<a href="{{ .Get "href" }}">
3+
<h3>{{ .Get "title" | markdownify }}</h3>
4+
</a>
5+
<video controls>
6+
<source src="{{ .Get "src" }}" />
7+
</video>
8+
<p>
9+
{{ .Inner | markdownify }}
10+
</p>
11+
12+
</figure>

0 commit comments

Comments
 (0)