This README explains the three different paramaterized faces for part2.
I still wanted to keep my abstract faces, and used if statements to change certain things about the eyes in my first face.
license: mit |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.3/seedrandom.min.js"></script> | |
<script src="https://d3js.org/d3-random.v1.min.js"></script> | |
<script language="javascript" type="text/javascript" src="z_purview_helper.js"></script> | |
<script language="javascript" type="text/javascript" src="sketch2.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> | |
<a href="index1.html">part1</a> | |
</div> | |
<div class="inner" id="controls" height="500px"> | |
<table> | |
<tr> | |
<td>Setting 1</td> | |
<td id="slider1Container"></td> | |
</tr> | |
<tr> | |
<td>Setting 2</td> | |
<td id="slider2Container"></td> | |
</tr> | |
<tr> | |
<td>Setting 3</td> | |
<td id="slider3Container"></td> | |
</tr> | |
<tr> | |
<td>Setting 4</td> | |
<td id="slider4Container"></td> | |
</tr> | |
<tr> | |
<td>Setting 5</td> | |
<td id="slider5Container"></td> | |
</tr> | |
<tr> | |
<td>Face</td> | |
<td id="selector1Container"></td> | |
</tr> | |
</table> | |
</div> | |
</div> | |
</table> | |
</body> |
<head> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/p5.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.6.1/addons/p5.dom.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/2.4.3/seedrandom.min.js"></script> | |
<script src="https://d3js.org/d3-random.v1.min.js"></script> | |
<script language="javascript" type="text/javascript" src="z_purview_helper.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>(future interface here)</td> | |
<td id="selector1Container"></td> | |
</tr> | |
</table> | |
</div> | |
</div> | |
</table> | |
</body> |
const canvasWidth = 960; | |
const canvasHeight = 500; | |
function setup () { | |
// create the drawing canvas, save the canvas element | |
main_canvas = createCanvas(canvasWidth, canvasHeight); | |
// position each element on the page | |
main_canvas.parent('canvasContainer'); | |
// rotation in degrees | |
angleMode(DEGREES); | |
} | |
// global variables for colors | |
const bg_color = "#1e0028"; | |
const fg_color1 = "#eaadff"; | |
const fg_color2 = "#8ce8ff"; | |
const stroke_color = "#ffffff"; | |
function draw () { | |
// background color | |
background(bg_color); | |
// stroke color | |
stroke(stroke_color) | |
// move to position1 | |
push(); | |
translate(1000/4, 300/2); | |
noFill(); | |
stroke(stroke_color); | |
strokeWeight(4); | |
ellipse(0, -6, 20, 20); //left eye | |
ellipse(80, -7, 20, 20); //right eye | |
bezier(95, 5, 10, 5, 90, 90, 15, 120); //nose | |
bezier(-30, 120, 30, 140, 60, 170, 100, 140); //mouth | |
bezier(-5, 180, 10, 200, 30, 200, 45, 190); | |
bezier(-40, -25, -30, 7, 0, 3, 20, 15); //eye underline | |
pop(); | |
// move to position2, rotate, draw "head" ellipse | |
push(); | |
translate(3*900/4, 300/2); | |
noFill(); | |
stroke(fg_color1); | |
strokeWeight(2); | |
bezier(-80, -25, -30, 10, 60, 10, 70, 160); //main line | |
//"sketch" lines | |
bezier(-80, -35, -30, 20, 50, 0, 70, 160); | |
bezier(-80, -25, -30, 15, 70, 20, 65, 160); | |
//left eye | |
bezier(-110, 50, -90, 70, -70, 60, -50, 50); //main line | |
//"sketch" lines | |
bezier(-110, 50, -90, 70, -70, 65, -50, 55); | |
bezier(-110, 55, -90, 70, -70, 60, -50, 50); | |
//nose | |
bezier(-50, 110, -10, 110, -20, 170, 30, 160); //main line | |
//"sketch" lines | |
bezier(-50, 115, -10, 110, -20, 170, 30, 155); | |
//mouth | |
bezier(20, 230, 50, 210, 60, 200, 120, 190); //main line | |
//"sketch" lines | |
bezier(20, 225, 50, 210, 60, 200, 120, 195); | |
pop(); | |
} | |
function keyTyped() { | |
if (key == '!') { | |
saveBlocksImages(); | |
} | |
else if (key == '@') { | |
saveBlocksImages(true); | |
} | |
} |
var canvasWidth = 960; | |
var canvasHeight = 500; | |
var slider1, slider2, slider3, slider4, slider5; | |
var faceSelector; | |
function setup () { | |
// create the drawing canvas, save the canvas element | |
var main_canvas = createCanvas(canvasWidth, canvasHeight); | |
main_canvas.parent('canvasContainer'); | |
// create sliders | |
slider1 = createSlider(0, 100, 50); | |
slider2 = createSlider(0, 100, 50); | |
slider3 = createSlider(0, 100, 50); | |
slider4 = createSlider(0, 100, 50); | |
slider5 = createSlider(0, 100, 50); | |
slider1.parent('slider1Container'); | |
slider2.parent('slider2Container'); | |
slider3.parent('slider3Container'); | |
slider4.parent('slider4Container'); | |
slider5.parent('slider5Container'); | |
faceSelector = createSelect(); | |
faceSelector.option('1'); | |
faceSelector.option('2'); | |
faceSelector.option('3'); | |
faceSelector.option('all') | |
faceSelector.value('all'); | |
faceSelector.parent('selector1Container'); | |
// rotation in degrees | |
angleMode(DEGREES); | |
} | |
// global variables for colors | |
var bg_color1 = [50, 0, 81]; | |
var bg_color2 = [0, 28, 81]; | |
var bg_color3 = [81, 0, 46]; | |
var fg_color1 = [239, 204, 255]; | |
var fg_color2 = [255, 204, 242]; | |
var fg_color3 = [204, 232, 255]; | |
var stroke_color1 = [95, 52, 8]; | |
var stroke_color2 = [210, 219, 189]; | |
var stroke_color3 = [50, 50, 50]; | |
var colorHair = [20, 20, 0]; | |
function drawFace1(x, y, w, h, tilt_value, eye_value, mouth_value) { | |
push(); | |
translate(x, y); | |
rotate(tilt_value); | |
var extent = 0; | |
if(h < w) { | |
extent = h / 2; | |
} | |
else { | |
extent = w / 2; | |
} | |
var scale = extent / 220.0; | |
stroke(fg_color1); | |
noFill(); | |
strokeWeight(2); | |
quad(-75, -100, 25, -50, 0, 63, -50, 5); //face | |
// eyes | |
if (eye_value === 1) { | |
quad( 0, -80, 20, -90, 40, -80, 20, -70); | |
quad( -60, -50, -40, -60, -20, -50, -40, -40); //left | |
} | |
if (eye_value == 2) { | |
quad( -60, -50, -40, -60, -20, -50, -40, -40); //left | |
quad( 0, -50, 20, -40, 40, -50, 20, -40); | |
} | |
if (eye_value == 3){ | |
quad( 0, -50, 20, -40, 40, -50, 20, -40); | |
quad( -60, -50, -40, -60, -20, -50, -40, -60); //left | |
} | |
// mouth | |
fill(bg_color1); | |
triangle(-30, 15, -20, 5, 0, 15); //top lip | |
triangle(-15, 20, 15, 20, 5, 30); | |
pop(); | |
} | |
function drawFace2(x, y, w, h, hair_value, eye_value, blink_value) { | |
rectMode(CENTER); | |
push(); | |
translate(x, y); | |
var extent = 0; | |
if(h < w) { | |
extent = h / 2; | |
} | |
else { | |
extent = w / 2; | |
} | |
var scale = extent / 220.0; | |
stroke(stroke_color3); | |
fill(fg_color3); | |
ellipse(0, 0, 300 * scale, 400 * scale); | |
// eyes. first check for blinking | |
if(blink_value > 0) { | |
fill(bg_color3); | |
ellipse(-50 * scale, -80 * scale, 50 * scale, 2 * scale); | |
ellipse( 50 * scale, -80 * scale, 50 * scale, 2 * scale); | |
} | |
else { | |
fill(bg_color3); | |
ellipse(-50 * scale, -80 * scale, 50 * scale, 18 * scale); | |
ellipse( 50 * scale, -80 * scale, 50 * scale, 18 * scale); | |
fill(fg_color3); | |
ellipse((-50 + eye_value) * scale, -80 * scale, 20 * scale, 20 * scale); | |
ellipse(( 50 + eye_value) * scale, -80 * scale, 20 * scale, 20 * scale); | |
} | |
// mouth | |
fill(bg_color3); | |
ellipse(0 * scale, 70 * scale, 150 * scale, 20 * scale); | |
// TODO: paramaterize hair | |
var follicles = [ | |
[346,138], | |
[391,120], | |
[391,67], | |
[439,76], | |
[463,42], | |
[487,18], | |
[481,101], | |
[520,102], | |
[520,78], | |
[533,54], | |
[560,108], | |
[580,76], | |
[596,124], | |
[618,124] | |
]; | |
resetMatrix(); | |
fill(colorHair); | |
var radius = hair_value * scale; | |
for(var i=0; i<follicles.length; i++) { | |
ellipse(240+follicles[i][0]/2, 120 + (follicles[i][1]/2), radius, radius); | |
} | |
rectMode(CORNER); | |
resetMatrix(); | |
} | |
function drawFace3(x, y, w, h, width_value, eye_value, mouth_value) { | |
push(); | |
rectMode(CENTER); | |
translate(x, y); | |
// rotate(width_value); | |
var extent = 0; | |
if(h < w) { | |
extent = h / 2; | |
} | |
else { | |
extent = w / 2; | |
} | |
var scale = extent / 220.0; | |
stroke(stroke_color2) | |
fill(fg_color2); | |
rect(0, 0, (300 + width_value) * scale, 400 * scale); | |
// eyes | |
if (eye_value === 1 || eye_value == 3) { | |
fill(bg_color2); | |
rect( 0, -80 * scale, 50 * scale, 30 * scale); | |
fill(fg_color2); | |
ellipse(-10 * scale, -80 * scale, 20 * scale, 20 * scale); | |
} | |
if (eye_value >= 2) { | |
fill(bg_color2); | |
rect(-60 * scale, -80 * scale, 50 * scale, 30 * scale); | |
rect( 60 * scale, -80 * scale, 50 * scale, 30 * scale); | |
fill(fg_color2); | |
ellipse(-60 * scale, -80 * scale, 20 * scale, 20 * scale); | |
ellipse( 60 * scale, -80 * scale, 20 * scale, 20 * scale); | |
} | |
// mouth | |
fill(bg_color2); | |
rect(0 * scale, 70 * scale, 150 * scale, mouth_value * scale); | |
rectMode(CORNER); | |
pop(); | |
} | |
function draw () { | |
noStroke(); | |
var mode = faceSelector.value(); | |
if (mode != 'all') { | |
if (mode == '1') { | |
background(bg_color1); | |
} | |
else if (mode == '2') { | |
background(bg_color2); | |
} | |
else if (mode == '3') { | |
background(bg_color3); | |
} | |
} | |
var s1 = slider1.value(); | |
var s2 = slider2.value(); | |
var s3 = slider3.value(); | |
var s4 = slider4.value(); | |
var s5 = slider5.value(); | |
// use same size / y_pos for all faces | |
var face_w = canvasWidth / 4; | |
var face_h = face_w; | |
var face_y = height / 2; | |
var face_x = width / 2; | |
if (mode == '1' || mode == 'all') { | |
// draw 1st face | |
fill(bg_color1); | |
rect(0, 0, width/3, height); | |
var tilt_value = map(s1, 0, 100, -90, 90); | |
var mouth_value = map(s3, 0, 100, 0, 200); | |
var eye_value = Math.floor(map(s2, 0, 100, 1, 3)); | |
if (mode == 'all') { | |
face_x = width / 6; | |
} | |
drawFace1(face_x, face_y, face_w, face_h, tilt_value, eye_value, mouth_value); | |
} | |
if (mode == '2' || mode == 'all') { | |
// draw 2nd face | |
fill(bg_color2); | |
rect(width/3, 0, 2*width/3, height); | |
var hair_value = map(s1, 0, 100, 2, 90); | |
var blink_value = Math.floor(map(s3, 0, 100, 0, 1)); | |
var eye_value = map(s2, 0, 100, -15, 15); | |
if (mode == 'all') { | |
face_x = 3 * width / 6; | |
} | |
drawFace2(face_x, face_y, face_w, face_h, hair_value, eye_value, blink_value); | |
} | |
if (mode == '3' || mode == 'all') { | |
// draw 3nd face | |
fill(bg_color3); | |
rect(2*width/3, 0, width, height); | |
var width_value = map(s1, 0, 100, 0, 100); | |
var mouth_value = map(s3, 0, 100, 0, 200); | |
var eye_value = Math.floor(map(s2, 0, 100, 0, 3)); | |
if (mode == 'all') { | |
face_x = 5 * width / 6; | |
} | |
drawFace3(face_x, face_y, face_w, face_h, width_value, eye_value, mouth_value); | |
} | |
} | |
function keyTyped() { | |
if (key == '!') { | |
saveBlocksImages(); | |
} | |
else if (key == '@') { | |
saveBlocksImages(true); | |
} | |
} |
// 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); | |
// call this function after 1 second | |
setTimeout(function(){ | |
p5.prototype.downloadFile(imageData, 'thumbnail.png', 'png'); | |
}, 1000); | |
} |