REPLACE ALL TEXT IN THIS FILE
This README should eventually explain the different paramaterised faces.
| . |
| /* | |
| * This program draws your arrangement of faces on the canvas. | |
| */ | |
| const canvasWidth = 960; | |
| const canvasHeight = 500; | |
| let curRandomSeed = 0; | |
| let lastSwapTime = 0; | |
| const millisPerSwap = 3000; | |
| function setup () { | |
| // create the drawing canvas, save the canvas element | |
| let main_canvas = createCanvas(canvasWidth, canvasHeight); | |
| main_canvas.parent('canvasContainer'); | |
| curRandomSeed = int(random(0, 1000)); | |
| // rotation in degrees | |
| angleMode(DEGREES); | |
| } | |
| function changeRandomSeed() { | |
| curRandomSeed = curRandomSeed + 1; | |
| lastSwapTime = millis(); | |
| } | |
| // global variables for colors | |
| const bg_color1 = [225, 206, 187]; | |
| function mouseClicked() { | |
| changeRandomSeed(); | |
| } | |
| function draw () { | |
| if(millis() > lastSwapTime + millisPerSwap) { | |
| changeRandomSeed(); | |
| } | |
| // reset the random number generator each time draw is called | |
| randomSeed(curRandomSeed); | |
| // clear screen | |
| background(bg_color1); | |
| noStroke(); | |
| // draw a 7x4 grid of faces | |
| let w = canvasWidth / 7; | |
| let h = canvasHeight / 4; | |
| for(let i=0; i<4; i++) { | |
| for(let j=0; j<7; j++) { | |
| let y = h/2 + h*i; | |
| let x = w/2 + w*j; | |
| if (i == 0) { | |
| // center face | |
| let eye_value = 2; | |
| let tilt_value = random(-15, 45); | |
| let mouth_value = random(1, 3); | |
| let is_cyclops = random(0, 100); | |
| if(is_cyclops < 10) { | |
| eye_value = 1; | |
| tilt_value = random(-5, 5); | |
| mouth_value = random(5, 10); | |
| } | |
| push(); | |
| translate(x, y); | |
| scale(w/25, h/25); | |
| drawFace3(tilt_value, eye_value, mouth_value); | |
| pop(); | |
| } | |
| else if (i > 0) { | |
| // all other faces | |
| push(); | |
| translate(x, y); | |
| scale(w/25, h/25); | |
| if((i+j)%2 == 0) { | |
| drawFace1(); | |
| } | |
| else { | |
| thinness_value = random(0, 100); | |
| drawFace2(thinness_value); | |
| } | |
| pop(); | |
| } | |
| } | |
| } | |
| } | |
| function keyTyped() { | |
| if (key == '!') { | |
| saveBlocksImages(); | |
| } | |
| else if (key == '@') { | |
| saveBlocksImages(true); | |
| } | |
| } |
| <head> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script> | |
| <script language="javascript" type="text/javascript" src="z_purview_helper.js"></script> | |
| <script language="javascript" type="text/javascript" src="face_code.js"></script> | |
| <script language="javascript" type="text/javascript" src="editor.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="index.html">arrangement</a> | |
| (<a href="arrangement.js">arrangement code</a>, | |
| <a href="face_code.js">face code</a>)<br> | |
| <a href="editor.html">editor</a> | |
| (<a href="editor.js">editor code</a>, | |
| <a href="face_code.js">face code</a>)<br> | |
| <a href="sketch.html">sketch</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>Setting 6</td> | |
| <td id="slider6Container"></td> | |
| </tr> | |
| <tr> | |
| <td>Setting 7</td> | |
| <td id="slider7Container"></td> | |
| </tr> | |
| <tr> | |
| <td>Setting 8</td> | |
| <td id="slider8Container"></td> | |
| </tr> | |
| <tr> | |
| <td>Setting 9</td> | |
| <td id="slider9Container"></td> | |
| </tr> | |
| <tr> | |
| <td>Setting 10</td> | |
| <td id="slider10Container"></td> | |
| </tr> | |
| <tr> | |
| <td>Show Target</td> | |
| <td id="checkbox1Container"></td> | |
| </tr> | |
| <tr> | |
| <td>Face</td> | |
| <td id="selector1Container"></td> | |
| </tr> | |
| </table> | |
| </div> | |
| </div> | |
| </table> | |
| </body> |
| /* | |
| * This editor shows the possible faces that can be created | |
| */ | |
| const canvasWidth = 960; | |
| const canvasHeight = 500; | |
| let slider1, slider2, slider3, slider4, slider5; | |
| let slider6, slider7, slider8, slider9, slider10; | |
| let faceSelector; | |
| let faceGuideCheckbox; | |
| function setup () { | |
| // create the drawing canvas, save the canvas element | |
| let 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); | |
| slider6 = createSlider(0, 100, 50); | |
| slider7 = createSlider(0, 100, 50); | |
| slider8 = createSlider(0, 100, 50); | |
| slider9 = createSlider(0, 100, 50); | |
| slider10 = createSlider(0, 100, 50); | |
| slider1.parent('slider1Container'); | |
| slider2.parent('slider2Container'); | |
| slider3.parent('slider3Container'); | |
| slider4.parent('slider4Container'); | |
| slider5.parent('slider5Container'); | |
| slider6.parent('slider6Container'); | |
| slider7.parent('slider7Container'); | |
| slider8.parent('slider8Container'); | |
| slider9.parent('slider9Container'); | |
| slider10.parent('slider10Container'); | |
| faceGuideCheckbox = createCheckbox('', false); | |
| faceGuideCheckbox.parent('checkbox1Container'); | |
| faceSelector = createSelect(); | |
| faceSelector.option('1'); | |
| faceSelector.option('2'); | |
| faceSelector.option('3'); | |
| faceSelector.value('1'); | |
| faceSelector.parent('selector1Container'); | |
| } | |
| const bg_color = [225, 206, 187]; | |
| function draw () { | |
| strokeWeight(0.2); | |
| let mode = faceSelector.value(); | |
| background(bg_color); | |
| let s1 = slider1.value(); | |
| let s2 = slider2.value(); | |
| let s3 = slider3.value(); | |
| let s4 = slider4.value(); | |
| let s5 = slider5.value(); | |
| let s6 = slider6.value(); | |
| let s7 = slider7.value(); | |
| let s8 = slider8.value(); | |
| let s9 = slider9.value(); | |
| let s10 = slider10.value(); | |
| let show_face_guide = faceGuideCheckbox.checked(); | |
| // use same size / y_pos for all faces | |
| let face_size = canvasWidth / 5; | |
| let face_scale = face_size / 10; | |
| let face_y = height / 2; | |
| let face_x = width / 2; | |
| push(); | |
| translate(face_x, face_y); | |
| scale(face_scale); | |
| push(); | |
| if (mode == '1') { | |
| // draw 1st face | |
| drawFace1(); | |
| } | |
| if (mode == '2') { | |
| // draw 2nd face - let slider value 1 indicate thinness | |
| drawFace2(s1); | |
| } | |
| if (mode == '3') { | |
| // draw 3rd face using values mapped from 3 sliders | |
| let tilt_value = map(s1, 0, 100, -90, 90); | |
| let mouth_value = map(s2, 0, 100, 0.5, 10); | |
| let eye_value = int(map(s3, 0, 100, 1, 3)); | |
| drawFace3(tilt_value, eye_value, mouth_value); | |
| } | |
| pop(); | |
| if(show_face_guide) { | |
| strokeWeight(0.1); | |
| rectMode(CORNER); | |
| noFill() | |
| stroke(0, 0, 255); | |
| // ellipse(0, 0, 20, 20); | |
| rect(-10, -10, 20, 20); | |
| line( 0, -11, 0, -10); | |
| line( 0, 10, 0, 11); | |
| line(-11, 0,-10, 0); | |
| line( 11, 0, 10, 0); | |
| } | |
| pop(); | |
| } | |
| function keyTyped() { | |
| if (key == '!') { | |
| saveBlocksImages(); | |
| } | |
| else if (key == '@') { | |
| saveBlocksImages(true); | |
| } | |
| } |
| /* | |
| * This file should contain code that draws your faces. | |
| * | |
| * Each function takes parameters and draws a face that is within | |
| * the bounding box (-10, -10) to (10, 10). | |
| * | |
| * These functions are used by your final arrangement of faces as well as the face editor. | |
| */ | |
| function drawFace1() { | |
| fill(60); | |
| noStroke(); | |
| // head | |
| ellipse(0, 0, 20); | |
| // eyes | |
| fill(200); | |
| ellipse(-3, -3, 3); | |
| ellipse( 3, -3, 3); | |
| } | |
| /* | |
| * thinness_value ranges from 0-100 and indicates how thin the face is | |
| */ | |
| function drawFace2(thinness_value) { | |
| // head | |
| noStroke(); | |
| fill(200, 150, 150); | |
| let head_width = map(thinness_value, 0, 100, 8, 20); | |
| rect(-head_width/2, -9, head_width, 18); | |
| // rect(-5, -10, 10, 20); | |
| // eyes | |
| fill(240); | |
| ellipse(-2, -4, 1); | |
| ellipse( 2, -4, 1); | |
| } | |
| /* | |
| * tilt_value is in degrees | |
| * eye_value is an integer number of eyes: either 0, 1, 2, or 3 | |
| * mouth_value is how open the mouth is and should generally range from 0.5 to 10 | |
| */ | |
| function drawFace3(tilt_value, eye_value, mouth_value) { | |
| const bg_color3 = [225, 206, 187]; | |
| const fg_color3 = [151, 102, 52]; | |
| // rotation in degrees | |
| angleMode(DEGREES); | |
| rotate(tilt_value); | |
| noStroke(); | |
| fill(fg_color3); | |
| ellipse(0, 0, 30/2, 40/2); | |
| // eyes | |
| if (eye_value === 1 || eye_value == 3) { | |
| fill(bg_color3); | |
| ellipse( 0, -8/2, 5/2, 3/2); | |
| fill(fg_color3); | |
| ellipse(-1/2, -8/2, 2/2, 2/2); | |
| } | |
| if (eye_value >= 2) { | |
| fill(bg_color3); | |
| ellipse(-5/2, -8/2, 5/2, 3/2); | |
| ellipse( 5/2, -8/2, 5/2, 3/2); | |
| fill(fg_color3); | |
| ellipse(-6/2, -8/2, 2/2, 2/2); | |
| ellipse( 4/2, -8/2, 2/2, 2/2); | |
| } | |
| // mouth | |
| fill(bg_color3); | |
| ellipse(0/2, 7/2, 15/2, mouth_value); | |
| } |
| <head> | |
| <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script> | |
| <script language="javascript" type="text/javascript" src="z_purview_helper.js"></script> | |
| <script language="javascript" type="text/javascript" src="face_code.js"></script> | |
| <script language="javascript" type="text/javascript" src="arrangement.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="index.html">arrangement</a> | |
| (<a href="arrangement.js">arrangement code</a>, | |
| <a href="face_code.js">face code</a>)<br> | |
| <a href="editor.html">editor</a> | |
| (<a href="editor.js">editor code</a>, | |
| <a href="face_code.js">face code</a>)<br> | |
| <a href="sketch.html">sketch</a> | |
| </div> | |
| <div class="inner" id="controls" height="500px"> | |
| <table> | |
| <tr> | |
| <td></td> | |
| <td id="slider1Container"></td> | |
| </tr> | |
| <tr> | |
| <td></td> | |
| <td id="slider2Container"></td> | |
| </tr> | |
| <tr> | |
| <td></td> | |
| <td id="slider3Container"></td> | |
| </tr> | |
| <tr> | |
| <td></td> | |
| <td id="slider4Container"></td> | |
| </tr> | |
| <tr> | |
| <td></td> | |
| <td id="slider5Container"></td> | |
| </tr> | |
| <tr> | |
| <td></td> | |
| <td id="selector1Container"></td> | |
| </tr> | |
| </table> | |
| </div> | |
| </div> | |
| </table> | |
| </body> |
| <head> | |
| <style> body {padding: 0; margin: 0;} </style> | |
| </head> | |
| <body style="background-color:white"> | |
| <img src="sketch.jpg" width="960" height="480"/> | |
| <p> | |
| <a href="index.html">arrangement</a> | |
| (<a href="arrangement.js">arrangement code</a>, | |
| <a href="face_code.js">face code</a>)<br> | |
| <a href="editor.html">editor</a> | |
| (<a href="editor.js">editor code</a>, | |
| <a href="face_code.js">face code</a>)<br> | |
| <a href="sketch.html">sketch</a> | |
| </body> |
| // 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); | |
| } |