A curated set of coursework and technical showcases. Choose a tile to jump directly to a project.
Click on any language to view its Fibonacci implementation in a glowing modal
const c = document.getElementById('c'), x = c.getContext('2d');
function R() {
c.width = innerWidth;
c.height = 400;
}
R();
let t = 0;
function D() {
t += 0.02;
const w = c.width, h = c.height;
for (let y = 0; y < h; y++) {
const v = Math.sin(y * 0.04 + t) * 90 + Math.sin(t * 2 + y * 0.015) * 70;
const r = 120 + v, g = 60 + v * 0.5, b = 200 + Math.sin(t + y * 0.03) * 40;
x.fillStyle = `rgb(${r | 0}, ${g | 0}, ${b | 0})`;
x.fillRect(0, y, w, 1);
}
x.globalAlpha = 0.1;
x.fillStyle = '#000';
for (let i = 0; i < h; i += 3) x.fillRect(0, i, w, 1);
x.globalAlpha = 0.15;
x.fillStyle = '#0f0';
x.fillRect(Math.sin(t) * 60 + w / 2 - 3, 0, 6, h);
x.globalAlpha = 1;
requestAnimationFrame(D);
}
addEventListener('resize', R);
D();
Python demo is meant to run locally (Tkinter).
Python Tkinter Demoscene
Run locally:
python3 demo.py
Requires Pillow + NumPy
pip install pillow numpy
#!/usr/bin/env python3
import time, math, tkinter as tk
from PIL import Image, ImageTk
WIDTH, HEIGHT = 320, 180
SCALE = 4
class DemoApp:
def __init__(self):
self.root = tk.Tk()
self.root.title("Tk Demoscene")
self.canvas = tk.Canvas(self.root, width=WIDTH*SCALE, height=HEIGHT*SCALE, bg="black")
self.canvas.pack()
self.img_id = self.canvas.create_image(0, 0, anchor="nw")
self.t0 = time.perf_counter()
self.photo = None
self.loop()
def loop(self):
t = time.perf_counter() - self.t0
img = Image.new("RGB", (WIDTH, HEIGHT), (int(127 + 128*math.sin(t)), 0, 120))
img = img.resize((WIDTH*SCALE, HEIGHT*SCALE), Image.NEAREST)
self.photo = ImageTk.PhotoImage(img)
self.canvas.itemconfig(self.img_id, image=self.photo)
self.root.after(16, self.loop)
def run(self):
self.root.mainloop()
if __name__ == "__main__":
DemoApp().run()
Full standalone HTML file (copy → save as space-demoscene.html → open in browser)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Space Demoscene</title>
<style>
:root { color-scheme: dark; }
* { box-sizing: border-box; margin: 0; padding: 0; }
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
canvas { display: block; }
.credits {
position: fixed;
bottom: 10px;
right: 16px;
font-size: 11px;
color: rgba(200, 200, 255, 0.5);
letter-spacing: 0.15em;
text-transform: uppercase;
pointer-events: none;
user-select: none;
}
</style>
</head>
<body>
<canvas id="scene"></canvas>
<div class="credits">Space Demoscene · HTML + JS</div>
<script>
(function () {
const canvas = document.getElementById('scene');
const ctx = canvas.getContext('2d');
let width = window.innerWidth;
let height = window.innerHeight;
let centerX = width / 2;
let centerY = height / 2;
function resize() {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
centerX = width / 2;
centerY = height / 2;
}
window.addEventListener('resize', resize);
resize();
const STAR_COUNT = 700;
const STAR_DEPTH = 32;
const stars = [];
function initStar() {
return {
x: (Math.random() * 2 - 1) * STAR_DEPTH,
y: (Math.random() * 2 - 1) * STAR_DEPTH,
z: Math.random() * STAR_DEPTH
};
}
for (let i = 0; i < STAR_COUNT; i++) stars.push(initStar());
const NEBULA_COUNT = 70;
const nebula = [];
function initNebulaParticle() {
const radius = Math.max(width, height) * (0.3 + Math.random() * 0.4);
const angle = Math.random() * Math.PI * 2;
return {
baseX: centerX + Math.cos(angle) * radius,
baseY: centerY + Math.sin(angle) * radius,
offset: Math.random() * Math.PI * 2,
size: 140 + Math.random() * 260,
hue: 190 + Math.random() * 80
};
}
function refreshNebula() {
nebula.length = 0;
for (let i = 0; i < NEBULA_COUNT; i++) nebula.push(initNebulaParticle());
}
refreshNebula();
const planet = { radiusBase: 130, rotation: 0 };
const title = "DEMO: SPACE";
const subtitle = "html + js · realtime";
let lastTime = performance.now();
let time = 0;
function drawStarfield(dt) {
const speed = 0.02 * dt;
ctx.save();
ctx.fillStyle = "black";
ctx.globalAlpha = 0.35;
ctx.fillRect(0, 0, width, height);
ctx.restore();
const focalLength = width / 2;
for (let i = 0; i < STAR_COUNT; i++) {
const s = stars[i];
s.z -= speed;
if (s.z <= 0) { stars[i] = initStar(); continue; }
const k = focalLength / s.z;
const x = s.x * k + centerX;
const y = s.y * k + centerY;
if (x < 0 || x >= width || y < 0 || y >= height) {
stars[i] = initStar();
continue;
}
const brightness = (1 - s.z / STAR_DEPTH);
const size = brightness * 2.2;
const alpha = 0.25 + brightness * 0.75;
ctx.beginPath();
ctx.fillStyle = `rgba(200, 220, 255, ${alpha.toFixed(3)})`;
ctx.rect(x, y, size, size);
ctx.fill();
}
}
function drawNebula() {
ctx.save();
ctx.globalCompositeOperation = "screen";
for (let i = 0; i < nebula.length; i++) {
const p = nebula[i];
const ox = Math.cos(time * 0.00012 + p.offset) * 60;
const oy = Math.sin(time * 0.00009 + p.offset) * 60;
const x = p.baseX + ox;
const y = p.baseY + oy;
const grd = ctx.createRadialGradient(x, y, 0, x, y, p.size);
grd.addColorStop(0, `hsla(${p.hue}, 80%, 70%, 0.4)`);
grd.addColorStop(0.5, `hsla(${p.hue + 20}, 90%, 40%, 0.12)`);
grd.addColorStop(1, "rgba(0,0,0,0)");
ctx.fillStyle = grd;
ctx.beginPath();
ctx.arc(x, y, p.size, 0, Math.PI * 2);
ctx.fill();
}
ctx.restore();
}
function drawPlanet(dt) {
planet.rotation += dt * 0.0002;
const r = planet.radiusBase * (0.8 + 0.2 * Math.sin(time * 0.0003));
const x = centerX;
const y = centerY;
ctx.save();
const glow = ctx.createRadialGradient(x, y, r * 0.2, x, y, r * 1.6);
glow.addColorStop(0, "rgba(180, 210, 255, 0.5)");
glow.addColorStop(1, "rgba(0, 0, 0, 0)");
ctx.fillStyle = glow;
ctx.beginPath();
ctx.arc(x, y, r * 1.6, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
ctx.save();
const g = ctx.createRadialGradient(
x - r * 0.3, y - r * 0.3, r * 0.1,
x, y, r
);
g.addColorStop(0, "rgb(230, 245, 255)");
g.addColorStop(0.4, "rgb(110, 160, 255)");
g.addColorStop(1, "rgb(15, 20, 40)");
ctx.fillStyle = g;
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.fill();
ctx.restore();
ctx.save();
ctx.translate(x, y);
ctx.strokeStyle = "rgba(220, 240, 255, 0.35)";
ctx.lineWidth = 1;
const latLines = 11;
const longLines = 18;
for (let i = 0; i <= latLines; i++) {
const v = (i / latLines) * Math.PI - Math.PI / 2;
const cy = Math.sin(v) * r;
const cr = Math.cos(v) * r;
ctx.beginPath();
for (let j = 0; j <= longLines; j++) {
const u = (j / longLines) * Math.PI * 2;
const px = Math.cos(u + planet.rotation) * cr;
const py = cy;
if (j === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);
}
ctx.stroke();
}
for (let i = 0; i < longLines; i++) {
const u = (i / longLines) * Math.PI * 2 + planet.rotation;
ctx.beginPath();
for (let j = 0; j <= latLines; j++) {
const v = (j / latLines) * Math.PI - Math.PI / 2;
const px = Math.cos(v) * Math.cos(u) * r;
const py = Math.sin(v) * r;
if (j === 0) ctx.moveTo(px, py); else ctx.lineTo(px, py);
}
ctx.stroke();
}
ctx.restore();
}
function drawText() {
const wobble = Math.sin(time * 0.003) * 12;
const glowPhase = (Math.sin(time * 0.004) + 1) / 2;
const titleY = centerY - planet.radiusBase * 1.4 - 20 + wobble;
const subtitleY = titleY + 28;
ctx.save();
ctx.textAlign = "center";
ctx.font = `600 ${Math.max(26, width * 0.028)}px "Segoe UI", system-ui, sans-serif`;
ctx.shadowColor = `rgba(160, 200, 255, ${0.4 + glowPhase * 0.5})`;
ctx.shadowBlur = 24 + glowPhase * 32;
ctx.fillStyle = "rgba(240, 250, 255, 0.95)";
ctx.fillText(title, centerX, titleY);
ctx.shadowBlur = 0;
ctx.globalCompositeOperation = "screen";
ctx.fillStyle = "rgba(80, 180, 255, 0.7)";
ctx.fillText(title, centerX + 1.5, titleY + 1.5);
ctx.fillStyle = "rgba(255, 120, 200, 0.4)";
ctx.fillText(title, centerX - 1.5, titleY - 1.0);
ctx.restore();
ctx.save();
ctx.textAlign = "center";
ctx.font = `400 ${Math.max(12, width * 0.012)}px "Segoe UI", system-ui, sans-serif`;
ctx.fillStyle = "rgba(190, 210, 255, 0.7)";
ctx.fillText(subtitle.toUpperCase(), centerX, subtitleY);
ctx.restore();
}
function drawScanlinesAndVignette() {
ctx.save();
ctx.globalAlpha = 0.12;
for (let y = 0; y < height; y += 3) {
ctx.beginPath();
ctx.moveTo(0, y + 0.5);
ctx.lineTo(width, y + 0.5);
ctx.strokeStyle = "black";
ctx.stroke();
}
ctx.restore();
ctx.save();
const grd = ctx.createRadialGradient(
centerX, centerY, Math.min(width, height) * 0.2,
centerX, centerY, Math.max(width, height) * 0.7
);
grd.addColorStop(0, "rgba(0,0,0,0)");
grd.addColorStop(1, "rgba(0,0,0,0.9)");
ctx.fillStyle = grd;
ctx.fillRect(0, 0, width, height);
ctx.restore();
}
function loop(now) {
const dt = now - lastTime;
lastTime = now;
time += dt;
drawStarfield(dt);
drawNebula();
drawPlanet(dt);
drawText();
drawScanlinesAndVignette();
requestAnimationFrame(loop);
}
requestAnimationFrame(loop);
})();
</script>
</body>
</html>
Full standalone HTML file (copy → save as polar.html → open in browser)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<title>Polar Demoscene</title>
<style>
:root {
color-scheme: dark;
}
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
html, body {
width: 100%;
height: 100%;
overflow: hidden;
background: #000;
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
}
canvas {
display: block;
}
.credits {
position: fixed;
bottom: 10px;
right: 16px;
font-size: 11px;
letter-spacing: 0.18em;
text-transform: uppercase;
color: rgba(210, 230, 255, 0.65);
pointer-events: none;
user-select: none;
}
</style>
</head>
<body>
<canvas id="scene"></canvas>
<div class="credits">Polar Demoscene · HTML + JS</div>
<script>
(function () {
const canvas = document.getElementById('scene');
const ctx = canvas.getContext('2d');
let width = window.innerWidth;
let height = window.innerHeight;
let centerX = width / 2;
let centerY = height / 2;
const horizonRatio = 0.58;
const STAR_COUNT = 450;
let stars = [];
const AURORA_BANDS = 3;
const AURORA_POINTS = 80;
let auroraBands = [];
const ICE_SHARDS = 140;
let iceShards = [];
function resize() {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
centerX = width / 2;
centerY = height * horizonRatio;
initStars();
initAurora();
initIce();
}
function initStars() {
stars = [];
const skyHeight = height * horizonRatio;
for (let i = 0; i < STAR_COUNT; i++) {
stars.push({
x: Math.random() * width,
y: Math.random() * skyHeight,
tw: Math.random() * Math.PI * 2,
s: 0.6 + Math.random() * 1.6
});
}
}
function initAurora() {
auroraBands = [];
const skyHeight = height * horizonRatio;
for (let b = 0; b < AURORA_BANDS; b++) {
const band = [];
const baseY = skyHeight * (0.20 + b * 0.07);
const offset = Math.random() * Math.PI * 2;
const hue = 140 + b * 25;
for (let i = 0; i < AURORA_POINTS; i++) {
const t = i / (AURORA_POINTS - 1);
const x = t * width * 1.1 - width * 0.05;
band.push({
x,
baseY,
offset,
amp: 40 + b * 12 + Math.random() * 12,
hue
});
}
auroraBands.push(band);
}
}
function initIce() {
const startY = centerY;
const maxDepth = height * 0.8;
iceShards = [];
for (let i = 0; i < ICE_SHARDS; i++) {
const t = Math.random();
const depth = startY + t * maxDepth;
const spread = (t * 1.4 + 0.1) * width;
const x = centerX + (Math.random() * 2 - 1) * spread;
const y = depth;
const h = 20 + Math.random() * 100 * (1 - t);
const w = 6 + Math.random() * 18 * (1 - t * 0.7);
iceShards.push({
x, y, h, w,
tilt: (Math.random() * 0.6 - 0.3),
phase: Math.random() * Math.PI * 2
});
}
}
function polarTunnel(time) {
const cx = centerX;
const cy = centerY * 0.5;
const maxR = Math.sqrt(cx * cx + cy * cy);
const rings = 18;
for (let i = 0; i < rings; i++) {
const t = i / rings;
const r = maxR * (0.2 + t * 0.8);
const wobble = Math.sin(time * 0.0004 + t * 9) * 10;
const radius = r + wobble;
const hue = 190 + Math.sin(time * 0.0003 + t * 6) * 40;
const alpha = 0.18 + 0.4 * (1 - t);
ctx.beginPath();
ctx.arc(cx, cy, radius, 0, Math.PI * 2);
ctx.strokeStyle = `hsla(${hue}, 80%, 55%, ${alpha})`;
ctx.lineWidth = 1.2 + (1 - t) * 3;
ctx.stroke();
}
}
const TITLE = "POLAR VORTEX";
const SUBTITLE = "js demoscene · polar coords";
let lastTime = performance.now();
let globalTime = 0;
function drawBackground() {
const skyHeight = height * horizonRatio;
const skyGrad = ctx.createLinearGradient(0, 0, 0, skyHeight);
skyGrad.addColorStop(0, "rgb(4, 10, 30)");
skyGrad.addColorStop(0.5, "rgb(10, 30, 70)");
skyGrad.addColorStop(1, "rgb(5, 12, 30)");
ctx.fillStyle = skyGrad;
ctx.fillRect(0, 0, width, skyHeight);
const iceGrad = ctx.createLinearGradient(0, skyHeight, 0, height);
iceGrad.addColorStop(0, "rgb(12, 35, 55)");
iceGrad.addColorStop(1, "rgb(8, 16, 24)");
ctx.fillStyle = iceGrad;
ctx.fillRect(0, skyHeight, width, height - skyHeight);
}
function drawStars(dt) {
const skyHeight = height * horizonRatio;
ctx.save();
for (let i = 0; i < stars.length; i++) {
const s = stars[i];
s.tw += dt * 0.005;
const twinkle = (Math.sin(s.tw) + 1) / 2;
const alpha = 0.2 + twinkle * 0.8;
ctx.fillStyle = `rgba(230, 240, 255, ${alpha.toFixed(3)})`;
const size = s.s + twinkle * 0.8;
ctx.fillRect(s.x, s.y, size, size);
}
ctx.restore();
const starGlow = ctx.createRadialGradient(
centerX, skyHeight * 0.15, skyHeight * 0.2,
centerX, skyHeight * 0.2, skyHeight * 0.7
);
starGlow.addColorStop(0, "rgba(60,120,255,0.15)");
starGlow.addColorStop(1, "rgba(0,0,0,0)");
ctx.fillStyle = starGlow;
ctx.fillRect(0, 0, width, skyHeight);
}
function drawAurora(time) {
const skyHeight = height * horizonRatio;
ctx.save();
ctx.globalCompositeOperation = "screen";
for (let b = 0; b < auroraBands.length; b++) {
const band = auroraBands[b];
ctx.beginPath();
for (let i = 0; i < band.length; i++) {
const p = band[i];
const t = i / (band.length - 1);
const wave =
Math.sin(time * 0.00045 + p.offset + t * 7) * p.amp +
Math.sin(time * 0.0008 + p.offset * 1.2 + t * 11) * (p.amp * 0.35);
const flicker = (Math.sin(time * 0.004 + t * 20) + 1) / 2;
const y = p.baseY + wave * (0.4 + flicker * 0.5);
if (i === 0) ctx.moveTo(p.x, y);
else ctx.lineTo(p.x, y);
}
const hue = band[0].hue;
const baseAlpha = 0.25 + 0.1 * Math.sin(time * 0.001 + b);
ctx.strokeStyle = `hsla(${hue}, 90%, 70%, ${baseAlpha})`;
ctx.lineWidth = 20;
ctx.stroke();
const grad = ctx.createLinearGradient(0, skyHeight * 0.05, 0, skyHeight * 0.7);
grad.addColorStop(0, `hsla(${hue}, 90%, 80%, 0.30)`);
grad.addColorStop(1, "rgba(0,0,0,0)");
ctx.fillStyle = grad;
ctx.fillRect(0, 0, width, skyHeight);
}
ctx.restore();
}
function drawIce(time) {
ctx.save();
ctx.globalCompositeOperation = "screen";
const skyHeight = height * horizonRatio;
const shimmerPhase = time * 0.0012;
const cx = centerX;
const cy = skyHeight;
const maxR = Math.sqrt(width * width + (height - cy) * (height - cy));
const radialSteps = 38;
for (let i = 0; i < radialSteps; i++) {
const t = i / radialSteps;
const r = maxR * t;
const wobble = Math.sin(shimmerPhase + t * 10) * 14;
const radius = r + wobble;
const hue = 180 + Math.sin(shimmerPhase * 0.6 + t * 13) * 20;
const alpha = 0.03 + (1 - t) * 0.08;
ctx.beginPath();
ctx.arc(cx, cy, radius, Math.PI, 0, false);
ctx.strokeStyle = `hsla(${hue}, 55%, 60%, ${alpha})`;
ctx.lineWidth = 2;
ctx.stroke();
}
ctx.restore();
ctx.save();
ctx.globalCompositeOperation = "lighter";
for (let i = 0; i < iceShards.length; i++) {
const s = iceShards[i];
const skyHeight = height * horizonRatio;
const t = (s.y - skyHeight) / (height - skyHeight + 1);
const brightness = 0.2 + (1 - t) * 0.7;
const shimmer = (Math.sin(time * 0.003 + s.phase) + 1) / 2;
const alpha = (0.12 + brightness * 0.25) * (0.4 + shimmer * 0.6);
ctx.save();
ctx.translate(s.x, s.y);
ctx.rotate(s.tilt);
const grad = ctx.createLinearGradient(0, -s.h, 0, 0);
grad.addColorStop(0, `rgba(200, 240, 255, ${alpha})`);
grad.addColorStop(1, `rgba(30, 80, 120, ${alpha * 0.05})`);
ctx.fillStyle = grad;
ctx.beginPath();
ctx.moveTo(-s.w * 0.4, 0);
ctx.lineTo(s.w * 0.4, 0);
ctx.lineTo(0, -s.h);
ctx.closePath();
ctx.fill();
ctx.restore();
}
ctx.restore();
ctx.save();
const fogGrad = ctx.createLinearGradient(0, skyHeight, 0, height);
fogGrad.addColorStop(0, "rgba(200,230,255,0.04)");
fogGrad.addColorStop(0.4, "rgba(180,210,255,0.05)");
fogGrad.addColorStop(1, "rgba(0,0,0,0.4)");
ctx.fillStyle = fogGrad;
ctx.fillRect(0, skyHeight, width, height - skyHeight);
ctx.restore();
}
function drawText(time) {
const skyHeight = height * horizonRatio;
const wobble = Math.sin(time * 0.0025) * 8;
const titleY = skyHeight * 0.22 + wobble;
const subtitleY = titleY + 30;
ctx.save();
ctx.textAlign = "center";
ctx.font = `700 ${Math.max(28, width * 0.036)}px "Segoe UI", system-ui, sans-serif`;
const phase = (Math.sin(time * 0.003) + 1) / 2;
ctx.shadowColor = `rgba(160, 220, 255, ${0.5 + phase * 0.4})`;
ctx.shadowBlur = 30 + phase * 40;
ctx.fillStyle = "rgba(240, 250, 255, 0.98)";
ctx.fillText(TITLE, centerX, titleY);
ctx.shadowBlur = 0;
ctx.globalCompositeOperation = "screen";
ctx.fillStyle = "rgba(90, 210, 255, 0.75)";
ctx.fillText(TITLE, centerX + 1.8, titleY + 1.2);
ctx.fillStyle = "rgba(255, 140, 220, 0.45)";
ctx.fillText(TITLE, centerX - 1.3, titleY - 1.0);
ctx.restore();
ctx.save();
ctx.textAlign = "center";
ctx.font = `400 ${Math.max(12, width * 0.013)}px "Segoe UI", system-ui, sans-serif`;
ctx.fillStyle = "rgba(190, 215, 255, 0.75)";
ctx.fillText(SUBTITLE.toUpperCase(), centerX, subtitleY);
ctx.restore();
}
function drawVignetteAndScanlines() {
ctx.save();
ctx.globalAlpha = 0.10;
for (let y = 0; y < height; y += 3) {
ctx.beginPath();
ctx.moveTo(0, y + 0.5);
ctx.lineTo(width, y + 0.5);
ctx.strokeStyle = "black";
ctx.stroke();
}
ctx.restore();
ctx.save();
const grad = ctx.createRadialGradient(
centerX, centerY * 0.7, Math.min(width, height) * 0.4,
centerX, centerY * 0.8, Math.max(width, height) * 0.95
);
grad.addColorStop(0, "rgba(0,0,0,0)");
grad.addColorStop(1, "rgba(0,0,0,0.88)");
ctx.fillStyle = grad;
ctx.fillRect(0, 0, width, height);
ctx.restore();
}
function loop(now) {
const dt = now - lastTime;
lastTime = now;
globalTime += dt;
drawBackground();
polarTunnel(globalTime);
drawStars(dt);
drawAurora(globalTime);
drawIce(globalTime);
drawText(globalTime);
drawVignetteAndScanlines();
requestAnimationFrame(loop);
}
window.addEventListener('resize', resize);
resize();
requestAnimationFrame(loop);
})();
</script>
</body>
</html>
Full standalone HTML file (copy → save as grid.html → open in browser)
<canvas id="a"></canvas>
<script>
a.width = a.height = 400;
const X = a.getContext("2d");
let t = 0;
function L(c, a, b) {
X.strokeStyle = c;
X.beginPath();
X.moveTo(a[0], a[1]);
X.lineTo(b[0], b[1]);
X.stroke();
}
function D() {
t += 0.02;
X.fillStyle = "#0003";
X.fillRect(0, 0, 400, 400);
for (let i = 0; i < 20; i++) {
X.strokeStyle = `hsl(${i * 18 + t * 50},100%,50%)`;
for (let j = 0; j < 20; j++) {
const x = 200 + Math.sin(t + i * 0.3) * 150 * Math.sin(j * 0.3 + t);
const y = 200 + Math.cos(t + i * 0.2) * 150 * Math.cos(j * 0.3 + t);
const s = 2 + 2 * Math.sin(t + i + j);
X.beginPath();
X.arc(x, y, s, 0, Math.PI * 2);
X.stroke();
}
}
X.globalCompositeOperation = "lighter";
X.fillStyle = "rgba(0,255,100,0.04)";
for (let i = 0; i < 400; i += 2) {
L("#0f03", [i, 0], [200 + Math.sin(t + i * 0.05) * 10, 400]);
}
X.globalCompositeOperation = "source-over";
requestAnimationFrame(D);
}
D();
</script>
<style>
body {
margin: 0;
background: #000;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
}
canvas {
filter: contrast(1.4) brightness(1.3) blur(.5px);
}
</style>
Click any essay to preview the PDF directly on the page
View the Industry Matrix presentation — scroll, zoom, or download the PDF below.
Scroll to view the presentation. Use controls below to download or open in new tab.
Loading PDF...
Midterm self-evaluation essay summarizing assignments, projects, and completed work throughout the semester.
PDF document — open or download below.
Screenshots showing SSH login, file navigation, and terminal sessions on a remote Linux server.
Screenshots of Email, Diaspora, XMPP, and Peertube accounts used for communication, collaboration, and coordination.
Screenshots showing the installation steps and configuration process for setting up a dual boot system with Windows and Linux Mint.
Conway's Game of Life is a zero-player cellular automaton. This interactive simulation is fully isolated from the rest of the website.
QUCS simulations of NAND and NOT gate circuits with transient analysis.
Transient simulation of digital logic circuits
NAND Gate Simulation
Click to expand
NOT Gate (Inverter) Simulation
Click to expand
Type: Transient
Start: 0 s
Stop: 20 ms
TR1 Type: lin
V2: U1=0V, T1=0, T2=1ms
V3: U1=0V, U2=1V, T1=0, T2=1ms
T5: V0=1.0V, Kp=2e-5, Lambda=0.0
T6: V0=1.0V, Kp=2e-5, Lambda=0.0
T7: V0=1.0V, Kp=2e-5, Lambda=0.0
VDD (V1): U = 5 V (DC)
V2 (Pulse): U1=0V, U2=5V
Timing: T1=0, T2=1ms
PMOS (T1):
Vt0 = -1.0 V, Kp = 2e-5, Lambda = 0.0
Source → VDD, Drain → OUT, Gate → IN
NMOS (T2):
Vt0 = 1.0 V, Kp = 2e-5, Lambda = 0.0
Source → GND, Drain → OUT, Gate → IN
Transient (TR1): Type = lin
Time Range: Start=0, Stop=5 ms
Node Voltages: IN=v(2), OUT=v(3)
Plot Range: X: 0-5 ms, Y: 0-5 V
This NAND gate simulation in QUCS demonstrates digital logic circuit behavior using transistor-level modeling with transient analysis to show timing characteristics and Boolean logic implementation.
CMOS NOT gate (inverter) simulation showing the complementary operation of PMOS and NMOS transistors. The transient analysis demonstrates the switching characteristics and propagation delay of the inverter circuit.