Creative Code
Where art and code meet.
In the future, I’d like to incorporate creative code into client work to solve specific problems, preferrably mixed with live exhibits or events. Combine this with my game design abilities and I could help create really awe-inspiring experiences!
Projects on page: Sea of Shapes, Palette Generator, Shader Sampler, Sol Lewitt, Architecture, Organic Rectangles, Color Stumbler, Negative Space, Concentric Blitzkrieg, Color Matcher, No Computer, and Chromatic Abberation.
[code language=”javascript”]
//This work is licensed under a Creative Commons Non-Commercial 4.0 International License
var colors = [];
var waves = [];
var wavesNum = 20;
var rOff = 0;
var xSpacing, ySpacing;
var maxSize = 30;
var fps = 60;
var testColor;
function setup() {
createCanvas(800, 800);
frameRate(fps);
colors = [
color(“#002535”),
color(“#003851”),
color(“#f57e7e”),
color(“#bfd2d9”),
color(“#3b89ac”),
];
shuffle(colors, true);
var longestSide = false;
xSpacing = round(width / wavesNum);
ySpacing = round(height / wavesNum);
waves = make2DArray(xSpacing, ySpacing);
for (i = 0; i < wavesNum; i++) { for (j = 0; j < wavesNum; j++) { randomColorNumber = round(random(1, colors.length - 1)); waves[i][j] = new Wave(colors[randomColorNumber]); } } noStroke(); } function draw() { background(colors[0]); for (i = 2; i < wavesNum - 1; i++) { for (j = 2; j < wavesNum; j++) { waves[i][j].display(xSpacing * i, ySpacing * j, PI, 0); } } } class Wave { constructor(color) { this.color = color; } display(xPos, yPos, start, stop) { rOff = sin(frameCount * 0.00003); var radius = sin((xPos + yPos) * rOff); radius *= radius; radius *= maxSize*1.15; fill(this.color); arc(xPos, yPos, radius * 2, radius * 2, start, stop); } } function make2DArray(cols, rows) { let arr = new Array(cols); for (let i = 0; i < arr.length; i++) { arr[i] = new Array(rows); } return arr; } } function getColor(aColor) { r = aColor._array[0]; g = aColor._array[1]; b = aColor._array[2]; a = aColor._array[3]; newColor = color(r, g, b, a); return newColor; } function subStep(gradient, steps) { return floor(gradient * steps) / steps; } [/code] [/ohio_text][vc_empty_space height="1vh" el_class="vc_hidden-xs vc_hidden-sm"][ohio_text text_typo="null"]
[code language=”javascript”]
//This work is licensed under a Creative Commons Non-Commercial 4.0 International License
let img = [];
var imgNumber = 0;
let pixelArray = [];
var fps = 60;
var dimensions = 800;
var t = 0;
var rando = 0;
var dark = false;
var imageIndex = 0;
function getImageFromASite() {
// var rand = round(random(0, 3));
// console.log(rand);
imageIndex = (imageIndex + 1) % 4;
if (imageIndex == 0) {
return loadImage(“https://picsum.photos/” + dimensions);
} else if (imageIndex == 1) {
return loadImage(
“https://source.unsplash.com/random/” +
dimensions +
“x” +
dimensions +
“sig=${Math.random()/?flower”
);
} else if (imageIndex == 2) {
return loadImage(
“https://source.unsplash.com/random/” +
dimensions +
“x” +
dimensions +
“sig=${Math.random()/?illustration”
);
} else {
return loadImage(
“https://source.unsplash.com/random/” +
dimensions +
“x” +
dimensions +
“sig=${Math.random()/?fruit”
);
}
}
function preload() {
//If two images are loaded here, they will be the same
img.push(getImageFromASite());
}
function setup() {
pixelDensity(1);
createCanvas(dimensions, dimensions);
frameRate(fps);
noStroke();
refresh();
}
function getNextImageNumber() {
imgNumber = (imgNumber + 1) % 2;
console.log(“Img number is now: ” + imgNumber);
return imgNumber;
}
function refresh() {
//If another image has been loaded, get the next one
if (img.length > 1) imgNumber = getNextImageNumber();
console.log(“Loading image: ” + imgNumber);
image(img[imgNumber], 0, 0, dimensions, dimensions);
loadPixels();
fill(pixels[0], pixels[1], pixels[2], 255 / 2);
pixelArray = pixels;
updatePixels();
//todo:: Check if the average value is dark or light and swap dark and light mode accordingly
// if (round(random(0, 1)) == 1) dark = true;
// console.log(“dark is: ” + dark);
rando = round(random(0, 3));
if (img.length == 1) {
img.push(getImageFromASite());
console.log(
“Added another image to img array. length is now: ” + img.length
);
} else {
imgNumber = getNextImageNumber();
console.log(“Splicing next image into: ” + imgNumber);
img.splice(imgNumber, 1, getImageFromASite());
//Flip back to the previously loaded image for draw()
imgNumber = getNextImageNumber();
}
t = 0;
console.log(“Ready to DRAW”);
console.log(“Pixels in Array: ” + pixelArray.length / 4);
console.log(“pixels in canvas: ” + dimensions * dimensions);
}
var lineWidth = 2;
function draw() {
image(img[imgNumber], 0, 0, dimensions, dimensions);
for (row = 0; row < dimensions; row++) {
var widthIndex;
if (t > (pixelArray.length / 4) * 0.5) {
// When you effectively hit the max
widthIndex = (pixelArray.length / 4 – t) * 8;
//console.log(widthIndex);
} else {
widthIndex = ((t * 2) % pixelArray.length) * 4;
}
var value =
(pixels[widthIndex + 0] +
pixels[widthIndex + 1] +
pixels[widthIndex + 2]) /
3;
var colorIndex = ((t * 2) % pixelArray.length) * 2;
lineColor = color(
pixelArray[colorIndex + 0],
pixelArray[colorIndex + 1],
pixelArray[colorIndex + 2],
255 * 0.95
);
fill(lineColor);
var mappedWidth;
if (!dark) mappedWidth = map(value, 0, 255, 0, width);
else mappedWidth = map(value, 0, 255, width, 0);
if (rando == 0) {
ellipse(0, row, mappedWidth * 3, lineWidth);
} else if (rando == 1) {
ellipse(height, row, mappedWidth * 3, lineWidth);
} else if (rando == 2) {
ellipse(row, 0, lineWidth, mappedWidth * 3);
} else {
ellipse(row, height, lineWidth, mappedWidth * 3);
}
// strokeWeight(2);
// stroke(lineColor);
// line(0, row, mappedWidth, row);
t++;
if (t > pixelArray.length / 4) {
console.log(“t: ” + t);
t = 0;
refresh();
console.log(“REFRESH!”);
}
}
}
function keyReleased() {
if (key == “s” || key == “S”) saveCanvas(gd.timestamp(), “png”);
}
[/code]
[code language=”javascript”]
//This work is licensed under a Creative Commons Non-Commercial 4.0 International License let colors; var structureCount = 100; var minDepth = 10; var structures = []; var fps = 60; var xOff = 0; function setup() { createCanvas(windowHeight, windowHeight, WEBGL); structureCount = random(20, 60); colors = [ color("#060606"), color("#1B9AAA"), color("#DDDBCB "), color("#F5F1E3 "), color("#FFFFFF"), ]; shuffle(colors, true); frameRate(fps); background(colors[0]); for (j = 0; j < structureCount; j++) { randomColorNumber = round(random(1, colors.length - 1)); newColor = color(colors[randomColorNumber]); newStrokeColor = color(colors[(randomColorNumber + 1) % colors.length]); randomHeight = (height * 1.2) / structureCount; randomWidth = noise(xOff) + j * 10; randomDepth = minDepth; structures[j] = new Structure( randomWidth, randomHeight, randomDepth, newColor, newStrokeColor ); xOff += 0.1; }} function draw() { background(colors[0]); translate(0, -height * 0.6, 0); ambientLight(255); directionalLight(255, 0, 0, 100, 20, 0); for (var i = 0; i < structureCount; i++) { translate(0, randomHeight, 0); structures[i].display((frameCount * 0.01) % fps, i); }} class Structure { constructor(w, h, d, color, strokeColor) { this.w = w; this.h = h; this.d = d; this.color = color; this.strokeColor = strokeColor; } display(yRotation, index) { push(); fill(this.color); stroke(colors[0]); strokeWeight(0.8); var rOff = cos(frameCount * 0.004); var rotation = (sin(index * rOff * 0.2))*1.3; rotation *= rotation; rotateY(rotation + index*2); box(this.w, this.h, rotation*400 + minDepth*index); pop(); } }
[/code]
[code language="javascript"]
//This work is licensed under a Creative Commons Non-Commercial 4.0 International License var fps = 60; var pieCount; var xCount, yCount; var rhombtangles = []; var radius = 25; var spacingBetweenShapes; var widthCropping, heightCropping; let colors = []; var asdf; var tlOff = 0; var trOff = 0; var brOff = 0; var blOff = 0; var heightFactor = 1.614; let timer = 5000; let nextChange = timer; //syncs the timer and change rate function setup() { rectMode(RADIUS); createCanvas(windowWidth, windowHeight); colors = [ color("#ECAAA7"), color("#F17273"), color("#D85265"), color("#B9203F"), color("#F6F5F5"), color("#1E3A58"), color("#1C3147"), ]; pixelDensity(1); frameRate(fps); noStroke(); restart(); } function restart() { shuffle(colors, true); widthCropping = width * 0.2; heightCropping = height * 0.1; spacingBetweenShapes = radius / 2; spacingBetweenShapes = 4; radius = random(4, 100); spacingBetweenShapes = random(2, radius*0.5); heightFactor = random(0.4, 1.614*2); console.log("radius:" + radius); console.log("spacing:" + spacingBetweenShapes); console.log("Height Diff: " + heightFactor); xCount = round( (width - widthCropping * 2 - radius) / (radius * 2 + spacingBetweenShapes) ); yCount = round( (height - heightCropping * 2 - radius * heightFactor) / (radius * heightFactor * 2 + spacingBetweenShapes) ); if(yCount <= 0 || xCount <= 0) { console.log("========x or yCount was 0, trying again========"); restart(); return; } console.log("xCount: " + xCount); console.log("yCount: " + yCount); rhombtangles = make2DArray(xCount, yCount); for (i = 0; i < xCount; i++) { for (j = 0; j < yCount; j++) { randomColorNumber = round(random(1, colors.length - 1)); rhombtangles[i][j] = new rhombtangle(radius, colors[randomColorNumber]); } } } function draw() { background(20); background(colors[0]); fill(colors[1]); // tlOff += 0.01; trOff = 0.01; brOff += 0.02; blOff += 0.03; for (i = 0; i < xCount; i++) { for (j = 0; j < yCount; j++) { rhombtangles[i][j].display( i * (radius * 2 + spacingBetweenShapes) + widthCropping + radius + spacingBetweenShapes, j * (radius * heightFactor * 2 + spacingBetweenShapes) + heightCropping + radius * heightFactor + spacingBetweenShapes, i, j ); } } if (millis() > nextChange) { nextChange = millis() + timer; restart(); //console.log(`time elapsed: ${round(millis() / 1000)}`); } class rhombtangle { constructor(radius, color) { this.radius = radius; this.color = color; } display(x, y, i, j) { //tlOff = sin(frameCount * 0.00003); tlOff = sin(frameCount * 0.03 + x + y); //tlOff = sin((x + y) * tlOff); tlOff *= tlOff; tlOff *= this.radius; // trOff = cos(frameCount * 0.0003); // trOff = sin((x + y) * trOff); trOff = cos(frameCount * 0.03 + x + y); trOff *= trOff; trOff *= this.radius; // brOff = sin(frameCount * 0.00003); // brOff = sin((x + y) * brOff); brOff = cos(frameCount * 0.03 + x + y); brOff *= brOff; brOff *= this.radius; // blOff = sin(frameCount * 0.00003); // blOff = cos((x + y) * blOff); blOff = cos(frameCount * 0.03 + x + y); blOff *= blOff; blOff *= this.radius; //fill(this.color); rect( x, y, this.radius + 1, this.radius * heightFactor + 1, tlOff, trOff, brOff, blOff //noise(blOff) * this.radius * 2 ); } } function make2DArray(cols, rows) { let arr = new Array(cols); for (let i = 0; i < arr.length; i++) { arr[i] = new Array(rows); } return arr; } function keyReleased() { if (key == "s" || key == "S") saveCanvas(gd.timestamp(), "png"); }
[/code]
[code language="javascript"]
var mouseMoveChange = true; var $saturation = 1; var $sat1 = 100; var $sat2 = 100; var $sat3 = 100; var $lightness = 100; var $lightnessOffset = 50; var $backgroundColor; var $textColor; var $thirdColor; var $pageX = 0; var $pageY = 0; var $color1 = 0; var $color2 = 120; var $color3 = 240; var $colorDist1 = 0; var $colorDist2 = 120; var $colorDist3 = 240; //Spacebar Lock colors $(window).keypress(function (e) { if (e.key === ' ' || e.key === 'Spacebar') { // ' ' is standard, 'Spacebar' was used by IE9 and Firefox < 37 e.preventDefault() mouseMoveChange = !mouseMoveChange; var onOff; if (mouseMoveChange) { onOff = "Off"; } else { onOff = "On"; } document.querySelector('.colorLock').innerHTML = onOff; } }) $(window).keypress(function (e) { if (e.key === 'r') { randomizeDistances(); } }) $(window).keypress(function (e) { if (e.key === 's') { randomizeSaturation(); } }) $(window).keypress(function (e) { if (e.key === 'c') { var copyText = document.querySelector('.color1').innerHTML + document.querySelector('.color2').innerHTML + document.querySelector('.color3').innerHTML; copyToClipboard(copyText); /* Alert the copied text */ alert("Copied:" + copyText); } }) $(window).keypress(function (e) { if (e.key === 'h') { $("div.hud").toggleClass("d-none"); } }) //Mousewheel Saturation - Firefox $(window).bind('DOMMouseScroll', function (e) { if (e.originalEvent.detail < 0 && $lightnessOffset > 0) { $lightnessOffset -= 2; } else if (e.originalEvent.detail > 0 && $lightnessOffset < 100) { $lightnessOffset += 2; } document.querySelector('.brightness').innerHTML = Math.round(100 - $lightnessOffset); updateColors(); //prevent page fom scrolling return false; }); //Mousewheel Saturation - Chromebone window.addEventListener('mousewheel', function (e) { if (e.wheelDelta > 0 && $lightnessOffset > 0) { $lightnessOffset -= 2; } else if (e.wheelDelta < 0 && $lightnessOffset < 100) { $lightnessOffset += 2; } document.querySelector('.brightness').innerHTML = Math.round(100 - $lightnessOffset); updateColors(); }); var $maxLightness = 100; function copyHex() { } //Get colors based on mouse position $(document).mousemove(function (e) { var $width; var $height; if (mouseMoveChange) { $width = ($(document).width()) / 360; $height = ($(document).height()) / $maxLightness; $pageX = parseInt(e.pageX / $width, 10); $pageY = parseInt(e.pageY / $height, 10); } updateColors(); }); function copyToClipboard(text) { var dummy = document.createElement("textarea"); // to avoid breaking orgain page when copying more words // cant copy when adding below this code // dummy.style.display = 'none' document.body.appendChild(dummy); //Be careful if you use texarea. setAttribute('value', value), which works with "input" does not work with "textarea". – Eduard dummy.value = text; dummy.select(); document.execCommand("copy"); document.body.removeChild(dummy); } function hslToHex(h, s, l) { h /= 360; s /= 100; l /= 100; let r, g, b; if (s === 0) { r = g = b = l; // achromatic } else { const hue2rgb = (p, q, t) => { if (t < 0) t += 1; if (t > 1) t -= 1; if (t < 1 / 6) return p + (q - p) * 6 * t; if (t < 1 / 2) return q; if (t < 2 / 3) return p + (q - p) * (2 / 3 - t) * 6; return p; }; const q = l < 0.5 ? l * (1 + s) : l + s - l * s; const p = 2 * l - q; r = hue2rgb(p, q, h + 1 / 3); g = hue2rgb(p, q, h); b = hue2rgb(p, q, h - 1 / 3); } const toHex = x => { const hex = Math.round(x * 255).toString(16); return hex.length === 1 ? '0' + hex : hex; }; return `#${toHex(r)}${toHex(g)}${toHex(b)}`; } function updateColors() { $color1 = ($pageX + $colorDist1) % 360; $color2 = ($pageX + $colorDist2) % 360; $color3 = ($pageX + $colorDist3) % 360; $lightness = $pageY + $lightnessOffset; $backgroundColor = "hsl(" + ($color1) + "," + ($sat1 * $saturation) + "%," + ($pageY) + "%)"; $textColor = "hsl(" + ($color2) + "," + ($sat2 * $saturation) + "%," + (100 - $lightnessOffset) + "%)"; $thirdColor = "hsl(" + ($color3) + "," + ($sat3 * $saturation) + "%," + (100 - $lightnessOffset) + "%)"; $("body").css("background-color", $backgroundColor); $("body").css("color", $textColor); $("h1").css("color", $textColor); $(".accentBar").css("background-color", $thirdColor); $(".ui-state-default").css("color", $textColor); $(".ui-state-default").css("background", $backgroundColor); $(".ui-state-default").css("border-color", $thirdColor); $(".ui-widget-header").css("background", $backgroundColor); $(".ui-widget-content").css("background", $textColor); $(".ui-widget-content").css("border-color", $thirdColor); $("svg").css("fill", $textColor); document.querySelector('.color1').innerHTML = "'" + hslToHex($color1, $sat1 * $saturation, $pageY) + "',"; document.querySelector('.color2').innerHTML = "'" + hslToHex($color2, $sat2 * $saturation, 100 - $lightnessOffset) + "',"; document.querySelector('.color3').innerHTML = "'" + hslToHex($color3, $sat3 * $saturation, 100 - $lightnessOffset) + "'"; } function randomizeDistances() { $maxRange = 360; $colorDist1 = (Math.floor(Math.random() * ($maxRange + 1))); $colorDist2 = (Math.floor(Math.random() * ($maxRange + 1))); $colorDist3 = (Math.floor(Math.random() * ($maxRange + 1))); $("#slider1").slider('value', $colorDist1); document.querySelector('#custom-handle1').innerHTML = $colorDist1; $("#slider2").slider('value', $colorDist2); document.querySelector('#custom-handle2').innerHTML = $colorDist2; $("#slider3").slider('value', $colorDist3); document.querySelector('#custom-handle3').innerHTML = $colorDist3; updateColors(); } function randomizeSaturation() { $maxRange = 100; $sat1 = (Math.floor(Math.random() * ($maxRange + 1))); $sat2 = (Math.floor(Math.random() * ($maxRange + 1))); $sat3 = (Math.floor(Math.random() * ($maxRange + 1))); $("#slider4").slider('value', $sat1); document.querySelector('#custom-handle4').innerHTML = $sat1; $("#slider5").slider('value', $sat2); document.querySelector('#custom-handle5').innerHTML = $sat2; $("#slider6").slider('value', $sat3); document.querySelector('#custom-handle6').innerHTML = $sat3; updateColors(); } $(function () { var handle = $("#custom-handle1"); $("#slider1").slider({ range: "max", min: 0, max: 360, value: 0, create: function () { handle.text($(this).slider("value")); }, slide: function (event, ui) { $colorDist1 = ui.value; handle.text(ui.value); $("#custom-handle1.ui-state-default").css("color", $backgroundColor); $("#custom-handle1.ui-state-active").css("background", $textColor); $("#custom-handle1.ui-state-active").css("border-color", $backgroundColor); updateColors(); } }); }); $(function () { var handle = $("#custom-handle2"); $("#slider2").slider({ range: "max", min: 0, max: 360, value: 120, create: function () { handle.text($(this).slider("value")); }, slide: function (event, ui) { $colorDist2 = ui.value; handle.text(ui.value); $("#custom-handle2.ui-state-default").css("color", $backgroundColor); $("#custom-handle2.ui-state-active").css("background", $textColor); $("#custom-handle2.ui-state-active").css("border-color", $backgroundColor); updateColors(); } }); }); $(function () { var handle = $("#custom-handle3"); $("#slider3").slider({ range: "max", min: 0, max: 360, value: 240, create: function () { handle.text($(this).slider("value")); }, slide: function (event, ui) { $colorDist3 = ui.value; handle.text(ui.value); $("#custom-handle3.ui-state-default").css("color", $backgroundColor); $("#custom-handle3.ui-state-active").css("background", $textColor); $("#custom-handle3.ui-state-active").css("border-color", $backgroundColor); updateColors(); } }); }); $(function () { var handle = $("#custom-handle4"); $("#slider4").slider({ range: "max", min: 0, max: 100, value: 100, create: function () { handle.text($(this).slider("value")); }, slide: function (event, ui) { $sat1 = ui.value; handle.text(ui.value); $("#custom-handle1.ui-state-default").css("color", $backgroundColor); $("#custom-handle1.ui-state-active").css("background", $textColor); $("#custom-handle1.ui-state-active").css("border-color", $backgroundColor); updateColors(); } }); }); $(function () { var handle = $("#custom-handle5"); $("#slider5").slider({ range: "max", min: 0, max: 100, value: 100, create: function () { handle.text($(this).slider("value")); }, slide: function (event, ui) { $sat2 = ui.value; handle.text(ui.value); $("#custom-handle1.ui-state-default").css("color", $backgroundColor); $("#custom-handle1.ui-state-active").css("background", $textColor); $("#custom-handle1.ui-state-active").css("border-color", $backgroundColor); updateColors(); } }); }); $(function () { var handle = $("#custom-handle6"); $("#slider6").slider({ range: "max", min: 0, max: 100, value: 100, create: function () { handle.text($(this).slider("value")); }, slide: function (event, ui) { $sat3 = ui.value; handle.text(ui.value); $("#custom-handle1.ui-state-default").css("color", $backgroundColor); $("#custom-handle1.ui-state-active").css("background", $textColor); $("#custom-handle1.ui-state-active").css("border-color", $backgroundColor); updateColors(); } }); }); $(window).on('load', function () { document.querySelector('.brightness').innerHTML = Math.round($lightnessOffset); randomizeDistances(); randomizeSaturation(); updateColors(); });
[/code]
https://caseyweeks.com/palpal/ (only works on desktop)
[code language="javascript"]
//This work is licensed under a Creative Commons Non-Commercial 4.0 International License var fps = 60; var rhombtangles = []; var radius = 25; let colors = []; var tlOff = 0; var trOff = 0; var brOff = 0; var blOff = 0; var heightFactor = 1.614; let timer = 3000; let nextChange = timer; //syncs the timer and change rate function setup() { rectMode(RADIUS); createCanvas(windowHeight, windowHeight); colors = [ color("#B9203F"), color("#F6F5F5"), color("#1C3147"), ]; pixelDensity(1); frameRate(fps); noStroke(); restart(); } function restart() { shuffle(colors, true); radius = width * 0.71; for (var i = 0; i < 4; i++) { randomColorNumber = round(random(1, colors.length - 1)); rhombtangles[i] = new rhombtangle(radius, colors[randomColorNumber]); } } function draw() { background(20); background(colors[0]); fill(colors[1]); tlOff += 0.03; trOff += 0.01; brOff += 0.02; asdfOff += 0.01; blOff += 0.015; var thingy = 1; for (i = 0; i < 4; i++) { if (i == 0) { thingy = sin(frameCount*0.001); rhombtangles[i].display(0, 0, i,thingy); } if (i == 1) { thingy = cos(frameCount*0.002); rhombtangles[i].display(width, 0, i,thingy); } if (i == 2) { thingy = cos(frameCount*0.003); rhombtangles[i].display(0, height, i,thingy); } if (i == 3) { thingy = sin(frameCount*0.004); rhombtangles[i].display(width, height, i,thingy); } } if (millis() > nextChange) { nextChange = millis() + timer; restart(); }} var asdfOff = 0; class rhombtangle { constructor(radius, color) { this.radius = radius; this.color = color; } display(x, y, i, thingy) { tlOff = blOff = sin(frameCount * 0.008); tlOff *= tlOff; tlOff *= this.radius; trOff = abs(cos(frameCount * 0.02)); trOff *= radius; var asdf = width * 0.5; brOff = sin(frameCount * 0.03); brOff = sin(brOff); brOff *= brOff; brOff *= this.radius; blOff = sin(frameCount * 0.01); blOff *= blOff; blOff *= this.radius;rect(x, y, radius*thingy, radius*thingy, tlOff, trOff, brOff, blOff); } }
[/code]
[code language="javascript"]
const canvasSketch = require('canvas-sketch'); const random = require('canvas-sketch-util/random'); const math = require('canvas-sketch-util/math'); const colorUtils = require('canvas-sketch-util/color'); let colors = ["#99B898", "#FECEAB", "#FF847C", "#E84A5F", "#2A363B"]; let currentColors = []; let backgroundNumber; let lineNumber; const setupColors = () => { backgroundNumber = Math.floor(random.range(0, colors.length)); for (let i = 0; i < colors.length; i++) { if (i == backgroundNumber) continue; currentColors.push(colors[i]); } } const randCol = () => { let rand = Math.floor(random.range(0, currentColors.length)); return currentColors[rand]; } const settings = { dimensions: [1080, 1080], animate: true }; const averagePointSize = 30; const sketch = ({context, width, height}) => { setupColors(); lineNumber = Math.floor(random.range(0, currentColors.length)); const agents = []; const iterations = 60; let maxLineWidth = averagePointSize * 0.4; for (let i = 0; i < iterations; i++) { const x = random.range(0, width); const y = random.range(0, height); agents.push(new Agent(x, y, random.range(averagePointSize / 1.618, averagePointSize * 2))); } return ({context, width, height}) => { context.fillStyle = colors[backgroundNumber]; 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 dist = agent.pos.getDistance(other.pos); const maxDistance = 200; if (dist > maxDistance) continue; //context.lineWidth = 20; let distancePercent = math.mapRange(dist, 0, maxDistance, 0, 1); context.save(); context.lineWidth = math.mapRange(dist, 0, maxDistance, maxLineWidth, 0); context.beginPath(); context.moveTo(agent.pos.x, agent.pos.y); context.lineTo(other.pos.x, other.pos.y); context.strokeStyle = currentColors[lineNumber]; context.stroke(); context.restore(); } } agents.forEach(agent => { agent.update(); agent.draw(context); agent.wrap(width, height); }); }; }; canvasSketch(sketch, settings); class Vector { constructor(x, y, radius) { this.x = x; this.y = y; } getDistance(v) { const dx = this.x - v.x; const dy = this.y - v.y; return Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2)); } } const speed = 1; class Agent { constructor(x, y, radius) { this.pos = new Vector(x, y); this.vel = new Vector(random.range(-1, 1), random.range(-1, 1)); this.radius = radius; this.color = randCol(); this.strokeColor = randCol(); this.strokeWeight = random.range(0, averagePointSize); } bounce(width, height) { if (this.pos.x <= 0 || this.pos.x >= width) this.vel.x *= -1; if (this.pos.y <= 0 || this.pos.y >= height) this.vel.y *= -1; } wrap(width, height) { if (this.pos.x < 0) this.pos.x = width; if (this.pos.x > width) this.pos.x = 0; if (this.pos.y < 0) this.pos.y = height; if (this.pos.y > height) this.pos.y = 0; } update() { this.pos.x += this.vel.x * speed * 2; this.pos.y += this.vel.y * speed; } draw(context) { context.save(); context.fillStyle = this.color; context.fillStyle = "rgba(255, 255, 255, 0)"; context.strokeStyle = this.strokeColor; context.translate(this.pos.x, this.pos.y); context.beginPath(); context.arc(0, 0, this.radius, 0, Math.PI * 2); context.fill(); context.restore(); } }
[/code]
At Dreamhack, I made a playdough color-matching game using MaKey-MaKey to promote game development at the Society of Play booth. The game required players to match the playdough colors to the colors on the screen, and convention-goers could compete for fastest color-toucher.
[code language="javascript"]
// This is a modification of: // http://www.generative-gestaltung.de/2/sketches/?01_P/P_3_2_5_01 // // Generative Gestaltung – Creative Coding im Web // ISBN: 978-3-87439-902-9, First Edition, Hermann Schmidt, Mainz, 2018 // Benedikt Groß, Hartmut Bohnacker, Julia Laub, Claudius Lazzeroni // with contributions by Joey Lee and Niels Poldervaart // Copyright 2018 // // http://www.generative-gestaltung.de // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. /** * Animated type using loadPixels() method to get font area * * MOUSE * position x/y : affect randomness * * KEYS * A-Z : type letters * Arrow up/down : increase/decrease point density * CONTROL : save png * * CONTRIBUTED BY * [Joey Lee](http://jk-lee.com) */ //'use strict'; var font; var textTyped = 'NO'; var drawMode = 2; var fontSize = 500; var padding = 10; var nOff = 0; var pointDensity = 5; var colors; var paths; var textImg; var pixelImage; var newColorsTimer = 2000; var t = 0; function preload() { font = loadFont('Kelson Sans Bold.otf'); brown = loadImage('brownHeart.png'); tan = loadImage('tanHeart.png'); orange = loadImage('orangeHeart.png'); } function setup() { pixelDensity(1); createCanvas(500, 500); frameRate(25); rectMode(CENTER); frameRate(10); //075352 //colors = [color("#106968"), color("#1e847f"), color("#ecc19c"), color("#075352")]; colors = [color("#E9E5C8"), color("#5D233C"), color("#E99D47"), color("#72C8BB")]; pixelDensity(1); shuffle(colors, true); t = newColorsTimer; setupText(); } function setupText() { shuffle(colors, true); // create an offscreen graphics object to draw the text into fontSize = round(height*0.65); textImg = createGraphics(round(fontSize*2.5), round(fontSize*2)); textImg.pixelDensity(1); textImg.background(255); textImg.textFont(font); textImg.textSize(fontSize); textImg.text(textTyped, round(width*0.5-fontSize*0.63), round(height*0.5+fontSize*0.35)); textImg.loadPixels(); noStroke(); } function draw() { background(colors[3]); nOff++; for (var y = textImg.height; y > 0; y -= pointDensity) { for (var x = textImg.width; x > 0; x -= pointDensity) { //for (var x = 0; x < textImg.width; x += pointDensity) { // Calculate the index for the pixels array from x and y var index = (x + y * textImg.width) * 4; //console.log(index); // Get the red value from image var r = textImg.pixels[index]; if (r < 128) { if (drawMode == 2) { push(); translate(x, y); var w = noise((x - nOff) / 10, (y + nOff * 0.1) / 10) * 20; var h = noise((x - nOff) / 10, (y + nOff * 0.1) / 10) * 10; var num = noise(x / 10, (y + nOff) / 10); if (num < 0.6) { fill(colors[0]); //image(tan, 0, 0, w, w); } else if (num < 0.7) { fill(colors[1]); //image(brown, 0, 0, w, w); } else { fill(colors[2]); //image(orange, 0, 0, w, w); } //ellipse(0, 0, w, w); // rect() is cool too //triangle(0,0, 0+w, 0+w, 0+h, 0-h); arc(0, 0, w, w, PI, TWO_PI); pop(); } } } } //noLoop(); //t+= millis(); if(millis() > t) { setupText(); t = millis() + newColorsTimer; } //console.log(t); } function keyPressed() { if (keyCode === CONTROL) saveCanvas(gd.timestamp(), 'png'); if (keyCode === DELETE || keyCode === BACKSPACE) { textTyped = textTyped.substring(0,max(0,textTyped.length - 1)); setupText(); } if (keyCode === ENTER || keyCode === RETURN) { textTyped += '\n'; setupText(); } if (keyCode === DOWN_ARROW) { pointDensity--; if (pointDensity < 4) pointDensity = 4; } if (keyCode === UP_ARROW) { pointDensity++; } } function keyTyped() { if (keyCode >= 32){ textTyped += key; setupText(); } }
[/code]
[code language="javascript"]
var spacing = 50; var size = 30; var xOff = 0; var fps = 60; function setup() { createCanvas(500, 500); frameRate(fps); blendMode(ADD); // Additive blend mode pg = createGraphics(500, 500); pixelAmount = width; pg.noStroke(); pg.fill(255); noiseRange = 10; // How far move each channel (how much to scale the noise) noiseTime = 0; // Continuously increasing time value for noise calculations noiseSpeed = 0.01; // `noiseTime` addend for each frame // Noise offsets per axis per channel noiseOffsetRX = random(100); noiseOffsetRY = random(100); noiseOffsetGX = random(100); noiseOffsetGY = random(100); noiseOffsetBX = random(100); noiseOffsetBY = random(100); function draw() { xOff += 0.1; // Normal drawing operations here, all prefixed with `pg.` pg.clear(); // Using `clear` instead of `background` clear(); background(0); //pg.circle(width / 2, height / 2, 300); // Arbitrary drawing op var cols = round(width / spacing); var rows = round(height / spacing); var stuff = false; for (var col = 1; col < cols; col++) { for (var row = 1; row < rows; row++) { var asdf = sin(row + xOff) * size + size; if (row % 2 == 1 && col % 2 == 1) { if (stuff) { //pg.circle(col * spacing, row * spacing, asdf); pg.arc( col * spacing, row * spacing, asdf * 0.5, asdf * 0.5, HALF_PI + sin(xOff), PI + HALF_PI - cos(xOff) ); } else { pg.arc( col * spacing, row * spacing, asdf * 0.5, asdf * 0.5, TWO_PI + sin(xOff), PI - cos(xOff) ); } } else { if (stuff) { //pg.circle(col * spacing, row * spacing, asdf); pg.arc( col * spacing, row * spacing, asdf * 0.5, asdf * 0.5, PI + HALF_PI + sin(xOff), TWO_PI + HALF_PI - cos(xOff) ); } else { pg.arc( col * spacing, row * spacing, asdf * 0.5, asdf * 0.5, PI + sin(xOff), TWO_PI - cos(xOff) ); } } stuff = !stuff; } } //pg.rect(width / 2, height / 2, size, size); // Make it spaz out on mouseDown // if (mouseIsPressed) { // noiseTime += noiseSpeed * 100; // } else { // noiseTime += noiseSpeed; // } // Post-processing with rendered image // Note that this is the actual point of this example // All the "noise" business is just to have the channels moving, for effect // The XY values of each `image` can just as easily be set manually tint(255, 0, 0); // Tint red image(pg, noiseFor(noiseOffsetRX), noiseFor(noiseOffsetRY)); // Render image to screen tint(0, 255, 0); // Tint green image(pg, noiseFor(noiseOffsetGX), noiseFor(noiseOffsetGY)); // Render image to screen tint(0, 0, 255); // Tint blue image(pg, noiseFor(noiseOffsetBX), noiseFor(noiseOffsetBY)); // Render image to screen // Get the perlin noise for the current `noiseTime` plus the given `offset`. // Result is mapped to the `noiseRange`. function noiseFor(offset) { return map(noise(noiseTime + offset), 0, 1, -noiseRange, noiseRange); }
[/code]