My website's design
Ever since I designed my first website back in January, I have learnt a lot about what I like/dislike with regards to web-design. However, designing things is hard and I suck at it. This iteration aims to keep the design as simple as possible. I’ll use threejs/WebGL for the “shiny” parts of my website… once I get around to it.
Here I am briefly going to go over the current design, choices of technologies and so forth…
The Astro Framework
Beforehand, I have used React + Next.js to build my website. However, I realise that I don’t necessarily need all the tools these frameworks provide. This website is not a fully featured web application. At most, I would use React for 3D development through the useful react-three-fiber library.
This is where Astro comes in. It is an all-in-one framework with speed in mind. I work with .astro file types which are essentially .html files with a little bit extra. Astro also allows me to optionally bundle frameworks likes React, Vue or Svelte into their own little components (I could even mix them together). So when I want to use those tools, I can contain them in their own little components whilst leaving the rest of the site to be pure HTML + CSS + JavaScript.
Color Scheme
I really like earthy-neutral tones and have tried to stick to the 60-30-10 rule as much as possible. This article on design systems from Maxime Heckel was extremely helpful in understanding some concepts. I’m not sure if its good practice, but I directly style HTML elements as of right now. You can see my defined CSS global variables in :root with your browser’s dev tools.
Markdown & MDX
Markdown is simple and easy so that is what I use for these posts. Additionally, I use MDX which allows for a mix of markdown and JSX for extra flexability (Astro seems to work quite nicely with it too).
Code
Of course I will be showing code here and there. Inline code is already styled but code blocks were a bit more tricky. I came across a fairly new library called expressive-code which was exactly what I was looking for. Examples of code blocks are shown below.
// this is some javascript codeconst geometry = new THREE.BoxGeometry()const material = new THREE.MeshNormalMaterial()const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)// this is some glsl codevoid main { gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);}Components in MDX
MDX allows for slotting in components which is extremely useful to add some dynamic presentation. The following threejs environment is a component that is slotted in directly into the .mdx file of this post. The code looks like this:
MDX allows for slotting in components...<DemoMDX />Which loads this threejs environment (you can rotate this by the way):
…and if you are interested the code for this looks like so:
import { shaderMaterial, OrbitControls } from "@react-three/drei";import { Canvas, extend, useFrame } from "@react-three/fiber";import { useRef } from "react";
const BlobMaterial = shaderMaterial( { u_time: null }, ` uniform float u_time; varying float v_displace;
float mod289(float x){return x - floor(x * (1.0 / 289.0)) * 289.0;} vec4 mod289(vec4 x){return x - floor(x * (1.0 / 289.0)) * 289.0;} vec4 perm(vec4 x){return mod289(((x * 34.0) + 1.0) * x);}
float noise(vec3 p){ vec3 a = floor(p); vec3 d = p - a; d = d * d * (3.0 - 2.0 * d);
vec4 b = a.xxyy + vec4(0.0, 1.0, 0.0, 1.0); vec4 k1 = perm(b.xyxy); vec4 k2 = perm(k1.xyxy + b.zzww);
vec4 c = k2 + a.zzzz; vec4 k3 = perm(c); vec4 k4 = perm(c + 1.0);
vec4 o1 = fract(k3 * (1.0 / 41.0)); vec4 o2 = fract(k4 * (1.0 / 41.0));
vec4 o3 = o2 * d.z + o1 * (1.0 - d.z); vec2 o4 = o3.yw * d.x + o3.xz * (1.0 - d.x);
return o4.y * d.y + o4.x * (1.0 - d.y); }
void main() {
vec3 pos = position;
v_displace = noise((1.6 * pos) + u_time) + noise((1.8* pos) - 1.33 * u_time); pos += normal * v_displace;
vec4 modelPosition = modelMatrix * vec4(pos, 1.0); vec4 viewPosition = viewMatrix * modelPosition; vec4 projectedPosition = projectionMatrix * viewPosition;
gl_Position = projectedPosition; } `, ` uniform float u_time; varying float v_displace;
void main() { vec3 col1 = vec3(1.0, 0.784 * (0.1 * sin(u_time)), 0.306); vec3 col2 = vec3(0.95, 0.396, 0.118);
vec3 fcol = mix( col1, col2, v_displace );
gl_FragColor = vec4(fcol, 1.0); } `)extend({ BlobMaterial })
function Blob() {
const material = useRef() useFrame((state, delta) => { material.current.u_time = state.clock.elapsedTime })
return( <mesh> <icosahedronGeometry args={[1, 12]} /> <blobMaterial ref={material} /> </mesh> )}
function DemoMDX() { return( <div style={{ marginBottom: '2rem', height: '40svh'}}> <Canvas> <Blob /> <OrbitControls /> </Canvas> </div> )}export default DemoMDXStuff for the Future
So far this is what I am working with. I intend to improve things over time once I realise what I actually need. At the moment, the only thing I have in mind is a contents section for navigating through headers.
Thanks for reading!
go back