Skip to content

Instantly share code, notes, and snippets.

@Michael-Kelly-Digital-Design
Forked from dribnet/.block
Created July 17, 2017 01:07
Show Gist options
  • Select an option

  • Save Michael-Kelly-Digital-Design/986477a7db0bca7cd8690e1f85c9582e to your computer and use it in GitHub Desktop.

Select an option

Save Michael-Kelly-Digital-Design/986477a7db0bca7cd8690e1f85c9582e to your computer and use it in GitHub Desktop.
17.2.MDDN342 PS1
license: mit
function resetFocusedRandom() {
return Math.seedrandom(arguments);
}
function focusedRandom(min, max, focus, mean) {
// console.log("hello")
if(max === undefined) {
max = min;
min = 0;
}
if(focus === undefined) {
focus = 1.0;
}
if(mean === undefined) {
mean = (min + max) / 2.0;
}
if(focus == 0) {
return d3.randomUniform(min, max)();
}
else if(focus < 0) {
focus = -1 / focus;
}
sigma = (max - mean) / focus;
val = d3.randomNormal(mean, sigma)();
if (val > min && val < max) {
return val;
}
return d3.randomUniform(min, max)();
}
// 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');
}

PS1 MDDN 342 2017

This README is a summation of the 5 parts in problem set 1 for MDDN342

Part 1 | First Faces

The first faces I drew for this project were those of Mario and Luigi of the Nintendo universe. We were told to draw 'Two recognisable faces' and I wanted to make mine two separate but similar faces that were individually recognisable. With a simple color change in the hat, I acheived this differentiation.

Part 2 | Drawing Styles

I thought my chubby-cheeked Mario looked ver bayish, and I the cutesy style that I had found with my first face. My second drawing became a drooling baby. My baby sparked in me a fascination with age extremes, so I flipped the coin and drew a geriatric man for my final face. I spent a long time tweaking the ranges of the parameters for these faces to make sure the interpolation between extremes was not jarring; this made part 4 (distribution) a lot easier.

Part 3 & 4 | Randomisation + Distribution

Moving from sliders to generated faces was a simple transition. I had already spent time curating a parameter range in part 2, and implementing Tom's code was fairly straight forward. Since I got to eliminate two drawing styles with these stages, there was a good deal of releif in paring the sketch file down by about 40%

Part 5 | Final

Having creative freedom with the layout of the final face population was a lot of fun. I opted for a radial design, 14 disembodied heads floating around an almighty aged leader. I imagined a cult of old heads the whole time I was coding this. Laughs were had.

<head>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/p5.js"></script>
<script src="http://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.11/addons/p5.dom.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.0/seedrandom.min.js"></script>
<script src="https://d3js.org/d3-random.v1.min.js"></script>
<script language="javascript" type="text/javascript" src=".purview_helper.js"></script>
<script language="javascript" type="text/javascript" src=".focused_random.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">
</div>
</div>
</table>
</body>
{
"commits": [
{
"sha": "65cc0d3a68bc8db94d0076bc61c77b2d56df010e",
"name": "final"
},
{
"sha": "bd71e918950c0dfc282fa0d4cc1dca3770554469",
"name": "distribution"
},
{
"sha": "3e8e5688564f9eec1227df4cee0c43e4c8f2b54f",
"name": "portraits"
},
{
"sha": "970c627ab3efdcb7ba2e0637af59f0392af7736f",
"name": "randomize"
},
{
"sha": "23077ba1ba4f4e4aa51b59409d844363b3e0427f",
"name": "drawing_styles"
}
]
}
var canvasWidth = 960;
var canvasHeight = 500;
var slider1, slider2, slider3, slider4, slider5;
var faceSelector;
var lastSwapTime = 0;
var millisPerSwap = 5000;
//color store
var skin_tone = "#ffe3d8";
var nose_tone = "#ffc8bf";
var blush_color = "#f9ab90";
var hat_color_green = "#7bbc60";
var hat_stroke_red = "#a32525"
var hat_color_red = "#ce4a4a";
var eye_color = "#83cbff";
var stache_color = "#593510";
var drool_color = "#99c0ff";
var spot_color = "#c18672";
// global variables for colors
var bg_color1 = [183, 214, 182];
var bg_color2 = [47, 59, 64];
var bg_color3 = [70, 70, 120];
function changeRandomSeed() { //focusedRandom now draws new random values
curRandomSeed = curRandomSeed + 1;
lastSwapTime = millis();
}
function mouseClicked() {
changeRandomSeed();
}
function setup() {
// create the drawing canvas, save the canvas element
var main_canvas = createCanvas(canvasWidth, canvasHeight);
main_canvas.parent('canvasContainer');
curRandomSeed = int(focusedRandom(0, 100)); //set new random seed
angleMode(DEGREES);
}
function faceGen(x, y, w, h) { //determine face parameters, draw face
var tilt_value = focusedRandom(-30, 30, 3, 1);
var ear_value = focusedRandom(0.6, 1.4, 2, 0.95);
var smile_value = focusedRandom(-0.1, 2.1);
if(smile_value<1){
var eye_value = focusedRandom(0.7, 1.3, 3, 1.1);
}
else{
var eye_value = focusedRandom(0.7, 1.3, 3, 0.9);
}
var wrinkle_value = focusedRandom(-0.2, 1, 2, 0.8);
var spots_value = focusedRandom(0, 4, 4, 2);
drawFace1(x, y, w, h, tilt_value, ear_value, eye_value, smile_value, wrinkle_value, spots_value);
}
function draw() {
if (millis() > lastSwapTime + millisPerSwap) {
changeRandomSeed();
}
background(255);
resetFocusedRandom(curRandomSeed);
noStroke();
push();
translate(width / 2, height / 2);
fill(bg_color1);
ellipse(0,0,height/1.01,height/1.01)
fill(255,12);
ellipse(0,0,height/1.2,height/1.2);
ellipse(0,0,height/1.4,height/1.4);
ellipse(0,0,height/1.6,height/1.6);
ellipse(0,0,height/1.8,height/1.8);
ellipse(0,0,height/2,height/2);
rotate(180);
faceGen(0,0, height / 2, height / 2);
rotate(-180);
for (var i = 0; i < 14; i++) {
rotate(360/14);
faceGen(0,height/2.5,height/6,height/6);
}
pop();
}
//_______________DRAW FUNCTIONS______________//
function drawFace1(x, y, w, h, tilt, ears, eyes, smile, frown, spots) {
//OLDMAN
push();
translate(x, y);
rotate(tilt+180);
scale(w/200,h/200);
var shadow_color = editAlpha(blush_color, 0.65);
fill(skin_tone);
ellipse(0, 0, 165, 185); // face
fill(shadow_color);
ellipse(0, 77, 30, 20); // lower frown line (upper shin shadow)
fill(skin_tone);
ellipse(0, 77, 32, 18); // mask for lower frown line
ellipse(-10, 84, 25, 25); // butt chin left
ellipse(10, 84, 25, 25); //butt chin right
//hair
fill(215 + 10 * spots);
push();
translate(-63, -40);
rotate(23);
ellipse(0, 0, 35, 60); //hair left
pop();
push();
translate(63, -40);
rotate(-23);
ellipse(0, 0, 35, 60); // hair right
pop();
//mouth
noFill();
stroke(blush_color);
strokeWeight(2 + 2 * Math.abs(smile - 1)); //scale stroke to smile amount, between 2pt and 4pt
curve(-40, 50 * smile, -20, 50, 20, 50, 40, 50 * smile); //curve(cpx1, cpy1, x1, y1, x2, y2, cpx2, cpy2);
strokeWeight(3);
//eyes (glasses)
noStroke();
fill(255, 140);
ellipse(-23, 8, 30 * eyes, 25 * eyes); //lens L Highlight
ellipse(23, 8, 30 * eyes, 25 * eyes); //lens R Highlight
stroke(180);
fill(255, 60);
ellipse(-25, 5, 35 * eyes, 35 * eyes); //lens L
ellipse(25, 5, 35 * eyes, 35 * eyes); //lens R
curve(-15, 20, -7.5 * ampLify(eyes, -2), 2, 7.5 * ampLify(eyes, -2), 2, 15, 20); //bridge
line(42 * ampLify(eyes, 0.35), -2 * ampLify(eyes, 0.35), 70, -12); //glasses leg R
line(-42 * ampLify(eyes, 0.35), -2 * ampLify(eyes, 0.35), -70, -12); //glasses leg L
noStroke();
//ears
push()
translate(-65 - ears * 20, 0);
scale(ears, ears);
fill(shadow_color);
ellipse(1, 2, 26, 49); //ear shadow left
fill(skin_tone);
ellipse(-0, 0, 30, 50); //ear left
fill(shadow_color);
ellipse(-2, 0, 12, 18); //inner ear shadow left
fill(skin_tone);
noStroke();
ellipse(4, 2, 10, 10); //inner shadow mask left
pop();
push();
translate(65 + ears * 20, 0)
scale(ears, ears);
fill(shadow_color);
ellipse(-1, 2, 26, 49); //ear shadow right
fill(skin_tone);
ellipse(0, 0, 30, 50); //ear right
fill(shadow_color);
ellipse(2, 0, 12, 18); // inner ear shadow right
fill(skin_tone);
noStroke();
ellipse(-4, 2, 10, 10); // inner shadow mask right
pop();
//frown lines
var frown_color_value = editAlpha(blush_color, frown);
stroke(frown_color_value);
strokeWeight(2);
curve(45, -70, 25, -50, -25, -50, -45, -70);
curve(45, -50, 15, -43, -15, -43, -45, -50);
curve(45, -25, 25, -35, -25, -35, -45, -25);
//liver spots
var spot_color_value;
spot_color_value = editAlpha(spot_color, spots / 5 + 0.25);
if (Math.floor(spots > 1)) {
push();
fill(spot_color_value);
translate(23, -63);
ellipse(0, 0, 4, 4);
pop();
}
if (Math.floor(spots > 2)) {
push();
fill(spot_color_value);
translate(20, -71);
rotate(-45);
ellipse(0, 0, 8, 6);
pop();
}
if (Math.floor(spots > 3)) {
push();
fill(spot_color_value);
translate(32, -68);
rotate(52);
ellipse(0, 0, 10, 7);
pop();
}
pop();
}
//___________LEVEL 2 FUNCTIONS__________\\
//used by ren
function ampLify(inp, ampChange) {// used to change parameter values relative to their deviation from 1 (amplitude)
var v = (inp - 1) * ampChange;
v += 1;
return v;
}
function editAlpha(col, val) {
//input color stored as hex code String
//return p5 color object feat. updated alpha
var v = color(col);
v._array[3] = val;
return v;
}
function keyTyped() {
if (key == '!') {
saveBlocksImages();
} else if (key == '@') {
saveBlocksImages(true);
console.log("printing")
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment