Skip to content

Instantly share code, notes, and snippets.

@Jcimat13
Forked from dribnet/.block
Last active April 11, 2017 11:36
Show Gist options
  • Save Jcimat13/3dbd9c4620d8c532ec9467be412c3f1d to your computer and use it in GitHub Desktop.
Save Jcimat13/3dbd9c4620d8c532ec9467be412c3f1d 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

Rauru

I used quads in my very first sketch in this project, I decided to continue to use them because they created interesting and sharp forms. So for the rest of this project, I have been experimenting with the placement and shape of quads until I reached my final glyph. This experimentation mostly included rotation, as I felt that my original idea of rows wouldn't work well with the rest of the project.

My final glyph is a ring of diamond-shaped quads. For the glyph_object, they spread out or shrink when the hue is changed, the colour of the quad and stroke changes in contrast when the saturation is changed, and, when the brightness is changed, the background ellipse lightens or darkens to match. This is very similar to the glyph_system that I had coded previously. However, I had to make adjustments on the size and placement so that my glyph would fit the new parameters and images.

As I was progressing through the different parts of the project, I attempted to stray away from rings of quads. However, I kept running into coding problems and could not figure out how to fix them on my own so I resorted back to my best glyph shape from the interpolation section.

At this point, I had to move onto the spot_color. At the start of the project, I chose the colour of purple and then switched it to red, to further explore the pattern I had made. For this part of the project, however, I decided to go with yellow. I did this because, as I progresses, my patterns started to look like various sunflowers, especially in my glyph_system, and when they were all together in image mode, they started to look like mandalas. In my head, I associated this with tattoos which helped me to choose a bright colour, such as yellow, and have the skull emoji as my starting point.

At first, I put the colour change under saturation, as my saturation from my glyph_object was not translating well. However, I noticed that because of this, too many emojis didn't have colour in them at all. This prompted the colour change to brightness. My saturation still wasn't working, so I added in a line of rotation code, which worked well. Although, because of the symmetry in my glyph, it was hard to tell when the glyph had been rotated. This led to me changing my glyph slightly by adjusting the i variable and the rotation of my quads.

I was left with a glyph that I feel works well with the various images and that the changes are appropriate for what I have made.

/*
* val4 is an array of 3 numbers that range from [0,1000]
* 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, 0, 200);
var rect_color = map(values[2], 0, 100, 200, 100);
//var ellipse_size = map(brightness, 0, 90, 10, 40);
stroke(rect_color);
fill(color1);
var s2 = size/2;
ellipse(s2, s2, s2, s2);
// 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, 20, 200);
var color3 = map(values[1], 0, 100, 200, 20);
fill(color2);
stroke(color3);
//noStroke();
// 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;
var quad_width = map(x_shift, 0, 100, 10, 90);
//ellipse(s2 + x_shift, s2, s3);
//quad(quad_width/2, 5, quad_width/2+10, 10, quad_width/2+20, 5, quad_width/2+10, 0);
for(var i = 0; i < 17; i++){ //changed from 20 so there's no overlapping of quads
push();
translate(s2, s2);
rotate(360 * i/2);
scale(0.7); //still within original ellipse but not too small
quad(quad_width, s2/20, quad_width+10, s2/20+5, quad_width+20, s2/20, quad_width+10, s2/20-5);
pop();
}
}
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, 0, 60);
var ellipse_colour = map(values[2], 0, 100, 200, 100);
stroke(ellipse_colour);
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, 20, 200);
var color3 = map(values[1], 0, 100, 200, 20); //opposite of color2
fill(color2);
stroke(color3);
// 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;
var quad_width = map(x_shift, 0, 100, 10, 39);
//changing stop 1 and stop2 so pattern doesn't pass the guide
//and isn't too small in comparison to background ellipse
for(var i = 0; i < 17; i++){
push();
translate(s2, s2);
rotate(360 * i/2);
scale(0.4 * size/50); //to adjust the pattern with the size
//quad(quad_width, s2/20, quad_width+10, s2/20+5, quad_width+20, s2/20, quad_width+10, s2/20-5);
//above = working quad from glyph.js
//the settings below work better as the pattern is bigger within the background ellipse, not too much empty space.
quad(quad_width, s2/20, quad_width+17, s2/20+5, quad_width+26, s2/20, quad_width+17, s2/20-5);
pop();
}
}
}
<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": "9dcc5b671c6baf818e94aa8bfcf98d559e1e59c8",
"name": "final"
},
{
"sha": "96a499d6d7aeeff6e8983caa5d1dc5d83e488476",
"name": "spot_color"
},
{
"sha": "ffb5536730d453ed59a762a857eb4cf38ccd87d8",
"name": "glyph_object"
},
{
"sha": "eff9be1f350f5ed6021b43cb918a1cecec800101",
"name": "glyph_system"
},
{
"sha": "584972ff1e7b653e303755ed16464cd059c322aa",
"name": "interpolate"
},
{
"sha": "2b6785e94c3e7be527c84faceebe0fb357af61fa",
"name": "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 = 382;
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(232, 232, 232)"
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;
}
colorMode(RGB);
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();
}
colorMode(HSB);
}
}
}
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;
// 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);
rect(half_size-rect_width/2, half_size-20, rect_width, 40, 20);
}
else if (row === 1) {
// saturation
var rect_width = map(column, 0, 4, 10, 80);
rect(half_size-rect_width/2, half_size-20, rect_width, 40, 20);
}
else {
// lightness
var fill_col = map(column, 0, 4, 30, 90);
fill(fill_col);
rect(half_size-rect_width/2, half_size-20, rect_width, 40, 20);
}
}
// some examples of how to specify a base color
// var my_color = "#d24632"
// var my_color = "rgb(245, 225, 50)"
var my_color = "rgb(51, 11, 112)" //dark purple
// 4, 13, 140 dark blue
var shapes_should_draw = false;
// 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);
pop();
}
}
}
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
}
else if (key == '@') {
saveBlocksImages(true);
}
}
function SpotGlyph() {
this.spot_hue = 50;
/*
* 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) {
var hue = values[0];
var sat = values[1];
var brt = values[2];
//brt
var color1 = map(values[2], 0, 100, 0, 80);
noStroke();
fill(color1)
var halfSize = size/2;
ellipse(halfSize, halfSize, size);
var inner_size = 0.2 + 0.4 * 0.3;
var s3 = size * inner_size;
//sat
var color2 = map(values[1], 0, 100, 10, 80);
fill(color2);
stroke(100);
translate(halfSize, halfSize);
rotate(color2);
translate(-halfSize, -halfSize);
//need something to show rotation better
// hue
var shift_frac = (values[0] - 180.0) / 180.0;
var max_shift = 0.5 * (size - s3);
var x_shift = shift_frac * max_shift;
var quad_width = map(x_shift, 0, 100, 10, 39);
if(brt > 50){
fill(this.spot_hue, 80, 100);
stroke(color1+20);
}
else {
fill(0);
}
for(var i = 0; i < 18; i++){
push();
translate(halfSize, halfSize);
rotate(180 * i/3); //changed to 180 degrees - makes a break in the glyph
//easier to tell that the gylph rotates when the saturation changes
scale(0.4 * size/50);
quad(quad_width, halfSize/20, quad_width+17, halfSize/20+5, quad_width+26, halfSize/20, quad_width+17, halfSize/20-5);
pop();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment