Skip to content

Instantly share code, notes, and snippets.

@oxbowmantella
Forked from dribnet/.block
Last active April 11, 2017 03:11
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 oxbowmantella/c6fd9519beb954695d0cd1c115fb188e to your computer and use it in GitHub Desktop.
Save oxbowmantella/c6fd9519beb954695d0cd1c115fb188e to your computer and use it in GitHub Desktop.
17.1.MDDN242 PS2
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');
}

PS2 MDDN 242 2017

##final### in this project we looked at making a system that took input from colors and gave a representation of what the color is in a grey space.

my thinking for this project was to make something that has function over form, rather than having states that a unqiue to each color sample, so i decided to go with something that i found would work in a grid layout and or as a stand alone.

the idea behind using ocotogons is that they arragne well and that i can have a duplicate of the shape within the shape so that it can be representative of other attribute of the glyph data

i went with a multi-layer design so that i can have objects effect each other as the values get changed, so i can have for example the attributes for saturations effect hue in some ways to show new information.

(refer to previous post in order to see how each attribute is represented)

/*
* val4 is an array of 3 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 gray_glyph(values, size) {
// replace this with your own version
// map brightness to large circle shade
var color1 = map(values[2], 0, 100, 10, 70) //brightness
stroke(color1);
fill(color1)
var s2 = size/2;
polygon(s2, s2, s2,8); //gives indicator for brightness
// inner size is set to 30%
var inner_size = 0.2 + 0.4 * 0.3;
var s3 = size * inner_size;
// inner color based on saturation
var color2 = map(values[1], 0, 100, color1+20, 240) //saturation
fill(color2);
stroke(color2);
// hue controls left/right shift
var shift_frac = (values[0] - 180.0) / 180.0;
var s4 = map(size, 0,100,10,60);
var max_shift = 0.5 * (size - s4);
var x_shift = shift_frac * max_shift;
polygon(s2 + x_shift, s2, s2/2, 8); //inner indicators for hue and saturation,
polygon(s2 - x_shift, s2, s2/2, 8); //futher aparts means dark hue, dark to light means saturation
var color3 = map(values[2], 0, 100, 0,300); //remap of colour for brightness
fill(color3); //new colour fill
polygon(s2, s2, s2/2, 8); //hue display on top of the brightness polygon
}
function polygon(x, y, radius, npoints) {
var angle = TWO_PI / npoints;
beginShape();
for (var a = 0; a < TWO_PI; a += angle) {
var sx = x + cos(a) * radius;
var sy = y + sin(a) * radius;
vertex(sx, sy);
}
endShape(CLOSE);
}
//backup
// function gray_glyph(values, size) {
// // replace this with your own version
// // map brightness to large circle shade
// var color1 = map(values[2], 0, 100, 10, 70)
// stroke(color1);
// fill(color1)
// var s2 = size/2;
// ellipse(s2, s2, size);
// // inner size is set to 30%
// var inner_size = 0.2 + 0.4 * 0.3;
// var s3 = size * inner_size;
// // inner color based on saturation
// var color2 = map(values[1], 0, 100, color1+20, 240)
// fill(color2);
// stroke(color2);
// // hue controls left/right shift
// var shift_frac = (values[0] - 180.0) / 180.0;
// var max_shift = 0.5 * (size - s3);
// var x_shift = shift_frac * max_shift;
// ellipse(s2 + x_shift, s2, s3);
// }
function GrayGlyph() {
/*
* values is an array of 3 numbers: [hue, saturation, brightness]
* + hue ranges from 0..360
* + saturation ranges from 0..100
* + brightness ranges from 0..100
* this matches the default range for p5.js colorMode(HSB) as describe at:
* https://p5js.org/reference/#/p5/colorMode
*
* size is the number of pixels for width and height
*
* use p5.js to draw a round grayscale glpyh
* the glyph should stay within the bounding box [0, 0, width, height]
* this is a grayscale glyph, so only brighness can be adjusted.
* the range for brighness is 0..100
*
* the color mode will be HSB, so you can either:
* + use a one argument grayscale call; this is easiest. examples:
* - fill(50); // ranges from 0-100
* - stroke(100); // white
* + use a three arguement HSB call with values but set both H and S to 0. examples:
* - fill(0, 0, 51); // equivalent to above
* - stroke(0, 0, 100); //
*/
this.draw = function(values, size) {
// map brightness to large circle shade
var color1 = map(values[2], 0, 100, 10, 70) //brightness
stroke(color1);
fill(color1)
var s2 = size/2;
polygon(s2, s2, s2,8); //gives indicator for brightness
// inner size is set to 30%
var inner_size = 0.2 + 0.4 * 0.3;
var s3 = size * inner_size;
// inner color based on saturation
var color2 = map(values[1], 0, 100, color1/2, 100) //saturation
fill(color2); //saturation
stroke(color2);
// hue controls left/right shift
var shift_frac = (values[0] - 180.0) / 180.0;
var s4 = map(size, 0,100,10,60);
var max_shift = 0.5 * (size - s4);
var x_shift = shift_frac * max_shift;
polygon(s2 + x_shift, s2, s2/2, 8); //inner indicators for hue and saturation,
polygon(s2 - x_shift, s2, s2/2, 8); //futher aparts means dark hue, dark to light means saturation
var color3 = map(values[2], 0, 100, 0,300); //remap of colour for brightness
fill(color3); //new colour fill
polygon(s2, s2, s2/2, 8); //hue display on top of the brightness polygon
}
function polygon(x, y, radius, npoints) {
var angle = TWO_PI / npoints;
beginShape();
for (var a = 0; a < TWO_PI; a += angle) {
var sx = x + cos(a) * radius;
var sy = y + sin(a) * radius;
vertex(sx, sy);
}
endShape(CLOSE);
}
// // replace this with your own version
// // map brightness to large circle shade
// var color1 = map(values[2], 0, 100, 10, 70)
// stroke(color1);
// fill(color1)
// var s2 = size/2;
// ellipse(s2, s2, size);
// // inner size is set to 30%
// var inner_size = 0.2 + 0.4 * 0.3;
// var s3 = size * inner_size;
// // inner color based on saturation
// var color2 = map(values[1], 0, 100, color1+20, 240)
// fill(color2);
// stroke(color2);
// // hue controls left/right shift
// var shift_frac = (values[0] - 180.0) / 180.0;
// var max_shift = 0.5 * (size - s3);
// var x_shift = shift_frac * max_shift;
// ellipse(s2 + x_shift, s2, s3);
//}
}
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.dom.js"></script>
<script language="javascript" type="text/javascript" src=".purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="grayglyph.js"></script>
<script language="javascript" type="text/javascript" src="spotglyph.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.0;
-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>hue</td>
<td id="slider1Container"></td>
</tr>
<tr>
<td>saturation</td>
<td id="slider2Container"></td>
</tr>
<tr>
<td>brightness</td>
<td id="slider3Container"></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>Show Guide</td>
<td id="checkContainer"></td>
</tr>
<tr>
<td></td>
<td id="buttonContainer"></td>
</tr>
</div>
</div>
</table>
</body>
{
"commits": [
{
"sha": "cf452505d35312e5f9ddfe8fbad8287a316fb99c",
"name": "Glyph final"
},
{
"sha": "61964ddde7b687fe51a5a986a70f62132f16a674",
"name": "Color Glyph - SPOT_COLOR"
},
{
"sha": "614f76e12e79e6812920c07e9076164f29af5b95",
"name": "Gif_Glyphs - OBJECTS"
},
{
"sha": "884d5fa6058b11a37186c9d74cf46faf733746e0",
"name": "Glyph_System"
},
{
"sha": "f5d83a75fc96ac9198c6cf588efe22b51258dd5a",
"name": "Interpolation"
},
{
"sha": "aeedcc49ed754daeb69b7855aa03ca08397a6ca5",
"name": "Colors_and_Glyphs - SKETCH"
}
]
}
<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/p5.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.7/addons/p5.dom.js"></script>
<script language="javascript" type="text/javascript" src=".purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="sketch2.js"></script>
</head>
<body style="background-color:white">
<div class="outer">
<div class="inner">
<div id="canvasContainer"></div>
</div>
</div>
</table>
</body>
var canvasWidth = 960;
var canvasHeight = 500;
var glyphSelector;
var modeSelector;
var sizeSelector;
var show_oddball = false;
var oddball_row = 0;
var oddball_col = 0;
var val_sliders = [];
var max_vals = [360, 100, 100];
var curEmoji = 76;
var NUM_EMOJI = 872;
var EMOJI_WIDTH = 38;
var lastKeyPressedTime;
var secondsUntilSwapMode = 10;
var secondsPerEmoji = 5;
var isSwappingEmoji = false;
var emojiSwapLerp = 0;
var prevEmoji = 0;
var lastEmojiSwappedTime;
var emojiImg;
var curEmojiImg;
var curEmojiPixels;
var curEmojiColors, nextEmojiColors, prevEmojiColors;
function preload() {
emojiImg = loadImage("twemoji36b_montage.png");
}
function setup() {
// create the drawing canvas, save the canvas element
var main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
var now = millis();
lastKeyPressedTime = now;
lastEmojiSwappedTime = now;
// create two sliders
for (i=0; i<3; i++) {
var slider = createSlider(0, 10*max_vals[i], 10*max_vals[i]/2);
slider.parent("slider" + (i+1) + "Container")
slider.changed(sliderUpdated);
slider.mouseMoved(sliderUpdated);
slider.touchMoved(sliderUpdated);
val_sliders.push(slider);
}
modeSelector = createSelect();
modeSelector.option('drive');
modeSelector.option('gradient');
modeSelector.option('random_grid');
modeSelector.option('oddball');
modeSelector.option('image');
modeSelector.changed(modeChangedEvent);
modeSelector.value('image');
modeSelector.parent('selector1Container');
glyphSelector = createSelect();
glyphSelector.option('show_color');
glyphSelector.option('gray');
glyphSelector.option('spot');
glyphSelector.changed(modeChangedEvent);
glyphSelector.value('spot');
glyphSelector.parent('selector2Container');
sizeSelector = createSelect();
sizeSelector.option('32');
sizeSelector.option('64');
sizeSelector.option('128');
sizeSelector.option('256');
sizeSelector.parent('selector3Container');
sizeSelector.value('32');
sizeSelector.changed(sizeChangedEvent);
guideCheckbox = createCheckbox('', false);
guideCheckbox.parent('checkContainer');
guideCheckbox.changed(guideChangedEvent);
button = createButton('redo');
button.mousePressed(buttonPressedEvent);
button.parent('buttonContainer');
curEmojiImg = createImage(36, 36);
// create an array for HSB values: [18][18][3]
curEmojiPixels = Array(18);
curEmojiColors = Array(18);
for(var i=0; i<18; i++) {
curEmojiPixels[i] = Array(18);
curEmojiColors[i] = Array(18);
for(var j=0; j<18; j++) {
curEmojiPixels[i][j] = Array(3);
}
}
gray_glyph = new GrayGlyph();
spot_glyph = new SpotGlyph();
colorMode(HSB);
refreshGridData();
modeChangedEvent();
}
function sliderUpdated() {
redraw();
}
function mouseClicked() {
if (mouseX > width/4) {
refreshGridData();
}
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
function clamp(num, min, max) {
return Math.min(Math.max(num, min), max);
}
function refreshGridData() {
var mode = modeSelector.value();
var glyphSize = parseInt(sizeSelector.value(), 10);
if (mode == "image") {
if(glyphSize == 32) {
numGridCols = 18;
numGridRows = 17;
gridOffsetX = 320;
gridSpacingX = 31;
gridOffsetY = 2;
gridSpacingY = 29;
}
else if(glyphSize == 64) {
numGridCols = 10;
numGridRows = 9;
gridOffsetX = 280;
gridSpacingX = 66;
gridOffsetY = -18;
gridSpacingY = 59;
}
else if(glyphSize == 128) {
numGridCols = 6;
numGridRows = 5;
gridOffsetX = 164;
gridSpacingX = 132;
gridOffsetY = -50;
gridSpacingY = 118;
}
else if(glyphSize == 256) {
numGridCols = 3;
numGridRows = 3;
gridOffsetX = 172;
gridSpacingX = 262;
gridOffsetY = -100;
gridSpacingY = 234;
}
}
else 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;
}
else if(glyphSize == 32) {
numGridCols = 24;
numGridRows = 13;
gridOffsetX = 4;
gridSpacingX = 40;
gridOffsetY = 4;
gridSpacingY = 38;
}
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);
}
}
if (mode == "gradient" || mode == 'oddball') {
var top_left = Array(3);
var top_right = Array(3);
var bottom_left = Array(3);
var bottom_right = Array(3);
for (var k=0; k<3; k++) {
top_left[k] = random(max_vals[k]);
top_right[k] = random(max_vals[k]);
bottom_left[k] = random(max_vals[k]);
bottom_right[k] = random(max_vals[k]);
}
for (var i=0; i<numGridRows; i++) {
if(numGridRows == 1) {
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);
}
}
if (mode == 'oddball') {
// replace an entry at random
oddball_row = Math.floor(random(numGridRows))
oddball_col = Math.floor(random(numGridCols))
for (var k=0; k<3; k++) {
gridValues[oddball_row][oddball_col][k] = random(max_vals[k]);
}
}
}
else if(mode == "image") {
for (var i=0; i<numGridRows; i++) {
for (var j=0; j<numGridCols; j++) {
for (var k=0; k<3; k++) {
gridValues[i][j][k] = curEmojiPixels[i][j][k];
}
}
}
}
else {
for (var i=0; i<numGridRows; i++) {
for (var j=0; j<numGridCols; j++) {
for (var k=0; k<3; k++) {
gridValues[i][j][k] = random(max_vals[k]);
}
}
}
}
}
function sizeChangedEvent() {
var mode = modeSelector.value();
if (mode != "drive") {
refreshGridData();
}
redraw();
}
function guideChangedEvent() {
show_oddball = guideCheckbox.checked();
redraw();
}
function modeChangedEvent() {
var mode = modeSelector.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(var i=0; i<3; i++) {
val_sliders[i].removeAttribute('disabled');
}
}
else {
// enable the button
// button.removeAttribute('disabled');
// disable the sliders
for(var i=0; i<3; i++) {
val_sliders[i].attribute('disabled','');
}
// enable the size selector
// sizeSelector.removeAttribute('disabled');
// refresh data
refreshGridData();
}
if (mode === "image") {
// get current emoji image
var offsetX = 36 * (curEmoji % 38);
var offsetY = 36 * Math.floor(curEmoji / 38);
var squareOffsets = [ [0,0], [0,1], [1,1], [1, 0] ];
curEmojiImg.copy(emojiImg, offsetX, offsetY, 36, 36, 0, 0, 36, 36);
curEmojiImg.loadPixels();
colorMode(RGB);
for(var i=0; i<17; i++) {
// i is y
var maxX = 18;
var offsetX = 0;
if (i%2 == 1) {
maxX = 17;
offsetX = 1;
}
for(var j=0; j<maxX; j++) {
// j is x
var sumColor = [0, 0, 0];
for(var k=0; k<4; k++) {
// k is summing over 4 adacent pixels
var curColor = curEmojiImg.get(j*2 + squareOffsets[k][0] + offsetX, 1 + i*2 + squareOffsets[k][1]);
for(var l=0; l<3; l++) {
sumColor[l] += curColor[l] / 4.0;
}
}
var curColor = color(sumColor);
curEmojiColors[i][j] = curColor;
curEmojiPixels[i][j][0] = curColor._getHue();
curEmojiPixels[i][j][1] = curColor._getSaturation();
curEmojiPixels[i][j][2] = curColor._getBrightness();
}
}
colorMode(HSB);
// refresh data
refreshGridData();
}
redraw();
}
function buttonPressedEvent() {
refreshGridData();
redraw();
}
var colorBack = "rgb(50, 50, 50)"
var colorFront = "rgb(192, 192, 255)"
function ColorGlyph() {
this.draw = function(values, size) {
fill(values[0], values[1], values[2]);
stroke(0);
var s2 = size/2;
ellipse(s2, s2, size);
}
}
var color_glyph = new ColorGlyph();
function highlightGlyph(glyphSize) {
halfSize = glyphSize / 2.0;
stroke(0, 0, 255, 128);
noFill();
strokeWeight(4);
ellipse(halfSize, halfSize, glyphSize+4);
fill(0);
strokeWeight(1);
}
function getGyphObject() {
var glyphMode = glyphSelector.value();
var glyph_obj = color_glyph;
if(glyphMode == "gray")
glyph_obj = gray_glyph;
else if(glyphMode == "spot")
glyph_obj = spot_glyph;
return(glyph_obj);
}
function drawDriveMode() {
var glyph_obj = getGyphObject();
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;
var val = [0,0,0];
for(i=0; i<3; i++) {
val[i] = val_sliders[i].value() / 10.0;
}
resetMatrix();
translate(middle_x - halfSize, middle_y - halfSize);
glyph_obj.draw(val, glyphSize);
if (show_oddball) {
resetMatrix();
translate(middle_x - halfSize, middle_y - halfSize);
highlightGlyph(glyphSize)
}
resetMatrix();
translate(middle_x + halfSize + 32, middle_y - halfSize);
color_glyph.draw(val, glyphSize);
}
function drawGridMode() {
var mode = modeSelector.value();
var glyph_obj = getGyphObject();
var glyphSize = parseInt(sizeSelector.value(), 10);
background(colorBack);
if (show_oddball && mode == 'oddball') {
resetMatrix();
translate(gridOffsetX + oddball_col * gridSpacingX, gridOffsetY + oddball_row * gridSpacingY);
highlightGlyph(glyphSize)
}
var hexOffset = (mode == "image");
for (var i=0; i<numGridRows; i++) {
var tweakedNumGridCols = numGridCols;
var offsetX = 0;
if (hexOffset && i%2 == 1) {
offsetX = gridSpacingX / 2;
tweakedNumGridCols = numGridCols - 1;
}
for (var j=0; j<tweakedNumGridCols; j++) {
resetMatrix();
translate(gridOffsetX + j * gridSpacingX + offsetX, gridOffsetY + i * gridSpacingY);
glyph_obj.draw(gridValues[i][j], glyphSize);
resetMatrix();
}
}
}
function colorCopyArray(c) {
d = Array(18);
for(var i=0; i<18; i++) {
d[i] = Array(18);
for(var j=0; j<18; j++) {
d[i][j] = c[i][j];
}
}
return d;
}
function checkImageUpdate() {
var mode = modeSelector.value();
isSwappingEmoji = false;
if (mode == "image") {
now = millis();
if(lastKeyPressedTime + 1000 * secondsUntilSwapMode < now) {
// key not pressed recently
if(lastEmojiSwappedTime + 1000 * secondsPerEmoji < now) {
prevEmoji = curEmoji;
prevEmojiColors = colorCopyArray(curEmojiColors);
// no swaps recently
updateEmoji(1);
nextEmojiColors = colorCopyArray(curEmojiColors);
lastEmojiSwappedTime = now;
}
if(now - lastEmojiSwappedTime < 1000) {
isSwappingEmoji = true;
emojiSwapLerp = (now - lastEmojiSwappedTime) / 1000.0;
// print("LERP: " + emojiSwapLerp);
for (var i=0; i<numGridRows; i++) {
for (var j=0; j<numGridCols; j++) {
// var curColor = lerpColor(prevEmojiColors[i][j], nextEmojiColors[i][j], emojiSwapLerp);
var curColor = prevEmojiColors[i][j];
if (curColor) {
curColor = lerpColor(prevEmojiColors[i][j], nextEmojiColors[i][j], emojiSwapLerp);
curEmojiPixels[i][j][0] = curColor._getHue();
curEmojiPixels[i][j][1] = curColor._getSaturation();
curEmojiPixels[i][j][2] = curColor._getBrightness();
}
}
}
refreshGridData();
}
else {
for (var i=0; i<numGridRows; i++) {
for (var j=0; j<numGridCols; j++) {
var curColor = nextEmojiColors[i][j];
if (curColor) {
curEmojiPixels[i][j][0] = curColor._getHue();
curEmojiPixels[i][j][1] = curColor._getSaturation();
curEmojiPixels[i][j][2] = curColor._getBrightness();
}
}
}
refreshGridData();
}
}
}
}
var is_drawing = false;
function draw () {
if (is_drawing) {
return;
}
is_drawing = true;
colorMode(HSB);
var mode = modeSelector.value();
checkImageUpdate();
if (mode == "drive") {
drawDriveMode();
}
else {
drawGridMode();
}
resetMatrix();
if (mode == "image") {
image(curEmojiImg, 32, height-32-36);
}
is_drawing = false;
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
else if (key == ' ') {
refreshGridData();
redraw();
}
else if (key == 'f') {
var curGlyph = glyphSelector.value()
if(curGlyph == "show_color") {
glyphSelector.value('gray');
}
else if(curGlyph == "gray") {
glyphSelector.value('spot');
}
else if(curGlyph == "spot") {
glyphSelector.value('show_color');
}
redraw();
}
else if (key == 's') {
var old_value = guideCheckbox.checked();
guideCheckbox.checked(!old_value);
guideChangedEvent();
}
else if (key == '1') {
sizeSelector.value('32');
sizeChangedEvent()
}
else if (key == '2') {
sizeSelector.value('64');
sizeChangedEvent()
}
else if (key == '3') {
sizeSelector.value('128');
sizeChangedEvent()
}
else if (key == '4') {
sizeSelector.value('256');
sizeChangedEvent()
}
else if (key == 'd') {
modeSelector.value('drive');
modeChangedEvent()
}
else if (key == 'g') {
modeSelector.value('gradient');
modeChangedEvent()
}
else if (key == 'r') {
modeSelector.value('random');
modeChangedEvent()
}
else if (key == 'o') {
modeSelector.value('oddball');
modeChangedEvent()
}
else if (key == 'i') {
modeSelector.value('image');
modeChangedEvent()
}
}
function updateEmoji(offset) {
curEmoji = (curEmoji + NUM_EMOJI + offset) % NUM_EMOJI;
modeChangedEvent()
}
function keyPressed() {
lastKeyPressedTime = millis();
if (keyCode == LEFT_ARROW) {
updateEmoji(-1);
}
else if (keyCode == RIGHT_ARROW) {
updateEmoji(1);
}
else if (keyCode == UP_ARROW) {
updateEmoji(-38);
}
else if (keyCode == DOWN_ARROW) {
updateEmoji(38);
}
}
function mouseMoved() {
lastKeyPressedTime = millis();
}
function mouseDragged() {
lastKeyPressedTime = millis();
}
var canvasWidth = 960;
var canvasHeight = 500;
function setup () {
// create the drawing canvas, save the canvas element
var main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
colorMode(HSL, 100); // Use HSB with scale of 0-100
// this means draw will only be called once
noLoop();
}
function draw_shape(column, row, size, cur_color) {
// replace this with your own logic
var half_size = size/2;
var spacer = 15;
// defaults
fill(60);
strokeWeight(2);
var rect_width = 60;
if (row === 0) {
// hue
var stroke_w = map(column, 0, 4, 1, 3);
strokeWeight(stroke_w);
triangle(90 , 75, 58, 20, 86, 75);
strokeWeight(0.5)
triangle(35 , 75, 58, 20, 30, 75);
strokeWeight(0.5);
rect((rect_width/2), 75, half_size+2,half_size/3);
}
else if (row === 1) {
// saturation
var rect_width = map(column, 0, 4, 10, 80);
strokeWeight(0.5);
triangle(90 , 75, 58, 20, 86, 75);
strokeWeight(stroke_w);
triangle(35 , 75, 58, 20, 30, 75);
strokeWeight(0.5);
rect((rect_width/2), 75, half_size+2,half_size/3);
}
else {
// lightness
var fill_col = map(column, 0, 4, 30, 90);
fill(fill_col);
strokeWeight(0.5);
triangle(90 , 75, 58, 20, 86, 75);
strokeWeight(0.5);
triangle(35 , 75, 58, 20, 30, 75);
strokeWeight(stroke_w);
rect((rect_width/2), 75, half_size+2,half_size/3);
}
}
// some examples of how to specify a base color
// var my_color = "#d24632"
var my_color = "rgb(164, 13, 255)"
// var my_color = "rgb(20%, 47%, 67%)"
var shapes_should_draw = true;
// draw five colors and then five glyphs
function draw () {
var size=120;
var xsteps = 5;
var xdiff = (width - xsteps * size) / xsteps;
var xstep = size + xdiff;
var ysteps = 3;
var ydiff = (height - ysteps * size) / ysteps;
var ystep = size + ydiff;
var bg_color = color("#ffffdc");
var base_color = color(my_color);
var base_hue = hue(base_color);
var base_sat = saturation(base_color);
var base_lgt = lightness(base_color);
background(bg_color);
noStroke();
for (var x=0; x<xsteps; x++) {
for (var y=0; y<ysteps; y++) {
var cur_color = base_color;
if (y == 0) {
// hue
var cur_hue = (85 + base_hue + 100 * 0.3 * x / xsteps) % 100;
cur_color = color(cur_hue, base_sat, base_lgt);
}
else if (y == 1) {
// saturation
var cur_sat = (5 + 90 * x / xsteps);
cur_color = color(base_hue, cur_sat, base_lgt);
}
else if (y == 2) {
// lightness
var cur_lgt = (5 + 90 * x / xsteps);
cur_color = color(base_hue, base_sat, cur_lgt);
}
fill(cur_color);
noStroke();
rect(xdiff/2 + xstep * x - 10, ydiff/2 + ystep * y - 10, size, size);
strokeWeight(2);
stroke(0);
fill(bg_color);
var curx = xdiff/2 + xstep * x + 10;
var cury = ydiff/2 + ystep * y + 10;
rect(curx, cury, size, size);
if (shapes_should_draw) {
push();
translate(curx, cury);
draw_shape(x, y, size, cur_color);
//rect(x,y,size/4,cur_color);
pop();
}
}
}
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
}
function SpotGlyph() {
this.spot_hue = 281; //pick a hue colour: purple
var SH;
//colorMode(HSB, this.spot_hue);
/*
* values is an array of 3 numbers: [hue, saturation, brightness]
* + hue ranges from 0..360
* + saturation ranges from 0..100
* + brightness ranges from 0..100
* this matches the default range for p5.js colorMode(HSB) as describe at:
* https://p5js.org/reference/#/p5/colorMode
*
* size is the number of pixels for width and height
*
* use p5.js to draw a round grayscale glpyh
* the glyph should stay within the bounding box [0, 0, width, height]
*
* this glyph can utilize changes in brightness and saturation, but only
* using the spot_hue set above. So:
*
* + hue will always be set to spot_hue (a value from 0-360)
* + saturation can vary from 0-100
* + brighness can vary from 0-100
*
* examples:
* - fill(this.spot_hue, 25, 50); // desaturated. middle brightness.
* - stroke(this.spot_hue, 100, 100); // fully saturated and maximum brightness
*/
this.draw = function(values, size) {
// map brightness to large circle shade
var color1 = map(values[2], 0, 100, 0, 100); //brightnes
var stroke1;
//looks at the values of the hue and then sets the stroke color
//if under halfway, stroke is blk, else if its bigger stroke is wht
if(values[0] <= 180){
stroke1 = 0;
}
else if(values[0] >= 180){
stroke1 = 255;
}
//brightness color octogon
stroke(stroke1);
fill(color1);
var s2 = size/2;
polygon(s2, s2, s2,8); //gives indicator for brightness
stroke(color1);
var inner_size = 0.2 + 0.4 * 0.3; // inner size is set to 30%
var s3 = size * inner_size;
//saturation color octogons
var color2 = map(values[1], 0, 100, color1/2, 100) //saturation
fill(color2); //saturation
stroke(color2/2);
var shift_frac = (values[0] - 180.0) / 180.0;
var s4 = map(size, 0,100,10,60);
var max_shift = 0.5 * (size - s4);
var x_shift = shift_frac * max_shift;
polygon(s2 + x_shift, s2, s2/2, 8); //inner indicators for hue and saturation,
polygon(s2 - x_shift, s2, s2/2, 8); //futher aparts means dark hue, dark to light means saturation
//hue color octogons
var color3 = map(values[2], 0, 100, 0,300); //remap of colour for brightness
fill(this.spot_hue, color1/2, color1); //hue
polygon(s2, s2 + x_shift, s2/2, 8); //inner indicators for hue and saturation,
polygon(s2, s2 - x_shift, s2/2, 8); //futher aparts means dark hue, dark to light means saturation
fill(this.spot_hue, color1, color1);
//fill(color3); //hue fill
polygon(s2, s2, s2/3, 8); //hue display on top of the brightness polygon
}
function polygon(x, y, radius, npoints) {
var angle = TWO_PI / npoints;
beginShape();
for (var a = 0; a < TWO_PI; a += angle) {
var sx = x + cos(a) * radius;
var sy = y + sin(a) * radius;
vertex(sx, sy);
}
endShape(CLOSE);
}
}
//backup
// this.draw = function(values, size) {
// var hue = values[0];
// var sat = values[1];
// var brt = values[2];
// var halfSize = size/2;
// var sqSize = size * Math.sqrt(2) / 2;
// noStroke();
// if(hue > this.spot_hue && hue < this.spot_hue + 90) {
// fill(this.spot_hue, sat, brt);
// }
// else {
// fill(this.spot_hue, 0, brt);
// }
// translate(halfSize, halfSize);
// rect(-sqSize/2, -sqSize/2, sqSize, sqSize);
// }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment