Skip to content

Instantly share code, notes, and snippets.

@prestojack
Forked from dribnet/.block
Last active October 13, 2016 04:07
Show Gist options
  • Select an option

  • Save prestojack/f781f2ac757ffa5dd2245fa32ef826c7 to your computer and use it in GitHub Desktop.

Select an option

Save prestojack/f781f2ac757ffa5dd2245fa32ef826c7 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');
}

Glyphs - PS4 MDDN 342 2016

The goal of this project was to create two glyphs, one which represented four strands of data and another which represented eight.

GLYPH4 - SquashBall:

The initial inspiration came from stress balls that are given to people to squeeze when they're under stress. I liked the alteration of shape caused by the pressure on the balls and I wanted to translate that into a glyph. The final glyph turned one strand of data into the tension that was on the stress ball and the other three into aesthetic changes, like colour and scale. The use of stress to represent data allowed me to create visually distinct shapes, making it easy to read outliers in the data.

GLYPH8 - Windmill:

I based this glyph on a simplified windmill. I wanted to use a shape that had four distinct regions which I could assign pairs of values to, as a realistic use of data is to show the relationships between different sets of values. The final windmill glyph was very effective at showing off the eight values, as each region could easily be examined independantly or as a cohesive whole to determine differences between glyphs. Addiionally the asymmetric nature of the glyph made it stand out and made variations in the overall shape of the glyph much more obvious.

/*
* 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
*/
var pointArray = Array(8);
function glyph4(values, size) {
//set initial fill/size values
var midx = size/2.0;
var midy = size/2.0;
var fillCol = map(values[0], 0, 100, 40, 220);
fill(fillCol);
stroke(fillCol - 40);
var m = size/64;
strokeWeight(m);
strokeCap(PROJECT);
//generate points on circle edge
var newSize = size;
var relativeCoords = generatePoint(midx, midy, newSize/2.0, -PI/4.0);
pointArray[0] = relativeCoords;
relativeCoords = generatePoint(midx, midy, newSize/2.0, 3*PI/4.0);
pointArray[1] = relativeCoords;
newSize = map(values[2], 0, 100, 5, size);
relativeCoords = generatePoint(midx, midy, newSize/2.0, PI/4.0);
pointArray[2] = relativeCoords;
relativeCoords = generatePoint(midx, midy, newSize/2.0, 5*PI/4.0);
pointArray[3] = relativeCoords;
newSize = size;
relativeCoords = generatePoint(midx, midy, size/2.0, 0);
pointArray[4] = relativeCoords;
relativeCoords = generatePoint(midx, midy, size/2.0, PI/2.0);
pointArray[5] = relativeCoords;
newSize = map(values[2], 0, 100, 5, size);
relativeCoords = generatePoint(midx, midy, size/2.0, PI);
pointArray[6] = relativeCoords;
relativeCoords = generatePoint(midx, midy, size/2.0, -PI/2.0);
pointArray[7] = relativeCoords;
fill(fillCol);
//set values to determine the squash-ball shape
var strapWidth = map(values[1], 0, 100, 2, size/2.56);
var dist = strapWidth/2.0;
var xoffset = dist*cos(PI/4.0);
var yoffset = dist*sin(PI/4.0);
var dif = size/6.4;
var ext = size/25.6;
//draw backfill of squash-ball
noStroke();
beginShape();
vertex(pointArray[0].x, pointArray[0].y);
bezierVertex(pointArray[4].x+ext, pointArray[4].y-dif, pointArray[4].x+ext, pointArray[4].y+dif, pointArray[2].x+xoffset, pointArray[2].y-yoffset);
bezierVertex(pointArray[2].x, pointArray[2].y, pointArray[2].x, pointArray[2].y, pointArray[2].x-xoffset, pointArray[2].y+yoffset);
bezierVertex(pointArray[5].x+dif, pointArray[5].y+ext, pointArray[5].x-dif, pointArray[5].y+ext, pointArray[1].x, pointArray[1].y);
bezierVertex(pointArray[6].x-ext, pointArray[6].y+dif, pointArray[6].x-ext, pointArray[6].y-dif, pointArray[3].x-xoffset, pointArray[3].y+yoffset);
bezierVertex(pointArray[3].x, pointArray[3].y, pointArray[3].x, pointArray[3].y, pointArray[3].x+xoffset, pointArray[3].y-yoffset);
bezierVertex(pointArray[7].x-dif, pointArray[7].y-ext, pointArray[7].x+dif, pointArray[7].y-ext, pointArray[0].x, pointArray[0].y);
endShape();
//draw outer colour bleed of squash-ball
strokeWeight(m+(size/16));
stroke(fillCol - 10);
noFill();
beginShape();
vertex(pointArray[0].x, pointArray[0].y);
bezierVertex(pointArray[4].x+ext, pointArray[4].y-dif, pointArray[4].x+ext, pointArray[4].y+dif, pointArray[2].x+xoffset, pointArray[2].y-yoffset);
bezierVertex(pointArray[2].x, pointArray[2].y, pointArray[2].x, pointArray[2].y, pointArray[2].x-xoffset, pointArray[2].y+yoffset);
bezierVertex(pointArray[5].x+dif, pointArray[5].y+ext, pointArray[5].x-dif, pointArray[5].y+ext, pointArray[1].x, pointArray[1].y);
bezierVertex(pointArray[6].x-ext, pointArray[6].y+dif, pointArray[6].x-ext, pointArray[6].y-dif, pointArray[3].x-xoffset, pointArray[3].y+yoffset);
bezierVertex(pointArray[3].x, pointArray[3].y, pointArray[3].x, pointArray[3].y, pointArray[3].x+xoffset, pointArray[3].y-yoffset);
bezierVertex(pointArray[7].x-dif, pointArray[7].y-ext, pointArray[7].x+dif, pointArray[7].y-ext, pointArray[0].x, pointArray[0].y);
endShape();
//draw outline of squash-ball
strokeWeight(m);
stroke(fillCol - 40);
noFill();
beginShape();
vertex(pointArray[0].x, pointArray[0].y);
bezierVertex(pointArray[4].x+ext, pointArray[4].y-dif, pointArray[4].x+ext, pointArray[4].y+dif, pointArray[2].x+xoffset, pointArray[2].y-yoffset);
bezierVertex(pointArray[2].x, pointArray[2].y, pointArray[2].x, pointArray[2].y, pointArray[2].x-xoffset, pointArray[2].y+yoffset);
bezierVertex(pointArray[5].x+dif, pointArray[5].y+ext, pointArray[5].x-dif, pointArray[5].y+ext, pointArray[1].x, pointArray[1].y);
bezierVertex(pointArray[6].x-ext, pointArray[6].y+dif, pointArray[6].x-ext, pointArray[6].y-dif, pointArray[3].x-xoffset, pointArray[3].y+yoffset);
bezierVertex(pointArray[3].x, pointArray[3].y, pointArray[3].x, pointArray[3].y, pointArray[3].x+xoffset, pointArray[3].y-yoffset);
bezierVertex(pointArray[7].x-dif, pointArray[7].y-ext, pointArray[7].x+dif, pointArray[7].y-ext, pointArray[0].x, pointArray[0].y);
endShape();
//draw ellipses
var wid = map (values[3], 0, 100, 3, size/3.2);
var dotDist = size/6.4;
fill(fillCol+20);
ellipse(pointArray[0].x-(dotDist*cos(PI/4.0)), pointArray[0].y+(dotDist*sin(PI/4.0)), wid, wid);
ellipse(pointArray[1].x+(dotDist*cos(PI/4.0)), pointArray[1].y-(dotDist*sin(PI/4.0)), wid, wid);
fill(fillCol + 60);
noStroke();
ellipse(pointArray[0].x-(dotDist*cos(PI/4.0)), pointArray[0].y+(dotDist*sin(PI/4.0)), 2*wid/3.0, 2*wid/3.0);
ellipse(pointArray[1].x+(dotDist*cos(PI/4.0)), pointArray[1].y-(dotDist*sin(PI/4.0)), 2*wid/3.0, 2*wid/3.0);
//draw decorative lines
stroke(fillCol - 40);
line(pointArray[0].x, pointArray[0].y, pointArray[1].x, pointArray[1].y);
line(pointArray[2].x, pointArray[2].y, pointArray[3].x, pointArray[3].y);
//draw strap
newSize = map(values[2], 0, 100, 5, size);
var strapWidth = map(values[1], 0, 100, 2, size/2.56);
var dist = strapWidth/2.0;
strokeWeight(m);
fill(fillCol+60);
stroke(fillCol-20);
push();
rectMode(CENTER);
translate(midx, midy);
rotate(PI/4.0);
rect(0, 0, newSize+(size/16), strapWidth);
fill(fillCol + 35);
noStroke();
rect(0, 0, newSize+(size/16)-2, strapWidth/2.0)
pop();
//draw decorative points
stroke(fillCol - 60);
strokeWeight((size/32)+2);
for (i = 0; i < 2; i++) {
point(pointArray[i].x, pointArray[i].y);
}
}
function generatePoint(midx, midy, radius, angle) {
var returnPoint = createVector(midx + radius*cos(angle), midy + radius*sin(angle));
return returnPoint;
}
/*
* 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) {
//set styling
noStroke();
//map width of top left square from values
var wid = map(values[0], 0, 100, 2, size/2.0);
//draw top left square with fill taken from values - dark blue
fill(map(values[4], 0, 100, 0, 255),map(values[4], 0, 100, 50, 255), 255);
rect(size/2.0 - wid, 0, wid, size/2.0);
fill(map(values[4], 0, 100, 0, 255)-55,map(values[4], 0, 100, 50, 255)-55, 200);
rect(size/2.0 - wid, (size/2.0)-(size/20.0), wid, size/20.0);
//map width of top right square from values
wid = map(values[1], 0, 100, 2, size/2.0);
//draw top right square with fill taken from values - pink
fill(255,map(values[5], 0, 100, 0, 255), 255);
rect(size/2.0, size/2.0-wid, size/2.0, wid);
fill(200,map(values[5], 0, 100, 0, 255)-55, 200);
rect(size/2.0, size/2.0-wid, size/20.0, wid);
//map width of bottom right square from values
wid = map(values[2], 0, 100, 2, size/2.0);
//draw bottom right square with fill taken from values - cyan
fill(map(values[6], 0, 100, 0, 255),255, 255);
rect(size/2.0, size/2.0, wid, size/2.0);
fill(map(values[6], 0, 100, 0, 255)-55,200, 200);
rect(size/2.0, size/2.0, wid, size/20.0);
//map width of bottom left square from values
wid = map(values[3], 0, 100, 2, size/2.0);
//draw bottom left square with fill taken from values - yellow
fill(255,255, map(values[7], 0, 100, 0, 255));
rect(0, size/2.0, size/2.0, wid);
fill(200,200, map(values[7], 0, 100, 0, 255)-55);
rect((size/2.0)-(size/20.0), size/2.0, size/20.0, wid);
}
<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.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