Skip to content

Instantly share code, notes, and snippets.

@jpdenford
Forked from dribnet/.block
Last active October 13, 2016 04:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jpdenford/d902771100c2605caa13db7dd3b67c86 to your computer and use it in GitHub Desktop.
Save jpdenford/d902771100c2605caa13db7dd3b67c86 to your computer and use it in GitHub Desktop.
Dimensional Glyph
license: mit
// note: this file is poorly named - it can generally be ignored.
// helper functions below for supporting blocks/purview
function saveBlocksImages(doZoom) {
if(doZoom == null) {
doZoom = false;
}
// generate 960x500 preview.jpg of entire canvas
// TODO: should this be recycled?
var offscreenCanvas = document.createElement('canvas');
offscreenCanvas.width = 960;
offscreenCanvas.height = 500;
var context = offscreenCanvas.getContext('2d');
// background is flat white
context.fillStyle="#FFFFFF";
context.fillRect(0, 0, 960, 500);
context.drawImage(this.canvas, 0, 0, 960, 500);
// save to browser
var downloadMime = 'image/octet-stream';
var imageData = offscreenCanvas.toDataURL('image/jpeg');
imageData = imageData.replace('image/jpeg', downloadMime);
p5.prototype.downloadFile(imageData, 'preview.jpg', 'jpg');
// generate 230x120 thumbnail.png centered on mouse
offscreenCanvas.width = 230;
offscreenCanvas.height = 120;
// background is flat white
context = offscreenCanvas.getContext('2d');
context.fillStyle="#FFFFFF";
context.fillRect(0, 0, 230, 120);
if(doZoom) {
// pixelDensity does the right thing on retina displays
var pd = this._pixelDensity;
var sx = pd * mouseX - pd * 230/2;
var sy = pd * mouseY - pd * 120/2;
var sw = pd * 230;
var sh = pd * 120;
// bounds checking - just displace if necessary
if (sx < 0) {
sx = 0;
}
if (sx > this.canvas.width - sw) {
sx = this.canvas.width - sw;
}
if (sy < 0) {
sy = 0;
}
if (sy > this.canvas.height - sh) {
sy = this.canvas.height - sh;
}
// save to browser
context.drawImage(this.canvas, sx, sy, sw, sh, 0, 0, 230, 120);
}
else {
// now scaledown
var full_width = this.canvas.width;
var full_height = this.canvas.height;
context.drawImage(this.canvas, 0, 0, full_width, full_height, 0, 0, 230, 120);
}
imageData = offscreenCanvas.toDataURL('image/png');
imageData = imageData.replace('image/png', downloadMime);
p5.prototype.downloadFile(imageData, 'thumbnail.png', 'png');
}

PS4 MDDN 342 2016

This sketch has two main components, the glyph4 and the glyph8. Each encodes a set of values as parameters for a small deterministic glyph/drawing. The two glyph styles are explained below.

Glyph4 - Symmetry

** Design Process **

For glyph4 I wanted to make something geometric (and possible symmetric). Since the designated area was a circle, I decided to work with this as a starting point.

I wanted to deconstruct the circle and make something which played with varying degrees of resolution eg. hexagons, triangles etc...

I began by constructing these basic shapes through a simple 'makecircle' function taking a resolution argument.

I then tried various combinations of shape including having circle or square ripples on each vertex. I decided to stick with this as I liked the inward spiraling look it brought, it also highlighted the symmetry of the design.

Next I layered several of the shapes on top of each other, and used this as a second paraemter. As it turned out this added a lot of extra noise to the final design but I think it still worked with the aesthetic.

** Final Design **

I feel the final design does have significant distinguishable features, however this might be since I have worked on it for a while. Two of my parameters are decreased in resolution (number of verteces and number of layers) so they don't always fill the gradient with completely different forms row to row. I feel however that there is enough differentiation between them overall. At one end of the spectrum, some glyphs can be quite dark but as a result of this the gradient (esp. 64) is interesting to look at and is almost a piece in itself.

I am happy with the possible sacrifice of 'encoding of information' for the more aesthetically interesting design and coherence, each glyph on its own feels interesting to look at.

Glyph8 - Drifting In Space

** Design Process **

For glyph8 I wanted to make something more pictorial than my previous one. I don't make these kinds of designs often (usually opting for a more geometric style) so I was interested to see where it would take me.

I began by making a list of possible parameters relating to a planet along with some initial sketches for inspiration.

  • stars
  • twilight/night
  • amount of population / cities
  • wars (bombs / explosions)
  • speed
  • direction
  • clouds
  • sky gradient
  • weather
  • aridness
  • moons
  • suns
  • rockets

I began by implementing a basic planet with continents and stars. From there I tried out some other parameters, opting for ones which would be easily distinguishable at both large and small sizes.

I also created a basic pallet for visual coherence.

One parameter which I stumbled upon and quite enjoy is the atmospheric glow, I think this added a lot aesthetically.

I had a problem with the number of stars as a parameter being indistinguishable due to rearranging each time. I managed to fix this through using a constant noise seed, each star that is added is added to the same existing set.

** Final Design **

The final design followed on from the initial idea although I had trouble with the colours and made some adjustments to the pallet accordingly. The final glyph is pretty coherent and I am happy with the style and distinguishable parameters.

I feel that it has encoded information well, as well as being interesting to look at.

Overall I am happy with the outcome, I feel it is memorable and coherent and it has given me drive to try more designs in a similar style in the future.

var v0;
var v1;
var v2;
var v3;
var glSize;
var v4;
var v5;
var v6;
var v7;
/*
* val4 is an array of 4 numbers that range from [0,100]
* size is the number of pixels for width and height
* use p5.js to draw a round grawscale glpyh within the bounding box
*/
function glyph4(values, size) {
stroke(0);
noFill();
var s2 = size/2
strokeWeight(glSize / 128);
ellipse(s2, s2, size);
v0 = values[0]/100.0; // polypoint size
v1 = values[1]/100.0; // rotation (not useful)
v2 = values[2]/100.0; // number of points
v3 = values[3]/100.0; // number of layered polys
glSize = size;
var rectSize = size;
push();
translate(rectSize*.5, rectSize*.5);
var rectHeight = rectSize / 2.85;
push();
// draw each polygon
var numPolys = max(ceil(v3 * 15), 1);
var numPoints = max(ceil(v2 * 12), 1);
var circMax = (glSize / 3.6);
push();
for (var i = numPolys; i > 0; i--) {
// rotate a tiny bit depending on v0
rotate(map(v0, 0, 1, 0, QUARTER_PI * 0.1));
var amt = i / numPolys;
var iSize = amt * rectHeight;
var circMin = map(amt, 0, 1, 0, circMax);
var circlePointSize = map(v1, 1, 0, circMin, circMax);
drawPoly(0, 0, iSize, numPoints, circlePointSize);
}
pop();
pop();
pop();
}
function drawPoly(x, y, size, numP, ripSize){
var numRips = 1;
var points = circlePoints(x, y, size, numP);
//draw polygon
push();
fill(255);
strokeWeight(glSize / 48);
beginShape();
for(var i = 0; i < points.length; i++){
var p = points[i];
vertex(p.x, p.y);
}
endShape(CLOSE);
pop();
//draw ellipses on points
push();
stroke(0);
for(var i = 0; i < points.length; i++){
var p = points[i];
for(var c = numRips; c > 0; c--){
var ripAmt = c / numRips;
var col = (1-ripAmt) * 255;
// console.log(ripAmt);
ellipse(p.x, p.y, ripAmt * ripSize, ripAmt * ripSize);
}
}
pop();
}
/*Returns a list of points that make up a circle/polygon*/
function circlePoints(x, y, size, numNodes){
var nodes = [];
for(var i = 0.0; i < numNodes; i++){
var node = {
x: 0,
y: 0
};
var amt = i/numNodes;
node.x = x + (sin(amt * TWO_PI) * size);
node.y = y + (cos(amt * TWO_PI) * size);
nodes[i] = node;
}
return nodes;
}
/*
* val8 is an array of 8 numbers that range from [0,100]
* size is the number of pixels for width and height
* use p5.js to draw a square color glpyh within the bounding box
*/
function glyph8(values, size) {
v0 = values[0]/100.0; // stars
v1 = values[1]/100.0; // land color (health)
v2 = values[2]/100.0; // war
v3 = values[3]/100.0; // planet direction
v4 = values[4]/100.0; // cloud position
v5 = values[5]/100.0; // planet speed
v6 = values[6]/100.0; // twilight / night
v7 = values[7]/100.0; // speed
glSize = size;
noFill();
sky();
stars();
push();
var plx = cos((v3 * TWO_PI) + PI) * glSize * 0.15 * v7;
var ply = sin((v3 * TWO_PI) + PI) * glSize * 0.15 * v7;
translate(plx, ply);
planet();
pop();
speedStrokes();
// pallet();
}
function sky(){
push();
var skyCol = lerpColor(color(cols.purple),color(0),v5);
fill(skyCol);
noStroke();
rect(0, 0, glSize, glSize);
pop();
}
function stars(){
noiseSeed(45234);
var numStars = v0 * 100;
for (var i = 0; i < numStars; i++) {
var x = noise(i * 3) * glSize;
var y = noise(i * 28736) * glSize;
star(x, y, noise(i * 123) * 5);
}
}
function star(x, y, sz){
push();
stroke(cols.yellow);
strokeWeight(glSize / 500);
var numPoints = 5;
for(var i = 0; i < numPoints; i++){
var amt = (i/numPoints) * PI;
line(x + sin(amt) * sz,y + cos(amt) * sz,x + sin(amt+PI) * sz,y + cos(amt+PI) * sz);
}
pop();
}
function planet(){
var planSize = glSize / 2;
push();
noStroke();
translate(glSize * .5, glSize * .5);
// atmosphere
var atmoCount = 10;
for (var i = 0; i < atmoCount; i++) {
var amt = (i+1.0) / atmoCount;
var scalar = map(amt, 0.0, 1, 1, 1.5);
fill(cols.blue[0],cols.blue[1],cols.blue[2],log((1-amt)+1)*50*v6);
// fill(255,0,0);
ellipse(0,0, planSize * scalar,planSize * scalar);
}
//planet
fill(cols.blue);
ellipse(0, 0, planSize, planSize);
countries(planSize);
pop();
}
function countries(size){
var c1 = [
{ x: -size/2.8, y: -size/3 },
{ x: -size*.5, y: 0 },
{ x: -size*.3, y: size*0.1},
{ x: -size*0.2, y: size*0.3},
{ x: -size*0.15, y: size*0.25},
{ x: -size*0.1, y: size*-0.1},
{ x: 0, y: size*-.4}
];
country(c1);
var c2 = [
{ x: size*.2, y: -size*0 },
{ x: size*0.5, y: 0 },
{ x: size*0.4, y: size*.3 },
{ x: size*0.2, y: size*.44 },
];
country(c2);
//explosions over c1
var points1 = getDistPoints(size*.4, size*.6, v2*20, v2*1234);
for (var i = 0; i < points1.length; i++) {
var p = points1[i];
explosion(p.x+c1[0].x, p.y+c1[0].y, glSize*.1*v2);
}
//explosions over c2
var points1 = getDistPoints(size*.3, size*.4, v2*20, v2*472);
for (var i = 0; i < points1.length; i++) {
var p = points1[i];
explosion(p.x+c2[0].x, p.y+c2[0].y, glSize*.1*v2);
}
clouds();
// c1 cities
// var cities1 =
// c2 cities
}
function country(points){
push();
stroke(color(cols.green[0],cols.green[1],cols.green[2]));
var from = color(cols.darkYellow);
var to = color(cols.green);
colorMode(RGB); // Try changing to HSB.
interA = lerpColor(from, to, v1);
fill(interA);
ellipseMode(CENTER);
stroke(0);
beginShape();
for (var i = 0; i <= points.length+2; i++) {
var x = points[i % points.length].x;
var y = points[i % points.length].y;
curveVertex(x,y);
// ellipse(x,y,3,3);
}
endShape();
pop();
}
function clouds(){
push();
var cloudSz = glSize * 0.5;
rotate(v4 * TWO_PI);
translate(glSize * 0.3,0);
rotate(HALF_PI);
translate(-cloudSz*.1, 0);
// translate(glSize * .5, glSize * .5);
ellipseMode(CENTER);
fill(cols.cream);
noStroke();
rect(0, 0, cloudSz * .2, cloudSz * .05);
ellipse(0, 0, cloudSz * .1, cloudSz * .1);
ellipse(cloudSz * .2, 0, cloudSz * .1, cloudSz * .1);
ellipse(cloudSz * .1, -cloudSz*.025, cloudSz * .12, cloudSz * .12);
//clouds
noFill();
strokeWeight(glSize * 0.008);
stroke(cols.cream);
push();
translate(glSize * 0.008,0);
// ellipse();
line(0, glSize * .04, glSize * .02, glSize * .1);
line(glSize * .04 , glSize * .04, glSize * .06, glSize * .1);
line(glSize * .08 , glSize * .04, glSize * .1, glSize * .1);
pop();
pop();
}
function explosion(x, y, size){
push();
fill(cols.red);
ellipse(x, y, size);
fill(cols.darkYellow);
ellipse(x, y, size/1.3);
pop();
}
function getDistPoints(wid, hei, num, seed){
var pts = [];
noiseSeed(seed);
for (var i = 0; i < num; i++) {
var x = noise(i*123) * wid;
var y = noise(i*12345) * hei;
pts.push({x:x,y:y});
}
return pts;
}
function speedStrokes(){
push();
translate(glSize * .5,glSize *.5);
rotate(v3 * TWO_PI);
stroke(cols.cream[0],cols.cream[1],cols.cream[2],200);
strokeWeight(glSize * 0.007);
var size = glSize * 0.3 * v7;
var xOff = glSize * 0.15;
translate((1-v7) * glSize * 0.3,0);
bezier(size * 0 + xOff,size * 0, size*.37+ xOff,size * .07, size * 0.59 + xOff, size * .05, size + xOff, size * -0.15);
translate(0,glSize * 0.05);
bezier(size * 0 + xOff,size * 0, size*.37+ xOff,size * .07, size * 0.59 + xOff, size * .05, size + xOff, size * -0.15);
translate(0,glSize * 0.05);
bezier(size * 0 + xOff,size * 0, size*.37+ xOff,size * .07, size * 0.59 + xOff, size * .05, size + xOff, size * -0.15);
pop();
}
function sketchyEllipse(xOrig, yOrig, wid, hei, funkAmt, seed){
var frequency = 3; //jaggedness
seed = seed | 70.8;
wid = wid * 0.5;
hei = hei * 0.5;
//noise seed based on position
noiseSeed(seed);
//set the max funkyness of the ellipse based on size & funk amt
var avgSizeOffset = ((wid + hei) * (constrain(funkAmt, 0, 1.0) * 0.7));
var numPoints = 50;
noiseSeed(seed * 10);
beginShape();
for(var k = 0; k <= numPoints; k++){
var amt = (k/numPoints) * TWO_PI;
var noiseX = (cos((k/numPoints)*TWO_PI) + 1)*frequency;
var noiseY = (sin((k/numPoints)*TWO_PI) + 1)*frequency;
var noiseAmt = noise(noiseX, noiseY) - 0.5;
var nextX = xOrig + sin(amt) * (wid + noiseAmt * avgSizeOffset);
var nextY = yOrig + cos(amt) * (hei + noiseAmt * avgSizeOffset);
vertex(nextX, nextY);
}
endShape(CLOSE);
}
function pallet(){
var colsKeys = Object.keys(cols);
for (var i = 0; i < colsKeys.length; i++) {
fill(cols[colsKeys[i]]);
// console.log(i,colsKeys[i]);
rect(i*10, 0, 10, 10);
}
}
var cols = {
black: [55, 55, 55],
yellow: [254, 209, 86],
red: [226, 79, 50],
cream: [226, 218, 183],
blue: [88, 182, 194],
darkYellow: [246, 163, 60],
green: [10, 208, 149],
purple: [75,59,125]
};
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.3/p5.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.3/addons/p5.dom.js"></script>
<script language="javascript" type="text/javascript" src=".purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="glyph.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
<style>
body { padding: 0; margin: 0; }
.inner { position: absolute; }
#controls {
font: 300 12px "Helvetica Neue";
padding: 5;
margin: 5;
background: #f0f0f0;
opacity: 0.1;
-webkit-transition: opacity 0.2s ease;
-moz-transition: opacity 0.2s ease;
-o-transition: opacity 0.2s ease;
-ms-transition: opacity 0.2s ease;
}
#controls:hover { opacity: 0.9; }
</style>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
</div>
<div class="inner" id="controls" height="500px">
<table>
<tr>
<td>1</td>
<td id="slider1Container"></td>
</tr>
<tr>
<td>2</td>
<td id="slider2Container"></td>
</tr>
<tr>
<td>3</td>
<td id="slider3Container"></td>
</tr>
<tr>
<td>4</td>
<td id="slider4Container"></td>
</tr>
<tr>
<td>5</td>
<td id="slider5Container"></td>
</tr>
<tr>
<td>6</td>
<td id="slider6Container"></td>
</tr>
<tr>
<td>7</td>
<td id="slider7Container"></td>
</tr>
<tr>
<td>8</td>
<td id="slider8Container"></td>
</tr>
<tr>
<td>
<hr>
</td>
</tr>
<tr>
<td>Mode</td>
<td id="selector1Container"></td>
</tr>
<tr>
<td>Glyph</td>
<td id="selector2Container"></td>
</tr>
<tr>
<td>Size</td>
<td id="selector3Container"></td>
</tr>
<tr>
<td></td>
<td id="buttonContainer"></td>
</tr>
</div>
</div>
</table>
</body>
var canvasWidth = 960;
var canvasHeight = 500;
var glyphSelector;
var modeSelector;
var sizeSelector;
var val_sliders = [];
function setup () {
// create the drawing canvas, save the canvas element
var main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
// create two sliders
for (i=0; i<8; i++) {
var slider = createSlider(0, 100, 50);
slider.parent("slider" + (i+1) + "Container")
slider.changed(sliderUpdated);
slider.mouseMoved(sliderUpdated);
slider.touchMoved(sliderUpdated);
val_sliders.push(slider);
}
modeSelector = createSelect();
modeSelector.option('gradient');
modeSelector.option('analogy');
modeSelector.option('drive');
modeSelector.option('random_grid');
modeSelector.changed(modeChangedEvent);
modeSelector.value('gradient');
modeSelector.parent('selector1Container');
glyphSelector = createSelect();
glyphSelector.option('glyph4');
glyphSelector.option('glyph8');
glyphSelector.changed(modeChangedEvent);
glyphSelector.value('glyph8');
glyphSelector.parent('selector2Container');
sizeSelector = createSelect();
sizeSelector.option('64');
sizeSelector.option('128');
sizeSelector.option('256');
sizeSelector.parent('selector3Container');
sizeSelector.value('128');
sizeSelector.changed(sizeChangedEvent);
button = createButton('redo');
button.mousePressed(buttonPressedEvent);
button.parent('buttonContainer');
noLoop();
refreshGridData();
modeChangedEvent();
}
function sliderUpdated() {
redraw();
}
function mouseClicked() {
analogyCycleStep = (analogyCycleStep + 1) % 3;
if(analogyCycleStep == 0) {
refreshAnalogyData();
}
redraw();
}
function dataInterpolate(data1, data2, val) {
var d = new Array(8);
for(var i=0; i<8; i++) {
d[i] = lerp(data1[i], data2[i], val);
}
return d;
}
var numGridRows;
var numGridCols;
var gridValues; // row, col order
var gridOffsetX, gridOffsetY;
var gridSpacingX, gridSpacingY;
// Generate data for putting glyphs in a grid
var numAnalogyChoices = 5;
var analogyValues = new Array(4);
var analogyChoices = new Array(numAnalogyChoices);
var analogyAnswer;
var analogyCycleStep;
function clamp(num, min, max) {
return Math.min(Math.max(num, min), max);
}
function refreshAnalogyData() {
for (var i=0; i<4; i++) {
analogyValues[i] = new Array(8);
}
for (var i=0; i<3; i++) {
for (var j=0; j<8; j++) {
analogyValues[i][j] = random(100);
}
}
for (var j=0; j<8; j++) {
analogyValues[3][j] = clamp(analogyValues[1][j] - analogyValues[0][j] + analogyValues[2][j], 0, 100);
// handle overflow
analogyValues[1][j] = clamp(analogyValues[3][j] - analogyValues[2][j] + analogyValues[0][j], 0, 100);
}
analogyAnswer = Math.floor(random(numAnalogyChoices))
for (var i=0; i<numAnalogyChoices; i++) {
analogyChoices[i] = new Array(8);
for (var j=0; j<8; j++) {
if (i == analogyAnswer) {
analogyChoices[i][j] = analogyValues[3][j];
}
else {
analogyChoices[i][j] = random(100);
}
}
}
analogyCycleStep = 0;
}
function refreshGridData() {
var glyphSize = parseInt(sizeSelector.value(), 10);
if(glyphSize == 128) {
numGridCols = 7;
numGridRows = 3;
gridOffsetX = 10;
gridSpacingX = 136;
gridOffsetY = 20;
gridSpacingY = 166;
}
else if(glyphSize == 256) {
numGridCols = 3;
numGridRows = 1;
gridOffsetX = 20;
gridSpacingX = 320;
gridOffsetY = 100;
gridSpacingY = 500;
}
else if(glyphSize == 64) {
numGridCols = 14;
numGridRows = 7;
gridOffsetX = 3;
gridSpacingX = 68;
gridOffsetY = 6;
gridSpacingY = 71;
}
gridValues = new Array(numGridRows);
for (var i=0; i<numGridRows; i++) {
gridValues[i] = new Array(numGridCols);
for (var j=0; j<numGridCols; j++) {
gridValues[i][j] = new Array(8);
}
}
var mode = modeSelector.value();
if (mode == "gradient") {
var top_left = Array(8);
var top_right = Array(8);
var bottom_left = Array(8);
var bottom_right = Array(8);
for (var k=0; k<8; k++) {
top_left[k] = random(100);
top_right[k] = random(100);
bottom_left[k] = random(100);
bottom_right[k] = random(100);
}
for (var i=0; i<numGridRows; i++) {
if(numGridRows == 0) {
var frac_down = 0;
}
else {
var frac_down = i / (numGridRows - 1.0);
}
d_left = dataInterpolate(top_left, bottom_left, frac_down);
d_right = dataInterpolate(top_right, bottom_right, frac_down);
for (var j=0; j<numGridCols; j++) {
if(numGridCols == 0) {
var frac_over = 0;
}
else {
var frac_over = j / (numGridCols - 1.0);
}
gridValues[i][j] = dataInterpolate(d_left, d_right, frac_over);
}
}
}
else {
for (var i=0; i<numGridRows; i++) {
for (var j=0; j<numGridCols; j++) {
for (var k=0; k<8; k++) {
gridValues[i][j][k] = random(100);
}
}
}
}
refreshAnalogyData();
}
function sizeChangedEvent() {
var mode = modeSelector.value();
if (mode != "drive") {
refreshGridData();
}
redraw();
}
function modeChangedEvent() {
var mode = modeSelector.value();
var glyph = glyphSelector.value();
// enable/disable sliders
if (mode === "drive") {
// disable the button
button.attribute('disabled','');
// enable the size selector
sizeSelector.removeAttribute('disabled');
// enable the first four sliders
for(i=0; i<4; i++) {
val_sliders[i].removeAttribute('disabled');
}
if(glyph === "glyph4") {
for(i=4; i<8; i++) {
val_sliders[i].attribute('disabled','');
}
}
else {
for(i=4; i<8; i++) {
val_sliders[i].removeAttribute('disabled');
}
}
}
else {
// enable the button
button.removeAttribute('disabled');
// disable the sliders
for(i=0; i<8; i++) {
val_sliders[i].attribute('disabled','');
}
if (mode == "analogy") {
// enable the size selector
sizeSelector.attribute('disabled','');
}
else {
// enable the size selector
sizeSelector.removeAttribute('disabled');
}
// refresh data
refreshGridData();
}
redraw();
}
function buttonPressedEvent() {
analogyCycleStep = 0;
refreshGridData();
redraw();
}
var colorBack = [128, 128, 128];
var colorFront = [200, 200, 200];
function drawDriveMode() {
var glyph_is_glyph4 = true;
if(glyphSelector.value() === "glyph8")
glyph_is_glyph4 = false;
var glyphSize = parseInt(sizeSelector.value(), 10);
var halfSize = glyphSize / 2;
background(colorBack);
var halfSize = glyphSize / 2;
var middle_x = canvasWidth / 2;
var middle_y = canvasHeight / 2;
resetMatrix();
translate(middle_x - halfSize, middle_y - halfSize);
var val = [0,0,0,0,0,0,0,0];
for(i=0; i<8; i++) {
val[i] = val_sliders[i].value();
}
stroke(128, 128, 192);
noFill();
if(glyph_is_glyph4) {
ellipse(halfSize, halfSize, glyphSize+2);
glyph4(val, glyphSize)
}
else {
rect(-1, -1, glyphSize+2, glyphSize+2);
glyph8(val, glyphSize)
}
}
function drawGridMode() {
var glyph_fn = glyph4;
if(glyphSelector.value() === "glyph8")
glyph_fn = glyph8;
var glyphSize = parseInt(sizeSelector.value(), 10);
background(colorBack);
for (var i=0; i<numGridRows; i++) {
for (var j=0; j<numGridCols; j++) {
resetMatrix();
translate(gridOffsetX + j * gridSpacingX, gridOffsetY + i * gridSpacingY);
for (var k=0; k<8; k++) {
glyph_fn(gridValues[i][j], glyphSize);
}
}
}
}
var analogyOffsetX = 350;
var analogyOffsetY = 40;
var analogySpacingX = 160;
var analogySpacingY = 160;
var analogyChoiceOffsetX = 260;
var analogyChoiceOffsetY = 380;
var analogyChoiceSpacingX = 100;
function drawAnalogy() {
background(colorBack);
var glyph_fn = glyph4;
if(glyphSelector.value() === "glyph8")
glyph_fn = glyph8;
resetMatrix();
translate(analogyOffsetX + 0 * analogySpacingX, analogyOffsetY + 0 * analogySpacingY);
glyph_fn(analogyValues[0], 128);
resetMatrix();
translate(analogyOffsetX + 1 * analogySpacingX, analogyOffsetY + 0 * analogySpacingY);
glyph_fn(analogyValues[1], 128);
resetMatrix();
translate(analogyOffsetX + 0 * analogySpacingX, analogyOffsetY + 1 * analogySpacingY);
glyph_fn(analogyValues[2], 128);
resetMatrix();
translate(analogyOffsetX + 1 * analogySpacingX, analogyOffsetY + 1 * analogySpacingY);
if(analogyCycleStep == 2) {
glyph_fn(analogyValues[3], 128);
}
else {
stroke(64, 64, 192);
noFill();
if(glyph_fn === glyph4) {
ellipse(64, 64, 128+2);
}
else {
rect(-1, -1, 128+2, 128+2);
}
}
if(analogyCycleStep != 0) {
for(var i=0; i<numAnalogyChoices; i++) {
resetMatrix();
translate(analogyChoiceOffsetX + i * analogyChoiceSpacingX, analogyChoiceOffsetY);
if(analogyCycleStep == 2 && analogyAnswer == i) {
stroke(64, 64, 192);
fill(64, 64, 192);
rect(-6, -6, 64+12, 64+12);
}
glyph_fn(analogyChoices[i], 64);
}
}
}
function draw () {
var mode = modeSelector.value();
if (mode == "drive") {
drawDriveMode();
}
else if (mode == "analogy") {
drawAnalogy();
}
else {
drawGridMode();
}
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment