Exercising My Programmer Brain
Over the past few years, I’ve been pretty focused on teaching, consulting, and managing projects in the tech industry. That’s where my skills and expertise lie, but I’ve always had a love for coding.
It’s been a while since I’ve really dug into programming, so I thought it was time to dust off my skills and have a little fun. I came across some online courses that focused on creative coding, and I figured it was the perfect opportunity to dive back in and see what I could create.
I had played around with Javascript and canvas in the past, creating a weird Minecraft creeper face design (refresh for different versions, every face is slightly different as the greens that make up its face were chosen from a range of greens). But it had been a while since I’d done any digital art with code, and I was excited to see what new techniques and ideas I could learn.
I didn’t have a ton of time to work on the courses last night, but even just tinkering with the code got me excited about programming again. I loved working through the exercises and trying out different approaches to see what I could create.
It was really refreshing to step away from my usual work and spend some time indulging in a creative outlet. It let me flex my technical muscles in a different way and explore new possibilities. The programming aspect is pretty basic stuff but the outcomes are quite fun.
The First Few Projects
This first little bit in the short online course is just getting familiar with the canvas and a framework called canvas-sketch which is used to help create generative art. Keep in mind that I am mostly following a course so nothing has been optimized, but I have included the full code and some outcomes below. I should say as well, that the original tutorial did not include colours. I added those to each of the projects to spice it up a little.
const canvasSketch = require('canvas-sketch');
const settings = {
dimensions: [1080,1080]
};
const sketch = () => {
return ({ context, width, height }) => {
context.fillStyle = 'white';
context.fillRect(0, 0, width, height);
context.lineWidth = width * 0.01;
const w = width * 0.10;
const h = height * 0.10;
const gap = width * 0.03;
const ix = width * 0.17;
const iy = height * 0.17
let x, y;
let randomColor = '#000000';
const offset = width * 0.02;
for (let i = 0; i < 5; i++) {
for (let j = 0; j < 5; j++) {
x = ix + (w + gap) * i;
y = iy + (h + gap) * j;
context.beginPath();
context.rect(x, y, w, h);
context.stroke();
if (Math.random() > 0.5) {
randomColor = Math.floor(Math.random() * 16777215).toString(16);
randomColor = '#' + randomColor;
context.fillStyle = randomColor;
context.beginPath();
context.rect(x + offset/2, y + offset/2, w - offset, h - offset);
//context.stroke();
context.fill();
}
}
}
};
};
canvasSketch(sketch, settings);
const canvasSketch = require('canvas-sketch');
const math = require('canvas-sketch-util/math');
const random = require('canvas-sketch-util/random');
const color = require('canvas-sketch-util/color');
const settings = {
dimensions: [ 1080, 1080 ]
};
const sketch = () => {
return ({ context, width, height }) => {
context.fillStyle = 'black';
const cx = width * 0.5;
const cy = height * 0.5;
const w = width * 0.01;
const h = height * 0.1;
let x,y;
const num = 40;
const radius = width * 0.3;
for (let i = 0; i < num; i++){
const slice = math.degToRad(360 / num);
const angle = slice * i;
x = cx + radius * Math.sin(angle);
y = cy + radius * Math.cos(angle);
context.save();
context.translate(x, y);
context.rotate(-angle);
context.scale(random.range(1,3), random.range(0.5,2));
context.beginPath();
context.rect(-w * 0.5, random.range(0, -h*0.5), w, h);
context.fill();
context.restore();
context.save();
context.translate(cx, cy);
context.rotate(-angle);
context.lineWidth = random.range(3,25);
context.beginPath();
context.arc(0,0, radius * random.range(0.7, 1.3), slice * random.range(1, -3), slice * random.range(1, 5));
randomColor = Math.floor(Math.random() * 16777215).toString(16);
randomColor = '#' + randomColor;
context.strokeStyle = randomColor;
context.stroke();
context.restore();
}
};
};
canvasSketch(sketch, settings);
const canvasSketch = require('canvas-sketch');
const math = require('canvas-sketch-util/math');
const random = require('canvas-sketch-util/random');
const color = require('canvas-sketch-util/color');
const settings = {
dimensions: [1080, 1080],
animate: true
};
const sketch = ({ context, width, height }) => {
const agents = [];
for (let i = 0; i < 70; i++) {
const x = random.range(0, width);
const y = random.range(0, height);
agents.push(new Agent(x, y));
}
return ({ context, width, height }) => {
context.fillStyle = 'white';
context.fillRect(0, 0, width, height);
for (let i = 0; i < agents.length; i++) {
const agent = agents[i];
for (let j = i + 1; j < agents.length; j++){
const other = agents[j];
const distance = agent.pos.getDistance(other.pos);
if (distance > 200) continue;
context.lineWidth = math.mapRange(distance,0,200, 15, 1);
context.beginPath();
context.moveTo(agent.pos.x, agent.pos.y);
context.lineTo(other.pos.x, other.pos.y);
context.stroke();
}
}
agents.forEach(agent => {
agent.update();
agent.draw(context);
agent.bounce(width,height);
})
};
};
canvasSketch(sketch, settings);
class Vector {
constructor(x, y, radius) {
this.x = x;
this.y = y;
this.radius = radius;
}
getDistance (v) {
const dx = this.x - v.x;
const dy = this.y - v.y;
return Math.sqrt(dx * dx + dy * dy);
}
}
class Agent {
constructor(x, y) {
this.pos = new Vector(x, y);
this.velocity = new Vector(random.range(-1,1),random.range(-1,1));
this.radius = random.range(10, 50);
let randomColor = Math.floor(Math.random() * 16777215).toString(16);
randomColor = '#' + randomColor;
this.fillStyle = randomColor;
}
bounce (width, height) {
if (this.pos.x <= 0 || this.pos.x >= width) this.velocity.x *= -1;
if (this.pos.y <= 0 || this.pos.y >= height) this.velocity.y *= -1;
}
update() {
this.pos.x += this.velocity.x;
this.pos.y += this.velocity.y;
}
draw(context) {
context.fillStyle = ('pink');
context.save();
context.translate(this.pos.x, this.pos.y);
context.lineWidth = 3;
context.beginPath();
context.arc(0, 0, this.radius, 0, Math.PI * 2);
context.fillStyle = this.fillStyle;
context.fill();
context.stroke();
context.restore();
}
}
Using Generative Art and AI
I decided I wanted to try out taking one of the items I created and using MidJourney to take that generated image someplace else. So I used one of the images created in part 2 and asked MidJourney to created “mysterious sci-fi item in the star trek universe” using the image as the first part of the prompt.
So there you have it. It was a fun time noodling about again with some code and creating some fun art. I am looking forward to finishing the rest of the first course and moving onto the second. I will be sure to share the progress.