Skip to content

Instantly share code, notes, and snippets.

@dribnet
Last active November 4, 2020 02:56
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 dribnet/ca4a114a0c18aa32dd66aad1126a8e1e to your computer and use it in GitHub Desktop.
Save dribnet/ca4a114a0c18aa32dd66aad1126a8e1e to your computer and use it in GitHub Desktop.
Interactive Facemap Prototype
license: mit

2020 MDDN342 Assignment 3: Face Mappings

The idea for my assignment is a stylised face with watercolour-esque shading on one side. The watercolour-esque effect is created through cascading shaded areas to create something similar to a gradient. An outline is added to these to imitate how watercolour can dry and create a fringe effect.

Five of the sliders are in control of: the thickness of the top eyelid the colour of the eyes style of the lip how bright the face is hue of the entire face

In the training, the parameters were picked based on these: The hue of the face is determined by the shade of the hair. Bluer hue - darker hair colour Reder hue - lighter hair colour Masculine faces have thinner eye outlines and feminine faces have filled in lips. The eye lightness corresponded to the lightness of the eyes in the images. The shade depended on the skin tone of the images.

Image links: -https://unsplash.com/photos/6tHTXiSRUi8 -https://unsplash.com/photos/hOF1bWoet_Q -https://unsplash.com/photos/2qvxIr_DXGo -https://unsplash.com/photos/zCG05KP0Jiw -https://unsplash.com/photos/q0Uc8fFdrUo

/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// these control the colors used
ch3_bodyPrimary = [204, 204, 204];
ch3_bodySecondary = [128, 128, 128];
ch3_detailPrimary = [0, 0, 0];
ch3_detailSecondary = [0, 0, 255];
function CampbellFace() {
// draw strokes with rounded joints
// strokeJoin(ROUND);
// set colour mode to HSB
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
colorMode(HSB);
strokeJoin(ROUND);
// variables of facial structure
var nose_pos = average_point(positions.nose_bridge);
var eye1_pos = average_point(positions.left_eye);
var eye2_pos = average_point(positions.right_eye);
var upperLip = average_point(positions.top_lip);
var bottomLip = average_point(positions.bottom_lip);
var face_pos = average_point(positions.chin);
var half_height = positions.chin[7][1] - nose_pos[1];
var face_width = positions.chin[positions.chin.length-1][0] - positions.chin[0][0];
var x = nose_pos[0];
var y = nose_pos[1];
var w = 2 * face_width;
var h = 2.5 * half_height;
// bolleans for whether face is looking left or right
var lookingLeft = false;
var lookingRight = false;
// compare nose landmarks to check if looking left or right
if(Math.abs(positions.nose_bridge[3][0] - positions.nose_bridge[0][0]) > 0.03){
if(positions.nose_bridge[3][0] < positions.nose_bridge[0][0])
lookingLeft = true;
if(positions.nose_bridge[3][0] > positions.nose_bridge[0][0])
lookingRight = true;
}
else {
lookingLeft = true;
}
// adjustable variables of character identity
var gender = map(this.genderValue, 0, 100, 0, 1);
var hair = map(this.hairValue, 0, 100, 80, 200);
var curlookDirection = map(this.lookDirection, 0, 100, -15, 15);
var curEyelidTop_height = map(this.eyelidTop_height, 0, 100, 0, 70);
var curEyelidBottom_height = map(this.eyelidBottom_height, 0, 100, 0, 70);
var curHue = map(this.hue, 0, 100, 0, 360);
var curSaturation = map(this.saturation, 0, 100, 0, 100);
var curBrightnessPrimary = map(this.brightness, 0, 100, 50, 100);
var curBrightnessSecondary = map(this.brightness, 0, 100, 20, 70);
// sets object scale
var extent = 0;
if(h < w) {
extent = h / 2;
}
else {
extent = w / 2;
}
var scale = extent / 220.0;
// draw left ear if male
// draw rectangle from a centre point
rectMode(CENTER)
// if male face and is looking left
if(gender == 1 & lookingLeft == true) {
// draw ear
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0] - (10 * scale), eye2_pos[1] - (100 * scale), 50 * scale, hair * scale, 100 * scale, 100 * scale, 0, 0);
}
// if male and is looking right
if(gender == 1 & lookingRight == true) {
// draw ear
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0] + (10 * scale), eye1_pos[1] - (100 * scale), 50 * scale, hair * scale, 100 * scale, 100 * scale, 0, 0);
}
// head
// draw rectangle from a centre point
rectMode(CENTER);
// draw face
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0], face_pos[1] - (70 * scale), 300 * scale, 320 * scale, 200 * scale, 200 * scale, 0, 0);
// draw dissection
fill(curHue, curSaturation, curBrightnessSecondary);
ellipse(face_pos[0], face_pos[1] + (90 * scale), 300 * scale, 80 * scale);
// draw bone
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(face_pos[0], face_pos[1] + (90 * scale), 150 * scale, 30 * scale);
// draw right ear if male
rectMode(CENTER);
// if male and looking left
if(gender == 1 & lookingLeft == true) {
// draw ear
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0] + (30 * scale), eye2_pos[1] - (100 * scale), 50 * scale, hair * scale, 100 * scale, 100 * scale, 0, 0);
//cover
noStroke();
fill(curHue, curSaturation, curBrightnessPrimary);
rectMode(CENTER);
rect(face_pos[0] + (30 * scale), eye2_pos[1] - (5 * scale), 70 * scale, 150 * scale);
}
// if male and looking right
if(gender == 1 & lookingRight == true) {
// draw ear
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
rect(face_pos[0] - (30 * scale), eye1_pos[1] - (100 * scale), 50 * scale, hair * scale, 100 * scale, 100 * scale, 0, 0);
//cover
noStroke();
fill(curHue, curSaturation, curBrightnessPrimary);
rectMode(CENTER);
rect(face_pos[0] - (30 * scale), eye1_pos[1] - (5 * scale), 70 * scale, 150 * scale);
}
// features for when looking left
if(lookingLeft == true) {
// left eye
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale);
// pupil
noStroke();
fill(ch3_detailPrimary);
arc(eye1_pos[0] + curlookDirection * scale, eye1_pos[1], (30) * scale, (50) * scale, 20, 340, PIE);
// eyelid
strokeWeight(7 * scale);
stroke(ch3_detailPrimary);
fill(curHue, curSaturation, curBrightnessSecondary);
// top eyelid
arc(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale, 265 - curEyelidTop_height, 275 + curEyelidTop_height, CHORD);
// bottom eyelid
arc(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale, 85 - curEyelidBottom_height, 95 + curEyelidBottom_height, CHORD);
// eyebrow
stroke(ch3_detailPrimary)
noFill();
arc(eye1_pos[0], (eye1_pos[1]), 130 * scale, 110 * scale, 240, 300);
// nose
// if female draw bird style
if(gender < 1) {
// translate to an offset of the centre of the face
push();
translate(face_pos[0] - (100 * scale), face_pos[1] - (70 * scale));
// draw beak
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(curHue, curSaturation, curBrightnessSecondary);
arc(0, 0, 250 * scale, 150 * scale, 335, 385, PIE);
// draw mouth
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
line(5 * scale, 0 * scale, 80 * scale, 0 * scale);
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
noFill();
arc(110 * scale, 0 * scale, 50 * scale, 50 * scale, 140, 210);
// teeth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
// check teeth value
if(Math.abs(upperLip[1] - bottomLip[1]) > 0.28) {
arc(40 * scale, 0 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) > 0.2) {
arc(60 * scale, 0 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) < 0.2) {
}
pop();
}
// if male draw dog style
if(gender == 1) {
// translate to an offset of centre of the face
push();
translate(face_pos[0] - (130 * scale), face_pos[1] - (100 * scale));
// draw snout
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
// top snout
rectMode(CORNER);
rect(0, 0, 140 * scale, 45 * scale, 18 * scale, 0, 0, 18 * scale);
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
// bottom snout
rect(30 * scale, 45 * scale, 110 * scale, 35 * scale, 14 * scale, 0, 0, 14 * scale);
noStroke();
fill(curHue, curSaturation, curBrightnessPrimary);
// re-fill / cover
rect(130 * scale, -7 * scale, 60 * scale, 100 * scale);
// draw nose
noStroke();
fill(ch3_detailPrimary);
push();
rotate(10);
ellipse(0 * scale, 0 * scale, 40 * scale, 28 * scale);
pop();
// mouth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
noFill();
arc(155 * scale, 40 * scale, 50 * scale, 50 * scale, 140, 210);
// teeth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
// check teeth value
if(Math.abs(upperLip[1] - bottomLip[1]) > 0.28) {
arc(70 * scale, 45 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) > 0.2) {
arc(90 * scale, 45 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) < 0.2) {
}
pop();
}
// right eye
// eye
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale);
// pupil
noStroke();
fill(ch3_detailPrimary);
arc(eye2_pos[0] + curlookDirection * scale, eye2_pos[1], (30) * scale, (50) * scale, 20, 340, PIE);
// eyelid
strokeWeight(7 * scale);
stroke(ch3_detailPrimary);
fill(curHue, curSaturation, curBrightnessSecondary);
// top eyelid
arc(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale, 265 - curEyelidTop_height, 275 + curEyelidTop_height, CHORD);
// bottom eyelid
arc(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale, 85 - curEyelidBottom_height, 95 + curEyelidBottom_height, CHORD);
// eyebrow
stroke(ch3_detailPrimary)
noFill();
arc(eye2_pos[0], (eye2_pos[1]), 130 * scale, 110 * scale, 240, 300);
}
// facial feature if looking right
if(lookingRight == true) {
// right eye
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale);
// pupil
noStroke();
fill(ch3_detailPrimary);
arc(eye2_pos[0] + curlookDirection * scale, eye2_pos[1], (30) * scale, (50) * scale, 20, 340, PIE);
// eyelid
strokeWeight(7 * scale);
stroke(ch3_detailPrimary);
fill(curHue, curSaturation, curBrightnessSecondary);
// top eyelid
arc(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale, 265 - curEyelidTop_height, 275 + curEyelidTop_height, CHORD);
// bottom eyelid
arc(eye2_pos[0], eye2_pos[1], 80 * scale, 80 * scale, 85 - curEyelidBottom_height, 95 + curEyelidBottom_height, CHORD);
// eyebrow
stroke(ch3_detailPrimary)
noFill();
arc(eye2_pos[0], (eye2_pos[1]), 130 * scale, 110 * scale, 240, 300);
// nose
// if female draw bird style
if(gender < 1) {
// translate to an offset of the centre of the face
push();
translate(face_pos[0] + (120 * scale), face_pos[1] - (70 * scale));
// draw beak
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(curHue, curSaturation, curBrightnessSecondary);
arc(0, 0, 250 * scale, 150 * scale, 155, 205, PIE);
// draw mouth
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
line(-5 * scale, 0 * scale, -80 * scale, 0 * scale);
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
noFill();
arc(-110 * scale, 0 * scale, 50 * scale, 50 * scale, 320, 390);
// teeth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
// check teeth value
if(Math.abs(upperLip[1] - bottomLip[1]) > 0.28) {
arc(-40 * scale, 0 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) > 0.2) {
arc(-60 * scale, 0 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) < 0.2) {
}
pop();
}
// if male draw dog style
if(gender == 1) {
// translate to an offset of the centre of the face
push();
translate(face_pos[0], face_pos[1] - (100 * scale));
// draw snout
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
// top snout
rectMode(CORNER);
rect(0, 0, 140 * scale, 45 * scale, 0, 18 * scale, 18 * scale, 0);
stroke(ch3_detailPrimary)
strokeWeight(10 * scale);
fill(curHue, curSaturation, curBrightnessPrimary);
// bottom snout
rect(0 * scale, 45 * scale, 110 * scale, 35 * scale, 0, 14 * scale, 14 * scale, 0);
noStroke();
fill(curHue, curSaturation, curBrightnessPrimary);
// re-fill / cover
rect(-50 * scale, -7 * scale, 60 * scale, 100 * scale);
// draw nose
noStroke();
fill(ch3_detailPrimary);
push();
rotate(-10);
ellipse(140 * scale, 30 * scale, 40 * scale, 28 * scale);
pop();
// mouth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
noFill();
arc(-15 * scale, 50 * scale, 50 * scale, 50 * scale, 320, 390);
// teeth
stroke(ch3_detailPrimary)
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
// check teeth value
if(Math.abs(upperLip[1] - bottomLip[1]) > 0.28) {
arc(40 * scale, 45 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) > 0.2) {
arc(60 * scale, 45 * scale, 20 * scale, 40 * scale, 0, 180, CHORD);
} if(Math.abs(upperLip[1] - bottomLip[1]) < 0.2) {
}
pop();
}
// left eye
stroke(ch3_detailPrimary);
strokeWeight(7 * scale);
fill(ch3_detailSecondary);
ellipse(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale);
// pupil
noStroke();
fill(ch3_detailPrimary);
arc(eye1_pos[0] + curlookDirection * scale, eye1_pos[1], (30) * scale, (50) * scale, 20, 340, PIE);
// eyelid
strokeWeight(7 * scale);
stroke(ch3_detailPrimary);
fill(curHue, curSaturation, curBrightnessSecondary);
// top eyelid
arc(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale, 265 - curEyelidTop_height, 275 + curEyelidTop_height, CHORD);
// bottom eyelid
arc(eye1_pos[0], eye1_pos[1], 80 * scale, 80 * scale, 85 - curEyelidBottom_height, 95 + curEyelidBottom_height, CHORD);
// eyebrow
stroke(ch3_detailPrimary)
noFill();
arc(eye1_pos[0], (eye1_pos[1]), 130 * scale, 110 * scale, 240, 300);
}
// colorMode(RGB);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.genderValue = settings[0];
this.hairValue = settings[1];
this.lookDirection = settings[2];
this.eyelidTop_height = settings[3];
this.eyelidBottom_height = settings[4];
this.hue = settings[5];
this.saturation = settings[6];
this.brightness = settings[7];
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
properties = new Array(8);
properties[0] = this.genderValue;
properties[1] = this.hairValue;
properties[2] = this.lookDirection;
properties[3] = this.eyelidTop_height;
properties[4] = this.eyelidBottom_height;
properties[5] = this.hue;
properties[6] = this.saturation;
properties[7] = this.brightness;
return properties;
}
}
// given a point, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
65,
57,
51,
68,
87,
5,
29,
42
],
"000002": [
50,
50,
36,
50,
87,
0,
50,
50
],
"000058": [
50,
50,
76,
71,
78,
4,
0,
0
],
"000005": [
50,
50,
50,
85,
62,
10,
45,
77
],
"000006": [
50,
50,
93,
59,
55,
8,
41,
22
],
"000007": [
100,
49,
50,
71,
38,
50,
0,
0
],
"000009": [
50,
50,
31,
50,
100,
5,
41,
29
],
"000010": [
50,
50,
50,
87,
70,
10,
31,
74
],
"000013": [
100,
33,
76,
47,
89,
13,
33,
78
],
"000014": [
50,
50,
50,
73,
85,
50,
0,
0
],
"000015": [
100,
65,
62,
89,
100,
7,
33,
13
],
"000016": [
100,
27,
99,
50,
100,
5,
37,
16
],
"000018": [
50,
50,
50,
70,
93,
11,
32,
65
],
"000020": [
100,
100,
77,
71,
100,
6,
33,
3
],
"000023": [
100,
17,
100,
51,
100,
5,
23,
0
],
"000025": [
100,
0,
48,
66,
66,
6,
32,
15
],
"000028": [
50,
50,
50,
56,
100,
4,
44,
36
],
"000029": [
50,
50,
50,
87,
70,
10,
31,
74
],
"000030": [
100,
79,
76,
59,
94,
9,
33,
40
],
"000031": [
50,
50,
50,
85,
62,
10,
45,
77
],
"000032": [
100,
50,
77,
71,
100,
6,
33,
3
],
"000035": [
50,
50,
50,
50,
50,
50,
0,
0
],
"000037": [
100,
0,
83,
50,
71,
50,
0,
0
],
"000038": [
100,
49,
50,
71,
91,
50,
0,
0
],
"000041": [
100,
100,
0,
45,
100,
50,
0,
0
],
"000042": [
50,
50,
50,
66,
67,
10,
43,
74
],
"000043": [
50,
50,
38,
43,
62,
4,
26,
2
],
"000044": [
50,
50,
50,
73,
85,
50,
0,
0
],
"000045": [
50,
50,
50,
56,
100,
4,
47,
52
],
"000050": [
100,
49,
50,
57,
100,
50,
0,
0
],
"000051": [
100,
0,
59,
60,
85,
0,
0,
49
],
"000048": [
100,
82,
50,
88,
77,
50,
0,
0
],
"000047": [
50,
50,
50,
77,
50,
6,
18,
0
],
"000040": [
50,
50,
50,
65,
70,
4,
19,
6
],
"000052": [
100,
65,
70,
57,
84,
2,
20,
0
],
"000054": [
50,
50,
44,
50,
100,
9,
27,
57
],
"000055": [
100,
53,
42,
61,
78,
38,
0,
0
],
"000056": [
50,
50,
41,
81,
66,
5,
0,
0
],
"000060": [
100,
0,
0,
50,
90,
4,
28,
0
],
"000064": [
100,
59,
52,
75,
89,
6,
28,
8
],
"000065": [
100,
76,
41,
81,
78,
5,
0,
0
],
"000068": [
100,
82,
72,
63,
65,
15,
0,
50
],
"000069": [
100,
41,
63,
0,
90,
31,
0,
0
],
"000071": [
50,
50,
50,
85,
62,
10,
45,
77
],
"000073": [
50,
50,
27,
85,
62,
2,
45,
21
],
"000076": [
100,
94,
25,
75,
89,
6,
16,
0
],
"000077": [
50,
50,
76,
71,
78,
4,
0,
0
],
"000078": [
50,
50,
50,
73,
85,
50,
0,
0
],
"000079": [
100,
0,
63,
66,
66,
5,
37,
48
],
"000080": [
100,
59,
18,
53,
79,
34,
0,
0
],
"000081": [
100,
34,
58,
60,
94,
46,
0,
0
],
"000083": [
50,
50,
39,
55,
81,
4,
46,
30
],
"000085": [
50,
50,
62,
53,
42,
3,
34,
19
],
"000086": [
50,
50,
50,
64,
92,
6,
33,
18
],
"000088": [
50,
50,
64,
61,
90,
5,
53,
61
],
"000091": [
100,
45,
45,
95,
100,
33,
0,
0
],
"000092": [
50,
50,
45,
65,
58,
11,
38,
67
],
"000096": [
50,
50,
50,
40,
71,
0,
38,
0
],
"000097": [
50,
50,
52,
44,
40,
6,
37,
43
],
"000099": [
50,
50,
50,
53,
100,
3,
30,
10
],
"000100": [
50,
50,
74,
48,
41,
7,
35,
31
],
"000103": [
50,
50,
27,
51,
85,
5,
30,
5
],
"000104": [
100,
18,
50,
44,
83,
8,
44,
54
],
"000108": [
50,
50,
37,
59,
76,
10,
38,
75
],
"000106": [
50,
50,
27,
50,
100,
5,
40,
0
],
"000109": [
100,
50,
57,
50,
70,
5,
31,
21
],
"000110": [
50,
50,
50,
50,
88,
5,
37,
23
],
"000111": [
50,
50,
74,
50,
94,
11,
27,
68
],
"000114": [
100,
29,
49,
51,
63,
5,
19,
0
],
"000115": [
100,
0,
50,
67,
79,
7,
18,
71
],
"000116": [
100,
59,
58,
52,
91,
3,
26,
28
],
"000117": [
50,
50,
66,
85,
78,
23,
0,
0
],
"000118": [
50,
50,
23,
61,
90,
0,
18,
0
],
"000121": [
50,
50,
63,
49,
81,
4,
30,
0
],
"000122": [
50,
50,
52,
57,
85,
8,
22,
56
],
"000125": [
100,
0,
48,
53,
76,
20,
0,
26
],
"000126": [
50,
50,
54,
62,
54,
11,
16,
70
],
"000129": [
100,
53,
72,
53,
81,
20,
0,
0
],
"000131": [
50,
50,
100,
63,
89,
4,
4,
0
],
"000132": [
50,
50,
64,
66,
89,
18,
0,
0
],
"000133": [
50,
50,
66,
49,
73,
8,
28,
42
],
"000134": [
100,
0,
0,
55,
80,
51,
0,
0
],
"000135": [
100,
28,
100,
52,
96,
19,
0,
0
],
"000137": [
100,
62,
91,
65,
86,
6,
23,
15
],
"000140": [
50,
50,
38,
55,
82,
10,
33,
61
],
"000142": [
50,
50,
44,
60,
83,
6,
39,
0
],
"000143": [
100,
39,
64,
63,
80,
7,
22,
28
],
"000145": [
50,
50,
46,
58,
100,
5,
26,
0
],
"000146": [
50,
50,
100,
43,
89,
0,
37,
0
],
"000147": [
50,
50,
72,
53,
53,
8,
37,
64
],
"000148": [
50,
50,
100,
59,
74,
0,
13,
0
],
"000150": [
100,
74,
49,
100,
52,
0,
50,
52
],
"000151": [
62,
53,
51,
66,
89,
6,
21,
0
],
"000152": [
100,
39,
44,
64,
100,
5,
23,
33
],
"000153": [
100,
23,
54,
60,
85,
4,
26,
0
],
"000155": [
50,
50,
49,
51,
75,
0,
49,
50
],
"000156": [
50,
50,
52,
58,
62,
8,
30,
45
],
"000157": [
50,
50,
43,
62,
77,
8,
22,
63
],
"000160": [
100,
44,
50,
56,
75,
38,
0,
0
],
"000161": [
50,
50,
31,
62,
73,
5,
0,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
var NUM_SLIDERS = 6;
// other variables can be in here too
//helmet colors
const chen_red = [197, 17, 18];
const lime = [100, 255, 51];
const cyan = [0, 255, 232];
const yellow = [255, 243, 0];
const brown = [95, 60, 12];
const chen_black = [50];
const white = [210];
//eye colors
const eye_blue = [0, 182, 255, 75];
const eye_black = [4, 27, 30, 30];
const eye_green = [20, 135, 49, 75];
const eye_brown = [74, 35, 6, 50];
//mask colors
const mask = [157, 200, 217];
const mask_shade = [76, 95, 109];
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function ChenFace() {
// these are state variables for a face
// (your variables should be different!)
this.helmet_color = 2; // variations of hair colors
this.eye_color = 4; // variations of eye colors
this.gender = 1;
this.ref_shift = 1.5; //location of reflection
this.ref_shift_2 = 1;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for(let i=0; i<segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if(i < segment.length - 1) {
let nx = segment[i+1][0];
let ny = segment[i+1][1];
line(px, py, nx, ny);
}
else if(do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
//helmet
stroke(0, 150);
strokeWeight(0.2);
if (this.helmet_color >= 0 && this.helmet_color <= 1){
fill(chen_black);
} else if (this.helmet_color > 1 && this.helmet_color <= 2){
fill(brown);
} else if (this.helmet_color > 2 && this.helmet_color <= 3){
fill(chen_red);
} else if (this.helmet_color > 3 && this.helmet_color <= 4){
fill(yellow);
} else if (this.helmet_color > 4 && this.helmet_color <= 5){
fill(white);
}
beginShape();
curveVertex(positions.chin[0][0]-0.2, positions.chin[0][1]-0.5);
curveVertex(positions.chin[0][0]-0.2, positions.chin[0][1]-0.5);
curveVertex(positions.chin[0][0]-0.2, positions.chin[0][1]+2.5);
curveVertex(positions.chin[16][0]+0.2, positions.chin[16][1]+2.5);
curveVertex(positions.chin[16][0]+0.2, positions.chin[16][1]-0.5);
curveVertex(positions.chin[16][0]+0.2, positions.chin[16][1]-0.5);
endShape();
beginShape();
vertex(positions.chin[0][0]-0.2, positions.chin[0][1]-0.45);
quadraticVertex(0, positions.nose_bridge[0][1]-4, positions.chin[16][0]+0.2, positions.chin[16][1]-0.45)
endShape();
//mask
noStroke();
fill(mask);
beginShape();
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[3][0]-0.1, positions.chin[3][1]);
curveVertex(positions.nose_tip[2][0], positions.nose_tip[2][1]+0.6);
curveVertex(positions.chin[13][0]-0.1, positions.chin[13][1]);
curveVertex(positions.chin[14][0], positions.chin[14][1]);
curveVertex(positions.chin[16][0], positions.chin[16][1]);
curveVertex(positions.right_eyebrow[4][0]-0.2, positions.right_eyebrow[4][1]);
curveVertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-1);
curveVertex(positions.left_eyebrow[0][0]+0.2, positions.left_eyebrow[0][1]);
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[3][0], positions.chin[3][1]);
endShape();
//eyes
noStroke();
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
if (this.eye_color > 0 && this.eye_color <= 1){
fill(eye_black);
} else if (this.eye_color >1 && this.eye_color <= 2){
fill(eye_brown);
} else if (this.eye_color >2 && this.eye_color <= 3){
fill(eye_green);
} else if (this.eye_color >3 && this.eye_color <= 4) {
fill(eye_blue);
}
if (this.gender >= 0 && this.gender <= 0.5){ //softer edges for female
ellipse(left_eye_pos[0], left_eye_pos[1]+0.25, 0.38, 0.28);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.25, 0.38, 0.28);
fill(255, 50); // eye reflection
ellipse(left_eye_pos[0]+0.1, left_eye_pos[1]+0.2, 0.1);
ellipse(right_eye_pos[0]+0.1, right_eye_pos[1]+0.2, 0.1);
} else{ //harder edges for male
beginShape(); //left eye
vertex(positions.left_eye[0][0], positions.left_eye[0][1]+0.25);
vertex(positions.left_eye[1][0],positions.left_eye[1][1]+0.25);
vertex(positions.left_eye[2][0], positions.left_eye[2][1]+0.25);
vertex(positions.left_eye[3][0], positions.left_eye[3][1]+0.25);
vertex(positions.left_eye[4][0], positions.left_eye[4][1]+0.25);
vertex(positions.left_eye[5][0], positions.left_eye[5][1]+0.25);
endShape();
beginShape(); //right eye
vertex(positions.right_eye[0][0], positions.right_eye[0][1]+0.25);
vertex(positions.right_eye[1][0],positions.right_eye[1][1]+0.25);
vertex(positions.right_eye[2][0], positions.right_eye[2][1]+0.25);
vertex(positions.right_eye[3][0], positions.right_eye[3][1]+0.25);
vertex(positions.right_eye[4][0], positions.right_eye[4][1]+0.25);
vertex(positions.right_eye[5][0], positions.right_eye[5][1]+0.25);
endShape();
// eye reflection
fill(255, 25);
ellipse(left_eye_pos[0]-0.08, left_eye_pos[1]+0.21, 0.15, 0.11);
ellipse(right_eye_pos[0]-0.08, right_eye_pos[1]+0.21, 0.15, 0.11);
}
//blush
if (this.gender >= 0 && this.gender <= 0.5){
fill(255, 222, 254);
ellipse(positions.left_eye[0][0], positions.left_eye[0][1]+0.6, 0.5, 0.1);
ellipse(positions.right_eye[3][0], positions.right_eye[3][1]+0.6, 0.5, 0.1);
} else {
fill(255, 222, 254, 150);
ellipse(positions.left_eye[0][0], positions.left_eye[0][1]+0.6, 0.4, 0.08);
ellipse(positions.right_eye[3][0], positions.right_eye[3][1]+0.6, 0.4, 0.08);
}
//nose
let nose_top = positions.nose_bridge[1];
let nose_bottom = positions.nose_bridge[3];
let nose_end = null;
stroke(76, 95, 109, 25);
strokeWeight(0.08);
line(nose_top[0], nose_top[1], nose_bottom[0], nose_bottom[1]-0.15);
//mouth
noStroke();
fill(255, 25);
beginShape();
vertex(positions.top_lip[1][0],positions.top_lip[1][1]-0.2);
vertex(positions.top_lip[2][0], positions.top_lip[2][1]-0.2);
vertex(positions.top_lip[3][0], positions.top_lip[3][1]-0.2);
vertex(positions.top_lip[4][0], positions.top_lip[4][1]-0.2);
vertex(positions.top_lip[5][0], positions.top_lip[5][1]-0.2);
vertex(positions.bottom_lip[10][0], positions.bottom_lip[10][1]-0.3);
vertex(positions.bottom_lip[9][0], positions.bottom_lip[9][1]-0.3);
vertex(positions.bottom_lip[8][0], positions.bottom_lip[8][1]-0.3);
endShape();
//reflection
let curRefShift = this.ref_shift;
let curRefShift_2 = this.ref_shift_2;
fill(254, 252, 255, 220);
if(nose_top[0] > nose_bottom[0]){
ellipse(positions.nose_bridge[3][0] + curRefShift, right_eye_pos[1]+0.22, 1, 0.5);
ellipse(positions.top_lip[3][0] - curRefShift_2 , positions.top_lip[1][1]-0.2, 0.2, 0.1);
} else{
ellipse(positions.nose_bridge[3][0] - curRefShift, right_eye_pos[1]+0.22, 1, 0.5);
ellipse(positions.top_lip[3][0] + curRefShift_2 , positions.top_lip[1][1]-0.2, 0.2, 0.1);
}
//mask outline
noFill();
stroke(0, 200);
strokeWeight(0.2);
beginShape();
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[3][0]-0.1, positions.chin[3][1]);
curveVertex(positions.nose_tip[2][0], positions.nose_tip[2][1]+0.6);
curveVertex(positions.chin[13][0]-0.1, positions.chin[13][1]);
curveVertex(positions.chin[14][0], positions.chin[14][1]);
curveVertex(positions.chin[16][0], positions.chin[16][1]);
curveVertex(positions.right_eyebrow[4][0]-0.2, positions.right_eyebrow[4][1]);
curveVertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-1);
curveVertex(positions.left_eyebrow[0][0]+0.2, positions.left_eyebrow[0][1]);
curveVertex(positions.chin[0][0], positions.chin[0][1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[3][0], positions.chin[3][1]);
endShape();
//decorations
if (this.gender >= 0 && this.gender <= 0.5){ //flower hat for female
stroke(0, 200);
strokeWeight(0.1);
fill(255, 192, 183);
push();
angleMode(DEGREES);
if (nose_top[0] > nose_bottom[0]){
translate(positions.chin[16][0]-0.1, positions.chin[16][1]-0.5);
} else {
translate(positions.chin[0][0]+0.1, positions.chin[0][1]-0.5);
}
for (let i = 0; i < 5; i++){
ellipse(0, 0.35, 0.37, 0.75);
rotate(360/5);
}
noStroke();
fill(236, 180, 172, 200);
ellipse(0, 0, 0.3);
pop();
} else { //plant hat for male
stroke(0, 200);
strokeWeight(0.1);
push();
translate(positions.nose_bridge[0][0], positions.nose_bridge[0][1]-1.3);
fill(3, 77, 13);
if (nose_top[0] > nose_bottom[0]){
beginShape();
vertex(-0.2, -0.4);
vertex(-0.2, -0.7);
quadraticVertex(-1.1, -0.85, -1.5, -1.4);
quadraticVertex(-0.6, -1.9, -0.1, -1.05);
quadraticVertex(0.55, -2.4, 1.4, -1.8);
quadraticVertex(0.9, -0.7, 0.2, -0.7);
vertex(0.2, -0.4);
vertex(-0.2, -0.4);
endShape();
} else {
beginShape();
vertex(0.2, -0.4);
vertex(0.2, -0.7);
quadraticVertex(1.1, -0.85, 1.5, -1.4);
quadraticVertex(0.6, -1.9, 0.1, -1.05);
quadraticVertex(-0.55, -2.4, -1.4, -1.8);
quadraticVertex(-0.9, -0.7, -0.2, -0.7);
vertex(-0.2, -0.4);
vertex(0.2, -0.4);
endShape();
}
pop();
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.helmet_color = map(settings[0], 0, 100, 0, 5);
this.eye_color = map(settings[1], 0, 100, 1, 4);
this.gender = map(settings[2], 0, 100, 0, 1);
this.ref_shift = map(settings[3], 0, 100, 1, 1.8);
this.ref_shift_2 = map(settings[4], 0, 100, 0.3, 1.2);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(6);
settings[0] = map(this.helmet_color, 0, 5, 0, 100);
settings[1] = map(this.eye_color, 1, 4, 0, 100);
settings[2] = map(this.gender, 0, 1, 0, 100);
settings[3] = map(this.ref_shift, 1, 1.8, 0, 100);
settings[4] = map(this.ref_shift_2, 0.3, 1.2, 0, 100);
return settings;
}
}
{
"000001": [
63,
26,
0,
100,
33,
null
],
"000002": [
46,
11.000000000000004,
0,
68,
21.000000000000004,
null
],
"000005": [
68,
16,
0,
68,
85.99999999999999,
null
],
"000006": [
21.000000000000004,
11.000000000000004,
0,
68,
21.000000000000004,
null
],
"000007": [
0,
15,
100,
69,
30,
null
],
"000009": [
23,
13.000000000000004,
0,
100,
30,
null
],
"000010": [
65,
81,
0,
56.99999999999999,
48.00000000000001,
null
],
"000013": [
69,
98,
100,
81.00000000000001,
52.99999999999999,
null
],
"000014": [
0,
0,
0,
81.00000000000001,
26.999999999999996,
null
],
"000015": [
27,
0,
100,
59,
67,
null
],
"000016": [
14.000000000000002,
15,
100,
80.00000000000001,
61.999999999999986,
null
],
"000018": [
71,
33,
0,
46.999999999999986,
61.999999999999986,
null
],
"000020": [
16.000000000000004,
0,
100,
50.99999999999999,
61.999999999999986,
null
],
"000023": [
11.000000000000002,
2.0000000000000018,
100,
56.99999999999999,
59.999999999999986,
null
],
"000025": [
28.000000000000004,
0,
100,
84.00000000000001,
61.999999999999986,
null
],
"000028": [
21.999999999999996,
0,
0,
48.999999999999986,
61.999999999999986,
null
],
"000029": [
64,
75,
0,
55.99999999999999,
57.999999999999986,
null
],
"000030": [
64,
17,
100,
94,
23.000000000000004,
null
],
"000031": [
63,
83,
0,
30,
74.99999999999999,
null
],
"000032": [
72,
0,
100,
34,
42,
null
],
"000035": [
0,
24,
0,
30,
40,
null
],
"000037": [
0,
16,
100,
100,
1.000000000000001,
null
],
"000038": [
19,
80.00000000000001,
100,
55.99999999999999,
30,
null
],
"000040": [
0,
18.000000000000004,
0,
73.00000000000001,
30,
null
],
"000041": [
0,
17,
100,
100,
0,
null
],
"000042": [
75,
69.99999999999999,
0,
68,
9.000000000000002,
null
],
"000043": [
40,
13.999999999999998,
0,
40.00000000000001,
46,
null
],
"000044": [
0,
0,
0,
40.00000000000001,
46,
null
],
"000045": [
43,
20.000000000000004,
0,
40.00000000000001,
46,
null
],
"000047": [
0,
0,
0,
53.99999999999999,
52.99999999999999,
null
],
"000048": [
0,
0,
100,
53.99999999999999,
52.99999999999999,
null
],
"000050": [
0,
13.000000000000004,
100,
86.00000000000001,
52.99999999999999,
null
],
"000051": [
100,
11.000000000000004,
100,
53.99999999999999,
52.99999999999999,
null
],
"000052": [
32,
80.00000000000001,
100,
53.99999999999999,
52.99999999999999,
null
],
"000054": [
67,
79,
0,
53.99999999999999,
52.99999999999999,
null
],
"000055": [
0,
17,
100,
68,
61.999999999999986,
null
],
"000056": [
0,
24,
0,
68,
46.99999999999999,
null
],
"000058": [
0,
77.99999999999999,
0,
56.99999999999999,
67,
null
],
"000060": [
32,
20.000000000000004,
100,
100,
67,
null
],
"000064": [
25,
8,
100,
56.99999999999999,
67,
null
],
"000065": [
0,
13.000000000000004,
100,
56.99999999999999,
67,
null
],
"000068": [
100,
11.000000000000004,
100,
71.00000000000001,
40,
null
],
"000069": [
0,
24,
100,
28.999999999999996,
94,
null
],
"000071": [
62,
45,
0,
84.00000000000001,
50.000000000000014,
null
],
"000073": [
32,
24,
0,
100,
28.000000000000007,
null
],
"000076": [
0,
8,
100,
57.99999999999999,
46.99999999999999,
null
],
"000077": [
31,
0,
0,
89.00000000000003,
46,
null
],
"000078": [
9.999999999999998,
4.0000000000000036,
0,
56.99999999999999,
70,
null
],
"000079": [
100,
24,
100,
87.00000000000003,
34,
null
],
"000080": [
0,
82,
100,
70,
17,
null
],
"000081": [
0,
20.000000000000004,
100,
78.00000000000001,
50.000000000000014,
null
],
"000083": [
25,
23,
0,
72.00000000000001,
50.000000000000014,
null
],
"000085": [
26,
10.000000000000002,
0,
72.00000000000001,
50.000000000000014,
null
],
"000086": [
35,
11.999999999999995,
0,
100,
18,
null
],
"000088": [
36,
23,
0,
79.00000000000001,
18,
null
],
"000091": [
0,
0,
100,
61,
18,
null
],
"000092": [
66,
67,
0,
84.00000000000001,
43,
null
],
"000096": [
27,
9.000000000000002,
0,
61,
48.00000000000001,
null
],
"000097": [
25,
90,
0,
61,
48.00000000000001,
null
],
"000099": [
25,
100,
0,
61,
48.00000000000001,
null
],
"000100": [
70,
1.0000000000000009,
0,
89.00000000000003,
30,
null
],
"000103": [
25,
41,
0,
62,
30,
null
],
"000104": [
62,
23,
100,
51.99999999999999,
39.00000000000001,
null
],
"000106": [
25,
17,
0,
82.00000000000001,
28.000000000000007,
null
],
"000108": [
69,
8,
0,
82.00000000000001,
28.000000000000007,
null
],
"000109": [
68,
50,
100,
67,
28.000000000000007,
null
],
"000110": [
21.999999999999996,
48,
0,
67,
28.000000000000007,
null
],
"000111": [
69,
8,
0,
100,
28.000000000000007,
null
],
"000114": [
0,
20.999999999999996,
100,
52.99999999999999,
39.00000000000001,
null
],
"000115": [
100,
45,
100,
52.99999999999999,
39.00000000000001,
null
],
"000116": [
27,
19.000000000000004,
100,
52.99999999999999,
39.00000000000001,
null
],
"000117": [
0,
27,
0,
87.00000000000003,
28.000000000000007,
null
],
"000118": [
19,
6.999999999999999,
0,
100,
15.999999999999998,
null
],
"000121": [
0,
15,
0,
45.000000000000014,
46.99999999999999,
null
],
"000122": [
66,
13.999999999999998,
0,
42.00000000000001,
65,
null
],
"000125": [
100,
72.00000000000001,
100,
84.00000000000001,
52.99999999999999,
null
],
"000126": [
61,
83,
0,
68,
43,
null
],
"000129": [
0,
4.9999999999999964,
100,
56.99999999999999,
43,
null
],
"000131": [
0,
0,
0,
90.00000000000003,
43,
null
],
"000132": [
0,
11.000000000000004,
0,
90.00000000000003,
43,
null
],
"000133": [
61,
69.99999999999999,
0,
51.99999999999999,
35,
null
],
"000134": [
0,
0,
100,
100,
23.000000000000004,
null
],
"000135": [
0,
0,
100,
85.00000000000001,
23.000000000000004,
null
],
"000137": [
100,
0,
100,
100,
3.9999999999999982,
null
],
"000140": [
70,
75,
0,
68,
24.999999999999993,
null
],
"000142": [
20.999999999999996,
24,
0,
51.99999999999999,
8.000000000000002,
null
],
"000143": [
24,
77.99999999999999,
100,
75.00000000000001,
26.000000000000007,
null
],
"000145": [
0,
10.000000000000002,
0,
82.00000000000001,
26.000000000000007,
null
],
"000146": [
49.00000000000001,
4.0000000000000036,
0,
100,
0,
null
],
"000147": [
64,
71,
0,
55.99999999999999,
0,
null
],
"000148": [
0,
48.99999999999999,
0,
100,
0,
null
],
"000150": [
51,
0,
100,
86.00000000000001,
12,
null
],
"000151": [
28.000000000000004,
0,
0,
36.00000000000001,
54.99999999999999,
null
],
"000152": [
22.000000000000004,
57.99999999999999,
100,
45.000000000000014,
72.99999999999999,
null
],
"000153": [
0,
18.000000000000004,
100,
45.000000000000014,
72.99999999999999,
null
],
"000155": [
54,
13.000000000000004,
0,
77.00000000000001,
61,
null
],
"000156": [
72,
0,
0,
98,
61,
null
],
"000157": [
69,
69,
0,
51.99999999999999,
61,
null
],
"000160": [
0,
6.999999999999999,
100,
51.99999999999999,
31,
null
],
"000161": [
0,
77.99999999999999,
0,
51.99999999999999,
54.000000000000014,
null
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 7;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
const cooper_brown =[250, 155, 117];
const brown1 =[209, 131, 100];
const brown2 =[135, 85, 65];
const brown3 = [79, 50, 38];
const brown4 = [43, 29, 21];
const lip = [247, 134, 89];
const lip1 = [204, 108, 69];
const lip2 = [107, 67, 51];
const lip3 = [79, 40, 25];
const lip4 = [33, 19, 10];
this.show_points = function (segment){
for(let i=0; i<segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
var number = i.toString();
textAlign(CENTER, CENTER);
textSize(0.2);
fill(0);
text(number, px, py, 0.1);
}
}
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function CooperFace() {
// these are state variables for a face
// (your variables should be different!)
this.faceSize = 3;
this.eye = 0.5;
this.lip = 1 ;
this.tooth = 2;
this.mouth = 1;
this.num_eyes = 2;
this.eye_shift = -1;
this.face_colour = 1;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for(let i=0; i<segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if(i < segment.length - 1) {
let nx = segment[i+1][0];
let ny = segment[i+1][1];
line(px, py, nx, ny);
}
else if(do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
let left_eye = segment_average(positions.left_eye);
let right_eye = segment_average(positions.right_eye);
let nose_tip = positions.nose_tip[2];
let top_lip = positions.top_lip[3];
let bottom_lip = positions.bottom_lip[0];
let whiskers = positions.nose_bridge[2];
let nostrils = positions.nose_bridge[2];
let tooth = positions.nose_bridge[3];
noStroke();
//head
if(this.face_colour == 0){
fill(cooper_brown);
}else
if(this.face_colour == 1){
fill(brown1);
}else
if(this.face_colour == 2){
fill(brown2);
}else
if(this.face_colour == 3){
fill(brown3);
}else
if(this.face_colour == 4){
fill(brown4);
}
ellipse(0, -0.3,this.faceSize,4);
// eyes
fill(255);
ellipse(left_eye[0], left_eye[1], 1,this.eye);
ellipse(right_eye[0], right_eye[1],1, this.eye);
let curEyeShift = 0.04 * this.eye_shift;
if(this.num_eyes == 2) {
fill(0);
ellipse(left_eye[0] + curEyeShift, left_eye[1], 0.5);
ellipse(right_eye[0] + curEyeShift, right_eye[1], 0.5);
}
else {
let eyePosX = (left_eye[0] + right_eye[0]) / 2;
let eyePosY = (left_eye[1] + right_eye[1]) / 2;
fill(0);
ellipse(eyePosX, eyePosY, 0.45, 0.27);
fill(0);
ellipse(eyePosX - 0.1 + curEyeShift, eyePosY, 0.18);
}
//mouth
fill(255, 201, 251);
ellipse(top_lip[0],top_lip[1],bottom_lip[0],this.mouth);
//teeth
if(this.tooth == 2){
noStroke();
push();
translate(tooth[0],tooth[1]);
fill(255);
triangle(0.25, 0.5, 0.5, 2, 0.75, 0.5);
triangle(-0.75, 0.5, -0.5, 2, -0.25, 0.5);
pop();
}else
if(this.tooth == 0){
noStroke();
push();
translate(tooth[0],tooth[1]);
fill(255);
triangle(0.25, 0.5, 0.5, 0, 0.75, 0.5);
triangle(-0.75, 0.5, -0.5, 0, -0.25, 0.5);
pop();
}
//lip
if(this.face_colour == 0){
fill(lip);
}else
if(this.face_colour == 1){
fill(lip1);
}else
if(this.face_colour == 2){
fill(lip2);
}else
if(this.face_colour == 3){
fill(lip3);
}else
if(this.face_colour == 4){
fill(lip4);
}
ellipse(nose_tip[0],nose_tip[1], 4, 1);
//nostrils
fill(0);
ellipse(nostrils[0],nostrils[1],this.lip, 0.5);
//whiskers
noFill();
stroke(255, 194, 115);
push();
translate(whiskers[0],whiskers[1]);
angleMode(DEGREES);
strokeWeight(0.05);
arc(0.4, 1, 1.6, 1.2, 290, 50);
arc(0.6, 1, 1.6, 1.2, 290, 50);
arc(0.8, 1, 1.6, 1.2, 290, 50);
arc(0, 1, 1.6, 1.2, 320, 50);
arc(0, 0.52, 0.8, 1.2, 360, 50);
arc(0, 0.6, 0.4, 1.2, 340, 50);
arc(-0.2, 0.6, 0.4, 1.2, 340, 50);
arc(-0.4, 0.6, 0.4, 1.2, 340, 50);
arc(-0.4, 1, 1.6, 1.2, 135, 250);
arc(-0.6, 1, 1.6, 1.2, 135, 250);
arc(-0.8, 1, 1.6, 1.2, 135, 250);
arc(-0.32, 0.96,1, 1.08, 120, 250);
arc(-0.2, 0.88, 0.4, 1.2, 180, 250);
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.faceSize = map(settings[0], 0, 100, 2.8, 4);
this.eye = map(settings[1], 0, 100, 0.5, 0.8);
this.lip = map(settings[2], 0, 100, 0.5, 2);
this.tooth = int(map(settings[3], 0, 100, 0, 2));
this.mouth = map(settings[4], 0, 100, 0.5, 1.5);
this.eye_shift = map(settings[5], 0, 100, -2, 2);
this.face_colour = int(map(settings[6], 0, 100, 0, 4));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(3);
settings[0] = map(this.faceSize, 2.8, 4, 0, 100);
settings[1] = map(this.eye, 0.5, 0.8, 0, 100);
settings[2] = map(this.lip, 0.5, 2, 0, 100);
settings[3] = int(map(this.tooth, 0, 2, 0, 100));
settings[4] = map(this.mouth,0.5,1.5,0,100);
settings[5] = map(this.eye_shift, -2, 2, 0, 100);
settings[6] = int(map(this.face_colour, 0, 4, 0, 100));
return settings;
}
}
{
"000001": [
63.000000000000014,
18.000000000000014,
17,
0,
5.000000000000004,
60,
0
],
"000002": [
77.99999999999999,
24.999999999999982,
4.0000000000000036,
0,
49,
38,
0
],
"000005": [
100,
13.000000000000009,
10.000000000000002,
0,
39,
46,
0
],
"000006": [
52,
16.00000000000001,
0,
0,
33.00000000000001,
95,
50
],
"000007": [
54,
22.000000000000018,
11.000000000000004,
100,
0,
60,
0
],
"000009": [
75.00000000000003,
20.99999999999998,
1.0000000000000009,
0,
37,
42,
0
],
"000010": [
100,
0,
16,
0,
0,
41,
0
],
"000013": [
100,
0,
0,
100,
14.000000000000002,
75,
0
],
"000014": [
100,
14.000000000000009,
9.000000000000002,
0,
0,
37,
75
],
"000015": [
54,
0,
20.999999999999996,
100,
7.000000000000006,
57.99999999999999,
0
],
"000016": [
50,
13.000000000000009,
8,
100,
0,
100,
25
],
"000018": [
81.00000000000003,
14.000000000000009,
19.000000000000004,
0,
30.000000000000004,
45,
0
],
"000020": [
60.00000000000001,
0,
17,
100,
19.999999999999996,
77,
0
],
"000023": [
58.00000000000001,
20.000000000000014,
20.999999999999996,
100,
6.000000000000005,
100,
0
],
"000025": [
66.00000000000001,
6.000000000000004,
4.9999999999999964,
100,
0,
44,
0
],
"000028": [
63.000000000000014,
11.000000000000009,
44.000000000000014,
0,
87.99999999999999,
54,
25
],
"000029": [
81.99999999999999,
17.00000000000001,
0,
0,
55.00000000000001,
45,
0
],
"000030": [
95,
14.000000000000009,
0,
100,
0,
43,
0
],
"000031": [
66.00000000000001,
5.0000000000000036,
22.000000000000007,
0,
25,
43,
0
],
"000032": [
61.00000000000001,
28.999999999999986,
4.0000000000000036,
100,
44.99999999999999,
54,
0
],
"000035": [
65.00000000000001,
39.99999999999999,
0,
0,
7.000000000000006,
53,
0
],
"000037": [
73.00000000000001,
51,
60,
100,
0,
94,
50
],
"000038": [
62.000000000000014,
3.000000000000002,
32,
100,
20.999999999999996,
71,
0
],
"000040": [
73.99999999999997,
33.999999999999986,
0,
0,
0,
66,
25
],
"000041": [
54,
26.000000000000018,
56.99999999999999,
100,
83,
0,
25
],
"000042": [
67.00000000000001,
13.000000000000009,
0,
0,
0,
34,
0
],
"000043": [
49,
23.000000000000018,
4.0000000000000036,
0,
56.999999999999986,
30,
0
],
"000044": [
34.999999999999986,
22.000000000000018,
23,
0,
0,
48,
100
],
"000045": [
56.00000000000001,
7.000000000000004,
6.999999999999999,
0,
66.00000000000001,
70,
25
],
"000047": [
66.00000000000001,
0,
5.999999999999997,
0,
23,
74,
25
],
"000048": [
83.99999999999999,
0,
11.000000000000004,
100,
0,
50,
0
],
"000050": [
75.00000000000003,
0,
28.000000000000004,
100,
79,
62,
25
],
"000051": [
92,
18.000000000000014,
38.99999999999999,
100,
0,
62,
25
],
"000052": [
64.00000000000001,
14.000000000000009,
31,
100,
0,
69,
25
],
"000054": [
71.00000000000001,
14.000000000000009,
6.999999999999999,
0,
55.00000000000001,
71,
0
],
"000055": [
71.00000000000001,
31.999999999999986,
16,
100,
0,
56.99999999999999,
25
],
"000056": [
77.00000000000003,
30.99999999999999,
11.000000000000004,
100,
0,
50,
0
],
"000058": [
77.00000000000003,
24.999999999999982,
5.999999999999997,
0,
0,
71,
0
],
"000060": [
100,
26.000000000000018,
20.000000000000004,
100,
20.999999999999996,
0,
100
],
"000064": [
100,
6.000000000000004,
18.000000000000004,
100,
0,
57.99999999999999,
0
],
"000065": [
75.99999999999997,
6.000000000000004,
40.00000000000001,
100,
23,
57.99999999999999,
25
],
"000068": [
61.00000000000001,
14.000000000000009,
13.000000000000004,
100,
20.999999999999996,
44,
0
],
"000069": [
61.00000000000001,
14.000000000000009,
13.000000000000004,
100,
20.999999999999996,
44,
0
],
"000071": [
81.00000000000003,
24.000000000000018,
1.0000000000000009,
0,
17.999999999999993,
62,
0
],
"000073": [
84.99999999999999,
26.999999999999986,
11.000000000000004,
0,
12,
20.999999999999996,
25
],
"000076": [
100,
26.999999999999986,
18.000000000000004,
100,
0,
15.000000000000002,
25
],
"000077": [
96,
18.000000000000014,
6.999999999999999,
0,
0,
79,
25
],
"000078": [
96,
0,
5.999999999999997,
0,
0,
39,
0
],
"000079": [
53,
13.000000000000009,
24,
100,
0,
80,
25
],
"000080": [
65.00000000000001,
16.00000000000001,
11.000000000000004,
100,
0,
54,
0
],
"000081": [
59.00000000000001,
17.00000000000001,
32,
100,
37,
100,
25
],
"000083": [
38.99999999999999,
18.000000000000014,
4.9999999999999964,
0,
0,
52,
0
],
"000085": [
95,
47,
5.999999999999997,
0,
0,
63,
0
],
"000086": [
100,
31.999999999999986,
5.999999999999997,
0,
27,
27,
0
],
"000088": [
87.99999999999999,
24.999999999999982,
10.000000000000002,
0,
18.999999999999993,
78,
25
],
"000091": [
79.00000000000003,
0,
13.000000000000004,
100,
0,
17.000000000000004,
0
],
"000092": [
73.00000000000001,
10.000000000000007,
5.999999999999997,
0,
0,
46,
0
],
"000096": [
100,
28.999999999999986,
23,
0,
0,
46,
0
],
"000097": [
100,
31.999999999999986,
17,
0,
19.999999999999996,
56.99999999999999,
0
],
"000099": [
52,
0,
23,
0,
47,
50,
0
],
"000100": [
79.99999999999999,
26.999999999999986,
23,
0,
0,
91,
0
],
"000103": [
75.99999999999997,
30.99999999999999,
1.0000000000000009,
0,
0,
43,
0
],
"000104": [
54,
0,
38.00000000000001,
100,
36,
61,
0
],
"000106": [
43.99999999999999,
20.99999999999998,
18.000000000000004,
0,
49,
46,
0
],
"000108": [
58.00000000000001,
22.000000000000018,
0,
0,
40.99999999999999,
51,
0
],
"000109": [
28.000000000000018,
13.000000000000009,
0,
100,
21.999999999999996,
60,
0
],
"000110": [
100,
19.000000000000014,
52,
0,
50,
50,
0
],
"000111": [
100,
19.000000000000014,
38.00000000000001,
0,
47,
100,
100
],
"000114": [
56.00000000000001,
31.999999999999986,
20.000000000000004,
100,
44.99999999999999,
60,
0
],
"000115": [
29.99999999999999,
10.000000000000007,
6.999999999999999,
100,
0,
68,
0
],
"000116": [
39.99999999999999,
0,
6.999999999999999,
100,
37,
76,
0
],
"000117": [
32.999999999999986,
0,
34.99999999999999,
0,
27,
68,
100
],
"000118": [
64.00000000000001,
19.000000000000014,
8,
0,
0,
34,
25
],
"000121": [
51,
23.000000000000018,
15,
0,
0,
56.99999999999999,
25
],
"000122": [
69.99999999999997,
36.999999999999986,
22.000000000000007,
0,
29.000000000000004,
66,
0
],
"000125": [
69.99999999999997,
24.999999999999982,
22.000000000000007,
100,
0,
50,
0
],
"000126": [
60.00000000000001,
24.999999999999982,
6.999999999999999,
0,
29.000000000000004,
80,
0
],
"000129": [
30.99999999999999,
17.00000000000001,
0,
100,
31.000000000000007,
80,
0
],
"000131": [
63.000000000000014,
0,
6.999999999999999,
0,
25,
100,
50
],
"000132": [
84.99999999999999,
24.000000000000018,
23,
0,
49,
82,
50
],
"000133": [
84.99999999999999,
24.000000000000018,
13.999999999999998,
0,
33.00000000000001,
53,
0
],
"000134": [
51,
20.000000000000014,
41.99999999999999,
100,
36,
0,
100
],
"000135": [
37.999999999999986,
22.000000000000018,
17,
100,
0,
100,
50
],
"000137": [
66.00000000000001,
3.000000000000002,
16,
100,
30.000000000000004,
100,
0
],
"000140": [
61.00000000000001,
22.000000000000018,
0,
0,
0,
38,
0
],
"000142": [
42.99999999999999,
20.000000000000014,
8,
0,
10.999999999999998,
38,
0
],
"000143": [
81.99999999999999,
19.000000000000014,
11.999999999999995,
100,
7.9999999999999964,
54,
0
],
"000145": [
67.00000000000001,
0,
8,
0,
76,
57.99999999999999,
0
],
"000146": [
79.00000000000003,
17.00000000000001,
8,
0,
56.999999999999986,
88,
25
],
"000147": [
81.99999999999999,
23.000000000000018,
5.999999999999997,
0,
8.999999999999996,
92,
0
],
"000148": [
47,
32.999999999999986,
2.0000000000000018,
0,
24,
100,
0
],
"000150": [
58.00000000000001,
13.000000000000009,
0,
100,
0,
55.00000000000001,
0
],
"000151": [
61.00000000000001,
13.000000000000009,
27,
0,
53,
59,
25
],
"000152": [
68.00000000000001,
0,
20.999999999999996,
100,
39,
41,
0
],
"000153": [
38.99999999999999,
14.000000000000009,
11.999999999999995,
100,
40.99999999999999,
50,
0
],
"000155": [
71.99999999999997,
20.99999999999998,
13.999999999999998,
0,
40,
59,
25
],
"000156": [
66.00000000000001,
20.99999999999998,
6.999999999999999,
0,
24,
69,
0
],
"000157": [
100,
20.99999999999998,
16,
0,
0,
52,
0
],
"000160": [
62.000000000000014,
13.000000000000009,
11.999999999999995,
100,
0,
63,
0
],
"000161": [
75.99999999999997,
15.00000000000001,
11.000000000000004,
0,
40,
39,
0
]
}
// https://d3js.org/d3-random/ v1.1.2 Copyright 2018 Mike Bostock
!function(n,r){"object"==typeof exports&&"undefined"!=typeof module?r(exports):"function"==typeof define&&define.amd?define(["exports"],r):r(n.d3=n.d3||{})}(this,function(n){"use strict";function r(){return Math.random()}var t=function n(r){function t(n,t){return n=null==n?0:+n,t=null==t?1:+t,1===arguments.length?(t=n,n=0):t-=n,function(){return r()*t+n}}return t.source=n,t}(r),u=function n(r){function t(n,t){var u,e;return n=null==n?0:+n,t=null==t?1:+t,function(){var o;if(null!=u)o=u,u=null;else do{u=2*r()-1,o=2*r()-1,e=u*u+o*o}while(!e||e>1);return n+t*o*Math.sqrt(-2*Math.log(e)/e)}}return t.source=n,t}(r),e=function n(r){function t(){var n=u.source(r).apply(this,arguments);return function(){return Math.exp(n())}}return t.source=n,t}(r),o=function n(r){function t(n){return function(){for(var t=0,u=0;u<n;++u)t+=r();return t}}return t.source=n,t}(r),i=function n(r){function t(n){var t=o.source(r)(n);return function(){return t()/n}}return t.source=n,t}(r),c=function n(r){function t(n){return function(){return-Math.log(1-r())/n}}return t.source=n,t}(r);n.randomUniform=t,n.randomNormal=u,n.randomLogNormal=e,n.randomBates=i,n.randomIrwinHall=o,n.randomExponential=c,Object.defineProperty(n,"__esModule",{value:!0})});
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
//color variables
skinMidtone_color = ["#ffd5be","#ebcebb", "#ffd5be", "#CAA288", "#8c6652"];
skinLowlight_color = ["#f4c4b0", "#e5bbac","#e5b6a2", "#b78c79", "#775041"]
n1= [244, 200, 176, 50];
n2= [229, 187, 172, 50];
n3 = [232, 188, 169, 40];
n4 = [188, 149, 126, 50];
n5 = [124, 84, 68, 50];
noseColor = [n1, n2,n3, n4, n5];
h1= [255, 255, 255, 10];
h2= [249, 245, 239, 10];
h3 = [249, 245, 239, 10];
h4 = [255, 231, 216, 10];
h5 = [255, 231, 216, 10];
noseHighlight = [h1, h2, h3, h4, h5];
skinShadow_color = ["#d6a995", "#d6a995","#ba9584", "#9b7768", "#725241"]
// stroke_color = [skinLowlight_color[1]];
upperLip_color = ["#ba8080", "#d1a3a1", "#dba69b", "#a5776b","#6d453d", "#54322b"]; // 1 longer than the rest for stroke
lowerLip_color = ["#db9d9d", "#ebbdbb", "#ffc9be", "#ca9588", "#8c5c52"];
teeth_color = ["#fcfaf4", "#fff", "#f2ece3", "#f7f2ea", "#efe6da"];
eye_color = ["#3e7191", "#22323d", "#3d4722", "#543f14", "#493127", "#000"];
pupil_color = "#000";
function DockertyFace() {
this.lookPos = 50;
this.eyeAngle = 100;
this.skinColor = 50;
this.eyeColor = 50;
this.eyeSize = 50;
this.draw = function(positions) {
var nose_pos = average_point(positions.nose_bridge);
var eye1_pos = average_point(positions.left_eye);
var eye2_pos = average_point(positions.right_eye);
var half_height = positions.chin[7][1] - nose_pos[1];
var face_width = positions.chin[positions.chin.length-1][0] - positions.chin[0][0];
var eye_squish = map(this.eyeAngle, 0, 100, 50, 100);
var skin_color_value = int(map(this.skinColor, 0, 100, 2, 4.9));
var eye_color_value = int(map(this.eyeColor, 0, 100, 0, 5.9));
var eye_size = map(this.eyeSize, 0, 100, 0.7, 1.5);
var x = nose_pos[0];
var y = nose_pos[1];
var w = 2 * face_width;
var h = 2.5 * half_height;
var extent = 0;
if(h < w) {
extent = h / 2;
}
else {
extent = w / 2;
}
var size = extent / 220.0;
// head
stroke(0, 0, 0, 100);
fill(skinMidtone_color[skin_color_value]);
beginShape();
curveVertex(positions.left_eyebrow[0][0], positions.left_eyebrow[0][1]);
for(var i=0; i<positions.chin.length;i++) {
curveVertex(positions.chin[i][0], positions.chin[i][1]);
}
for(var i=positions.right_eyebrow.length-1; i>=0;i--) {
curveVertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
for(var i=positions.left_eyebrow.length-1; i>=0;i--) {
curveVertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
curveVertex(positions.chin[0][0], positions.chin[0][1]);
endShape(CLOSE);
/////////////////////////////////////////// mouth
//inner mouth
stroke(upperLip_color[skin_color_value+1]);
strokeWeight(0.005);
fill(teeth_color[skin_color_value]);
beginShape();
for(var i=0; i<positions.top_lip.length/2;i++) {
vertex(positions.top_lip[i][0], positions.top_lip[i][1]);
}
for(var i=0; i<6;i++) {
if (i!=3 && i!=9){
vertex(positions.bottom_lip[i][0], positions.bottom_lip[i][1]);
}
}
endShape(CLOSE);
//lips
fill(upperLip_color[skin_color_value]);
beginShape();
for(var i=0; i<positions.top_lip.length;i++) {
curveVertex(positions.top_lip[i][0], positions.top_lip[i][1]);
}
endShape(CLOSE);
fill(lowerLip_color[skin_color_value]);
beginShape();
for(var i=0; i<positions.bottom_lip.length;i++) {
if (i!=3 && i!=9){
curveVertex(positions.bottom_lip[i][0], positions.bottom_lip[i][1]);
}
}
endShape(CLOSE);
noStroke();
///////////////////////////////////////////left eye
eyeball_color = teeth_color[skin_color_value];
iris_color = eye_color[eye_color_value];
push();
scale(1.4);
translate(0.2, 0.4);
//eyeball
beginShape();
fill(eyeball_color)
for(var i=0; i<positions.left_eye.length;i++) {
curveVertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
endShape(CLOSE);
//eye center
push();
translate((eye1_pos[0]-0.1)+(this.lookPos/500), eye1_pos[1]-0.03);
scale(eye_squish/100, 1);
fill(iris_color);
ellipse(0, 0, 20 * size *eye_size, 20 * size*eye_size);
if (eye_color_value == 5){
fill(255, 144, 96, 20);
} else if (eye_color_value == 4){
fill(255, 183, 96, 20);
}else {
fill(230, 250, 200, 20);
}
for(var i=0; i<8;i++) {
ellipse(0, 0, (12+i) * size*eye_size, (12+i) * size*eye_size);
}
fill(pupil_color);
ellipse(0, 0, 8 * size*eye_size, 8 * size*eye_size);
pop();
//eye highlights
fill(255, 255, 255, 5);
for (var i=4; i>0;i-=0.02) {
ellipse((eye1_pos[0]-0.03), eye1_pos[1]-0.07, i * size, i* size)
}
push();
translate(eye1_pos[0], eye1_pos[1]);
rotate(-30);
for (var i=6; i>0;i-=0.02) {
ellipse(0, 0, i * (size/2), i*size);
}
pop();
//lower lid shadow
for(var j=0.04; j>0; j-= 0.02){
push();
translate(-0.02, -j);
scale(0.98, 1)
fill(0, 0, 0, (20/(j*30)));
beginShape();
curveVertex(positions.left_eye[0][0], positions.left_eye[0][1]);
for(var i=5; i>=3;i--) {
curveVertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
for(var i=3; i<=5;i++) {
curveVertex(positions.left_eye[i][0], (positions.left_eye[i][1])+0.1);
}
endShape(CLOSE);
pop();
}
//lower lid shape
beginShape();
fill(skinMidtone_color[skin_color_value]);
curveVertex(positions.left_eye[0][0], positions.left_eye[0][1]);
for(var i=5; i>=3;i--) {
curveVertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
for(var i=3; i<=5;i++) {
curveVertex(positions.left_eye[i][0], (positions.left_eye[i][1])+0.15);
}
endShape(CLOSE);
//eyelid shadow
for(var j=0.01; j<0.1; j+= 0.01){
push();
translate(-0.02, j);
scale(0.98, 1)
beginShape();
fill(0, 0, 0, (20/(j*20)));
curveVertex((positions.left_eye[0][0]), (positions.left_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.left_eye[i][1] + positions.left_eyebrow[i+1][1])/2.2);
var eyelid_value_x = ((positions.left_eye[i][0] + positions.left_eyebrow[i][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
for(var i=3; i>=0;i--) {
curveVertex((positions.left_eye[i][0]), (positions.left_eye[i][1]));
}
endShape(CLOSE);
pop();
}
//eyelid shape
beginShape();
fill(skinLowlight_color[skin_color_value]);
curveVertex((positions.left_eye[0][0]), (positions.left_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.left_eye[i][1] + positions.left_eyebrow[i+1][1])/2.2);
var eyelid_value_x = ((positions.left_eye[i][0] + positions.left_eyebrow[i][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
for(var i=3; i>=0;i--) {
curveVertex((positions.left_eye[i][0]), (positions.left_eye[i][1]));
}
endShape(CLOSE);
//browbone shape
beginShape();
fill(skinMidtone_color[skin_color_value]);
vertex((positions.left_eye[0][0]), (positions.left_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.left_eye[i][1] + positions.left_eyebrow[i+1][1])/2.2);
var eyelid_value_x = ((positions.left_eye[i][0] + positions.left_eyebrow[i][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
curveVertex((positions.left_eyebrow[4][0]+positions.left_eyebrow[3][0])/2.5, (positions.left_eyebrow[3][1]+0.2));
curveVertex((positions.left_eyebrow[1][0]+0.2), (positions.left_eyebrow[1][1])+0.1);
endShape(CLOSE);
pop();
//////////////////////////////////////////////////right eye
push();
scale(1.4);
translate(-0.2, 0.4);
//eyeball
beginShape();
fill(eyeball_color)
for(var i=0; i<positions.right_eye.length;i++) {
curveVertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
endShape(CLOSE);
push();
translate((eye2_pos[0]-0.1)+(this.lookPos/500), eye2_pos[1]-0.03);
scale(eye_squish/100, 1);
//iris
fill(iris_color);
ellipse(0, 0, 20 * size*eye_size, 20 * size*eye_size);
if (eye_color_value == 5){
fill(255, 144, 96, 20);
} else if (eye_color_value == 4){
fill(255, 183, 96, 20);
}else {
fill(230, 250, 200, 20);
}
for(var i=0; i<8;i++) {
ellipse(0, 0, (12+i) * size*eye_size, (12+i) * size*eye_size);
}
//pupil
fill(pupil_color);
ellipse(0, 0, 8 * size*eye_size, 8 * size*eye_size);
pop();
//eye highlights
fill(255, 255, 255, 5);
for (var i=4; i>0;i-=0.02) {
ellipse((eye2_pos[0]-0.1)+0.07, eye2_pos[1]-0.07, i * size, i* size)
}
push();
translate(eye2_pos[0], eye2_pos[1]);
rotate(-30);
for (var i=6; i>0;i-=0.01) {
ellipse(0, 0, i * (size/2), i*size);
}
pop();
//lower lid shadow
for(var j=0.04; j>0; j-= 0.02){
push();
translate(0.02, -j);
scale(0.98, 1)
fill(0, 0, 0, (20/(j*30)));
beginShape();
curveVertex(positions.right_eye[0][0], positions.right_eye[0][1]);
for(var i=5; i>=3;i--) {
curveVertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
for(var i=3; i<=5;i++) {
curveVertex(positions.right_eye[i][0], (positions.right_eye[i][1])+0.1);
}
endShape(CLOSE);
pop();
}
//lower lid shape
beginShape();
fill(skinMidtone_color[skin_color_value]);
curveVertex(positions.right_eye[0][0], positions.right_eye[0][1]);
for(var i=5; i>=3;i--) {
curveVertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
for(var i=3; i<=5;i++) {
curveVertex(positions.right_eye[i][0], (positions.right_eye[i][1])+0.15);
}
endShape(CLOSE);
//eyelid shadow
for(var j=0.01; j<0.1; j+= 0.02){
push();
translate(0.02, j);
scale(0.98, 1)
beginShape();
fill(0, 0, 0, (20/(j*20)));
curveVertex((positions.right_eye[0][0]), (positions.right_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.right_eye[i][1] + positions.right_eyebrow[i][1])/2.2);
var eyelid_value_x = ((positions.right_eye[i][0] + positions.right_eyebrow[i+1][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
for(var i=3; i>=0;i--) {
curveVertex((positions.right_eye[i][0]), (positions.right_eye[i][1]));
}
endShape(CLOSE);
endShape(CLOSE);
pop();
}
//eyelid shape
beginShape();
fill(skinLowlight_color[skin_color_value]);
curveVertex((positions.right_eye[0][0]), (positions.right_eye[0][1]));
for(var i=0; i<4;i++) {
var eyelid_value_y = ((positions.right_eye[i][1] + positions.right_eyebrow[i][1])/2.2);
var eyelid_value_x = ((positions.right_eye[i][0] + positions.right_eyebrow[i+1][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
for(var i=3; i>=0;i--) {
curveVertex((positions.right_eye[i][0]), (positions.right_eye[i][1]));
}
endShape(CLOSE);
//browbone shape
beginShape();
fill(skinMidtone_color[skin_color_value]);
for(var i=3; i>=0;i--) {
var eyelid_value_y = ((positions.right_eye[i][1] + positions.right_eyebrow[i][1])/2.2);
var eyelid_value_x = ((positions.right_eye[i][0] + positions.right_eyebrow[i+1][0])/2.3);
curveVertex((eyelid_value_x), (eyelid_value_y));
}
curveVertex((positions.right_eyebrow[0][0]+0.15), (positions.right_eyebrow[0][1])+0.1);
curveVertex((positions.right_eyebrow[1][0]+0.15), (positions.right_eyebrow[1][1])+0.1);
curveVertex((positions.right_eyebrow[2][0]+positions.right_eyebrow[3][0])/2.5, (positions.right_eyebrow[2][1]+0.15));
endShape(CLOSE);
pop();
////////////////////////////////////////eyebrows
//left eyebrow
var browScale = 0.2
for (var j=0; j<10; j++){
browScale-=0.02;
beginShape();
fill(0, 0, 0, 30);
for(var i=1; i<3;i++) {
vertex((positions.left_eyebrow[i+1][0]), (positions.left_eyebrow[i+1][1]+0.2));
}
vertex((positions.left_eyebrow[4][0]-browScale), (positions.left_eyebrow[4][1]+0.2)-(browScale/2));
vertex((positions.left_eyebrow[4][0]-browScale), (positions.left_eyebrow[4][1])-(browScale/2));
for(var i=3; i>=0;i--) {
if (i!=1){
vertex((positions.left_eyebrow[i][0]), (positions.left_eyebrow[i][1]));
}
}
endShape(CLOSE);
}
//right eyebrow
var browScale = 0
for (var j=0; j<10; j++){
browScale-=0.02;
beginShape();
vertex((positions.right_eyebrow[0][0]-browScale), (positions.right_eyebrow[0][1]+0.2)+(browScale/2));
for(var i=1; i<4;i++) {
vertex((positions.right_eyebrow[i-1][0]), (positions.right_eyebrow[i-1][1]+0.2));
}
for(var i=4; i>=0;i--) {
if (i!= 3){
vertex((positions.right_eyebrow[i][0]), (positions.right_eyebrow[i][1]));
}
}
vertex((positions.right_eyebrow[0][0]-browScale), (positions.right_eyebrow[0][1])+(browScale/2));
endShape(CLOSE);
}
////////////////////////////////////////////// nose
//bottom of nose
beginShape();
fill(skinShadow_color[skin_color_value]);
stroke(0, 0, 0, 80)
strokeWeight(0.02);
vertex(positions.nose_tip[positions.nose_tip.length-1][0], positions.nose_tip[positions.nose_tip.length-1][1]);
vertex(positions.nose_bridge[positions.nose_bridge.length-1][0], positions.nose_bridge[positions.nose_bridge.length-1][1]);
for(var i=0; i<positions.nose_tip.length;i++) {
vertex(positions.nose_tip[i][0], positions.nose_tip[i][1]);
}
vertex(positions.nose_bridge[positions.nose_bridge.length-1][0], positions.nose_bridge[positions.nose_bridge.length-1][1]);
endShape(CLOSE);
//nose bridge
noStroke();
fill(skinMidtone_color[skin_color_value]);
beginShape();
vertex(((positions.nose_bridge[0][0]+positions.right_eye[4][0])/2)-0.3, positions.nose_bridge[0][1]);
vertex(((positions.nose_bridge[0][0]+positions.left_eye[4][0])/2)+0.3, positions.nose_bridge[0][1]);
vertex(positions.nose_tip[0][0], positions.nose_tip[0][1]);
vertex(positions.nose_tip[2][0], positions.nose_bridge[positions.nose_bridge.length-1][1]+0.3);
vertex(positions.nose_tip[4][0], positions.nose_tip[4][1]);
endShape(CLOSE);
fill(noseColor[skin_color_value]);
var noseWidth = 0;
for (var j=0; j<20; j++){
noseWidth+=0.02
beginShape();
vertex(((positions.nose_bridge[0][0]+positions.right_eye[4][0])/2)-0.3, positions.nose_bridge[0][1]+noseWidth);
vertex(((positions.nose_bridge[0][0]+positions.left_eye[4][0])/2)+0.3, positions.nose_bridge[0][1]+noseWidth);
vertex(positions.nose_tip[0][0]+noseWidth, positions.nose_tip[0][1]);
vertex(positions.nose_tip[2][0], positions.nose_bridge[positions.nose_bridge.length-1][1]+0.3);
vertex(positions.nose_tip[4][0]-noseWidth, positions.nose_tip[4][1]);
endShape(CLOSE);
}
//nose highlight
fill(noseHighlight[skin_color_value]);
var highlightWidth = 0.2;
for (var j=0; j<20; j++){
highlightWidth -= 0.01;
beginShape();
vertex(((positions.nose_bridge[1][0]+positions.right_eye[4][0])/2)-0.4, positions.nose_bridge[1][1]+highlightWidth);
vertex(((positions.nose_bridge[1][0]+positions.left_eye[4][0])/2)+0.4, positions.nose_bridge[1][1]+highlightWidth);
vertex(positions.nose_tip[1][0]+highlightWidth, positions.nose_bridge[positions.nose_bridge.length-1][1]+0.2);
vertex(positions.nose_tip[2][0], positions.nose_bridge[positions.nose_bridge.length-1][1]+0.3);
vertex(positions.nose_tip[3][0]-highlightWidth, positions.nose_bridge[positions.nose_bridge.length-1][1]+0.2);
endShape(CLOSE);
}
}
/*// set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.lookPos = settings[0];
this.eyeAngle = settings[1];
this.skinColor = settings[2];
this.eyeColor = settings[3];
this.eyeSize = settings[4];
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
properties = new Array(4);
properties[0] = this.lookPos;
properties[1] = this.eyeAngle;
properties[2] = this.skinColor;
properties[3] = this.eyeColor;
properties[4] = this.eyeSize;
return properties;
}
}
// given a point, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
100,
90,
14,
100,
47
],
"000002": [
44,
72,
0,
66,
42
],
"000058": [
75,
100,
0,
0,
31
],
"000005": [
50,
100,
23,
61,
30
],
"000006": [
64,
84,
51,
100,
36
],
"000007": [
50,
100,
39,
72,
23
],
"000009": [
8,
100,
24,
64,
34
],
"000010": [
50,
100,
19,
0,
73
],
"000013": [
76,
82,
11,
0,
28
],
"000014": [
21,
100,
69,
100,
42
],
"000015": [
36,
84,
20,
23,
0
],
"000016": [
100,
100,
23,
76,
30
],
"000018": [
17,
100,
0,
26,
20
],
"000020": [
73,
100,
21,
15,
9
],
"000023": [
100,
72,
28,
0,
33
],
"000025": [
58,
100,
50,
54,
23
],
"000028": [
50,
100,
32,
86,
71
],
"000029": [
36,
100,
19,
0,
31
],
"000030": [
9,
100,
50,
80,
50
],
"000031": [
50,
100,
23,
0,
6
],
"000032": [
58,
92,
9,
59,
23
],
"000035": [
44,
100,
0,
58,
31
],
"000037": [
65,
62,
50,
100,
50
],
"000038": [
50,
100,
0,
0,
12
],
"000040": [
50,
100,
26,
71,
47
],
"000041": [
28,
38,
50,
75,
64
],
"000042": [
31,
100,
0,
0,
43
],
"000043": [
37,
100,
0,
57,
44
],
"000044": [
45,
100,
69,
100,
65
],
"000045": [
59,
100,
32,
75,
57
],
"000047": [
90,
100,
38,
80,
74
],
"000048": [
82,
100,
0,
80,
38
],
"000050": [
39,
69,
25,
75,
38
],
"000051": [
73,
100,
23,
100,
32
],
"000052": [
62,
100,
0,
0,
37
],
"000054": [
23,
100,
24,
0,
64
],
"000055": [
37,
84,
22,
60,
31
],
"000056": [
29,
90,
20,
0,
38
],
"000060": [
65,
62,
50,
100,
43
],
"000064": [
48,
96,
21,
22,
29
],
"000065": [
49,
100,
38,
70,
50
],
"000068": [
25,
100,
14,
76,
21
],
"000069": [
45,
100,
25,
65,
22
],
"000071": [
50,
100,
23,
61,
45
],
"000073": [
29,
61,
23,
29,
61
],
"000076": [
4,
100,
21,
78,
26
],
"000077": [
100,
79,
0,
0,
74
],
"000078": [
7,
100,
31,
100,
60
],
"000079": [
85,
100,
40,
82,
40
],
"000080": [
26,
100,
21,
24,
36
],
"000081": [
51,
82,
37,
77,
23
],
"000083": [
43,
100,
27,
55,
20
],
"000085": [
52,
100,
24,
32,
88
],
"000086": [
8,
100,
31,
63,
59
],
"000088": [
90,
94,
23,
89,
63
],
"000091": [
54,
88,
11,
20,
44
],
"000092": [
17,
100,
10,
25,
45
],
"000096": [
33,
100,
16,
15,
53
],
"000097": [
57,
100,
30,
0,
62
],
"000099": [
27,
100,
0,
26,
50
],
"000100": [
58,
77,
27,
72,
58
],
"000103": [
27,
100,
18,
30,
49
],
"000104": [
36,
100,
32,
19,
37
],
"000106": [
9,
100,
50,
63,
80
],
"000108": [
43,
100,
21,
0,
45
],
"000109": [
66,
100,
29,
24,
33
],
"000110": [
27,
87,
27,
54,
100
],
"000111": [
83,
100,
35,
22,
70
],
"000114": [
44,
100,
30,
80,
46
],
"000115": [
60,
82,
30,
56,
22
],
"000116": [
45,
100,
26,
80,
31
],
"000117": [
64,
89,
71,
94,
71
],
"000118": [
17,
100,
37,
98,
79
],
"000121": [
48,
100,
16,
100,
55
],
"000122": [
43,
91,
27,
57,
55
],
"000125": [
50,
100,
30,
20,
36
],
"000126": [
79,
100,
14,
0,
86
],
"000129": [
72,
97,
34,
27,
31
],
"000131": [
100,
100,
16,
100,
66
],
"000132": [
52,
100,
48,
87,
67
],
"000133": [
48,
100,
19,
26,
57
],
"000134": [
21,
69,
79,
85,
48
],
"000135": [
96,
79,
38,
100,
70
],
"000137": [
80,
93,
19,
66,
17
],
"000140": [
29,
100,
30,
0,
59
],
"000142": [
38,
96,
25,
27,
41
],
"000143": [
66,
100,
24,
2,
43
],
"000145": [
46,
100,
7,
72,
68
],
"000146": [
45,
56,
37,
100,
34
],
"000147": [
67,
100,
10,
0,
66
],
"000148": [
75,
47,
10,
28,
37
],
"000150": [
40,
100,
19,
11,
39
],
"000151": [
34,
100,
38,
100,
48
],
"000152": [
41,
94,
25,
57,
23
],
"000153": [
44,
98,
17,
68,
33
],
"000155": [
50,
100,
29,
100,
88
],
"000156": [
50,
75,
24,
49,
74
],
"000160": [
40,
100,
26,
70,
36
],
"000161": [
45,
100,
14,
23,
34
],
"000157": [
50,
100,
50,
50,
71
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// other variables can be in here too
// these control the colors used
function FelizardoFace() {
const bg_color = [225, 206, 187];
const fg_color = [151, 102, 52];
const stroke_color = [95, 52, 8];
// these are state variables for a face
// (your variables may be different)
this.tilt_value = 0;
this.mouth_value = 1;
this.eye_size = 0;
this.eyelid = 0;
this.mouth_open = 1;
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
colorMode(HSL, 360, 100, 100, 1);
//head
let head_location = average_point(positions.chin)
//eyes
let eye_L = average_point(positions.left_eye)
let eye_R = average_point(positions.right_eye)
//mouth points
//*top
let m_left = positions.top_lip[0];
let m_m_left = positions.top_lip[1];
let m_top = positions.top_lip[3];
let m_m_right = positions.top_lip[5]
let m_right = positions.top_lip[6];
let m_bot = positions.bottom_lip[9];
//bottom
let m_b1 = positions.bottom_lip[0];
let m_b2 = positions.bottom_lip[1];
let m_b3 = positions.bottom_lip[4];
let m_b4 = positions.bottom_lip[6];
//mouth pts for teeth
let m_teeth = positions.top_lip[10];
let m_teeth2 = positions.top_lip[8];
let m_teeth3 = positions.top_lip[7];
let m_teeth4 = positions.top_lip[11];
//brow points
let b_r1 = positions.right_eyebrow[0];
let b_r2 = positions.right_eyebrow[4];
let b_l1 = positions.left_eyebrow[0];
let b_l2 = positions.left_eyebrow[4];
//cheek pts
let ch_1 = positions.chin[2];
let ch_2 = positions.chin[14];
//CHIN PTS
let b_ch_1 = positions.chin[5];
let b_ch_2 = positions.chin[7];
let b_ch_3 = positions.chin[8];
let b_ch_4 = positions.chin[9];
let b_ch_5 = positions.chin[11];
//*******************************************************************************
//********************** E Y E S ************************************
//*******************************************************************************
//**************** e y e s h a p e **************************
noStroke();
fill(255);
ellipse(eye_L[0], eye_L[1], .9 * this.eye_size, .9 * this.eye_size);
ellipse(eye_R[0], eye_R[1], .9 * this.eye_size, .9 * this.eye_size);
//**************** e y e c o l o u r **************************
//******cornea
fill(1 * this.eye_colour, 75, 50, 1); // eye colour
ellipse(eye_L[0], eye_L[1], .6 * this.eye_size, .6 * this.eye_size);
ellipse(eye_R[0], eye_R[1], .6 * this.eye_size, .6 * this.eye_size);
//********* iris
fill(0);
ellipse(eye_L[0], eye_L[1], .2 * this.eye_size, .2 * this.eye_size);
ellipse(eye_R[0], eye_R[1], .2 * this.eye_size, .2 * this.eye_size);
//************* e y e l i d s *******************
//********** SURPRISED
if (this.eyelid == 0) {
fill(0);
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, 15, 165, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, 15, 165, CHORD);
}
//*********** MELLOW
if (this.eyelid == 1) {
fill(0);
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, -180, 0, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, -180, 0, CHORD);
}
//*********** ANGRY
if (this.eyelid == 2) {
fill(0);
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, -150, 20, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, 160, -30, CHORD);
//lower lids
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, -150, 20, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, 160, -30, CHORD);
}
//*********** SCHLEEP
if (this.eyelid == 3) {
fill(0);
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, -180, 0, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, -180, 0, CHORD);
//lower lids
arc(eye_L[0], eye_L[1], 1 * this.eye_size, 1 * this.eye_size, 20, 160, CHORD);
arc(eye_R[0], eye_R[1], 1 * this.eye_size, 1 * this.eye_size, 20, 160, CHORD);
}
//*******************************************************************************
//********************** C H I N ******************************
//*******************************************************************************
stroke(0);
strokeWeight(.02);
line(b_ch_2[0], b_ch_2[1], ch_1[0], ch_1[1]); //cheek to jaw connector
line(b_ch_4[0], b_ch_4[1], ch_2[0], ch_2[1]);
fill(20, 0, this.skin);
noStroke();
beginShape();
vertex(b_ch_1[0], b_ch_1[1]);
vertex(b_ch_2[0], b_ch_2[1] + 1 * this.chin);
vertex(b_ch_3[0], b_ch_3[1] + 1 * this.chin);
vertex(b_ch_4[0], b_ch_4[1] + 1 * this.chin);
vertex(b_ch_5[0], b_ch_5[1]);
endShape();
fill(0);
ellipse(b_ch_2[0], b_ch_2[1] - .08, .07, .07); //peg
ellipse(b_ch_4[0], b_ch_4[1] - .08, .07, .07);
//*******************************************************************************
//********************** M O U T H **************************
//*******************************************************************************
//********** bottom lip *check if working properly.
//cheek pivot
fill(0);
ellipse(ch_2[0], ch_2[1], .2, .2);
ellipse(ch_1[0], ch_1[1], .2, .2);
//cheek wires
strokeWeight(.02);
stroke(0);
noFill();
line(ch_2[0], ch_2[1], m_b1[0], m_b1[1]);
line(ch_2[0], ch_2[1], m_b1[0], (m_b1[1] * this.mouth_open) + .05);
line(ch_1[0], ch_1[1], m_b4[0], m_b4[1]);
line(ch_1[0], ch_1[1], m_b4[0], (m_b4[1] * this.mouth_open) + .05);
stroke(360, 70, 60, 1); //bottom lip colour
strokeWeight(.4);
noFill();
bezier(m_b1[0], m_b1[1], m_b2[0], m_b2[1] * this.mouth_open, m_b3[0], m_b3[1] * this.mouth_open, m_b4[0], m_b4[1]);
//********** top_lip
noFill();
strokeWeight(.5);
stroke(360, 100, 60, 1); //thick top lip colour
bezier(m_left[0], m_left[1], m_m_left[0], m_m_left[1] - .2, m_m_right[0], m_m_right[1] - .2, m_right[0], m_right[1]);
strokeWeight(.3);
stroke(360, 100, 40, 1); //top lip shade
bezier(m_left[0], m_left[1] + .1, m_m_left[0], m_m_left[1], m_m_right[0], m_m_right[1], m_right[0], m_right[1] + .1);
//************* top teeth
fill(225);
noStroke();
arc(m_teeth3[0], m_teeth3[1], .45 * .5, .7 * .5, 15 + 20, 165, CHORD); //right back
arc(m_teeth3[0] - .2, m_teeth3[1], .45 * .5, .7 * .5, 15, 165, CHORD); //right back 2
arc(m_teeth4[0], m_teeth4[1], .45 * .5, .7 * .5, 15 - 20, 165 - 10, CHORD); //left back
arc(m_teeth4[0] + .2, m_teeth4[1], .45 * .5, .7 * .5, 15, 165, CHORD); //left back 2
fill(255);
arc(m_teeth[0], m_teeth[1] - .15, .45, .7, 15, 165, CHORD);
arc(m_teeth2[0], m_teeth2[1] - .15, .45, .7, 15, 165, CHORD);
//*******************************************************************************
//********************** M or F **************************************
//*******************************************************************************
if (this.horn == 0) {
fill(100, 0, 50);
ellipse(head_location[0], head_location[1] - 3.29, .5, .25);
fill(20, 0, this.skin);
ellipse(head_location[0], head_location[1] - 3.31, .5, .2);
stroke(200, 0, this.skin - 10);
strokeWeight(.1);
line(head_location[0], head_location[1] - 3.4, head_location[0], head_location[1] - 4.5)
noStroke(0);
fill(20, 0, this.skin + 10);
ellipse(head_location[0], head_location[1] - 4.5, .3, .3);
}
//*******************************************************************************
//********************** B R O W S **************************
//*******************************************************************************
//eyebrow background mechanics
fill(0);
strokeWeight(.02);
stroke(0);
ellipse(head_location[0], head_location[1] - 3, .2, .2);
line(head_location[0], head_location[1] - 3, b_l1[0] * .8, b_l1[1] * 1.4 * this.eyebrows);
line(head_location[0], head_location[1] - 3, b_l2[0] * .8, b_l2[1] * 1.1 * this.eyebrows);
line(head_location[0], head_location[1] - 3, b_r1[0] * .8, b_r1[1] * 1.1 * this.eyebrows);
line(head_location[0], head_location[1] - 3, b_r2[0] * .8, b_r2[1] * 1.4 * this.eyebrows);
strokeWeight(.55);
stroke(20, 0, this.skin);
line(b_l1[0] * .8, b_l1[1] * 1.4 * this.eyebrows, b_l2[0] * .8, b_l2[1] * 1.1 * this.eyebrows); // left eyebrow
line(b_r1[0] * .8, b_r1[1] * 1.1 * this.eyebrows, b_r2[0] * .8, b_r2[1] * 1.4 * this.eyebrows); // right eyebrow
fill(0)
noStroke();
ellipse(b_l1[0] * .8, b_l1[1] * 1.4 * this.eyebrows, .06, .06);
ellipse(b_l2[0] * .8, b_l2[1] * 1.1 * this.eyebrows, .06, .06);
ellipse(b_r1[0] * .8, b_r1[1] * 1.1 * this.eyebrows, .06, .06);
ellipse(b_r2[0] * .8, b_r2[1] * 1.4 * this.eyebrows, .06, .06);
//*******************************************************************************
//*******************************************************************************
//*******************************************************************************
}
/* set internal properties based on list numbers 0-100 */
//put all slider elements here first
this.setProperties = function(settings) {
this.eye_size = map(settings[0], 0, 100, .9, 1.1);
this.eyelid = int(map(settings[1], 0, 100, 0, 4));
this.eyebrows = map(settings[2], 0, 100, .9, 1.1);
this.mouth_open = map(settings[4], 0, 100, 1, 1.5);
this.eye_colour = map(settings[3], 0, 100, 1, 359);
this.horn = int(map(settings[5], 0, 100, 0, 1));
this.skin = map(settings[6], 0, 100, 100, 50);
this.chin = map(settings[7], 0, 100, 0, 1);
}
/* get internal properties as list of numbers 0-100 */
//then wire them up here in this order (flip it round)
this.getProperties = function() {
let settings = new Array(8);
settings[0] = map(this.eye_size, .9, 1.1, 0, 100);
settings[1] = map(this.eyelid, 0, 4, 0, 100);
settings[2] = map(this.eyebrows, 1, 1.5, 0, 100);
settings[4] = map(this.mouth_open, 1, 1.5, 0, 100);
settings[3] = map(this.eye_colour, 1, 359, 0, 100);
settings[5] = map(this.horn, 0, 1, 0, 100);
settings[6] = map(this.skin, 100, 50, 0, 100);
settings[7] = map(this.chin, 0, 1, 0, 100);
return settings;
}
}
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for (var i = 0; i < list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
24,
56,
-12,
27,
42,
100,
69,
1
],
"000002": [
50.999999999999964,
0,
-19.999999999999996,
0,
33.00000000000001,
100,
100,
12
],
"000058": [
51.99999999999997,
75,
-14.79999999999999,
56.00000000000001,
29.000000000000004,
100,
81,
2
],
"000005": [
49.99999999999997,
50,
-19.999999999999996,
28.000000000000004,
10.999999999999988,
100,
76,
32
],
"000006": [
48.99999999999997,
50,
-19.999999999999996,
91,
50,
100,
50,
26
],
"000007": [
49.99999999999997,
25,
-19.999999999999996,
70,
22.00000000000002,
0,
73,
50
],
"000009": [
49.99999999999997,
50,
-19.999999999999996,
0,
78.00000000000003,
100,
63,
0
],
"000010": [
49.99999999999997,
50,
-19.999999999999996,
16,
50,
100,
62,
24
],
"000013": [
49.99999999999997,
0,
-14.399999999999991,
18,
50,
0,
50,
50
],
"000014": [
49.99999999999997,
50,
-19.999999999999996,
65,
50,
100,
32,
50
],
"000015": [
0,
75,
-19.999999999999996,
97,
100,
0,
82,
38
],
"000016": [
49.99999999999997,
50,
-19.999999999999996,
96,
50,
0,
56.00000000000001,
22
],
"000018": [
0,
75,
-19.999999999999996,
17,
18.000000000000014,
100,
77,
2
],
"000020": [
8.000000000000004,
75,
-19.999999999999996,
92,
100,
0,
67,
34
],
"000028": [
0,
50,
-19.999999999999996,
22,
50,
100,
50,
3
],
"000023": [
0,
50,
-15.199999999999992,
90,
50,
0,
87,
20
],
"000025": [
0,
50,
-19.999999999999996,
89,
50,
0,
42,
0
],
"000029": [
0,
75,
-11.99999999999999,
20,
29.000000000000004,
100,
86,
26
],
"000030": [
100,
100,
11.20000000000001,
51,
8.000000000000007,
0,
70,
19
],
"000031": [
15.000000000000007,
75,
-15.999999999999993,
30,
50,
100,
32,
64
],
"000032": [
0,
25,
20.000000000000018,
98,
89.00000000000001,
0,
63,
48
],
"000035": [
100,
100,
-19.999999999999996,
69,
45.000000000000014,
100,
100,
13
],
"000037": [
61.99999999999998,
50,
-19.999999999999996,
75,
41.99999999999999,
0,
31,
60
],
"000038": [
100,
0,
20.000000000000018,
86,
37.999999999999986,
0,
75,
31
],
"000040": [
49.99999999999997,
50,
10.000000000000009,
67,
54,
100,
82,
0
],
"000041": [
70.99999999999999,
0,
20.000000000000018,
69,
50.99999999999998,
0,
59,
45
],
"000042": [
100,
100,
8.000000000000007,
8,
50,
100,
62,
0
],
"000043": [
48.99999999999997,
100,
15.600000000000014,
56.00000000000001,
23,
100,
69,
0
],
"000044": [
100,
25,
0,
66,
14.000000000000012,
100,
20,
18
],
"000045": [
22.00000000000001,
0,
4.400000000000004,
11,
46,
100,
66,
9
],
"000047": [
49.99999999999997,
50,
0,
68,
50,
100,
28.999999999999996,
0
],
"000048": [
100,
75,
1.200000000000001,
61,
43.000000000000014,
0,
100,
57.99999999999999
],
"000050": [
100,
100,
20.000000000000018,
70,
98,
0,
73,
83
],
"000051": [
49.99999999999997,
0,
-16.39999999999999,
46,
50,
0,
57.99999999999999,
0
],
"000052": [
55.99999999999997,
25,
12.800000000000011,
71,
58.999999999999986,
0,
56.00000000000001,
46
],
"000054": [
100,
75,
20.000000000000018,
25,
66.00000000000001,
100,
61,
0
],
"000055": [
100,
25,
2.400000000000002,
72,
39.000000000000014,
0,
70,
44
],
"000056": [
100,
25,
4.800000000000004,
65,
62.000000000000014,
0,
80,
0
],
"000060": [
19.00000000000001,
100,
-19.999999999999996,
67,
100,
0,
11,
36
],
"000064": [
0,
0,
4.800000000000004,
88,
69,
0,
63,
32
],
"000065": [
0,
25,
-5.999999999999983,
64,
41.99999999999999,
0,
28.000000000000004,
23
],
"000068": [
97,
25,
18.000000000000014,
40,
79.99999999999999,
0,
22,
37
],
"000069": [
100,
100,
20.000000000000018,
69,
100,
0,
67,
44
],
"000071": [
62.99999999999998,
0,
-19.199999999999996,
23,
50,
100,
72,
0
],
"000073": [
100,
75,
-6.799999999999984,
67,
66.00000000000001,
100,
70,
0
],
"000076": [
100,
75,
20.000000000000018,
74,
81.99999999999999,
0,
65,
55.00000000000001
],
"000077": [
49.99999999999997,
75,
-7.999999999999985,
60,
25.99999999999998,
100,
71,
0
],
"000078": [
100,
75,
5.200000000000005,
74,
64.99999999999999,
100,
77,
18
],
"000079": [
15.000000000000007,
100,
10.000000000000009,
46,
50,
0,
33,
30
],
"000080": [
100,
25,
6.000000000000005,
72,
23,
0,
57.99999999999999,
26
],
"000081": [
100,
0,
12.400000000000011,
65,
50.99999999999998,
0,
77,
50
],
"000083": [
100,
75,
10.80000000000001,
0,
50,
100,
91,
0
],
"000085": [
93,
100,
12.00000000000001,
0,
22.00000000000002,
100,
74,
0
],
"000086": [
100,
75,
18.400000000000016,
0,
62.000000000000014,
100,
88,
0
],
"000088": [
0,
100,
3.600000000000003,
79,
20.999999999999996,
100,
100,
0
],
"000091": [
49.99999999999997,
50,
14.400000000000013,
70,
25.99999999999998,
0,
64,
23
],
"000092": [
12.000000000000007,
0,
15.200000000000014,
23,
50,
100,
50,
0
],
"000096": [
57.99999999999997,
25,
10.40000000000001,
91,
69,
100,
26,
0
],
"000097": [
69.99999999999999,
75,
8.800000000000008,
40,
14.999999999999991,
100,
50,
0
],
"000099": [
100,
75,
20.000000000000018,
87,
52,
100,
60,
23
],
"000100": [
100,
100,
5.600000000000005,
28.000000000000004,
37.000000000000014,
100,
81,
0
],
"000103": [
51.99999999999997,
50,
0,
66,
50,
100,
50,
0
],
"000104": [
100,
75,
2.8000000000000025,
85,
33.00000000000001,
0,
50,
50
],
"000106": [
93,
0,
20.000000000000018,
90,
66.00000000000001,
100,
30,
0
],
"000108": [
49.99999999999997,
50,
-8.399999999999984,
20,
50,
100,
73,
0
],
"000109": [
49.99999999999997,
100,
8.400000000000007,
74,
49.00000000000002,
0,
54,
27
],
"000110": [
100,
75,
1.200000000000001,
91,
58.00000000000001,
100,
76,
0
],
"000111": [
100,
75,
20.000000000000018,
33,
69,
100,
0,
0
],
"000114": [
49.99999999999997,
50,
0,
71,
50,
0,
50,
50
],
"000115": [
49.99999999999997,
50,
0,
46,
0,
0,
50,
50
],
"000116": [
100,
100,
0,
68,
50,
0,
79,
36
],
"000117": [
100,
25,
-15.59999999999999,
73,
35.00000000000001,
100,
0,
0
],
"000118": [
49.99999999999997,
50,
9.200000000000008,
69,
50,
100,
33,
2
],
"000121": [
49.99999999999997,
0,
0,
62,
50,
100,
50,
0
],
"000122": [
100,
25,
2.0000000000000018,
42,
75,
100,
100,
0
],
"000125": [
96,
0,
20.000000000000018,
53,
60.999999999999986,
0,
43,
27
],
"000126": [
49.99999999999997,
50,
0,
50,
50,
100,
76,
0
],
"000129": [
49.99999999999997,
50,
0.40000000000000036,
62,
24.00000000000002,
0,
73,
43
],
"000131": [
100,
75,
6.000000000000005,
72,
54,
100,
26,
0
],
"000132": [
100,
75,
7.600000000000007,
71,
41.99999999999999,
100,
0,
0
],
"000133": [
92,
75,
17.200000000000017,
22,
28.000000000000025,
100,
33,
0
],
"000134": [
49.99999999999997,
50,
7.200000000000006,
65,
41.000000000000014,
0,
0,
50
],
"000135": [
100,
0,
0,
63,
10.999999999999988,
0,
24,
37
],
"000137": [
0,
75,
-7.5999999999999845,
46,
29.000000000000004,
0,
85,
17
],
"000140": [
100,
100,
-2.39999999999998,
22,
20.999999999999996,
100,
100,
0
],
"000142": [
88.99999999999999,
75,
4.400000000000004,
90,
56.999999999999986,
100,
100,
0
],
"000143": [
100,
25,
20.000000000000018,
86,
69,
0,
50,
35
],
"000145": [
100,
75,
20.000000000000018,
76,
50,
100,
75,
0
],
"000146": [
93,
100,
20.000000000000018,
89,
37.000000000000014,
100,
67,
0
],
"000147": [
94,
100,
20.000000000000018,
50,
50,
100,
67,
0
],
"000148": [
100,
75,
5.200000000000005,
76,
62.999999999999986,
100,
67,
2
],
"000150": [
49.99999999999997,
50,
0,
100,
28.000000000000025,
0,
100,
14.000000000000002
],
"000151": [
0,
100,
14.000000000000012,
68,
50,
100,
79,
0
],
"000152": [
100,
75,
7.200000000000006,
71,
50,
0,
92,
40
],
"000153": [
49.99999999999997,
50,
0,
85,
50,
0,
83,
36
],
"000155": [
93,
100,
12.800000000000011,
0,
49.00000000000002,
100,
65,
0
],
"000156": [
100,
100,
20.000000000000018,
26,
33.00000000000001,
100,
74,
0
],
"000157": [
49.99999999999997,
75,
6.000000000000005,
16,
23,
100,
81,
0
],
"000160": [
49.99999999999997,
50,
0,
69,
25.99999999999998,
0,
79,
83
],
"000161": [
100,
75,
8.000000000000007,
70,
33.999999999999986,
100,
93,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 8;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function HillFace() {
const eye_position = 0.85;
const eye_size1 = 0.6;
const eye_size2 = 0.8;
const pupil_size1 = 0.25;
const pupil_size2 = 0.25;
const rect_height = 4;
const rect_width = 3.5;
const mouth_wide = 1.25;
//BAG COLOURS//
const bag_light = [209, 182, 150];
const bag_mid = [187, 145, 100];
const bag_dark = [144, 102, 73];
const side_shadow_light = [163, 138, 107];
const side_shadow_mid = [140, 109, 75];
const side_shadow_dark = [108, 77, 55];
const top_shadow_light = [182, 158, 129];
const top_shadow_mid = [164, 127, 88];
const top_shadow_dark = [126, 89, 64];
this.eye_value = 2; //1-2
this.eye_brow = 2; //1-2
this.nose_value = 1; //1-2
this.bag_colour = 1; //1-3
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
rectMode(CENTER);
scale(1.5);
noStroke();
///HEAD//////
//front
let face_pos = segment_average(positions.chin);
if (this.bag_colour == 1) {
fill(bag_light);
}
else if (this.bag_colour == 2) {
fill(bag_mid);
}
else if (this.bag_colour == 3) {
fill(bag_dark);
}
rect(0, -0.25, rect_width, rect_height);
//pointy detail
triangle(-1.75, 1.74, -1.75, 2.25, -1.25, 1.74);
push();
triangle(-0.6, 1.74, -0.95, 2.25, -1.3, 1.74);
translate(0.5, 0);
triangle(-0.4, 1.74, -0.75, 2.25, -1.1, 1.74);
translate(0.7, 0);
triangle(-0.4, 1.74, -0.75, 2.25, -1.1, 1.74);
translate(0.6, 0);
triangle(-0.4, 1.74, -0.75, 2.25, -1.1, 1.74);
pop();
triangle(1.25, 1.74, 1.75, 2.25, 1.75, 1.74);
//top
if (this.bag_colour == 1) {
fill(top_shadow_light);
}
else if (this.bag_colour == 2) {
fill(top_shadow_mid);
}
else if (this.bag_colour == 3) {
fill(top_shadow_dark);
}
quad(-2.5, -2.5, -1.75, -2.25, 1.75, -2.25, 1, -2.5);
//side
if (this.bag_colour == 1) {
fill(side_shadow_light);
}
else if (this.bag_colour == 2) {
fill(side_shadow_mid);
}
else if (this.bag_colour == 3) {
fill(side_shadow_dark);
}
quad(-2.5, 1.25, -2.5, -2.5, -1.75, -2.25, -1.75, 1.75);
triangle(-1.75, 1.7, -1.75, 2.25, -2.25, 1.4);
triangle(-2.5, 1.9, -2.5, 1.25, -2, 1.4);
noFill();
stroke(0);
strokeWeight(0.06);
///NOSE//////
let nose_top = positions.nose_bridge[1];
let nose_bottom = positions.nose_bridge[3];
let nose_center = positions.nose_tip[2];
if (this.nose_value == 1) {
line(nose_top[0], nose_top[1], nose_bottom[0], nose_bottom[1]);
line(nose_top[0] - 0.02, nose_top[1], nose_bottom[0], nose_bottom[1]);
arc(nose_center[0], nose_center[1], 0.5, 0.5, 0, 180);
arc(nose_center[0], nose_center[1], 0.5, 0.55, 0, 180);
}
else if (this.nose_value == 2) {
arc(nose_center[0], nose_center[1], 0.5, 0.5, 0, 180);
arc(nose_center[0], nose_center[1], 0.5, 0.55, 0, 180);
}
///MOUTH/////
let mouth_pos = segment_average(positions.bottom_lip);
let lip_top = positions. top_lip[9];
let lip_bottom = positions. bottom_lip[9];
let d = dist(lip_top[0], lip_top[1], lip_bottom[0], lip_bottom[1]);
let mouth = map(d, 0, 1, 0, 10);
let mouth_open = map(mouth, 0, 10, 0, 1);
if (d < 0.2) {
d = 0;
}
ellipse(mouth_pos[0], mouth_pos[1] + 0.1, mouth_wide, mouth_open);
ellipse(mouth_pos[0], mouth_pos[1] + 0.1, mouth_wide, mouth_open + 0.05);
///EYEBROWS/////
let left_eyebrow_pos = segment_average(positions.left_eyebrow);
let right_eyebrow_pos = segment_average(positions.right_eyebrow);
if (this.eye_brow == 1) {
rect(left_eyebrow_pos[0], left_eyebrow_pos[1], 0.7, 0.01);
rect(right_eyebrow_pos[0], right_eyebrow_pos[1], 0.7, 0.01);
}
else if (this.eye_brow == 2) {
fill(0);
rect(left_eyebrow_pos[0], left_eyebrow_pos[1], 0.5, 0.06);
rect(right_eyebrow_pos[0], right_eyebrow_pos[1], 0.5, 0.06);
}
///EYES//////
noFill();
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
if (this.eye_value == 1) {
ellipse(left_eye_pos[0], left_eye_pos[1], eye_size1 - 0.1, eye_size1);
ellipse(right_eye_pos[0], right_eye_pos[1], eye_size1 - 0.1, eye_size1);
ellipse(left_eye_pos[0], left_eye_pos[1], eye_size1 - 0.1, eye_size1 + 0.05);
ellipse(right_eye_pos[0], right_eye_pos[1], eye_size1 - 0.1, eye_size1 + 0.05);
fill(0);
ellipse(left_eye_pos[0], left_eye_pos[1], pupil_size1);
ellipse(right_eye_pos[0], right_eye_pos[1], pupil_size1);
}
else if (this.eye_value == 2) {
arc(left_eye_pos[0], left_eye_pos[1], eye_size2 - 0.2, eye_size2, 0, 180, CHORD);
arc(right_eye_pos[0], right_eye_pos[1], eye_size2 - 0.2, eye_size2, 0, 180, CHORD);
arc(left_eye_pos[0], left_eye_pos[1], eye_size2 - 0.2, eye_size2 + 0.05, 0, 180, CHORD);
arc(right_eye_pos[0], right_eye_pos[1], eye_size2 - 0.2, eye_size2 + 0.05, 0, 180, CHORD);
fill(0);
ellipse(left_eye_pos[0], left_eye_pos[1] + 0.15, pupil_size2);
ellipse(right_eye_pos[0], right_eye_pos[1] + 0.15, pupil_size2);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.eye_value = int(map(settings[0], 0, 100, 1, 2));
this.eye_brow = int(map(settings[1], 0, 100, 1, 2));
this.nose_value = int(map(settings[2], 0, 100, 1, 2));
this.bag_colour = int(map(settings[3], 0, 100, 1, 3));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(4);
settings[0] = map(this.eye_value, 1, 2, 0, 100);
settings[1] = map(this.eye_brow, 1, 2 , 0, 100);
settings[2] = map(this.nose_value, 1, 2, 0, 100);
settings[3] = map(this.bag_colour, 1, 3, 0, 100);
return settings;
}
}
{
"000018": [
100,
100,
100,
0
],
"000020": [
100,
100,
0,
0
],
"000023": [
0,
100,
0,
0
],
"000025": [
100,
100,
0,
0
],
"000028": [
100,
100,
100,
50
],
"000029": [
0,
0,
100,
0
],
"000030": [
100,
0,
0,
0
],
"000031": [
0,
100,
100,
0
],
"000032": [
100,
0,
0,
0
],
"000035": [
100,
100,
100,
0
],
"000037": [
100,
100,
0,
100
],
"000038": [
0,
100,
0,
0
],
"000040": [
100,
100,
100,
0
],
"000041": [
100,
100,
0,
50
],
"000042": [
0,
0,
100,
0
],
"000043": [
100,
100,
100,
0
],
"000044": [
100,
100,
100,
100
],
"000045": [
100,
100,
100,
0
],
"000047": [
100,
100,
100,
50
],
"000048": [
100,
100,
0,
0
],
"000050": [
100,
100,
0,
0
],
"000051": [
100,
0,
0,
0
],
"000052": [
0,
100,
0,
50
],
"000054": [
0,
0,
100,
0
],
"000055": [
100,
100,
0,
0
],
"000056": [
0,
100,
0,
0
],
"000058": [
0,
100,
100,
0
],
"000060": [
100,
100,
0,
100
],
"000064": [
0,
100,
0,
0
],
"000065": [
100,
100,
0,
50
],
"000068": [
100,
0,
0,
0
],
"000069": [
100,
100,
0,
0
],
"000071": [
0,
0,
100,
0
],
"000073": [
100,
100,
100,
0
],
"000076": [
100,
100,
0,
0
],
"000077": [
100,
100,
100,
0
],
"000078": [
100,
100,
100,
0
],
"000079": [
100,
0,
0,
50
],
"000080": [
0,
100,
0,
0
],
"000081": [
100,
100,
0,
50
],
"000083": [
100,
100,
100,
0
],
"000085": [
0,
100,
100,
0
],
"000086": [
100,
100,
100,
0
],
"000088": [
100,
100,
100,
0
],
"000091": [
100,
100,
0,
0
],
"000092": [
0,
0,
100,
0
],
"000096": [
100,
100,
100,
0
],
"000097": [
0,
0,
100,
0
],
"000099": [
0,
0,
100,
0
],
"000100": [
100,
0,
100,
0
],
"000103": [
0,
100,
100,
0
],
"000001": [
100,
0,
100,
0
],
"000002": [
100,
100,
100,
0
],
"000005": [
0,
0,
100,
0
],
"000006": [
100,
0,
100,
50
],
"000007": [
100,
100,
0,
0
],
"000009": [
100,
100,
100,
0
],
"000010": [
0,
0,
100,
0
],
"000013": [
0,
0,
0,
0
],
"000014": [
100,
100,
100,
100
],
"000015": [
100,
100,
0,
0
],
"000016": [
100,
100,
0,
0
],
"000161": [
0,
100,
100,
0
],
"000160": [
100,
100,
0,
0
],
"000157": [
0,
0,
100,
0
],
"000156": [
0,
0,
100,
0
],
"000155": [
100,
100,
100,
0
],
"000153": [
100,
100,
0,
0
],
"000152": [
0,
100,
0,
0
],
"000151": [
100,
100,
100,
50
],
"000150": [
0,
100,
0,
0
],
"000148": [
0,
100,
100,
0
],
"000147": [
0,
0,
100,
0
],
"000146": [
100,
100,
100,
50
],
"000145": [
100,
100,
100,
0
],
"000143": [
0,
0,
0,
0
],
"000142": [
0,
100,
100,
0
],
"000140": [
0,
0,
100,
50
],
"000137": [
100,
100,
0,
0
],
"000135": [
100,
100,
0,
50
],
"000134": [
100,
100,
0,
100
],
"000133": [
0,
0,
100,
0
],
"000132": [
100,
100,
100,
50
],
"000131": [
100,
100,
100,
0
],
"000129": [
0,
100,
0,
0
],
"000126": [
0,
0,
100,
0
],
"000125": [
0,
100,
0,
0
],
"000122": [
100,
0,
100,
0
],
"000121": [
100,
100,
100,
0
],
"000118": [
100,
100,
100,
50
],
"000117": [
100,
100,
100,
100
],
"000116": [
100,
100,
0,
0
],
"000115": [
0,
0,
0,
0
],
"000114": [
100,
100,
0,
0
],
"000111": [
100,
0,
100,
50
],
"000110": [
0,
100,
100,
0
],
"000109": [
0,
0,
0,
0
],
"000108": [
0,
0,
100,
0
],
"000106": [
100,
100,
100,
0
],
"000104": [
0,
0,
0,
0
]
}
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 8;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function HoFace() {
// these are state variables for a face
// (your variables should be different!)
//pumpkin colour (Hair)
const yellow = color(255, 255, 0);
const mid_yellow = color(255, 117, 24);
const dark_yellow = color(127, 51, 0);
const error_green = color(0, 255, 0);
//eye colour
const brown = color(69,24,0);
const blue = color(135,206,250);
const grey = color(128,128,128);
const pink = color(255,182,193);
/*
* earSize can vary from 0 to 4
* earDist is the distance between ears and varies from 0 to 4
* faceColor is 1,2,3,4 for yellow,blue,red, or violet respectively
*/
this.leafSize = 5;
this.leafDist = 5;
this.hairColor = 1;
this.eyeColor = 1;
this.blushColor = 1;
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
noStroke();
push();
if(this.hairColor == 0) {
fill(yellow);
}
else if (this.hairColor==1) {
fill(mid_yellow);
}
else if (this.hairColor==2) {
fill(dark_yellow);
}
else {
fill(error_green);
}
// head
push();
scale(1/3);
translate(-4,0);
noStroke();
ellipse(0, 0, 7,10);
ellipse(2, 0, 5,10);
ellipse(4, 0, 8,10);
ellipse(6, 0, 5,10);
ellipse(8, 0, 7,10);
pop();
pop();
//leaf//
push();
scale(1/3);
let leafRadius = map(this.leafSize, 0, 10, 0.3, 2);
let leafXPos = map(this.leafDist, 0, 10, 0.5, 2);
fill(58,23,11);
noStroke();
rect(-2+leafXPos,-8.5,leafRadius+1.5,4,0.2,1,1,1);
pop();
//leaf//
push();
//nose//
let nose_top = positions.nose_bridge[0];
let nose_bottom = positions.nose_bridge[3];
stroke(0);
strokeWeight(0.15);
// line(nose_top[0], nose_top[1], nose_bottom[0], nose_bottom[1]); //top
fill(0);
triangle(nose_bottom[0], nose_bottom[1], nose_top[0], nose_top[0],nose_bottom[1], nose_bottom[1]);
let nose_end = null;
if(nose_top[0] < nose_bottom[0]) {
nose_end = positions.nose_tip[0];
}
else {
nose_end = positions.nose_tip[4];
}
// let nose_end = positions.nose_tip[4];
let nose_center = positions.nose_tip[2];
pop();
// line(nose_end[0], nose_end[1], nose_center[0], nose_center[1]); //bottom
//nose//
//mouth//
// let top_lip = positions.top_lip[0];
// let bottom_lip = positions.bottom_lip[]
push();
push();
fill(0);
noStroke();
ellipse(positions.bottom_lip[7][0], positions.bottom_lip[6][1],0.2);
ellipse(positions.bottom_lip[8][0], positions.bottom_lip[8][1],0.2);
ellipse(positions.bottom_lip[9][0], positions.bottom_lip[9][1],0.2);
ellipse(positions.bottom_lip[10][0], positions.bottom_lip[10][1],0.2);
ellipse(positions.bottom_lip[0][0], positions.bottom_lip[0][1],0.2);
pop();
pop();
push();
if(this.eyeColor == 0) {
fill(brown);
}
else if (this.eyeColor==1) {
fill(blue);
}
else if (this.eyeColor==2) {
fill(grey);
}
else {
fill(error_green);
}
//eyes//
noStroke();
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
push();
translate(0,0.5);
push();
fill(255);
ellipse(left_eye_pos[0], left_eye_pos[1], 0.5);
ellipse(right_eye_pos[0], right_eye_pos[1], 0.5);
pop();
push();
translate(0,0);
ellipse(left_eye_pos[0], left_eye_pos[1], 0.3);
ellipse(right_eye_pos[0], right_eye_pos[1], 0.3);
pop();
pop();
pop();
//eyes//
if(this.blushColor == 0) {
fill(pink);
}
else if (this.eyeColor==1) {
noFill();
}
else if (this.eyeColor==2) {
noFill();
}
else {
noFill();
}
//blush
ellipse(1.5,0,0.5,0.25);
ellipse(-1.5,0,0.5,0.25);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.leafSize = map(settings[0], 0, 100, 0, 10);
this.leafDist = map(settings[1], 0, 100, 0, 10);
this.hairColor = int(map(settings[2], 0, 100, 0, 3));
this.eyeColor = int(map(settings[3], 0, 100, 0, 3));
this.blushColor = int(map(settings[4], 0, 100, 0, 3));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(5);
settings[0] = map(this.leafSize, 0, 10, 0, 100);
settings[1] = map(this.leafDist, 0, 10, 0, 100);
settings[2] = map(this.hairColor, 0, 4, 0, 100);
settings[3] = map(this.eyeColor, 0, 4, 0, 100);
settings[4] = map(this.blushColor, 0, 4, 0, 100);
return settings;
}
}
{
"000001": [
50,
50,
0,
0,
50
],
"000002": [
50,
50,
50,
0
],
"000005": [
50,
50,
0,
75
],
"000006": [
50,
50,
0,
0
],
"000007": [
50,
50,
75,
0,
50
],
"000009": [
50,
50,
75,
0,
0
],
"000010": [
50,
50,
0,
50,
0
],
"000013": [
50,
50,
0,
0,
75
],
"000014": [
50,
50,
75,
0,
0
],
"000015": [
50,
50,
50,
0,
75
],
"000016": [
50,
50,
75,
0,
50
],
"000018": [
50,
50,
0,
0,
0
],
"000020": [
50,
50,
75,
0,
50
],
"000023": [
50,
50,
75,
0,
50
],
"000025": [
50,
50,
75,
0,
50
],
"000028": [
50,
50,
0,
0,
0
],
"000029": [
50,
50,
0,
25,
0
],
"000030": [
50,
50,
0,
0,
75
],
"000031": [
50,
50,
0,
50,
0
],
"000032": [
50,
50,
0,
0,
75
],
"000035": [
50,
50,
50,
0,
0
],
"000037": [
50,
50,
50,
0,
75
],
"000038": [
50,
50,
50,
50,
50
],
"000040": [
50,
50,
50,
0,
0
],
"000041": [
50,
50,
50,
0,
75
],
"000042": [
50,
50,
0,
50,
0
],
"000043": [
50,
50,
75,
25,
0
],
"000044": [
50,
50,
75,
0,
0
],
"000045": [
50,
50,
50,
0,
0
],
"000047": [
50,
50,
75,
0,
0
],
"000048": [
50,
50,
75,
0,
50
],
"000050": [
50,
50,
75,
0,
25
],
"000051": [
50,
50,
0,
0,
75
],
"000052": [
50,
50,
50,
50,
75
],
"000054": [
50,
50,
0,
0,
0
],
"000055": [
50,
50,
75,
0,
25
],
"000056": [
50,
50,
75,
0,
25
],
"000058": [
50,
50,
75,
25,
0
],
"000060": [
50,
50,
75,
0,
50
],
"000064": [
50,
50,
50,
0,
0
],
"000065": [
50,
50,
75,
0,
50
],
"000068": [
50,
50,
0,
0,
75
],
"000069": [
50,
50,
75,
0,
25
],
"000071": [
50,
50,
0,
0,
0
],
"000073": [
50,
50,
75,
0,
0
],
"000076": [
50,
50,
75,
0,
50
],
"000077": [
50,
50,
75,
0,
0
],
"000078": [
50,
50,
75,
0,
0
],
"000079": [
50,
50,
0,
0,
75
],
"000080": [
50,
50,
75,
0,
50
],
"000081": [
50,
50,
75,
0,
50
],
"000083": [
50,
50,
50,
25,
0
],
"000085": [
50,
50,
50,
0,
0
],
"000086": [
50,
50,
0,
0,
0
],
"000088": [
50,
50,
50,
0,
0
],
"000091": [
50,
50,
75,
0,
50
],
"000092": [
50,
50,
0,
50,
0
],
"000096": [
50,
50,
75,
0,
0
],
"000097": [
50,
50,
50,
0,
0
],
"000099": [
50,
50,
50,
0,
0
],
"000100": [
50,
50,
0,
0,
0
],
"000103": [
50,
50,
75,
25,
0
],
"000104": [
50,
50,
0,
0,
75
],
"000106": [
50,
50,
0,
0,
0
],
"000108": [
50,
50,
0,
50,
0
],
"000109": [
50,
50,
0,
0,
75
],
"000110": [
50,
50,
0,
0,
0
],
"000111": [
50,
50,
0,
0,
0
],
"000114": [
50,
50,
75,
0,
50
],
"000115": [
50,
50,
0,
0,
75
],
"000116": [
50,
50,
50,
0,
50
],
"000117": [
50,
50,
75,
0,
0
],
"000118": [
50,
50,
75,
0,
0
],
"000121": [
50,
50,
75,
0,
0
],
"000122": [
50,
50,
0,
0,
0
],
"000125": [
50,
50,
0,
50,
75
],
"000126": [
50,
50,
0,
0,
0
],
"000129": [
50,
50,
75,
0,
50
],
"000131": [
50,
50,
75,
0,
0
],
"000132": [
50,
50,
75,
0,
0
],
"000133": [
50,
50,
0,
50,
0
],
"000134": [
50,
50,
75,
0,
50
],
"000135": [
50,
50,
75,
0,
50
],
"000137": [
50,
50,
75,
0,
25
],
"000140": [
50,
50,
0,
25,
0
],
"000142": [
50,
50,
75,
25,
0
],
"000143": [
50,
50,
50,
0,
50
],
"000145": [
50,
50,
75,
0,
0
],
"000146": [
50,
50,
50,
0,
0
],
"000147": [
50,
50,
0,
25,
0
],
"000148": [
50,
50,
75,
25,
0
],
"000150": [
50,
50,
75,
0,
50
],
"000151": [
50,
50,
75,
0,
0
],
"000152": [
50,
50,
0,
0,
75
],
"000153": [
50,
50,
75,
0,
50
],
"000155": [
50,
50,
75,
0,
0
],
"000156": [
50,
50,
0,
25,
0
],
"000157": [
50,
50,
0,
25,
0
],
"000160": [
50,
50,
75,
0,
50
],
"000161": [
50,
50,
75,
0,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 3;
// This where you define your own face object
function HowardFace() {
const light = color(250, 200, 140);
const middle = color(230, 155, 75);
const dark = color(170, 125, 70);
const tan = color(250, 235, 200);
//this.mouth_value
this.fur_colour = 1;
this.ear_length = -1;
this.blush = 0;
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
let left_eye = average_point(positions.left_eye);
let right_eye = average_point(positions.right_eye);
let left_eyebrow = average_point(positions.left_eyebrow);
let right_eyebrow = average_point(positions.right_eyebrow);
let left_d = dist(left_eye[0], left_eye[1], left_eyebrow[0], left_eyebrow[1]);
let right_d = dist(right_eye[0], right_eye[1], right_eyebrow[0], right_eyebrow[1]);
let left_eb_move = map(left_d, 0.4, 0.7, 0.6, 1.5, true);
let right_eb_move = map(right_d, 0.4, 0.7, 0.6, 1.5, true);
left_eye[0] *= 3;
left_eye[1] *= 3;
right_eye[0] *= 3;
right_eye[1] *= 3;
if (this.fur_colour == 1) {
fill(light);
} else if (this.fur_colour == 2) {
fill(middle);
} else {
fill(dark);
}
noStroke();
ellipse(0, 0.15, 5, 5.5);
stroke(tan);
noFill();
strokeWeight(0.3);
fill(tan);
ellipse(0, 1.5, 3, 2.2);
// head outline
noFill();
strokeWeight(0.25);
stroke(60, 50, 50);
beginShape();
vertex(0, -2.625);
//bezierVertex(3, -7.5, 7, -5, 8, 1);
//bezierVertex(8, 1, 10, 8, 0, 9);
bezierVertex(1.05, -2.625, 2.45, -1.75, 2.45, 0.35);
bezierVertex(2.45, 0.35, 2.625, 2.8, 0, 2.8);
bezierVertex(-2.625, 2.8, -2.625, 0.25, -2.55, 0.35);
bezierVertex(-2.45, -1.75, -1.05, -2.625, 0, -2.625);
endShape();
//ears
//Ear colour
if (this.fur_colour == 1) {
fill(light);
} else if (this.fur_colour == 2) {
fill(middle);
} else {
fill(dark);
}
//left ear
beginShape();
curveVertex(-2.4, -0.7);
curveVertex(-2.4, -0.7);
curveVertex(-2.8, -1.4 + this.ear_length);
curveVertex(-2.45, -2.45 + this.ear_length);
curveVertex(-1.05, -2.38);
curveVertex(-1.05, -2.38);
endShape();
//right ear
beginShape();
curveVertex(2.345, -0.7);
curveVertex(2.345, -0.7);
curveVertex(2.8, -1.4 + this.ear_length);
curveVertex(2.45, -2.45 + this.ear_length);
curveVertex(1.05, -2.38);
curveVertex(1.05, -2.38);
endShape();
fill(tan);
stroke(tan);
//left ear inside
beginShape();
curveVertex(-2.1, -1.4);
curveVertex(-2.1, -1.4);
curveVertex(-2.24, -1.225 + this.ear_length);
curveVertex(-2.24, -1.75 + this.ear_length);
curveVertex(-1.575, -2);
curveVertex(-1.575, -2);
endShape();
//left ear inside line
beginShape();
curveVertex(-2.1, -1.4);
curveVertex(-2.1, -1.4);
curveVertex(-1.925, -1.645);
curveVertex(-1.6625, -1.925);
curveVertex(-1.575, -2);
curveVertex(-1.575, -2);
endShape();
//right ear inside
beginShape();
curveVertex(2.1, -1.4);
curveVertex(2.1, -1.4);
curveVertex(2.24, -1.225 + this.ear_length);
curveVertex(2.24, -1.75 + this.ear_length);
curveVertex(1.575, -2);
curveVertex(1.575, -2);
endShape();
//right ear inside line
beginShape();
curveVertex(2.1, -1.4);
curveVertex(2.1, -1.4);
curveVertex(1.925, -1.645);
curveVertex(1.6625, -1.925);
curveVertex(1.575, -2);
curveVertex(1.575, -2);
endShape();
//left brow
push();
strokeWeight(0.375)
translate(0, 1 - left_eb_move);
beginShape();
curveVertex(-1.225, -1.12);
curveVertex(-1.225, -1.12);
curveVertex(-1.05, -1.19);
curveVertex(-0.91, -1.19);
curveVertex(-0.805, -1.12);
curveVertex(-0.805, -1.12);
endShape();
beginShape();
curveVertex(-1.225, -1.12);
curveVertex(-1.225, -1.12);
curveVertex(-1.05, -1.085);
curveVertex(-0.91, -1.085);
curveVertex(-0.805, -1.12);
curveVertex(-0.805, -1.12);
endShape();
//right brow
beginShape();
curveVertex(1.225, -1.12);
curveVertex(1.225, -1.12);
curveVertex(1.05, -1.19);
curveVertex(0.91, -1.19);
curveVertex(0.805, -1.12);
curveVertex(0.805, -1.12);
endShape();
beginShape();
curveVertex(1.225, -1.12);
curveVertex(1.225, -1.12);
curveVertex(1.05, -1.085);
curveVertex(0.91, -1.085);
curveVertex(0.805, -1.12);
curveVertex(0.805, -1.12);
endShape();
pop();
// eyes
const green = color('#3bb44a');
const darkGreen = color('#046538');
const lightBlue = color('#9bcde1');
const darkBlue = color('#0c76c1');
const lightBrown = color('#8b5f3c');
const pink = color('#ff9292');
//outline
noStroke();
fill(40);
ellipse(-1.05, -0.175, 0.735);
ellipse(1.05, -0.175, 0.735);
//iris
if (this.blush < 5) {
fill(lightBlue);
} else {
fill(pink);
}
ellipse(-1.05, -0.175, 0.7);
ellipse(1.05, -0.175, 0.7);
//
fill(40);
ellipse(-1.05, -0.175, 0.455);
ellipse(1.05, -0.175, 0.455);
//white reflection
fill(255);
ellipse(-1.225, -0.35, 0.175, 0.14);
ellipse(0.875, -0.35, 0.175, 0.14);
//mouth open
let top_lip_point = positions.top_lip[9];
let bottom_lip_point = positions.bottom_lip[9];
// fill(255, 0, 0);
let d = dist(top_lip_point[0], top_lip_point[1], bottom_lip_point[0], bottom_lip_point[1])
let mouth = map(d, 0, 0.5, 0, 10);
let mouth_size = map(mouth, 0, 10, 0, 1.5);
fill(250, 100, 100);
stroke(40);
strokeWeight(0.15)
ellipse(0, 1.2, 1.5, mouth_size);
//tongue cover
noStroke();
fill(tan);
ellipse(0.525, 1.12, 1.05, 0.77)
ellipse(-0.525, 1.12, 1.05, 0.77)
if (this.fur_colour == 1) {
fill(light);
} else if (this.fur_colour == 2) {
fill(middle);
} else {
fill(dark);
}
ellipse(0, 0.2, 1.4, 1.5);
fill(tan);
ellipse(0, 0.7, 2.1, 0.9);
//nose
fill(40);
ellipse(0, 0.875, 0.7, 0.525);
//mouth
stroke(40)
noFill();
strokeWeight(0.1575);
beginShape();
curveVertex(-0.07, 1.05);
curveVertex(-0.07, 1.05);
curveVertex(0.35, 1.505);
curveVertex(0.77, 1.54);
curveVertex(1.05, 1.33);
curveVertex(1.05, 1.33);
endShape();
beginShape();
curveVertex(0.07, 1.05);
curveVertex(0.07, 1.05);
curveVertex(-0.35, 1.505);
curveVertex(-0.77, 1.54);
curveVertex(-1.05, 1.33);
curveVertex(-1.05, 1.33);
endShape();
//blush
if (this.blush < 5) {
} else {
noStroke()
fill(200, 50, 50, 180);
ellipse(-1.4, 0.7, 0.8, 0.5);
ellipse(1.4, 0.7, 0.8, 0.5);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.fur_colour = int(map(settings[0], 0, 100, 1, 4));
this.ear_length = map(settings[1], 0, 100, 0, -1);
this.blush = map(settings[2], 0, 100, 0, 10);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(4);
settings[0] = map(this.fur_colour, 1, 4, 0, 100);
settings[1] = map(this.ear_length, 0, -1, 0, 100);
settings[2] = map(this.blush, 0, 10, 0, 100);
return settings;
}
}
// given an array of [x,y] points, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for (var i = 0; i < list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
0,
0,
100
],
"000002": [
0,
28.999999999999996,
100
],
"000005": [
0,
0,
100
],
"000006": [
50,
49,
100
],
"000007": [
0,
100,
0
],
"000009": [
0,
56.99999999999999,
100
],
"000010": [
0,
0,
100
],
"000013": [
0,
0,
0
],
"000014": [
50,
100,
100
],
"000015": [
0,
77,
0
],
"000016": [
0,
86,
0
],
"000018": [
0,
0,
100
],
"000020": [
0,
65,
0
],
"000023": [
0,
76,
0
],
"000025": [
0,
62,
0
],
"000028": [
0,
68,
100
],
"000029": [
0,
0,
100
],
"000030": [
0,
0,
0
],
"000031": [
0,
77,
100
],
"000032": [
0,
50,
0
],
"000035": [
0,
100,
100
],
"000037": [
100,
100,
0
],
"000038": [
0,
83,
0
],
"000040": [
0,
83,
100
],
"000041": [
0,
92,
0
],
"000042": [
0,
30,
100
],
"000043": [
0,
75,
100
],
"000044": [
100,
100,
100
],
"000045": [
0,
65,
100
],
"000047": [
50,
100,
100
],
"000048": [
0,
88,
0
],
"000050": [
0,
88,
0
],
"000051": [
0,
0,
0
],
"000052": [
0,
84,
0
],
"000054": [
0,
0,
100
],
"000055": [
0,
100,
0
],
"000056": [
0,
100,
0
],
"000058": [
0,
100,
100
],
"000060": [
100,
0,
0
],
"000064": [
0,
71,
0
],
"000065": [
0,
100,
0
],
"000068": [
0,
0,
0
],
"000069": [
0,
100,
0
],
"000071": [
0,
0,
100
],
"000073": [
0,
62,
100
],
"000076": [
0,
100,
0
],
"000077": [
0,
71,
100
],
"000078": [
0,
71,
100
],
"000079": [
0,
0,
0
],
"000080": [
0,
100,
0
],
"000081": [
0,
100,
0
],
"000083": [
0,
41,
100
],
"000085": [
0,
53,
100
],
"000086": [
0,
37,
100
],
"000088": [
0,
49,
100
],
"000091": [
0,
93,
0
],
"000092": [
0,
0,
100
],
"000096": [
0,
84,
100
],
"000097": [
0,
62,
100
],
"000099": [
0,
53,
100
],
"000100": [
0,
30,
100
],
"000103": [
0,
76,
100
],
"000104": [
0,
33,
0
],
"000106": [
0,
70,
100
],
"000108": [
0,
0,
100
],
"000109": [
0,
46,
0
],
"000110": [
0,
54,
100
],
"000111": [
100,
19,
100
],
"000114": [
0,
100,
0
],
"000115": [
0,
0,
0
],
"000116": [
0,
59,
0
],
"000117": [
100,
100,
100
],
"000118": [
0,
100,
100
],
"000121": [
0,
100,
100
],
"000122": [
0,
0,
100
],
"000125": [
0,
35,
0
],
"000126": [
50,
0,
100
],
"000129": [
0,
90,
0
],
"000131": [
50,
100,
100
],
"000132": [
50,
100,
100
],
"000133": [
0,
51,
100
],
"000134": [
100,
100,
0
],
"000135": [
50,
100,
0
],
"000137": [
0,
17,
0
],
"000140": [
50,
0,
100
],
"000142": [
0,
66,
100
],
"000143": [
0,
54,
0
],
"000145": [
0,
84,
100
],
"000146": [
0,
63,
100
],
"000147": [
0,
0,
100
],
"000148": [
0,
86,
100
],
"000150": [
0,
24,
0
],
"000151": [
0,
84,
100
],
"000152": [
0,
61,
0
],
"000153": [
0,
61,
0
],
"000155": [
0,
34,
100
],
"000156": [
0,
0,
100
],
"000157": [
0,
0,
100
],
"000160": [
0,
100,
0
],
"000161": [
0,
100,
100
]
}
//var DEBUG_MODE = true;
// var NUM_SLIDERS = 8;
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
function HuFace() {
const face = [134, 89, 54];
const brown = [96, 60, 16];
const orange = [181, 135, 78];
const yellow = [164, 116, 10];
const grey = [129, 120, 101];
const pink = [217, 194, 182];
const horns_color = [254, 233, 217];
const nose_color = [53, 37, 18];
const ear_color = [234, 192, 158];
this.earringc = 1;
this.earDist = 0.3;
this.eyeDist = 0;
this.mouthDist = -0.1;
this.faceColor = 1;
this.fur = 1;
this.furColor = 3;
this.horns = -0.1;
this.draw = function(positions) {
noStroke();
//horns
fill(horns_color);
beginShape();
vertex(positions.chin[0][0]+0.5, positions.left_eyebrow[2][1]-0.3);
vertex(positions.chin[0][0]-0.1,positions.left_eyebrow[2][1]+0.3);
vertex(positions.chin[0][0]-0.5,positions.left_eyebrow[2][1]-1.3);
vertex(positions.left_eyebrow[0][0], positions.left_eyebrow[2][1]-3-this.horns);
vertex(positions.chin[0][0], positions.left_eyebrow[2][1]-1.5);
endShape();
beginShape();
vertex(positions.chin[16][0]-0.4, positions.right_eyebrow[2][1]-0.3);
vertex(positions.chin[16][0]-1.4,positions.right_eyebrow[2][1]+1.3);
vertex(positions.chin[16][0]-0.5,positions.right_eyebrow[2][1]-1.5);
vertex(positions.right_eyebrow[4][0], positions.right_eyebrow[2][1]-3-this.horns);
vertex(positions.chin[16][0], positions.right_eyebrow[2][1]-1.3);
endShape();
//earring
if(this.earringc == 1) {
fill(255, 255, 255);
}
else if (this.earringc == 2) {
fill(pink);
}
else if (this.earringc == 3) {
fill(ear_color);
}
else if (this.earringc == 4) {
fill(yellow);
}
else {
fill(horns_color);
}
ellipse(positions.chin[0][0]-0.3, positions.chin[0][1]-0.1, this.earDist, 0.6);
//fur
if(this.furColor == 1) {
fill(brown);
}
else if (this.furColor == 2) {
fill(pink);
}
else if (this.furColor == 3) {
fill(grey);
}
else if (this.furColor == 4) {
fill(face);
}
else {
fill(horns_color);
}
bezier(positions.chin[0][0]-1.1, positions.chin[0][1]-0.7,positions.chin[0][0]-2, positions.chin[0][1]-this.fur, positions.chin[0][0], positions.chin[0][1], positions.chin[0][0]+1.5, positions.left_eyebrow[2][1]-0.1);
bezier(positions.chin[16][0]+0.9, positions.chin[16][1]-0.7,positions.chin[16][0]+2, positions.chin[16][1]-this.fur, positions.chin[16][0], positions.chin[16][1], positions.chin[16][0]-1.5, positions.right_eyebrow[2][1]-0.1);
//ear
push();
fill(ear_color);
bezier(positions.chin[0][0]-1, positions.chin[0][1]-1,positions.chin[0][0]-2, positions.chin[0][1], positions.chin[0][0], positions.chin[0][1], positions.chin[0][0]+1.5, positions.left_eyebrow[2][1]-0.5);
bezier(positions.chin[16][0]+0.8, positions.chin[16][1]-1,positions.chin[16][0]+2, positions.chin[16][1], positions.chin[16][0], positions.chin[16][1], positions.chin[16][0]-1.5, positions.right_eyebrow[2][1]-0.5);
pop();
// face
if(this.faceColor == 1) {
fill(face);
}
else if (this.faceColor== 2) {
fill(orange);
}
else if (this.faceColor== 3) {
fill(yellow);
}
else if (this.faceColor== 4) {
fill(grey);
}
else {
fill(brown);
}
noStroke();
beginShape();
vertex(positions.chin[0][0]-0.3, positions.chin[0][1]-0.8);
vertex(positions.chin[16][0]-0.3, positions.chin[16][1]-0.8);
vertex(positions.chin[8][0], positions.chin[8][1]);
endShape();
bezier(positions.chin[0][0]-0.3, positions.chin[0][1]-0.79,positions.left_eyebrow[0][0], positions.left_eyebrow[2][1]-1.2, positions.right_eyebrow[4][0], positions.right_eyebrow[2][1]-1.2,positions.chin[16][0]-0.3, positions.chin[16][1]-0.79);
bezier(positions.chin[0][0]-0.29, positions.chin[0][1]-0.8, positions.chin[0][0]-0.4,positions.chin[1][1], positions.chin[7][0], positions.chin[8][1], positions.chin[8][0]+0.01, positions.chin[8][1]);
bezier(positions.chin[16][0]-0.31, positions.chin[16][1]-0.8, positions.chin[16][0]+0.4, positions.chin[15][1], positions.chin[9][0], positions.chin[8][1], positions.chin[8][0]-0.01, positions.chin[8][1]);
//nose bridge
stroke(0);
noFill();
bezier(positions.right_eyebrow[0][0], positions.right_eyebrow[0][1]+0.2, positions.nose_bridge[0][0], positions.nose_bridge[0][1],positions.nose_bridge[2][0]+0.3, positions.nose_bridge[2][1], positions.nose_tip[4][0], positions.nose_tip[4][1]);
bezier(positions.left_eyebrow[4][0], positions.left_eyebrow[4][1]+0.2, positions.nose_bridge[0][0], positions.nose_bridge[0][1],positions.nose_bridge[2][0]+0.3, positions.nose_bridge[2][1], positions.nose_tip[0][0], positions.nose_tip[0][1]);
//up nose
fill(nose_color);
noStroke();
let nose_up = positions.nose_tip[0];
let nose_upr = positions.nose_tip[4];
ellipse(nose_up[0], nose_up[1]+0.3,0.5, 0.3);
ellipse(nose_upr[0], nose_up[1]+0.3,0.5, 0.3);
stroke(2);
noFill();
bezier(positions.nose_tip[0][0]-0.1,positions.nose_tip[0][1]+0.1,positions.nose_tip[2][0],positions.nose_tip[2][1]+0.1,positions.nose_tip[2][0]+0.3,positions.nose_tip[2][1],positions.nose_tip[4][0]+0.1,positions.nose_tip[4][1]+0.1);
//eyebows
let left_eyebrow1 = positions.left_eyebrow[4];
let left_eyebrow2 = positions.left_eyebrow[2];
let left_eyebrow3 = positions.left_eyebrow[0];
let right_eyebrow1 = positions.right_eyebrow[4];
let right_eyebrow2 = positions.right_eyebrow[2];
let right_eyebrow3 = positions.right_eyebrow[0];
noFill();
bezier(left_eyebrow1[0], left_eyebrow1[1], left_eyebrow2[0], left_eyebrow2[1], left_eyebrow2[0], left_eyebrow2[1], left_eyebrow3[0], left_eyebrow3[1]);
bezier(right_eyebrow1[0], right_eyebrow1[1], right_eyebrow2[0], right_eyebrow2[1], right_eyebrow2[0], right_eyebrow2[1], right_eyebrow3[0], right_eyebrow3[1]);
//eyes
stroke(0);
fill(255);
ellipse(positions.left_eye[1][0], positions.left_eye[5][1], 0.8, 0.5);
ellipse(positions.right_eye[2][0], positions.right_eye[4][1], 0.8, 0.5);
noStroke();
fill(0);
ellipse(positions.left_eye[1][0]-this.eyeDist, positions.left_eye[5][1], 0.7, 0.48);
ellipse(positions.right_eye[2][0]-this.eyeDist,positions.right_eye[4][1], 0.7, 0.48);
//mouth
let up_mouth = positions.top_lip[0];
stroke(0);
noFill();
bezier(positions.top_lip[0][0]-this.mouthDist,positions.bottom_lip[5][1],positions.bottom_lip[4][0],positions.bottom_lip[4][1]+0.1, positions.bottom_lip[2][0],positions.bottom_lip[2][1]+0.1, positions.bottom_lip[0][0]+this.mouthDist,positions.bottom_lip[1][1]);
}
this.setProperties = function(settings) {
this.earDist = map(settings[0], 0, 100, 0.1, 0.3);
this.eyeDist = map(settings[1], 0, 100, -0.07, 0.08);
this.faceColor = int(map(settings[2], 0, 100, 0, 4));
this.earringc = int(map(settings[3], 0, 100, 0, 4));
this.mouthDist = map(settings[4], 0, 100, -0.2, 0);
this.fur = map(settings[5], 0, 100, 0, -0.6);
this.furColor = int(map(settings[6], 0, 100, 0, 4));
this.horns = map(settings[7], 0, 100, -0.5, 0.3);
}
this.getProperties = function() {
let settings = new Array(7);
settings[0] = map(this.earDist, 0.1, 0.3, 0, 100);
settings[1] = map(this.eyeDist, -0.05, 0.06, 0, 100);
settings[2] = map(this.faceColor, 0, 4, 0, 100);
settings[3] = map(this.earringc, 0, 4, 0, 100);
settings[4] = map(this.mouthDist, -0.2, -0.1, 0, 100);
settings[5] = map(this.fur, 0, -0.6, 0, 100);
settings[6] = map(this.furColor, 0, 4, 0, 100);
settings[7] = map(this.horns, -0.5, 0.3,0, 100);
return settings;
}
}
{
"000001": [
100,
40.45454545454545,
25,
100,
0,
0,
75,
50
],
"000002": [
34.99999999999999,
50.000000000000014,
50,
25,
88,
34,
75,
35.99999999999999
],
"000005": [
100,
30.909090909090914,
25,
25,
0,
0,
75,
50
],
"000006": [
100,
30.909090909090914,
25,
50,
49,
19,
25,
28.000000000000004
],
"000007": [
56.999999999999986,
45.909090909090914,
0,
50,
49,
100,
25,
15
],
"000009": [
56.999999999999986,
103.18181818181822,
75,
25,
50,
72,
50,
54
],
"000010": [
25.999999999999996,
41.818181818181834,
100,
50,
36.99999999999999,
21.000000000000004,
75,
95
],
"000013": [
25.999999999999996,
35,
100,
50,
147.99999999999997,
21.000000000000004,
75,
95
],
"000014": [
25.999999999999996,
58.18181818181819,
100,
50,
200,
21.000000000000004,
75,
95
],
"000015": [
25.999999999999996,
60.909090909090914,
25,
50,
0,
21.000000000000004,
75,
95
],
"000016": [
25.999999999999996,
-18.181818181818183,
25,
50,
0,
21.000000000000004,
75,
95
],
"000018": [
25.999999999999996,
40.45454545454545,
100,
50,
0,
26,
25,
95
],
"000020": [
25.999999999999996,
36.36363636363637,
100,
0,
0,
100,
0,
0
],
"000023": [
25.999999999999996,
-18.181818181818183,
25,
0,
102,
17,
0,
73.99999999999999
],
"000025": [
25.999999999999996,
58.18181818181819,
25,
0,
200,
38,
25,
65
],
"000028": [
25.999999999999996,
48.63636363636365,
75,
0,
200,
13,
0,
100
],
"000029": [
0,
48.63636363636365,
100,
0,
200,
13,
0,
100
],
"000030": [
17.000000000000004,
48.63636363636365,
50,
0,
200,
13,
0,
100
],
"000031": [
17.000000000000004,
48.63636363636365,
0,
0,
200,
13,
25,
100
],
"000032": [
17.000000000000004,
43.181818181818194,
25,
0,
200,
13,
25,
100
],
"000035": [
17.000000000000004,
40.45454545454545,
50,
0,
200,
13,
100,
100
],
"000037": [
17.000000000000004,
36.36363636363637,
100,
0,
200,
16,
0,
100
],
"000038": [
17.000000000000004,
47.27272727272728,
75,
0,
200,
16,
25,
100
],
"000040": [
37.99999999999999,
47.27272727272728,
25,
100,
104,
0,
25,
94
],
"000041": [
37.99999999999999,
45.909090909090914,
0,
100,
200,
45.00000000000001,
50,
75.00000000000001
],
"000042": [
37.99999999999999,
44.54545454545456,
25,
100,
200,
45.00000000000001,
50,
75.00000000000001
],
"000043": [
37.99999999999999,
43.181818181818194,
25,
100,
200,
45.00000000000001,
50,
75.00000000000001
],
"000044": [
37.99999999999999,
40.45454545454545,
25,
100,
200,
45.00000000000001,
0,
75.00000000000001
],
"000045": [
37.99999999999999,
36.36363636363637,
25,
100,
200,
45.00000000000001,
75,
75.00000000000001
],
"000047": [
37.99999999999999,
30.909090909090914,
0,
0,
200,
45.00000000000001,
75,
75.00000000000001
],
"000048": [
37.99999999999999,
14.545454545454545,
25,
0,
200,
100,
75,
0
],
"000050": [
37.99999999999999,
70.45454545454547,
75,
100,
200,
19,
25,
0
],
"000051": [
37.99999999999999,
48.63636363636365,
25,
100,
200,
19,
25,
85
],
"000052": [
37.99999999999999,
29.545454545454547,
50,
75,
200,
35,
0,
85
],
"000054": [
37.99999999999999,
43.181818181818194,
25,
50,
128,
33,
75,
85
],
"000055": [
37.99999999999999,
45.909090909090914,
25,
50,
0,
33,
75,
85
],
"000056": [
37.99999999999999,
56.818181818181834,
100,
50,
200,
42.00000000000001,
0,
85
],
"000058": [
37.99999999999999,
39.090909090909086,
100,
50,
200,
42.00000000000001,
0,
85
],
"000060": [
37.99999999999999,
62.27272727272728,
0,
50,
40.00000000000001,
19,
25,
56.00000000000001
],
"000064": [
100,
48.63636363636365,
25,
50,
80.00000000000001,
19,
25,
56.00000000000001
],
"000065": [
100,
48.63636363636365,
25,
50,
160.00000000000003,
19,
25,
56.00000000000001
],
"000068": [
100,
50.000000000000014,
0,
0,
49.999999999999986,
19,
75,
56.00000000000001
],
"000069": [
100,
50.000000000000014,
0,
0,
100,
19,
75,
56.00000000000001
],
"000071": [
100,
40.45454545454545,
100,
0,
200,
30,
25,
100
],
"000073": [
100,
51.36363636363637,
100,
50,
200,
30,
25,
100
],
"000076": [
100,
51.36363636363637,
100,
50,
200,
30,
0,
100
],
"000077": [
100,
28.181818181818187,
75,
50,
200,
30,
25,
100
],
"000078": [
100,
45.909090909090914,
75,
50,
200,
30,
25,
100
],
"000079": [
100,
40.45454545454545,
75,
50,
200,
30,
25,
100
],
"000080": [
100,
85.45454545454547,
75,
50,
200,
30,
25,
100
],
"000081": [
100,
54.0909090909091,
25,
50,
200,
6,
50,
72.99999999999999
],
"000083": [
100,
55.45454545454547,
50,
25,
0,
35,
0,
100
],
"000085": [
100,
56.818181818181834,
50,
25,
0,
35,
0,
100
],
"000086": [
100,
107.2727272727273,
0,
25,
0,
35,
0,
100
],
"000088": [
100,
28.181818181818187,
0,
25,
0,
35,
0,
100
],
"000091": [
100,
20.000000000000004,
0,
75,
200,
69,
100,
100
],
"000092": [
100,
63.63636363636365,
50,
75,
200,
69,
100,
100
],
"000096": [
100,
69.09090909090911,
75,
75,
0,
69,
100,
100
],
"000097": [
100,
36.36363636363637,
75,
75,
0,
69,
100,
100
],
"000099": [
100,
33.63636363636364,
25,
0,
0,
17,
0,
100
],
"000100": [
100,
51.36363636363637,
25,
0,
0,
59,
50,
39.00000000000001
],
"000103": [
100,
60.909090909090914,
50,
50,
76.00000000000001,
49,
75,
87
],
"000104": [
100,
47.27272727272728,
100,
50,
152.00000000000003,
49,
75,
87
],
"000106": [
56.999999999999986,
45.909090909090914,
0,
50,
16.000000000000014,
47,
0,
56.99999999999999
],
"000108": [
56.999999999999986,
44.54545454545456,
0,
50,
32,
47,
75,
56.99999999999999
],
"000109": [
56.999999999999986,
43.181818181818194,
0,
50,
64,
47,
100,
56.99999999999999
],
"000110": [
35.99999999999999,
60.909090909090914,
50,
50,
128,
81,
25,
56.99999999999999
],
"000111": [
35.99999999999999,
-18.181818181818183,
50,
50,
23.999999999999993,
30,
0,
56.99999999999999
],
"000114": [
35.99999999999999,
50.000000000000014,
50,
50,
47.999999999999986,
54,
25,
56.99999999999999
],
"000115": [
35.99999999999999,
44.54545454545456,
25,
50,
96,
33,
50,
56.99999999999999
],
"000116": [
35.99999999999999,
45.909090909090914,
25,
25,
47.999999999999986,
54,
50,
56.99999999999999
],
"000117": [
35.99999999999999,
44.54545454545456,
50,
25,
96,
54,
0,
56.99999999999999
],
"000118": [
35.99999999999999,
95,
50,
25,
192,
54,
0,
56.99999999999999
],
"000121": [
35.99999999999999,
36.36363636363637,
50,
25,
200,
54,
0,
56.99999999999999
],
"000122": [
35.99999999999999,
30.909090909090914,
100,
25,
200,
54,
25,
56.99999999999999
],
"000125": [
35.99999999999999,
55.45454545454547,
75,
25,
200,
54,
75,
56.99999999999999
],
"000126": [
35.99999999999999,
56.818181818181834,
25,
25,
0,
36,
0,
56.99999999999999
],
"000129": [
35.99999999999999,
-18.181818181818183,
25,
50,
113.99999999999999,
56.99999999999999,
0,
56.99999999999999
],
"000131": [
35.99999999999999,
-18.181818181818183,
25,
50,
200,
56.99999999999999,
0,
56.99999999999999
],
"000132": [
35.99999999999999,
-18.181818181818183,
50,
50,
38.00000000000001,
56.99999999999999,
0,
56.99999999999999
],
"000133": [
100,
-18.181818181818183,
0,
50,
139.99999999999997,
34,
0,
56.99999999999999
],
"000134": [
100,
118.18181818181819,
0,
50,
200,
34,
0,
56.99999999999999
],
"000135": [
100,
-18.181818181818183,
100,
50,
46.000000000000014,
34,
75,
56.99999999999999
],
"000137": [
100,
-18.181818181818183,
25,
50,
92,
34,
75,
56.99999999999999
],
"000140": [
100,
66.36363636363637,
50,
50,
145.99999999999997,
34,
50,
56.99999999999999
],
"000142": [
100,
71.81818181818184,
0,
50,
0,
0,
25,
89
],
"000143": [
53.000000000000014,
44.54545454545456,
50,
50,
0,
0,
25,
89
],
"000145": [
53.000000000000014,
43.181818181818194,
75,
75,
94,
48,
75,
89
],
"000146": [
100,
40.45454545454545,
50,
25,
188,
48,
75,
100
],
"000147": [
100,
59.54545454545455,
25,
25,
86,
48,
75,
100
],
"000148": [
100,
63.63636363636365,
100,
25,
100,
64,
100,
100
],
"000150": [
100,
69.09090909090911,
0,
25,
200,
64,
100,
100
],
"000151": [
70,
50.000000000000014,
50,
25,
0,
51,
50,
100
],
"000152": [
70,
50.000000000000014,
50,
25,
0,
51,
50,
100
],
"000153": [
70,
50.000000000000014,
100,
25,
0,
51,
50,
100
],
"000155": [
70,
50.000000000000014,
100,
25,
0,
73,
75,
100
],
"000156": [
24.999999999999996,
37.727272727272734,
0,
25,
0,
49,
100,
100
],
"000157": [
24.999999999999996,
33.63636363636364,
0,
25,
0,
49,
100,
100
],
"000160": [
24.999999999999996,
28.181818181818187,
75,
25,
36.00000000000001,
80,
50,
100
],
"000161": [
24.999999999999996,
48.63636363636365,
25,
25,
72.00000000000001,
80,
75,
100
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 4;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
//skin colour
//brown
const brownS = [74, 52, 33];
//white
const whiteS = [232, 223, 218];
//tan
const tanS = [191, 148, 107];
//hair colour
//red
const redH = [181, 63, 16];
//blonde
const blondeH = [214, 171, 77];
//brown
const brownH = [51, 29, 0];
//black
const blackH = [28, 27, 26];
this.show_points = function(segment) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
var number = i.toString();
textAlign(CENTER, CENTER);
textSize(0.2);
fill(0);
text(number, px, py, 0.1);
}
}
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i = 0; i < s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len, sum_y / s_len];
}
// This where you define your own face object
function IdrisFace() {
// these are state variables for a face
// (your variables should be different!)
//all to max, chnage later
this.green = 3;
this.flower = 1.8;
this.facex = 3;
this.bflower = 1.4;
this.skin = 2;
this.hair = 4;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if (i < segment.length - 1) {
let nx = segment[i + 1][0];
let ny = segment[i + 1][1];
line(px, py, nx, ny);
} else if (do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
// outer fuzz for female hair
//red
if (this.hair == 1) {
if (this.green == 3 || this.green === 2) {
fill(redH);
push();
angleMode(DEGREES);
translate(0, -1.4);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1.8, 1.44);
rotate(20);
}
pop();
}
}
//blonde
if (this.hair == 2) {
if (this.green == 3 || this.green === 2) {
fill(blondeH);
push();
angleMode(DEGREES);
translate(0, -1.4);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1.8, 1.44);
rotate(20);
}
pop();
}
}
//brown
if (this.hair == 3) {
if (this.green == 3 || this.green === 2) {
fill(brownH);
push();
angleMode(DEGREES);
translate(0, -1.4);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1.8, 1.44);
rotate(20);
}
pop();
}
}
//black
if (this.hair == 4) {
if (this.green == 3 || this.green === 2) {
fill(blackH);
push();
angleMode(DEGREES);
translate(0, -1.4);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1.8, 1.44);
rotate(20);
}
pop();
}
}
//female hair
//red
if (this.hair == 1) {
if (this.green == 3 || this.green === 2) {
noStroke();
fill(redH);
ellipse(0, -1.4, 4.68);
fill(50, 168, 82);
push();
angleMode(DEGREES);
translate(-0.72, -2.7);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.8, -2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.72, -3);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
}
}
//blonde
if (this.hair == 2) {
if (this.green == 3 || this.green === 2) {
noStroke();
fill(blondeH);
ellipse(0, -1.4, 4.68);
fill(23, 158, 191);
push();
angleMode(DEGREES);
translate(-0.72, -2.7);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.8, -2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.72, -3);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
}
}
//brown
if (this.hair == 3) {
if (this.green == 3 || this.green === 2) {
noStroke();
fill(brownH);
ellipse(0, -1.4, 4.68);
fill(204, 8, 96);
push();
angleMode(DEGREES);
translate(-0.72, -2.7);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.8, -2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.72, -3);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
}
}
//black
if (this.hair == 4) {
if (this.green == 3 || this.green === 2) {
noStroke();
fill(blackH);
ellipse(0, -1.4, 4.68);
fill(255);
push();
angleMode(DEGREES);
translate(-0.72, -2.7);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.8, -2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.72, -3);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.4);
rotate(180 / 5);
}
pop();
}
}
// head code
if (this.skin == 1) {
fill(brownS);
noStroke();
ellipse(0, -0.4, this.facex, 3.6);
}
if (this.skin == 2) {
fill(tanS);
noStroke();
ellipse(0, -0.4, this.facex, 3.6);
}
if (this.skin == 3) {
fill(whiteS);
noStroke();
ellipse(0, -0.4, this.facex, 3.6);
}
//beard
//red
if (this.hair == 1) {
fill(redH);
if (this.green < 2) {
ellipse(0, 1.75, 2.5, 2.5);
push();
angleMode(DEGREES);
translate(0, 1.75);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1, 1);
rotate(20);
}
//flowers for beard
pop();
fill(50, 168, 82);
push();
angleMode(DEGREES);
translate(-0.9, 2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.2, 1.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.3, 2.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
}
}
//blonde
if (this.hair == 2) {
fill(blondeH);
if (this.green < 2) {
ellipse(0, 1.75, 2.5, 2.5);
push();
angleMode(DEGREES);
translate(0, 1.75);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1, 1);
rotate(20);
}
//flowers for beard
pop();
fill(23, 158, 191);
push();
angleMode(DEGREES);
translate(-0.9, 2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.2, 1.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.3, 2.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
}
}
//brown
if (this.hair == 3) {
fill(brownH);
if (this.green < 2) {
ellipse(0, 1.75, 2.5, 2.5);
push();
angleMode(DEGREES);
translate(0, 1.75);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1, 1);
rotate(20);
}
//flowers for beard
pop();
fill(204, 8, 96);
push();
angleMode(DEGREES);
translate(-0.9, 2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.2, 1.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.3, 2.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
}
}
//black
if (this.hair == 4) {
fill(blackH);
if (this.green < 2) {
ellipse(0, 1.75, 2.5, 2.5);
push();
angleMode(DEGREES);
translate(0, 1.75);
noStroke();
for (let i = 0; i < 20; i++) {
ellipse(0, 1, 1);
rotate(20);
}
//flowers for beard
pop();
fill(255);
push();
angleMode(DEGREES);
translate(-0.9, 2);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(1.2, 1.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
push();
angleMode(DEGREES);
translate(0.3, 2.5);
noStroke();
for (let i = 0; i < 10; i++) {
ellipse(0, 0, 0.36, 1.2);
rotate(180 / 5);
}
pop();
}
}
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
//blush
if (this.green == 3 || this.green === 2) {
fill(196, 118, 118, 60);
noStroke();
ellipse(left_eye_pos[0], left_eye_pos[1] + 1, 0.7, 0.5);
ellipse(right_eye_pos[0], right_eye_pos[1] + 1, 0.7, 0.5);
}
//nose
let nose_top = positions.nose_bridge[0];
let nose_bottom = positions.nose_bridge[2];
let nose_bottom2 = positions.nose_bridge[3];
// print(nose_top, nose_bottom);
stroke(59, 41, 26);
strokeWeight(0.1);
line(nose_top[0], nose_top[1], nose_bottom[0], nose_bottom[1]);
fill(255);
stroke(59, 41, 26);
let nose_end = null;
if (nose_top[0] < nose_bottom[0]) {
nose_end = positions.nose_tip[0];
} else {
nose_end = positions.nose_tip[4];
}
let nose_center = positions.nose_tip[2];
push();
noFill()
strokeWeight(0.1);
angleMode(DEGREES);
arc(nose_bottom2[0], nose_bottom2[1], 0.5, 0.5, 180, 0, OPEN);
pop();
noStroke();
fill(59, 41, 26);
ellipse(nose_bottom2[0] - 0.07, nose_bottom2[1], 0.07, 0.1);
ellipse(nose_bottom2[0] + 0.07, nose_bottom2[1], 0.07, 0.1);
//glasses code
fill(40, 43, 43);
stroke(122, 122, 122);
strokeWeight(0.072);
ellipse(left_eye_pos[0], left_eye_pos[1], 1.2);
ellipse(right_eye_pos[0], right_eye_pos[1], 1.2);
//middlerim
fill(0);
push();
stroke(122, 122, 122);
rectMode(CENTER);
rect(nose_top[0], nose_top[1], 0.72, 0.108);
pop();
//mouth code
let mouthstart = positions.top_lip[0];
let mouthstart2 = positions.top_lip[7];
let mouthbot = positions.bottom_lip[0];
let mouthbot2 = positions.bottom_lip[7];
let mouth = segment_average(positions.top_lip);
let mouth2 = segment_average(positions.bottom_lip);
fill(92, 40, 19);
noStroke();
stroke(64, 27, 27);
strokeWeight(0.07);
push();
//bottom lip
translate(mouth2[0], mouth2[1]);
angleMode(DEGREES)
arc(0, mouth[0], mouthbot[0], 0.5, 0, 180, OPEN);
//top lip
strokeWeight(0.2);
arc(0, mouth[0], mouthbot[0], 0.2, 180, 0, OPEN);
pop();
noStroke();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.facex = map(settings[1], 0, 100, 2.52, 3);
this.green = int(map(settings[0], 0, 100, 1, 3));
this.flower = map(settings[0], 0, 100, 0.36, 1.8);
this.earingsy = map(settings[3], 0, 100, 0.72, 2);
this.bflower = map(settings[0], 0, 100, 0.36, 1.4);
this.skin = int(map(settings[2], 0, 100, 1, 3));
this.hair = int(map(settings[3], 0, 100, 1, 4));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(4);
settings[1] = map(this.facex, 2.52, 3, 0, 100);
settings[0] = map(this.green, 1, 3, 0, 100);
settings[0] = map(this.flower, 0.36, 1.8, 0, 100);
settings[3] = map(this.earingsy, 0.72, 2, 0, 100);
settings[0] = map(this.bflower, 0.36, 1.4, 0, 100);
settings[2] = map(this.skin, 1, 3, 0, 100);
settings[3] = map(this.hair, 1, 4, 0, 100);
return settings;
}
}
{
"000001": [
0,
93,
100,
100
],
"000002": [
100,
46.00000000000002,
100,
0
],
"000005": [
67,
57.000000000000014,
50,
33.33333333333333
],
"000006": [
98.00000000000001,
53.99999999999998,
0,
33.33333333333333
],
"000007": [
0,
100,
100,
100
],
"000009": [
100,
100,
100,
66.66666666666666
],
"000010": [
86,
78.00000000000001,
100,
33.33333333333333
],
"000013": [
0,
100,
100,
33.33333333333333
],
"000014": [
100,
31.00000000000001,
0,
100
],
"000015": [
0,
100,
100,
66.66666666666666
],
"000016": [
0,
100,
50,
66.66666666666666
],
"000018": [
96.00000000000001,
78.00000000000001,
100,
33.33333333333333
],
"000020": [
0,
100,
100,
66.66666666666666
],
"000023": [
0,
100,
100,
100
],
"000025": [
0,
100,
50,
66.66666666666666
],
"000028": [
100,
51.000000000000036,
50,
66.66666666666666
],
"000029": [
92.00000000000001,
67.00000000000003,
50,
33.33333333333333
],
"000030": [
0,
100,
50,
33.33333333333333
],
"000031": [
100,
100,
100,
66.66666666666666
],
"000032": [
0,
100,
100,
33.33333333333333
],
"000035": [
100,
47.999999999999986,
100,
100
],
"000037": [
0,
100,
0,
100
],
"000038": [
0,
100,
100,
100
],
"000040": [
100,
100,
50,
100
],
"000041": [
0,
100,
50,
100
],
"000042": [
94,
66.00000000000004,
100,
33.33333333333333
],
"000043": [
100,
57.000000000000014,
50,
66.66666666666666
],
"000044": [
100,
10.999999999999991,
0,
100
],
"000045": [
100,
35.00000000000003,
50,
0
],
"000047": [
100,
47.00000000000001,
50,
100
],
"000048": [
0,
100,
100,
100
],
"000050": [
0,
74,
100,
100
],
"000051": [
0,
100,
100,
33.33333333333333
],
"000052": [
0,
19.000000000000036,
100,
66.66666666666666
],
"000054": [
100,
88.00000000000003,
100,
33.33333333333333
],
"000055": [
0,
100,
100,
100
],
"000056": [
0,
72.00000000000003,
100,
100
],
"000058": [
100,
81.99999999999996,
100,
100
],
"000060": [
0,
100,
0,
100
],
"000064": [
0,
100,
100,
66.66666666666666
],
"000065": [
0,
100,
50,
100
],
"000068": [
0,
100,
100,
100
],
"000069": [
0,
100,
100,
100
],
"000071": [
82,
63.99999999999999,
100,
33.33333333333333
],
"000073": [
68.00000000000001,
59.999999999999964,
50,
0
],
"000076": [
0,
100,
100,
100
],
"000077": [
100,
100,
100,
66.66666666666666
],
"000078": [
100,
100,
50,
66.66666666666666
],
"000079": [
0,
100,
100,
66.66666666666666
],
"000080": [
0,
100,
100,
100
],
"000081": [
0,
100,
0,
100
],
"000083": [
100,
34.00000000000005,
100,
0
],
"000085": [
100,
100,
100,
0
],
"000086": [
100,
100,
100,
66.66666666666666
],
"000088": [
100,
42.00000000000001,
100,
0
],
"000091": [
0,
100,
100,
100
],
"000092": [
87.99999999999999,
69.99999999999997,
50,
33.33333333333333
],
"000096": [
100,
100,
100,
0
],
"000097": [
70,
84.99999999999999,
50,
0
],
"000099": [
100,
25.00000000000002,
100,
0
],
"000100": [
87.99999999999999,
81.99999999999996,
100,
33.33333333333333
],
"000103": [
100,
54.99999999999996,
100,
66.66666666666666
],
"000104": [
25,
86.99999999999996,
100,
33.33333333333333
],
"000106": [
100,
27.999999999999968,
100,
66.66666666666666
],
"000108": [
87.99999999999999,
78.00000000000001,
100,
33.33333333333333
],
"000109": [
0,
84.99999999999999,
50,
0
],
"000110": [
100,
100,
100,
66.66666666666666
],
"000111": [
94.99999999999999,
32.99999999999997,
0,
33.33333333333333
],
"000114": [
0,
100,
100,
100
],
"000115": [
0,
100,
100,
66.66666666666666
],
"000116": [
0,
100,
100,
66.66666666666666
],
"000117": [
100,
0,
0,
100
],
"000118": [
100,
71.00000000000006,
50,
66.66666666666666
],
"000121": [
100,
100,
50,
100
],
"000122": [
98.00000000000001,
83.00000000000001,
100,
33.33333333333333
],
"000125": [
0,
100,
100,
66.66666666666666
],
"000126": [
84,
71.00000000000006,
50,
33.33333333333333
],
"000129": [
0,
42.00000000000001,
100,
100
],
"000131": [
100,
83.00000000000001,
0,
100
],
"000132": [
100,
100,
0,
100
],
"000133": [
84,
57.000000000000014,
50,
33.33333333333333
],
"000134": [
0,
100,
0,
100
],
"000135": [
0,
100,
0,
100
],
"000137": [
0,
100,
100,
66.66666666666666
],
"000140": [
96.00000000000001,
71.00000000000006,
50,
33.33333333333333
],
"000142": [
100,
41.00000000000002,
100,
66.66666666666666
],
"000143": [
0,
100,
100,
66.66666666666666
],
"000145": [
100,
100,
100,
100
],
"000146": [
100,
100,
50,
0
],
"000147": [
82,
74.99999999999997,
50,
33.33333333333333
],
"000148": [
100,
54.99999999999996,
100,
100
],
"000150": [
0,
100,
100,
0
],
"000151": [
100,
74.99999999999997,
50,
100
],
"000152": [
0,
100,
100,
0
],
"000153": [
0,
100,
100,
66.66666666666666
],
"000155": [
100,
100,
100,
0
],
"000156": [
64,
83.00000000000001,
100,
33.33333333333333
],
"000157": [
82,
85.99999999999997,
100,
33.33333333333333
],
"000160": [
0,
100,
100,
100
],
"000161": [
100,
100,
100,
100
]
}
<head>
<script language="javascript" type="text/javascript" src="p5.js"></script>
<script language="javascript" type="text/javascript" src="seedrandom.min.js"></script>
<script language="javascript" type="text/javascript" src="d3-random.v1.min.js"></script>
<script language="javascript" type="text/javascript" src="z_clmtrackr.js"></script>
<script language="javascript" type="text/javascript" src="z_model_pca_20_svm.js"></script>
<script language="javascript" type="text/javascript" src="z_purview_helper.js"></script>
<script language="javascript" type="text/javascript" src="z_focused_random.js"></script>
<script language="javascript" type="text/javascript" src="z_face_system.js"></script>
<script language="javascript" type="text/javascript" src="z_kdTree.js"></script>
<script language="javascript" type="text/javascript" src="z_face-api.js"></script>
<script language="javascript" type="text/javascript" src="z_training_images.js"></script>
<script language="javascript" type="text/javascript" src="z_testing_images.js"></script>
<!-- 2020 -->
<script language="javascript" type="text/javascript" src="chen_face.js"></script>
<script language="javascript" type="text/javascript" src="cooper_face.js"></script>
<script language="javascript" type="text/javascript" src="hill_face.js"></script>
<script language="javascript" type="text/javascript" src="ho_face.js"></script>
<script language="javascript" type="text/javascript" src="howard_face.js"></script>
<script language="javascript" type="text/javascript" src="hu_face.js"></script>
<script language="javascript" type="text/javascript" src="idris_face.js"></script>
<script language="javascript" type="text/javascript" src="lee_face.js"></script>
<script language="javascript" type="text/javascript" src="luo_face.js"></script>
<script language="javascript" type="text/javascript" src="mckendry_face.js"></script>
<script language="javascript" type="text/javascript" src="mcsweeney_face.js"></script>
<script language="javascript" type="text/javascript" src="ng_face.js"></script>
<script language="javascript" type="text/javascript" src="nuesca_face.js"></script>
<script language="javascript" type="text/javascript" src="park_face.js"></script>
<script language="javascript" type="text/javascript" src="ruan_face.js"></script>
<script language="javascript" type="text/javascript" src="to_face.js"></script>
<script language="javascript" type="text/javascript" src="truong_face.js"></script>
<script language="javascript" type="text/javascript" src="tuala_face.js"></script>
<script language="javascript" type="text/javascript" src="wang_face.js"></script>
<script language="javascript" type="text/javascript" src="yee_face.js"></script>
<script language="javascript" type="text/javascript" src="zhang_face.js"></script>
<script language="javascript" type="text/javascript" src="zhao_face.js"></script>
<!-- 2019 -->
<script language="javascript" type="text/javascript" src="jaegers_face.js"></script>
<script language="javascript" type="text/javascript" src="kelly19_face.js"></script>
<script language="javascript" type="text/javascript" src="trewavas_face.js"></script>
<!-- 2018 -->
<script language="javascript" type="text/javascript" src="felizardo_face.js"></script>
<script language="javascript" type="text/javascript" src="jordan_face.js"></script>
<script language="javascript" type="text/javascript" src="joy_face.js"></script>
<script language="javascript" type="text/javascript" src="salazar_face.js"></script>
<!-- 2017 -->
<script language="javascript" type="text/javascript" src="campbell_face.js"></script>
<script language="javascript" type="text/javascript" src="dockerty_face.js"></script>
<script language="javascript" type="text/javascript" src="kelly_face.js"></script>
<script language="javascript" type="text/javascript" src="petris_face.js"></script>
<script language="javascript" type="text/javascript" src="prezo_runner.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:#323232">
<div class="outer">
<div class="inner" id="controls" height="500">
<table>
<tr>
<td>Lash Thickness</td>
<td id="slider1Container"></td>
</tr>
<tr>
<td>Eye Shade</td>
<td id="slider2Container"></td>
</tr>
<tr>
<td>Lip Style</td>
<td id="slider3Container"></td>
</tr>
<tr>
<td>Face Shade</td>
<td id="slider4Container"></td>
</tr>
<tr>
<td>Face Hue</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>setting 11</td>
<td id="slider11Container"></td>
</tr>
<tr>
<td>setting 12</td>
<td id="slider12Container"></td>
</tr>
<tr>
</tr>
<tr>
<td>show target</td>
<td id="sliderTintContainer"></td>
</tr>
<tr>
<td>Draw function</td>
<td id="selector1Container"></td>
</tr>
<tr>
<td>Face Draw</td>
<td id="checkbox1Container"></td>
</tr>
<tr>
<td>Face Targets</td>
<td id="checkbox2Container"></td>
</tr>
<tr>
<td>Face Points</td>
<td id="checkbox3Container"></td>
</tr>
<tr>
<td></td>
<td id="button1Container"></td>
</tr>
<tr>
<td></td>
<td id="button2Container"></td>
</tr>
<tr>
<td></td>
<td id="button3Container"></td>
</tr>
<tr>
<td></td>
<td id="button4Container"></td>
</tr>
</table>
</div>
<div>
<div id="canvasContainer"></div>
</div>
</div>
<pre>
<p id="output">
</p>
</pre>
</body>
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// other variables can be in here too
// these control the colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
function JaegersFace() {
// these are state variables for a face
// (your variables may be different)
// this.eye_value = 2; // can be either 2 (eyes) or 3 (no eyes)
// this.mouth_value = 1; // range is 0.5 to 8
// this.tilt_value = 0; // range is -30 to 30
this.length = 340;
this.curly = 100;
this.e = 100;
this.eyeColour = 200;
this.acc = 6;
this.hair = 50;
this.makeupStrength = 100;
this.eyeBrowSize = 0.15;
this.skin = 50;
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
translate(0, -0.2);
scale(1.3);
scale(0.4, 0.4);
let skew = this.turn;
let superWhiteSkin = color(255, 230, 209);
let whiteSkin = color(237, 203, 175);
let tanSkin = color(217, 180, 141);
let darkSkin = color(179, 146, 116);
let skinColour;
let whiteHair = color(232, 237, 237);
let blondeHair = color(255, 218, 115);
let gingerHair = color(230, 150, 90);
let brownHair = color(181, 91, 58);
let blackHair = color(100, 100, 100);
let hairColour = color(100, 100, 100);
//skin colour
if(this.skin < 33){
skinColour = lerpColor(superWhiteSkin, whiteSkin, this.skin/33);
} else if(this.skin < 66){
skinColour = lerpColor(whiteSkin, tanSkin, (this.skin-33)/33);
} else {
skinColour = lerpColor(tanSkin, darkSkin, (this.skin-66)/33);
}
angleMode(DEGREES);
let L = this.length;
let eyeSize = this.e;
fill(255, 218, 115);
//hair colour
if(this.hair < 25){
hairColour = lerpColor(whiteHair, blondeHair, this.hair/25);
} else if(this.hair < 50){
hairColour = lerpColor(blondeHair, gingerHair, (this.hair-25)/25);
} else if(this.hair < 75){
hairColour = lerpColor(gingerHair, brownHair, (this.hair-50)/25);
} else{
hairColour = lerpColor(brownHair, blackHair, (this.hair-75)/25);
}
fill(hairColour);
stroke(hairColour.red -50, green(hairColour) - 50, blue(hairColour) - 50);
//strokeWeight(width/960/10);
strokeWeight(0.04);
randomSeed(23);
let cheekboneLeftX = positions.chin[4][0];
let cheekboneLeftY = positions.chin[4][1];
let cheekboneRightX = positions.chin[12][0];
let cheekboneRightY = positions.chin[12][1];
let eliSize = (positions.chin[16][0] - positions.chin[0][0])/2;
let eliX = positions.chin[0][0] + eliSize;
let eliY = positions.chin[0][1]+(positions.chin[16][1] - positions.chin[0][1])/2;
push();
translate(eliX*2.5, ((eliY-((eliSize*1.5)))*2.5)+9);
this.drawHair(L, this.curly, hairColour);
pop();
//ears
push();
scale(2.5, 2.5);
fill(skinColour);
stroke(red(skinColour)-20, green(skinColour)-42, blue(skinColour)-58);
let headTurn = (eliX - positions.nose_bridge[0][0])*0.3;
push();
translate(positions.chin[1][0]+0.3+headTurn, positions.chin[1][1]);
ellipse(0, 0, 1,1.5 );
pop();
push();
translate(positions.chin[15][0]-0.3+headTurn, positions.chin[15][1]);
ellipse(0, 0, 1,1.5 );
pop();
pop();
//head
fill(skinColour);
stroke(red(skinColour)-20, green(skinColour)-42, blue(skinColour)-58);
push();
scale(2.5, 2.5);
ellipse(eliX, eliY, eliSize*2);
beginShape();
vertex(positions.chin[0][0], positions.chin[0][1]);
bezierVertex(positions.chin[0][0], positions.chin[0][1],
cheekboneLeftX+(positions.chin[0][0] - cheekboneLeftX)/2, positions.chin[3][1] , cheekboneLeftX, cheekboneLeftY); // cheekboneLeftX+(positions.chin[0][0] - cheekboneLeftX)/2.5, cheekboneLeftY
vertex(cheekboneLeftX, cheekboneLeftY);
bezierVertex(cheekboneLeftX, cheekboneLeftY, cheekboneLeftX + 0, cheekboneLeftY*1.25 , positions.chin[7][0], positions.chin[7][1]); // cheekboneLeftX + 0.1, cheekboneLeftY*1.15
vertex(positions.chin[7][0], positions.chin[7][1]); //CHIN
bezierVertex(positions.chin[7][0], positions.chin[7][1], positions.chin[8][0], positions.chin[8][1] + 0.15, positions.chin[9][0], positions.chin[9][1]);
vertex(positions.chin[9][0], positions.chin[9][1]); //CHIN
bezierVertex(positions.chin[9][0], positions.chin[9][1], cheekboneRightX - 0, cheekboneRightY*1.25 , cheekboneRightX, cheekboneRightY); // cheekboneRightX - 0.1, cheekboneRightY*1.15
vertex(cheekboneRightX, cheekboneRightY);
bezierVertex(cheekboneRightX, cheekboneRightY, cheekboneRightX+(positions.chin[16][0] - cheekboneRightX)/2, positions.chin[13][1] , positions.chin[16][0], positions.chin[16][1]); // cheekboneRightX+(positions.chin[16][0] - cheekboneRightX)/2.5, cheekboneRightY
vertex(positions.chin[16][0], positions.chin[16][1]);
endShape();
pop();
//FACIAL FEATURES
push();
// eyes
fill(255);
push();
push();
this.makeup(this.makeupStrength, eyeSize, skew, positions);
pop();
push();
scale(2.5, 2.5);
let buffer = 0.5;
let eyeShearLeft = (positions.left_eye[0][1] - positions.left_eye[3][1])*-100;
let eyeShearRight = (positions.right_eye[0][1] - positions.right_eye[3][1])*-100;
let scaleOffset = (eliX - positions.nose_bridge[0][0]);
push(); //left eye
stroke(255);
translate(average_point(positions.left_eye)[0], average_point(positions.left_eye)[1] + buffer);
//translate(average_point(positions.left_eye)[0], average_point(positions.left_eye)[1] + 0);
this.eyeBrow(hairColour, positions, -0.1, this.eyeBrowSize);
if(scaleOffset > 0){
scale((eliSize*0.6)-(scaleOffset*0.5), eliSize*0.6);
} else {
scale(eliSize*0.6, eliSize*0.6);
}
rotate(eyeShearLeft);
this.eye(-0.1, eyeSize, hairColour, this.eyeColour); //left eye
pop();
push(); //right eye
stroke(255);
translate(average_point(positions.right_eye)[0], average_point(positions.right_eye)[1] + buffer);
this.eyeBrow(hairColour, positions, 0.1, this.eyeBrowSize);
if(scaleOffset < 0){
scale((eliSize*0.6)+(scaleOffset*0.5), eliSize*0.6);
} else {
scale(eliSize*0.6, eliSize*0.6);
}
rotate(eyeShearRight);
this.eye(0.1, eyeSize, hairColour, this.eyeColour); //right eye
pop();
pop();
pop();
//nose
noFill();
strokeWeight(0.05);
stroke(75);
push();
scale(2.5, 2.5);
strokeWeight(0.05);
stroke(204, 60, 35, 40);
line(positions.nose_bridge[0][0],positions.nose_bridge[3][1], positions.nose_bridge[3][0], average_point(positions.nose_tip)[1]);
push();
noFill();
strokeWeight(0.05);
stroke(75);
translate(0, -0.4);
translate(positions.nose_tip[2][0], positions.nose_tip[2][1]+(buffer/2));
scale(0.4, 0.4);
bezier(-0.45, 1.05, -0.4, 1, -0.35, 1 ,-0.2, 1.15);
bezier(0.45, 1.05, 0.4, 1, 0.35, 1 ,0.2, 1.15);
noStroke();
fill(204, 60, 35, 40);
push();
translate(0, 0.5);
scale(0.6, 0.8);
beginShape(); //nose shadow
vertex(0.5, 0.4);
bezierVertex(0.5, 0.4, 1.75, 0.75 ,0, 1.4); //bottomright
vertex(0, 1.4);
bezierVertex(0, 1.4, -1.75, 0.75 , -0.5, 0.4); //bottomleft
vertex(-0.5, 0.4);
bezierVertex(-0.5, 0.4, -0.4, 0.35,0, 0.5); //top left
vertex(0, 0.5);
bezierVertex(0, 0.5, 0.4, 0.35 ,0.5, 0.4); //top right
endShape(CLOSE);
pop();
pop();
pop();
//mouth
let lipsDiff=
(positions.bottom_lip[10][1] - positions.top_lip[8][1]) + (positions.bottom_lip[8][1] - positions.top_lip[10][1]);
stroke(0);
push();
scale(2.5,2.5);
translate(0, buffer/1.5 );
stroke(0);
strokeWeight(0.015);
let b1x = positions.top_lip[7][0]+(positions.top_lip[8][0]-positions.top_lip[7][0])/2;
let b1y = positions.top_lip[7][1];
let b4x = positions.top_lip[10][0]+(positions.top_lip[11][0]-positions.top_lip[10][0])/2;
let b4y = positions.top_lip[11][1];
fill(red(skinColour)-15, green(skinColour)-35, blue(skinColour)-35);
//fill(222, 218, 213);
beginShape();
vertex(b1x, b1y);
bezierVertex(b1x, b1y,positions.top_lip[9][0] , positions.top_lip[9][1] ,b4x, b4y);
vertex(b4x, b4y);
if(lipsDiff < 0.1) {
bezierVertex(b4x, b4y,positions.top_lip[9][0] , positions.top_lip[9][1] ,b1x, b1y);
} else {
bezierVertex(b4x, b4y,positions.bottom_lip[9][0] , positions.bottom_lip[9][1] + buffer/2 ,b1x, b1y);
}
vertex(b1x, b1y);
endShape();
//teeth
if(lipsDiff > 0.1) {
fill(242, 228, 225);
beginShape();
vertex(b1x, b1y);
bezierVertex(b1x, b1y,positions.top_lip[9][0] , positions.top_lip[9][1] ,b4x, b4y);
vertex(b4x, b4y);
bezierVertex(b4x, b4y,positions.bottom_lip[9][0] ,
positions.top_lip[9][1]+((positions.bottom_lip[9][1] + buffer/2)-positions.top_lip[9][1])/3
,b1x, b1y);
vertex(b1x, b1y);
endShape();
}
pop();
//mouth shadow
fill(204, 60, 35, 30);
noStroke();
translate(0, buffer/2);
beginShape();
vertex(0, 3.25);
bezierVertex(0, 3.25, 0.6, 3.25, 0.3, 3.5);
vertex(0.3, 3.5);
bezierVertex(0.3, 3.5, 0, 3.75, -0.3, 3.5);
vertex(-0.3, 3.5);
bezierVertex(-0.3, 3.5, -0.6, 3.25, 0, 3.25);
endShape(CLOSE);
pop();
//hair
noStroke();
fill(255, 50);
fill(255, 218, 115);
stroke(230, 188, 73);
fill(hairColour);
stroke(red(hairColour) -50, green(hairColour) - 50, blue(hairColour) - 50);
push();
this.Fringe(L, this.curly, positions);
pop();
//accessories
push(); //right accessories
translate(eliX*2.5, ((eliY-((eliSize*1.5)))*2.5)+9);
if(skew > 0){ //right getting shrunk
scale(1-(skew*0.1), 1-(skew*0.1));
translate(skew*0.8, -skew*0.25);
} else {
scale(1+(-skew*0.1), 1+(-skew*0.1));
translate(skew*0.8, -skew*0.25);
}
if(this.acc > 2){ //2 flower RIGHT
push();
this.flower1(L, 1);
pop();
}
if(this.acc > 3){ //3 flower RIGHT
push();
this.flower1(L, 0.8);
pop();
}
if(this.acc > 0){ //0 bow RIGHT
push();
this.bow(L, this.curly, 1);
pop();
}
pop();
push(); //left accessories
translate(0, 0);
translate(eliX*2.5, ((eliY-((eliSize*1.5)))*2.5)+9);
if(skew < 0){ //right getting shrunk
scale(1-(-skew*0.1), 1-(-skew*0.1));
translate(skew*0.8, skew*0.25);
} else {
scale(1+(skew*0.1), 1+(skew*0.1));
translate(skew*0.8, skew*0.25);
}
if(this.acc > 4){ //4 flower LEFT
push();
this.flower2(L, this.curly);
pop();
}
if(this.acc > 1){ //1 bow LEFT
push();
this.bow(L, this.curly, -1);
pop();
}
pop();
}
this.eyeBrow = function(col, positions, pos, size){
push();
let hairColour = col;
colorMode(HSB, 360, 100, 100, 100);
fill(hairColour);
stroke(hue(hairColour), saturation(hairColour), brightness(hairColour)-20);
strokeWeight(0.03);
let browSize = size; //0 -> 0.25
if(pos < 0){ //left eye
translate(-average_point(positions.left_eye)[0], -average_point(positions.left_eye)[1]);
beginShape();
vertex(positions.left_eyebrow[0][0],positions.left_eyebrow[0][1]); //start
bezierVertex(positions.left_eyebrow[0][0],positions.left_eyebrow[0][1],
positions.left_eyebrow[0][0],positions.left_eyebrow[1][1]+(positions.left_eyebrow[0][1]-positions.left_eyebrow[1][1])/2,
positions.left_eyebrow[1][0],positions.left_eyebrow[1][1]);
vertex(positions.left_eyebrow[1][0],positions.left_eyebrow[1][1]);
bezierVertex(positions.left_eyebrow[1][0],positions.left_eyebrow[1][1],
positions.left_eyebrow[2][0],positions.left_eyebrow[3][1]*1.05,
positions.left_eyebrow[4][0],positions.left_eyebrow[4][1]);
vertex(positions.left_eyebrow[4][0],positions.left_eyebrow[4][1]); //end
vertex(positions.left_eyebrow[4][0],positions.left_eyebrow[4][1]-browSize);
bezierVertex(positions.left_eyebrow[4][0],positions.left_eyebrow[4][1]-browSize,
positions.left_eyebrow[2][0],positions.left_eyebrow[3][1]*1.05-(browSize*1),
positions.left_eyebrow[1][0]-(browSize*0.3),positions.left_eyebrow[1][1]-(browSize*0.4));
vertex(positions.left_eyebrow[1][0]-(browSize*0.3),positions.left_eyebrow[1][1]-(browSize*0.4));
bezierVertex(positions.left_eyebrow[1][0]-(browSize*0.3),positions.left_eyebrow[1][1]-(browSize*0.4),
positions.left_eyebrow[0][0],
(positions.left_eyebrow[1][1]-(browSize*0.4))+(positions.left_eyebrow[0][1]-(positions.left_eyebrow[1][1]-(browSize*0.4)))/2,
positions.left_eyebrow[0][0],positions.left_eyebrow[0][1]);
vertex(positions.left_eyebrow[0][0],positions.left_eyebrow[0][1]); //start
endShape();
} else { //right eye
translate(-average_point(positions.right_eye)[0], -average_point(positions.right_eye)[1]);
beginShape();
vertex(positions.right_eyebrow[4][0],positions.right_eyebrow[4][1]); //start
bezierVertex(positions.right_eyebrow[4][0],positions.right_eyebrow[4][1],
positions.right_eyebrow[4][0],positions.right_eyebrow[3][1]+(positions.right_eyebrow[4][1]-positions.right_eyebrow[3][1])/2, //average
positions.right_eyebrow[3][0],positions.right_eyebrow[3][1]);
vertex(positions.right_eyebrow[3][0],positions.right_eyebrow[3][1]);
bezierVertex(positions.right_eyebrow[3][0],positions.right_eyebrow[3][1],
positions.right_eyebrow[2][0],positions.right_eyebrow[1][1]*1.05,
positions.right_eyebrow[0][0],positions.right_eyebrow[0][1]);
vertex(positions.right_eyebrow[0][0],positions.right_eyebrow[0][1]); //end
vertex(positions.right_eyebrow[0][0],positions.right_eyebrow[0][1]-browSize);
bezierVertex(positions.right_eyebrow[0][0],positions.right_eyebrow[0][1]-browSize,
positions.right_eyebrow[2][0],positions.right_eyebrow[1][1]*1.05-(browSize*1),
positions.right_eyebrow[3][0]+(browSize*0.3),positions.right_eyebrow[3][1]-(browSize*0.4));
vertex(positions.right_eyebrow[3][0]+(browSize*0.3),positions.right_eyebrow[3][1]-(browSize*0.4));
bezierVertex(positions.right_eyebrow[3][0]+(browSize*0.3),positions.right_eyebrow[3][1]-(browSize*0.4),
positions.right_eyebrow[4][0],
(positions.right_eyebrow[3][1]-(browSize*0.4))+(positions.right_eyebrow[4][1]-(positions.right_eyebrow[3][1]-(browSize*0.4)))/2, //average
positions.right_eyebrow[4][0],positions.right_eyebrow[4][1]);
vertex(positions.right_eyebrow[4][0],positions.right_eyebrow[4][1]); //start
endShape();
}
colorMode(RGB, 255);
pop();
}
this.makeup = function(strength, eyeSize ,skew, positions){
let buffer = 0.5;
//blush
let eliSize = (positions.chin[16][0] - positions.chin[0][0])/2;
let scaleOffset = ((positions.chin[0][0] + eliSize) - positions.nose_bridge[0][0]);
for(let i = 0; i < 10; i++){
noStroke();
fill(255, 64, 118, 0.05*strength); //0.05
push();
if(scaleOffset > 0){
scale((eliSize*0.6)-(scaleOffset*0.5), (eliSize*0.6)-(scaleOffset*0.3));
translate(scaleOffset*-1, 0);
} else {
scale(eliSize*0.6, eliSize*0.6);
}
translate(0, buffer/2);
ellipse(-2.75, 0, i*0.3, i*0.3); //left blush
pop();
push();
if(scaleOffset < 0){
scale((eliSize*0.6)-(scaleOffset*-0.5), (eliSize*0.6)-(scaleOffset*-0.3));
translate(scaleOffset*-1, 0);
} else {
scale(eliSize*0.6, eliSize*0.6);
}
translate(0, buffer/2);
ellipse(2.75, 0, i*0.3, i*0.3); //right blush
pop();
}
//cheek lines
strokeWeight(0.05);
stroke(199, 143, 107, strength*2.55);
push();
if(scaleOffset > 0){
scale((eliSize*0.6)-(scaleOffset*0.5), (eliSize*0.6)-(scaleOffset*0.3));
translate(scaleOffset*-1,0);
} else {
scale(eliSize*0.6, eliSize*0.6);
}
//left lines
line(-3, 0, -3.2, 0.5);
line(-2.75, 0.05, -2.95, 0.55);
line(-2.5, 0.1, -2.7, 0.6);
line(-2.25, 0.15, -2.45, 0.65);
pop();
push();
if(scaleOffset < 0){
scale((eliSize*0.6)-(scaleOffset*-0.5), (eliSize*0.6)-(scaleOffset*-0.3));
translate(scaleOffset*-1, 0);
} else {
scale(eliSize*0.6, eliSize*0.6);
}
//right lines
line(3.2, 0, 3, 0.5);
line(2.95, 0.05, 2.75, 0.55);
line(2.7, 0.1, 2.5, 0.6);
line(2.45, 0.15, 2.25, 0.65);
pop();
//lipstick
push();
let lipsDiff= (positions.bottom_lip[10][1] - positions.top_lip[8][1]) + (positions.bottom_lip[8][1] - positions.top_lip[10][1]);
scale(2.5,2.5);
translate(0, buffer/1.5 );
stroke(0);
strokeWeight(0.02);
let b4x = positions.top_lip[7][0]+(positions.top_lip[8][0]-positions.top_lip[7][0])/2;
let b4y = positions.top_lip[7][1];
let b1x = positions.top_lip[10][0]+(positions.top_lip[11][0]-positions.top_lip[10][0])/2;
let b1y = positions.top_lip[11][1];
let topMid;
if(b4y - b1y < 0){
topMid = b4y+(b1y - b4y)/2;
} else {
topMid = b1y+(b4y - b1y)/2;
}
fill(255, 64, 118, 1.5*strength); //0.75
stroke(255, 64, 118, 3*strength);
beginShape();
vertex(b1x, b1y);
bezierVertex(b1x, b1y, positions.top_lip[2][0],positions.top_lip[2][1]-(0.15*buffer) ,positions.top_lip[3][0], topMid);
vertex(positions.top_lip[3][0], topMid);
bezierVertex(positions.top_lip[3][0], topMid, positions.top_lip[4][0],positions.top_lip[4][1]-(0.15*buffer), b4x, b4y);
vertex(b4x, b4y);
if(lipsDiff < 0.1) {
bezierVertex(b4x, b4y, average_point(positions.bottom_lip)[0], positions.bottom_lip[3][1]+ buffer*0.25, b1x, b1y);
} else {
bezierVertex(b4x, b4y, average_point(positions.bottom_lip)[0], positions.bottom_lip[3][1] + buffer*0.75,b1x, b1y);
}
vertex(b1x, b1y);
endShape();
pop();
}
this.flower2 = function(len, curl){
if(len > 190){
translate(map(len, 190, 340, -5.5,-6.5+curl/200), map(len, 190, 340, -1, 5+curl/50));
}else {
translate(map(len, 0, 190, -5, -5.5),
map(len, 0, 190, -3.5, -1));
}
stroke(163, 120, 57);
for(let i = 0; i < 5; i++){
rotate(72);
push();
translate(0, -1);
fill(250, 236, 192);
bezier(-0.25, 0.5, -1.5, -1.25, 1.5, -1.25 ,0.25, 0.5);
fill(237, 196, 135);
noStroke();
bezier(-0.15, 0.5, -1, -0.75, 1, -0.75 ,0.15, 0.5);
pop();
}
fill(222, 178, 113);
ellipse(0, 0, 1, 1);
}
this.flower1 = function(len, sc){
scale(sc, sc);
if(sc < 1){
translate(2, -1);
}
if(len > 190){
translate(6, map(len, 190, 340, -2, 3));
} else {
translate(map(len, 0, 190, 4, 6),
map(len, 0, 190, -6.5, -2));
}
if(sc < 1){
stroke(131, 87, 173);
} else {
stroke(78, 127, 207);
}
for(let i = 0; i < 5; i++){
rotate(72);
if(sc < 1){
fill(180-i*10, 140-i*10, 219);
} else {
fill(166-i*10, 200-i*10, 255);
}
push();
translate(0, -0.75);
ellipse(0, 0, 1.5, 1.5);
pop();
}
if(sc < 1){
fill(230, 172, 110);
} else {
fill(245, 208, 115);
}
ellipse(0, 0, 1, 1);
}
this.bow = function(len,curl, pos){
c = curl/100;
let scale1 = map(len, 0, 340, 0.7, 1);
if(pos < 0){
translate(-6*(1-scale1), -3*(1-scale1));
} else {
translate(6*(1-scale1), -3*(1-scale1));
}
scale(scale1, scale1);
scale(pos, 1);
scale(0.8, 0.8);
if(len > 190){
translate(7.25+map(len, 190, 340, 0, c),
-4+map(len, 190, 340, 0, c));
} else {
translate(7.25-map(len, 0, 190, 2, 0), -4-map(len, 0, 190, 3, 0)); //short
scale(map(len, 0, 190, 0.75, 1), map(len, 0, 190, 0.75, 1));
}
rotate(0);
fill(255, 204, 225);
stroke(171, 65, 108);
strokeWeight(0.05);
beginShape();
vertex(0, 1);
bezierVertex(0, 1, 0.25, 3, 1.5, 5);
vertex(3, 5);
bezierVertex(3, 5, 1, 3.5, 0.5, 1);
endShape();
beginShape();
vertex(0.25, 1);
bezierVertex(0.25, 1, 0.75, 3, 4, 5);
vertex(5, 4);
bezierVertex(5, 4, 1.5, 3.5, 0.75, 1);
endShape();
//big left
beginShape();
vertex(0, 0);
bezierVertex(0, 0,-3, -3, -3, -2);
vertex(-2, 0);
bezierVertex(-2, 0, -3, 1, -2, 1.5);
vertex(0, 1);
endShape();
//big right
beginShape();
vertex(1, 0);
bezierVertex(1, 0,3, -3, 3, -2);
vertex(3, -2);
vertex(2.25, 0);
bezierVertex(2, 0, 3, 1, 2, 1.5);
vertex(2, 1.5);
vertex(1, 1);
endShape();
//outline
fill(255, 150, 193);
noStroke();
bezier(2, 1.5, 2.5, 0.75, 1, 0.5 ,1, 1);
//outline2
bezier(-2, 1.5, -2, 0.5, 0, 0.3 ,0, 1);
//upper outline
beginShape();
vertex(1, 0);
bezierVertex(1, 0 ,3, -3, 3, -2);
vertex(1, 0.25);
endShape();
beginShape();
vertex(0, 0);
bezierVertex(0, 0,-3, -3, -3, -2);
vertex(0, 0.25);
endShape();
//shadow
fill(171, 65, 108);
stroke(171, 65, 108);
bezier(2, 1.5, 2, 1, 1.5, 1 ,1, 1);
line(2, 1.5, 1, 1);
//shadow2
bezier(-2, 1.5, -1.5, 0.75, -0.5, 0.75 ,0, 1);
line(-2, 1.5, 0, 1);
fill(255, 204, 225);
rect(-0.1, -0.1, 1.1,1.1, 0.3);
}
this.eye = function(pos, size, col, eyeCol){
colorMode(HSB, 360, 100, 100, 100);
let coll = eyeCol;
let bright;
if(size > 25){
bright = map(size, 25, 100, 1, 0);
} else {
bright = 1;
}
let Med = color(coll, 83 - (59*bright), 79 - (30*bright)); //59
let Dark = color(coll, 53- (29*bright), 52 - (30*bright)); //29
let Light = color(coll, 68 - (44*bright), 92 - (30*bright)); //44
let hairColour = col;
push();
scale(0.24, 0.24);
translate(pos, 0);
let sc = 0.57;
stroke(0);
strokeWeight(0.2*sc);
strokeCap(SQUARE);
push();
if(pos < 0){
scale(-1, 1);
translate(-0.15, 0);
}
//eyebrow
strokeWeight(0.2*sc);
//outter white eye //3
if(size > 50 && size < 75){
sc = map(size, 50, 75, 0, 0.57);
} else if(size >= 75){
sc = 0.57;
} else {
sc = 0;
}
noStroke();
beginShape();
fill(255);
vertex(-3.5*sc, -0.5*sc);
bezierVertex(-3.5*sc, -1*sc, 1.5*sc, -5.5*sc , 4.5*sc , 0);
vertex(4.5*sc, 0);
bezierVertex(5*sc, 0, 1.5*sc, 5*sc, -2.5*sc, 2*sc);
endShape();
//outline
stroke(0);
noFill();
beginShape();
vertex(-3.5*sc, -0.5*sc);
bezierVertex(-3.5*sc, -1*sc, 1.5*sc, -5.5*sc , 4.5*sc , 0);
vertex(4.5*sc, 0);
endShape();
pop();
strokeWeight(0.3*sc);
//bulk blue //2
if(size > 25 && size < 50){
sc = map(size, 25, 50, 0, 0.57);
} else if(size >= 50){
sc = 0.57;
} else {
sc = 0;
}
stroke(Dark);
fill(Dark);
ellipse(0.1*sc, 0, 5*sc, 5*sc);
noStroke();
//blue shading //2
fill(Med);
ellipse(0, 0.5*sc, 4.5*sc, 3*sc);
fill(Light);
ellipse(0, 1*sc, 4*sc, 2.5*sc);
//noisey dots //4
if(size > 75){
sc = map(size, 75, 100, 0, 0.57);
} else {
sc = 0;
}
//lines from center //4
stroke(0);
strokeWeight(0.1*sc);
rotate(30);
let cent;
for(let i = 0; i < 16; i++){
cent = map(i, 0, 15, -1, 1);
if(cent < 0){cent = cent*-1;}
if(i % 2 == 0){
stroke(0);
line(-1*sc, 1*sc, (-1.75+cent/3)*sc, (1.75-cent/3)*sc);
} else {
stroke(100);
line(-1.4*sc, 1.4*sc, (-1.25+cent/3)*sc, (1.25-cent/3)*sc);
}
rotate(-10);
}
//lower white cirles //4
fill(255, 50);
noStroke();
rotate(-160);
for(let j = 0; j < 6; j++){
ellipse(1.25*sc, 1.5*sc, 0.6*sc, 0.6*sc);
rotate(-12);
}
//black center //1
sc = 0.57;
fill(0);
push();
translate(0, -0.25);
ellipse(0, 0, 1.5*sc, 2.25*sc);
if(size > 75){
sc = map(size, 75, 100, 0, 0.57);
} else {
sc = 0;
}
pop();
//white circles highlight //2
if(size > 25 && size < 50){
sc = map(size, 25, 50, 0, 0.57);
} else if(size >= 50){
sc = 0.57;
} else {
sc = 0;
}
fill(255);
ellipse(0.75*sc, -0.75*sc, 0.75*sc, 0.75*sc);
ellipse(1.75*sc, -1.5*sc, 1.25*sc, 1*sc);
ellipse(-2*sc, 1*sc, 1*sc, 1*sc);
pop();
colorMode(RGB, 255);
}
this.Fringe = function(Len, cur, positions){
rectMode(CORNERS);
let L;
if(Len > 140){
L = 340;
} else if(Len > 106){
L = map(Len, 105, 140, 0, 340);
} else {
L = 0;
}
let skew = positions.nose_bridge[0][0]*3.5;
push();
let eliSize = (positions.chin[16][0] - positions.chin[0][0])/2;
let eliX = positions.chin[0][0] + eliSize;
let eliY = positions.chin[0][1]+(positions.chin[16][1] - positions.chin[0][1])/2;
fill(255);
pop();
let tr = -positions.right_eyebrow[2][0];
let trMultiplier = map(L, 0, 340, -1, 1);
translate(0, 7);
translate(0, eliY*2.5-(eliSize*2.5));
if(L > 0){
let xSc = map(L, 0, 340, 0.4-(cur/250), map(cur, 0, 100, 1.5, 1.25));
let ySc = map(L, 0, 340, 0, map(cur, 0, 100, 2, 1.4));
let c = map(cur, 0, 100, 0.8*ySc, 0);
let c2 = cur/100;
translate(0, map(L, 0, 340, -6.5, map(cur, 0, 100, -4.5, -4)));
for(let i = 0; i <5; i++){
push();
if((i+1) % 2 == 0){ //even, left
translate((map(i-1, 0, 4, 4, 0)), ((-0.55-cur/400)+(i-1)*0.09)*(i-1)); //2, 4
} else { //odd, right
translate((map(i, 0, 4, -4, 0)), ((-0.55-cur/400)+i*0.09)*i); //1, 3, 5
}
if(i == 0){ //left 1
if(skew > 0){
scale(1+(skew*0.5), 1+(skew*0.3));
translate(skew*0, 0);
} else {
scale(1-(0.2*-skew), 1);
translate(-0.5*skew, 0.15*-skew);
}
} else if(i ==1){ //right 1
if(skew > 0){
scale(1-(0.2*skew), 1);
translate(-0.5*skew, 0.15*skew);
} else {
scale(1+(-skew*0.5), 1+(-skew*0.3));
translate(skew*0, 0);
}
} else if(i ==2){ //left 2
if(skew > 0){
scale(1+(skew*0.25), 1+(skew*0.1));
translate((skew*0.1), 0);
} else {
scale(1-(-skew*0.15), 1);
translate(0.5*skew , 0.3*-skew);
}
}else if(i ==3){ //right 2
if(skew > 0){
scale(1-(skew*0.1), 1);
translate(0.5*skew , 0.3*skew);
} else {
scale(1+(-skew*0.25), 1+(-skew*0.1));
translate((skew*0.1), 0);
}
}else if(i ==4){ //middle
if(skew > 0){
scale(1, 1);
translate(1*skew, 0);
} else {
scale(1, 1);
translate(1*skew, 0);
}
}
beginShape();
let test = 1;
vertex(-xSc, -ySc);
bezierVertex(-xSc, -ySc, 0, -2*(ySc)+c, xSc, -ySc); //top curve
vertex(xSc, -ySc);
bezierVertex(xSc, -ySc, 2*xSc-c, 0, xSc, ySc); //east curve
vertex(xSc, ySc);
bezierVertex(xSc, ySc, 0, 2*(ySc)-c, -xSc, ySc); //bottom curve
vertex(-xSc, ySc);
bezierVertex(-xSc, ySc, -2*xSc+c, 0, -xSc, -ySc); //west curve
endShape(CLOSE);
pop();
}
}
}
this.drawHair = function(Len, cur, col){
let hairColour = col;
let L = Len
//let curl = map(cur, 0, 100, 180, -90);
let curl;
if(L > 240){
curl = map(cur, 0, 100, 180, map(L, 240, 340, 180, -90));
} else {
curl = 180;
}
let curly = cur;
let curlScale;
if (L < 139){
curlScale = map(
curly, 0, 100, 0,
map(L, 0, 139, 0.1, 2));
} else {
curlScale = map(curly, 0, 100, 0, map(L, 139, 340, 2, 3));
}
push();
translate(0, -3);
rotate(10);
for(let i = 0; i < 5; i++){
rotate(28);
if(L < 139){
if(L > 90){
ellipse(-4, 0, 4, map(curly, 0, 100, map(L, 90, 139, 0.01, 8), map(L, 90, 139, 2.5, 4)));
} else {
ellipse(map(L, 0, 90, -2.9, -4), 0, 4, map(curly, 0, 100, 0.01, 2.5));
}
}
else {
ellipse(-4, 0, 4, map(curly, 0, 100, 8, 4));
}
}
pop();
if(L < 139){ //shorter hair
translate(0, map(L, 0, 139, 7, 0));
scale(map(L, 0, 139, 0.2, 1), map(L, 0, 139, 0.5, 1));
arc(3+0, -5, 6, 6, 170, 221+L, CHORD); //ARAAC
arc(-3-0, -5, 6, 6, 320-L, 371, CHORD); //mirror
let HairLength = -5+map(L, 0, 139, -130, 0);
push(); //right curl
translate(3 + ((3+curlScale) * cos(221+L)) +0 , -5 + ((3+curlScale) * sin(221+L)));
rotate(HairLength);
beginShape();
let cX = map(HairLength, -135, -5, -0.2, -0.9);
let cY = map(HairLength, -135, -5, -0.0, -0.8);
let radiuss = map(HairLength, -135, -5, 0.1, curlScale*1.5)/2;
let anglee = -20;
endShape();
fill(225, 206, 187);
fill(hairColour);
pop();
HairLength = -5+map(L, 0, 139, 160, 30);
push(); //left curl
translate(-3 - ((3+curlScale) * cos(221+L)) -0 , -5 + ((3+curlScale) * sin(221+L)));
rotate(HairLength);
beginShape();
cX = map(HairLength, 155, 25, 0.2, 0.4);
cY = map(HairLength, 155, 25, -0.0, -1.1 );
radiuss = map(HairLength, 155, 25, 0.1, curlScale*1.4)/2;
anglee = 170;
endShape();
fill(225, 206, 187);
fill(hairColour);
pop();
} else { //longer hair
fill(255, 218, 115);
fill(hairColour);
arc(3, -5, 6, 6, 170, 360, CHORD); //top hair ARAAC
arc(-3-0, -5, 6, 6, 180, 370, CHORD);
let HairLength = -5+map(L, 139, 360, 0, 14*1);
//big curls
let x1 = (6+0 + 2+0)/2;
let y1 = (-5-6.5)/2;
let x2 = (6+map(L, 139, 360,0, 1)+0-map(HairLength, -5, 9, 0, curlScale) + (6+0)-map(HairLength, -5, 9, 0, curlScale))/2;
let y2 = (-5+map(L, 139, 360, 0, 14*1)+-5+map(L, 139, 360, 0, 14*1))/2;
for(let i = 0; i < 3; i++){
ellipse(lerp(x1, x2, 0.2 + (0.3*i)), lerp(y1, y2, 0.2 + (0.3*i)),
map(curly, 0, 100, 0, map(L, 139, 360, 0.5, 9-i)),
map(L, 139, 360, 0, 8-i));
}
beginShape(); //long strands
vertex(6+0, -5); //1
vertex(6+map(L, 139, 360,0, 1)+0-map(HairLength, -5, 9, 0, curlScale), //2
-5+map(L, 139, 360, 0, 14*1));
vertex((6+0)-map(HairLength, -5, 9, 0, curlScale), //3
-5+map(L, 139, 360, 0, 14*1));
vertex(2+0, -6.5); //4
endShape();
//big curls Mirror
x1 = (-6-0 + -2-0)/2;
y1 = (-5 + -6.5)/2;
x2 = (-6-map(L, 139, 360,0, 1)-0+map(HairLength, -5, 9, 0, curlScale) + -6-0+map(HairLength, -5, 9, 0, curlScale))/2;
y2 = (-5+map(L, 139, 360, 0, 14*1) + -5+map(L, 139, 360, 0, 14*1))/2;
for(let i = 0; i < 3; i++){
ellipse(lerp(x1, x2, 0.2 + (0.3*i)), lerp(y1, y2, 0.2 + (0.3*i)),
map(curly, 0, 100, 0, map(L, 139, 360, 0.5, 9-i)),
map(L, 139, 360, 0, 8-i));
}
beginShape(); //long strands mirror
vertex(-6-0, -5);
vertex(-6-map(L, 139, 360,0, 1)-0+map(HairLength, -5, 9, 0, curlScale),
-5+map(L, 139, 360, 0, 14*1));
vertex(-6-0+map(HairLength, -5, 9, 0, curlScale),
-5+map(L, 139, 360, 0, 14*1));
vertex(-2-0, -6.5);
endShape();
beginShape();
for(let i = 0; i < 50; i++){ //outer curl
vertex((5.95+0)-map(HairLength, -5, 9+0, 0, curlScale)+curlScale+
curlScale*cos(map(curl, 180, -90, 180, 180-(4.5*i))),
HairLength-map(L, 139, 340, 0, 0.75)+
curlScale*sin(map(curl, 180, -90, 180, 180-(4.5*i))));
}
for(let i = 15; i > 0; i--){ //inner curl
let shrink = 1;
shrink = map(i, 15, 0, 1.2, 5);
vertex(
(6+map(L, 139, 360,0, 1)+0)-map(HairLength, -5, 9+0, 0, curlScale)+curlScale/shrink+
curlScale/shrink*cos(map(curl, 180, -90, 180, 180-(17*i))),
HairLength-map(L, 139, 340, 0, 0.75)+
curlScale/shrink*sin(map(curl, 180, -90, 180, 180-(15 *i)))
);
}
endShape();
beginShape();
for(let i = 0; i < 50; i++){ //outer curl mirror
vertex((-5.95-0)+map(HairLength, -5, 9+0, 0, curlScale)-curlScale+
curlScale*cos(map(curl, 180, -90, 0, (4.5*i))),
HairLength-map(L, 139, 340, 0, 0.75)+
curlScale*sin(map(curl, 180, -90, 0, (4.5 *i))));
}
for(let i = 15; i > 0; i--){ //inner curl mirror
let shrink = 1;
shrink = map(i, 15, 0, 1.2, 5);
vertex(
(-6-map(L, 139, 360,0, 1)-0)+map(HairLength, -5, 9+0, 0, curlScale)-curlScale/shrink+
curlScale/shrink*cos(map(curl, 180, -90, -10, (17*i))),
HairLength-map(L, 139, 340, 0, 0.75)+curlScale/shrink*sin(map(curl, 180, -90, -10, (15 *i)))
);
}
endShape();
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
// this.eye_value = int(map(settings[0], 0, 100, 2, 3));
// this.mouth_value = map(settings[1], 0, 100, 0.5, 8);
// this.tilt_value = map(settings[2], 0, 100, -30, 30);
this.length = map(settings[0], 0, 100, 0, 340);
this.curly = settings[1];
this.e = settings[2];
this.eyeColour = map(settings[3], 0, 100, 0, 360);
this.acc = int(map(settings[4], 0, 100, 0, 8))
this.hair = settings[5];
this.makeupStrength = settings[6];
this.eyeBrowSize = map(settings[7], 0, 100, 0, 0.4);
this.skin = settings[8];
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(8);
settings[0] = map(this.length, 0, 340, 0, 100);
settings[1] = this.curly;
settings[2] = this.e;
settings[3] = map(this.eyeColour, 0, 360, 0, 100);
settings[4] = map(this.acc, 0, 8, 0, 100);
settings[5] = this.hair;
settings[6] = this.makeupStrength;
settings[7] = map(this.eyeBrowSize, 0, 0.4, 0, 100);
settings[8] = this.skin;
return settings;
}
}
// given an array of [x,y] points, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
100,
74,
100,
56.00000000000001,
12.5,
61,
100,
31,
30
],
"000002": [
100,
0,
100,
0,
0,
52,
52,
20.000000000000004,
0
],
"000005": [
100,
0,
100,
56.00000000000001,
0,
6,
100,
55.00000000000001,
24
],
"000007": [
0,
100,
0,
100,
0,
95,
0,
75.00000000000001,
27
],
"000009": [
100,
100,
100,
54,
50,
92,
100,
28.000000000000004,
21
],
"000010": [
100,
100,
100,
53,
25,
3,
50,
31,
18
],
"000013": [
0,
100,
0,
56.00000000000001,
0,
6,
0,
61,
14
],
"000014": [
100,
100,
100,
95.99999999999999,
25,
100,
100,
56.00000000000001,
100
],
"000015": [
34,
0,
0,
50,
0,
14,
0,
55.00000000000001,
21
],
"000016": [
0,
61,
0,
56.00000000000001,
0,
89,
0,
61,
24
],
"000018": [
100,
100,
100,
56.00000000000001,
25,
0,
100,
42,
15
],
"000020": [
49,
100,
0,
51,
0,
100,
0,
62,
23
],
"000023": [
28.000000000000004,
48,
0,
49,
0,
91,
0,
61,
15
],
"000025": [
1,
0,
0,
53,
0,
85,
0,
62,
52
],
"000028": [
100,
100,
100,
90,
25,
100,
100,
39.00000000000001,
67
],
"000029": [
100,
100,
100,
53,
25,
8,
100,
28.000000000000004,
18
],
"000030": [
37,
53,
0,
56.00000000000001,
0,
0,
0,
71.99999999999999,
33
],
"000031": [
100,
100,
100,
56.00000000000001,
0,
19,
100,
31,
21
],
"000032": [
22,
54,
0,
51,
0,
10,
0,
43,
21
],
"000035": [
100,
48,
100,
11.999999999999998,
0,
100,
100,
25,
13
],
"000037": [
0,
0,
0,
50,
0,
100,
0,
72.99999999999999,
100
],
"000038": [
27,
0,
0,
51,
0,
88,
0,
79.00000000000001,
22
],
"000006": [
100,
100,
100,
99,
0,
100,
100,
34,
100
],
"000040": [
100,
0,
100,
93,
100,
100,
100,
44,
28
],
"000041": [
54,
100,
0,
51,
12.5,
100,
0,
67,
100
],
"000042": [
100,
100,
100,
53,
25,
11,
100,
27,
18
],
"000043": [
100,
100,
100,
23,
25,
100,
100,
49,
20
],
"000044": [
100,
100,
100,
78,
100,
100,
100,
50,
92
],
"000045": [
100,
100,
100,
90,
0,
91,
100,
24,
35
],
"000047": [
100,
100,
100,
100,
25,
100,
100,
16,
45
],
"000048": [
48,
100,
0,
56.00000000000001,
0,
100,
0,
71.99999999999999,
0
],
"000050": [
30,
100,
0,
51,
0,
100,
0,
89,
39
],
"000051": [
0,
0,
0,
50,
0,
100,
0,
83,
56
],
"000052": [
34,
42,
0,
53,
0,
90,
0,
84,
17
],
"000054": [
100,
100,
100,
56.99999999999999,
25,
7,
100,
28.000000000000004,
33
],
"000055": [
20.999999999999996,
100,
0,
51,
0,
100,
0,
76.00000000000001,
22
],
"000056": [
56.00000000000001,
100,
51,
94,
0,
100,
100,
38.00000000000001,
0
],
"000058": [
100,
100,
100,
56.00000000000001,
25,
100,
100,
7.000000000000001,
7
],
"000060": [
0,
0,
0,
50,
0,
100,
0,
0,
100
],
"000064": [
14.000000000000002,
57,
0,
50,
0,
100,
0,
80.00000000000001,
17
],
"000065": [
30,
0,
0,
100,
0,
100,
0,
91,
56
],
"000068": [
45,
100,
2,
0,
87.5,
100,
0,
0,
34
],
"000069": [
27,
100,
0,
53,
0,
100,
0,
67,
16
],
"000071": [
100,
100,
100,
56.00000000000001,
50,
4,
100,
33,
24
],
"000073": [
100,
100,
100,
100,
25,
91,
100,
41,
18
],
"000076": [
75.99999999999999,
10,
0,
50,
12.5,
100,
0,
100,
100
],
"000077": [
100,
100,
100,
56.00000000000001,
25,
100,
100,
33,
48
],
"000078": [
100,
100,
100,
38,
0,
100,
100,
83,
37
],
"000079": [
1,
0,
0,
53,
0,
97,
0,
53,
42
],
"000160": [
30,
100,
0,
51,
0,
100,
0,
77.00000000000001,
32
],
"000157": [
100,
47,
100,
55.00000000000001,
0,
17,
75,
43,
35
],
"000156": [
52,
100,
100,
56.00000000000001,
0,
11,
100,
31,
35
],
"000153": [
0,
52,
0,
52,
0,
100,
0,
54,
34
],
"000152": [
0,
57,
0,
51,
37.5,
76,
0,
45,
34
],
"000151": [
100,
51,
100,
94,
0,
100,
35,
47,
78
],
"000150": [
30,
0,
0,
52,
62.5,
100,
0,
61,
12
],
"000148": [
96,
0,
100,
45,
25,
99,
100,
28.000000000000004,
28
],
"000147": [
100,
35,
100,
62,
0,
13,
91,
31,
46
],
"000146": [
100,
100,
100,
0,
0,
94,
100,
40.00000000000001,
74
],
"000145": [
100,
100,
100,
38,
0,
100,
100,
32,
75
],
"000143": [
14.000000000000002,
0,
0,
52,
0,
42,
0,
65,
24
],
"000142": [
100,
100,
100,
73,
0,
100,
100,
44,
24
],
"000140": [
100,
45,
100,
51,
0,
12,
100,
34,
51
],
"000137": [
0,
0,
0,
52,
100,
94,
0,
65,
23
],
"000135": [
28.000000000000004,
63,
0,
0,
0,
100,
0,
100,
85
],
"000134": [
0,
0,
0,
0,
0,
100,
0,
76.00000000000001,
100
],
"000133": [
100,
0,
100,
47.99999999999999,
25,
17,
100,
40.00000000000001,
48
],
"000132": [
100,
51,
100,
0,
0,
100,
100,
55.00000000000001,
100
],
"000131": [
100,
100,
100,
0,
12.5,
100,
100,
38.00000000000001,
70
],
"000129": [
37,
0,
0,
51,
0,
100,
0,
67,
27
],
"000126": [
100,
100,
100,
50,
12.5,
0,
100,
50,
39
],
"000125": [
0,
0,
0,
52,
0,
100,
0,
71.99999999999999,
57
],
"000122": [
100,
100,
100,
69,
25,
0,
100,
34,
0
],
"000121": [
100,
100,
100,
8,
0,
100,
100,
36.99999999999999,
100
],
"000080": [
1,
100,
0,
51,
0,
100,
0,
69.99999999999999,
39
],
"000081": [
14.000000000000002,
100,
0,
0,
0,
100,
0,
71.99999999999999,
69
],
"000083": [
100,
100,
100,
54,
12.5,
50,
100,
28.999999999999996,
23
],
"000085": [
100,
100,
100,
37,
25,
89,
100,
31,
33
],
"000086": [
100,
0,
100,
42,
0,
81,
79,
50,
24
],
"000088": [
100,
100,
100,
95.99999999999999,
12.5,
53,
93,
26,
13
],
"000091": [
13,
100,
0,
56.99999999999999,
0,
100,
0,
68.99999999999999,
26
],
"000092": [
100,
100,
100,
56.00000000000001,
0,
8,
97,
31,
38
],
"000096": [
100,
100,
100,
0,
0,
100,
100,
39.00000000000001,
31
],
"000097": [
100,
0,
100,
70,
0,
44,
88,
36.99999999999999,
42
],
"000099": [
100,
45,
100,
31,
12.5,
91,
100,
36.99999999999999,
36
],
"000100": [
43,
0,
100,
100,
0,
17,
100,
35.99999999999999,
27
],
"000103": [
100,
48,
100,
44,
25,
100,
100,
31,
33
],
"000104": [
0,
0,
0,
64,
0,
14,
0,
55.00000000000001,
22
],
"000106": [
100,
48,
100,
34,
12.5,
50,
100,
35.99999999999999,
28
],
"000108": [
100,
100,
100,
54,
0,
7,
100,
31,
42
],
"000109": [
28.999999999999996,
46,
0,
51,
0,
21,
0,
61,
24
],
"000110": [
100,
100,
100,
56.00000000000001,
0,
50,
94,
42,
26
],
"000111": [
100,
100,
100,
63,
0,
100,
100,
39.00000000000001,
84
],
"000114": [
51,
100,
0,
95,
0,
100,
0,
65,
71
],
"000115": [
0,
0,
0,
51,
0,
16,
0,
39.00000000000001,
24
],
"000116": [
20.999999999999996,
100,
0,
64,
0,
92,
0,
70.99999999999999,
28
],
"000117": [
100,
100,
100,
0,
25,
100,
100,
39.00000000000001,
64
],
"000118": [
100,
100,
100,
90,
0,
100,
97,
40.00000000000001,
100
],
"000155": [
100,
0,
99,
0,
0,
100,
99,
43,
27
],
"000161": [
100,
40,
100,
54,
0,
100,
100,
45,
0
]
}
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
function JordanFace() {
const bg_color = [0, 0, 0];
const fg_color = [255, 255, 255];
const stroke_color = [95, 52, 8];
this.eyepaint_value = 2;
this.mouth_value = 1;
this.tilt_value = 0;
this.colour2_value = 0;
this.draw = function(positions) {
rotate(this.tilt_value);
var eye1_pos = positions.left_eye;
var eye2_pos = positions.right_eye;
var toplip_pos = positions.top_lip;
var bottomlip_pos = positions.bottom_lip;
// Here I set my colour variables for the face and eye paint colour
if (this.colour_value === 1) {
var colour1 = color(240,10,10,120);
}
if (this.colour_value === 2) {
var colour1 = color(0,0,255,150);
}
if (this.colour_value === 3) {
var colour1 = color(255,255,255,120);
}
if (this.colour2_value === 1) {
var colour2 = color(240,10,10,80);
}
if (this.colour2_value === 2) {
var colour2 = color(0,0,255,80);
}
if (this.colour2_value === 3) {
var colour2 = color(255,255,255,80);
}
if (this.colour2_value === 4) {
var colour2 = color(255,255,255,0);
}
//face
// Here I use the points around the jaw and eyebrows to make a face shape that is filled
// to provide a base for the face paint
fill(colour2);
noStroke();
beginShape();
for(var i=0; i<positions.chin.length;i++) {
vertex(positions.chin[i][0], positions.chin[i][1]);
}
for(var i=positions.right_eyebrow.length-1; i>=0;i--) {
vertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
for(var i=positions.left_eyebrow.length-1; i>=0;i--) {
vertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
endShape(CLOSE);
// eyes
if (this.eyepaint_value === 1) {
;
// This is my first variant of the eye make up that makes a curved triangle going down from the eye.
fill(colour1);
beginShape();
vertex(eye1_pos[4][0]+.2 , eye1_pos[3][1]+.21);
quadraticVertex(-1.5, -.2, eye1_pos[1][0] -.4 , 1.2);
quadraticVertex(-1.5, -.2, eye1_pos[0][0] , eye1_pos[3][1]+.25);
endShape();
beginShape();
vertex(eye2_pos[4][0]-.2 , eye2_pos[3][1]+.21);
quadraticVertex(1.5, -.2, eye2_pos[1][0] +.4 , 1.2);
quadraticVertex(1.5, -.2, eye2_pos[3][0], eye2_pos[0][1]+.25);
endShape();
noStroke();
}
if (this.eyepaint_value === 2) {
;
// For my second eye make-up variant I've made a diamond shape mapped to the eye corners.
fill(colour1);
triangle(eye1_pos[3][0] +.2,eye1_pos[3][1],eye1_pos[0][0]-.25,eye1_pos[0][1],eye1_pos[2][0],-2.5);
triangle(eye1_pos[3][0]+.2,eye1_pos[3][1],eye1_pos[0][0]-.25,eye1_pos[0][1],eye1_pos[1][0],.5);
triangle(eye2_pos[3][0]+.25,eye2_pos[3][1],eye2_pos[0][0]-.2,eye2_pos[0][1],eye2_pos[1][0],-2.5);
triangle(eye2_pos[3][0]+.25,eye2_pos[3][1],eye2_pos[0][0]-.2,eye2_pos[0][1],eye2_pos[2][0],.5);
}
if (this.eyepaint_value === 3) {
;
// I've made a variant of the eye make up that is a stripe across the face
// I didn't end up using this variant as it does not work well visually
// However I've kept the code in place to show my process and so that it can be seen when changing the settings
fill(colour1);
rect(eye1_pos[0][0] -.25 ,eye1_pos[2][1] -.2,3,.6,.2);
}
// I've seperated the dark makeup around the eye from the other parts so I can turn it on and off independently.
// However I've left it on for all variants as it works best visually.
if (this.eyeshadow_value === 1) {
fill(0,0,0,120)
bezier(eye1_pos[3][0]+.2 , eye1_pos[3][1], -1.6 , -1.9 , -1.8 , -.3, eye1_pos[3][0]+.2 , eye1_pos[3][1] );
bezier(eye2_pos[0][0] -.2, eye2_pos[0][1], 1.6 , -1.9 , 1.8 , -.3, eye2_pos[0][0]-.2 , eye2_pos[0][1]);
fill(255,0,0);
fill(fg_color);
}
// mouth
if (this.mouth_value === 1) {
// My first mouth variant is a quad below the lip
fill(0,0,0,120);
quad(bottomlip_pos[2][0],bottomlip_pos[2][1],bottomlip_pos[4][0],bottomlip_pos[4][1],
bottomlip_pos[4][0] +.1,bottomlip_pos[4][1]+.6,bottomlip_pos[2][0] -.1,bottomlip_pos[2][1]+.6,2);
}
if (this.mouth_value === 2) {
// The second mouth variant is a kind of exaggerated lipstick that makes the mouth appear much larger.
fill(0,0,0,120);
bezier(toplip_pos[0][0]-.2, toplip_pos[0][1],0,toplip_pos[4][1]-.2,0,toplip_pos[4][1]-.2,toplip_pos[6][0]+.2,toplip_pos[6][1]);
bezier(toplip_pos[0][0]-.2, toplip_pos[0][1],-.4,bottomlip_pos[3][1]+.3,.4,bottomlip_pos[3][1]+.3,toplip_pos[6][0]+.2,toplip_pos[6][1]);
}
}
this.setProperties = function(settings) {
this.eyepaint_value = int(map(settings[0], 0, 100, 1, 3));
this.mouth_value = int(map(settings[1], 0, 100, 1, 2));
this.colour_value = int(map(settings[3], 0, 100 ,1, 3));
this.eyeshadow_value = int(map(settings[4], 0, 100 ,1, 2));
this.colour2_value = int(map(settings[5], 0, 100 ,1, 3));
}
this.getProperties = function() {
let settings = new Array(5);
settings[0] = map(this.eyepaint_value, 1, 3, 0, 100);
settings[1] = map(this.mouth_value, 1, 2, 0, 100);
settings[3] = map(this.colour_value, 1, 3, 0, 100);
settings[4] = map(this.eyeshadow_value, 1, 2, 0, 100);
settings[5] = map(this.colour2_value, 1, 3, 0, 100);
console.log(settings[5]);
return settings;
}
}
{
"000001": [
0,
75,
0,
0,
0,
100
],
"000002": [
50,
50,
null,
0,
0,
100
],
"000005": [
0,
0,
null,
0,
0,
100
],
"000006": [
50,
50,
null,
50,
0,
0
],
"000007": [
0,
100,
null,
0,
0,
100
],
"000009": [
50,
50,
null,
0,
0,
100
],
"000010": [
50,
50,
null,
0,
0,
100
],
"000013": [
0,
100,
null,
0,
0,
100
],
"000014": [
0,
0,
null,
50,
0,
0
],
"000015": [
0,
100,
null,
0,
0,
100
],
"000016": [
0,
100,
null,
0,
0,
100
],
"000018": [
50,
50,
null,
0,
0,
100
],
"000020": [
50,
100,
null,
0,
0,
100
],
"000023": [
0,
100,
null,
0,
0,
100
],
"000025": [
0,
100,
null,
0,
0,
100
],
"000028": [
50,
0,
null,
0,
0,
100
],
"000029": [
50,
50,
null,
0,
0,
100
],
"000030": [
0,
100,
null,
0,
0,
100
],
"000031": [
0,
0,
null,
0,
0,
100
],
"000032": [
0,
100,
null,
0,
0,
100
],
"000035": [
50,
50,
null,
0,
0,
100
],
"000037": [
0,
100,
null,
50,
0,
0
],
"000038": [
0,
100,
null,
0,
0,
100
],
"000040": [
0,
0,
null,
0,
0,
100
],
"000041": [
50,
100,
null,
100,
0,
50
],
"000042": [
50,
50,
null,
0,
0,
100
],
"000043": [
50,
50,
null,
0,
0,
100
],
"000044": [
50,
50,
null,
50,
0,
0
],
"000045": [
50,
0,
null,
0,
0,
100
],
"000047": [
50,
50,
null,
50,
0,
0
],
"000048": [
0,
100,
null,
0,
0,
100
],
"000050": [
0,
100,
null,
0,
0,
100
],
"000051": [
0,
100,
null,
0,
0,
100
],
"000052": [
0,
100,
null,
100,
0,
50
],
"000054": [
50,
50,
null,
0,
0,
100
],
"000055": [
0,
100,
null,
0,
0,
100
],
"000056": [
50,
0,
null,
0,
0,
100
],
"000058": [
50,
50,
null,
0,
0,
100
],
"000060": [
0,
100,
null,
50,
0,
0
],
"000064": [
0,
100,
null,
0,
0,
100
],
"000065": [
0,
100,
null,
100,
0,
50
],
"000068": [
0,
100,
null,
100,
0,
50
],
"000069": [
0,
100,
null,
0,
0,
100
],
"000071": [
50,
50,
null,
0,
0,
100
],
"000073": [
50,
50,
null,
0,
0,
100
],
"000076": [
0,
100,
null,
0,
0,
100
],
"000077": [
50,
50,
null,
0,
0,
100
],
"000078": [
50,
50,
null,
0,
0,
100
],
"000079": [
0,
100,
null,
0,
0,
100
],
"000080": [
0,
100,
null,
0,
0,
100
],
"000081": [
0,
100,
null,
0,
0,
100
],
"000083": [
50,
50,
null,
0,
0,
100
],
"000085": [
50,
50,
null,
0,
0,
100
],
"000086": [
0,
0,
null,
0,
0,
100
],
"000088": [
50,
50,
null,
0,
0,
100
],
"000091": [
0,
100,
null,
0,
0,
100
],
"000092": [
50,
50,
null,
0,
0,
100
],
"000096": [
50,
50,
null,
100,
0,
50
],
"000097": [
50,
50,
null,
0,
0,
100
],
"000099": [
50,
50,
null,
0,
0,
100
],
"000100": [
0,
0,
null,
0,
0,
100
],
"000103": [
50,
0,
null,
0,
0,
100
],
"000104": [
0,
100,
null,
0,
0,
100
],
"000106": [
50,
0,
null,
0,
0,
100
],
"000108": [
50,
50,
null,
0,
0,
100
],
"000109": [
0,
100,
null,
100,
0,
50
],
"000110": [
50,
50,
null,
0,
0,
100
],
"000111": [
0,
0,
null,
50,
0,
0
],
"000114": [
0,
100,
null,
0,
0,
100
],
"000115": [
0,
100,
null,
0,
0,
100
],
"000116": [
0,
100,
null,
0,
0,
100
],
"000117": [
50,
50,
null,
50,
0,
0
],
"000118": [
0,
0,
null,
50,
0,
0
],
"000121": [
50,
0,
null,
0,
0,
100
],
"000122": [
0,
0,
null,
0,
0,
100
],
"000125": [
0,
100,
null,
100,
0,
50
],
"000126": [
50,
50,
null,
100,
0,
50
],
"000129": [
0,
100,
null,
0,
0,
100
],
"000131": [
50,
50,
null,
100,
0,
50
],
"000132": [
50,
50,
null,
50,
0,
0
],
"000133": [
50,
0,
null,
0,
0,
100
],
"000134": [
0,
100,
null,
50,
0,
0
],
"000135": [
0,
100,
null,
50,
0,
0
],
"000137": [
0,
100,
null,
0,
0,
100
],
"000140": [
50,
0,
null,
0,
0,
100
],
"000142": [
50,
50,
null,
0,
0,
100
],
"000143": [
0,
100,
null,
0,
0,
100
],
"000145": [
50,
50,
null,
0,
0,
100
],
"000146": [
50,
50,
null,
100,
0,
50
],
"000147": [
50,
0,
null,
0,
0,
100
],
"000148": [
0,
0,
null,
0,
0,
100
],
"000150": [
0,
100,
null,
0,
0,
100
],
"000151": [
50,
50,
null,
50,
0,
0
],
"000152": [
0,
100,
null,
0,
0,
100
],
"000153": [
0,
100,
null,
0,
0,
100
],
"000155": [
50,
50,
null,
0,
0,
100
],
"000156": [
0,
0,
null,
0,
0,
100
],
"000157": [
50,
50,
null,
0,
0,
100
],
"000160": [
0,
100,
null,
0,
0,
100
],
"000161": [
50,
50,
null,
0,
0,
100
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// other variables can be in here too
// these control the colors used
const truLip = "#E37D55";
const truWhite = "#E3CFB9";
const truShadow = "#A06644";
const truMouth = "#2B1C17";
function JoyFace() {
// these are state variables for a face
// (your variables may be different)
this.wink_value = 1;//keep
this.colour_value = 0.5;//keep
this.hair_colour_value = 0.5;
this.eye_colour_value = 0.5;
this.brow_value = 0.5;
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
//Variables for face size and mouth status
var faceWidth = positions.chin[16][0] - positions.chin[0][0];//right of face - left of face = face width
var faceHeight = positions.chin[16][1] - positions.chin[0][1];//bottom of face - top of face = face height
//variables to indicate which side the face tends toward
var faceCenter = positions.chin[16][0] - faceWidth/2;//right of face - (face width/2) = center face position
var faceAngle = map(positions.nose_tip[2][0], positions.chin[0][0], positions.chin[16][0], -1, 1);//map middle of nose value to face width from left face-right face to -1 - +1
// print(faceAngle);
//if above val is >0, nose is on right. if val < 0, nose is on left
if((positions.top_lip[9][1] - positions.top_lip[0][1])>0){
var smile_Value = positions.top_lip[9][1] - positions.top_lip[0][1]
}
else{
var smile_Value = positions.top_lip[9][1] - positions.top_lip[6][1]; //corners of mouth are above/below mid top lip
}
var smile_Value = 2*positions.top_lip[9][1] - positions.top_lip[6][1]- positions.top_lip[0][1];
var mouthOpen_Value = positions.bottom_lip[9][1] - positions.top_lip[9][1]/*bottom of top lip*/; // distance between bottom middle of top lip and top middle of bottom lip
if(smile_Value > 0){//if smile_value is positive, smiling, else not smiling
var smile = true;
}
else{
var smile = false;
}
if (mouthOpen_Value > 0.1){// if mouthOpen_value is small (close to 0), the mouth is closed, else it is open
var mouthOpen = true;
}
else{
var mouthOpen = false;
}
if(faceAngle < 0.05){
var centerFaceDraw = positions.nose_tip[2][0] - faceCenter;
}
else if(faceAngle > 0.05){
var centerFaceDraw = positions.nose_tip[2][0] - faceCenter*-1;
}
else{
var centerFaceDraw = 0;
}
//face
var truBase = color(241, 141, 83);
var truBase2 = color(255, 199, 113);
var curBaseColour = lerpColor(truBase2, truBase, this.colour_value);
fill(curBaseColour);
noStroke();
beginShape();
for(var i=0; i<positions.chin.length;i++) {
vertex(positions.chin[i][0], positions.chin[i][1]);
}
for(var i=positions.right_eyebrow.length-1; i>=2;i--) {
vertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1] - 1);
}
for(var i=positions.left_eyebrow.length-3; i>=0;i--) {
vertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1] - 1);
}
endShape();
//eye fake tan rims
push();
scale(0.03);
noFill();
var l = 0.5*509.0/255;
strokeWeight(1.5);
push();
translate(-28, -32.5);
for (var i = 1; i<225*4; i+=32) {
stroke ( 255, 255, 240, 255-(i+200)/(l));
ellipse(positions.left_eye[0][0], positions.left_eye[0][1], i, i);
}
pop();
push();
translate(28, -32.5);
for (var i = 1; i<225*4; i+=32) {
stroke ( 255, 255, 210, 255-(i+200)/(l));
ellipse(positions.right_eye[0][0], positions.right_eye[0][1], i, i);
}
pop();
noStroke()
pop();
//eyes
//eye rim
//R
push();
scale(1.2);
translate(-0.1, 0.17);
fill(truShadow);
if (this.wink_value >= 0.5 ){
beginShape();
for(var i=0; i<positions.right_eye.length;i++) {
vertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
endShape();
}
else{
beginShape();
for(var i=0; i<positions.right_eye.length - 2;i++) {
vertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
vertex(positions.right_eye[1][0] + (positions.right_eye[2][0] - positions.right_eye[1][0])/2 - 0.04, positions.right_eye[1][1] +0.03 );
vertex(positions.right_eye[1][0] + (positions.right_eye[2][0] - positions.right_eye[1][0])/2 + 0.05, positions.right_eye[1][1] +0.02 );
endShape();
}
pop();
push()
scale(1.2);
translate(0.1, 0.17);
//L
fill(truShadow);
beginShape();
for(var i=0; i<positions.left_eye.length;i++) {
vertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
endShape();
pop();
//eye whites
//R
fill(truWhite);
if (this.wink_value >= 0.5 ){
beginShape();
for(var i=0; i<positions.right_eye.length;i++) {
vertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
endShape();
}
//L
fill(truWhite);
beginShape();
for(var i=0; i<positions.left_eye.length;i++) {
vertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
endShape();
noStroke();
//irises
var truIris1 = color(136, 173, 150);
var truIris2 =color(0, 47, 54);
var truIris3 = color(163, 97, 10);
var truIris4 =color(61, 33, 0);
//setting eye colour
if(this.eye_colour_value < 0.4){
var truIris = lerpColor(truIris1, truIris2, this.eye_colour_value);
}
else if(this.eye_colour_value >= 0.4 && this.eye_colour_value < 0.6){
var truIris = lerpColor(truIris2, truIris3, this.eye_colour_value);
}
else{
var truIris = lerpColor(truIris3, truIris4, this.eye_colour_value);
}
fill(truIris);
//R
if (this.wink_value >= 0.5 ){
beginShape();
vertex(positions.right_eye[1][0], positions.right_eye[1][1]);
vertex(positions.right_eye[2][0], positions.right_eye[2][1]);
vertex(positions.right_eye[4][0], positions.right_eye[4][1]-0.03);
vertex(positions.right_eye[5][0]+(positions.right_eye[4][0]-positions.right_eye[5][0])/2, positions.right_eye[4][1])
vertex(positions.right_eye[5][0], positions.right_eye[5][1]-0.03);
endShape();
}
//L
beginShape();
vertex(positions.left_eye[1][0], positions.left_eye[1][1]);
vertex(positions.left_eye[2][0], positions.left_eye[2][1]);
vertex(positions.left_eye[4][0], positions.left_eye[4][1]-0.03);
vertex(positions.left_eye[5][0]+(positions.left_eye[4][0]-positions.left_eye[5][0])/2, positions.left_eye[4][1])
vertex(positions.left_eye[5][0], positions.left_eye[5][1]-0.03);
endShape();
let bottomLip5 = positions.bottom_lip[3];
let topLip1 = positions.top_lip[0];
let topLip4 = positions.top_lip[3];
let topLip7 = positions.top_lip[6];
//lips
if (!smile && !mouthOpen){ //draw pucker
push();
translate (positions.nose_tip[2][0] - 3.1, positions.nose_tip[2][1] - 4.8);
scale(0.008, 0.0089);
fill(truLip);
beginShape();
vertex(390,571);
vertex(375,565);
vertex(367,570);
vertex(351,595);
vertex(334,623);
vertex(327,629);
vertex(331,634);
vertex(344,675);
vertex(366,703);
vertex(396,707);
vertex(417,698);
vertex(433,677);
vertex(442,644);
vertex(439,630);
vertex(445,627);
vertex(435,618);
vertex(427,594);
vertex(416,573);
vertex(405,565);
endShape();
//inside
fill(truMouth);
push();
scale(0.5);
translate(390, 650);
beginShape();
vertex(387,591);
vertex(369,597);
vertex(362,613);
vertex(356,625);
vertex(363,649);
vertex(387,653);
vertex(413,644);
vertex(418,623);
vertex(412,610);
vertex(404,589);
endShape();
pop();
pop();
}
else if (!smile && mouthOpen){ //draw shouting mouth
push();
translate (positions.nose_tip[2][0] - 3.1, positions.nose_tip[2][1] - 4.8);
scale(0.008, 0.0089);
fill(truLip);
beginShape();
vertex(390,571);
vertex(375,565);
vertex(367,570);
vertex(351,595);
vertex(334,623);
vertex(327,629);
vertex(331,634);
vertex(344,675);
vertex(366,703);
vertex(396,707);
vertex(417,698);
vertex(433,677);
vertex(442,644);
vertex(439,630);
vertex(445,627);
vertex(435,618);
vertex(427,594);
vertex(416,573);
vertex(405,565);
endShape();
//inside
fill(truMouth);
beginShape();
vertex(387,591);
vertex(369,597);
vertex(362,613);
vertex(356,625);
vertex(363,649);
vertex(387,653);
vertex(413,644);
vertex(418,623);
vertex(412,610);
vertex(404,589);
endShape();
//teeth1
fill(truWhite);
beginShape();
vertex(418,619);
vertex(386,618);
vertex(356,620);
vertex(363,649);
vertex(387,644);
vertex(413,644);
endShape();
//teeth2
beginShape();
vertex(409,599);
vertex(405,589);
vertex(369,596);
vertex(369,601);
vertex(369,596);
endShape();
pop();
}
else if (smile && !mouthOpen){ //grumpy face
push();
translate (positions.nose_tip[2][0] - 3.1, positions.nose_tip[2][1] - 4.9);
scale(0.008, 0.0089);
fill(truLip);
beginShape();
vertex(390,617);//cupids bow
vertex(375,617);//highest
vertex(367,617);
vertex(327,639);//left
vertex(366,650);
vertex(396,660);//lowest
vertex(417,650);
vertex(445,637);//right
vertex(416,627);
vertex(405,620);//highest2
endShape();
//inside
fill(truShadow);
beginShape();
vertex(387,630);//highest
vertex(362,635);
vertex(295,665);//left
vertex(363,649);
vertex(387,642);//lowest
vertex(413,645);
vertex(465,660);//right
vertex(412,630);
endShape();
pop();
}
else if (smile && mouthOpen){ //normal smile
//teeth
noStroke();
fill(truWhite);
beginShape();
vertex(topLip1[0], topLip1[1]);
vertex(topLip4[0], topLip4[1]);
vertex(topLip7[0], topLip7[1]);
vertex(bottomLip5[0], bottomLip5[1]);
vertex(topLip1[0], topLip1[1]);
endShape();
//lips
noStroke();
fill(truLip);
beginShape();
for(var i=0; i<positions.top_lip.length;i++) {
vertex(positions.top_lip[i][0], positions.top_lip[i][1]);
}
endShape();
beginShape();
for(var i=0; i<positions.bottom_lip.length;i++) {
vertex(positions.bottom_lip[i][0], positions.bottom_lip[i][1]);
}
endShape();
//under-mouth shadow
fill(truShadow);
beginShape();
if(faceAngle > -0.5){ //if not facing left
vertex(positions.bottom_lip[3][0] - 0.4,positions.bottom_lip[3][1] + 0.1);
vertex(positions.bottom_lip[3][0] - 0.3,positions.bottom_lip[3][1] + 0.08);
vertex(positions.bottom_lip[3][0] - 0.3,positions.bottom_lip[3][1] + 0.07);
}
else{
vertex(positions.bottom_lip[3][0] - 0,positions.bottom_lip[3][1] + 0.1);
vertex(positions.bottom_lip[3][0] - 0.1,positions.bottom_lip[3][1] + 0.08);
vertex(positions.bottom_lip[3][0] - 0.15,positions.bottom_lip[3][1] + 0.07);
}
vertex(positions.bottom_lip[3][0] - 0.03,positions.bottom_lip[3][1]);//bottom-most lip point
if(faceAngle < 0.5){ // if not facing right
vertex(positions.bottom_lip[3][0] + 0.2,positions.bottom_lip[3][1] + 0.03);
vertex(positions.bottom_lip[3][0] + 0.3,positions.bottom_lip[3][1] + 0.07);
vertex(positions.bottom_lip[3][0] + 0.3,positions.bottom_lip[3][1] + 0.08);
vertex(positions.bottom_lip[3][0] + 0.4,positions.bottom_lip[3][1] + 0.1);
}
else{
vertex(positions.bottom_lip[3][0] + 0.15,positions.bottom_lip[3][1] + 0.03);
vertex(positions.bottom_lip[3][0] + 0.2,positions.bottom_lip[3][1] + 0.07);
vertex(positions.bottom_lip[3][0] + 0.25,positions.bottom_lip[3][1] + 0.08);
vertex(positions.bottom_lip[3][0] + 0.15,positions.bottom_lip[3][1] + 0.1);
}
vertex(positions.bottom_lip[3][0],positions.bottom_lip[3][1] + 0.09);//mid bottom
endShape();
}
//Nose
let noseMidX = positions.nose_tip[2][0];
let noseMidY = positions.nose_tip[2][1];
let noseMLeftX = positions.nose_tip[1][0];
let noseMLeftY = positions.nose_tip[1][1];
let noseLeftX = positions.nose_tip[0][0];
let noseLeftY = positions.nose_tip[0][1];
let noseRightX = positions.nose_tip[4][0];
let noseRightY = positions.nose_tip[4][1];
let noseMRightX = positions.nose_tip[3][0];
let noseMRightY = positions.nose_tip[3][1];
fill(curBaseColour);
beginShape();
if(faceAngle <=-0.1){ // if face is pointed more toward the right
vertex(noseLeftX + 0.2, noseLeftY - 0.5);//left high
vertex(noseLeftX - 0.02, noseLeftY - 0.1);//left
vertex(noseLeftX + 0.08, noseLeftY + 0.08);
}
vertex(noseMLeftX - 0.02 , noseMLeftY - 0.05);
vertex(noseMLeftX + 0.05, noseMLeftY - 0.2);//left nostril
vertex(noseMLeftX + 0.1, noseMLeftY + 0.05);//left tip
vertex(noseMidX + 0.08, noseMidY - 0.08);//right tip
vertex(noseMRightX, noseMRightY - 0.1);//right nostril
vertex(noseMRightX + 0.05, noseMRightY + 0.05);
vertex(noseRightX, noseRightY);
if(faceAngle > 0.1){ //if face is pointed toward the left more
vertex(noseRightX - 0.2, noseRightY-0.5);//right high
}
endShape();
fill(truShadow);
beginShape();
if(faceAngle <=-0.1){ // if face is pointed more toward the right
vertex(noseLeftX + 0.2, noseLeftY - 0.8);//left high
vertex(noseLeftX - 0.02, noseLeftY - 0.1);//left
vertex(noseLeftX + 0.08, noseLeftY + 0.08);
}
vertex(noseMLeftX - 0.02 , noseMLeftY - 0.05);
vertex(noseMLeftX + 0.05, noseMLeftY - 0.2);//left nostril
vertex(noseMLeftX + 0.1, noseMLeftY + 0.05);//left tip
vertex(noseMidX + 0.08, noseMidY - 0.08);//right tip
vertex(noseMRightX, noseMRightY - 0.1);//right nostril
vertex(noseMRightX + 0.05, noseMRightY + 0.05);
vertex(noseRightX, noseRightY);
if(faceAngle > 0.1){ //if face is pointed toward the left more
vertex(noseRightX - 0.2, noseRightY-0.8);//right high
}
vertex(noseMRightX + 0.25, noseMRightY - 0.05);
vertex(noseMRightX + 0.03, noseMRightY + 0.1);
vertex(noseMRightX - 0.05, noseMRightY + 0.1);
vertex(noseMidX + 0.1, noseMidY + 0.04);
vertex(noseMidX - 0.13, noseMidY + 0.05);
vertex(noseMLeftX, noseMLeftY + 0.07);
vertex(noseMLeftX - 0.09 , noseMLeftY + 0.08);
vertex(noseLeftX - 0.02, noseLeftY + 0.1);
vertex(noseLeftX - 0.1, noseLeftY + 0.0);
endShape();
//shadows
//eyelids
//R
beginShape();
vertex(positions.right_eye[0][0], positions.right_eye[0][1] - 0.12);
vertex(positions.right_eye[1][0], positions.right_eye[1][1] - 0.1);
vertex(positions.right_eye[2][0], positions.right_eye[2][1] - 0.1);
vertex(positions.right_eye[3][0], positions.right_eye[3][1] - 0.12);
vertex(positions.right_eye[2][0], positions.right_eye[2][1] - 0.15);
vertex(positions.right_eye[1][0], positions.right_eye[1][1] - 0.15);
endShape();
beginShape();
vertex(positions.left_eye[0][0], positions.left_eye[0][1] - 0.1);
vertex(positions.left_eye[1][0], positions.left_eye[1][1] - 0.1);
vertex(positions.left_eye[2][0], positions.left_eye[2][1] - 0.1);
vertex(positions.left_eye[3][0], positions.left_eye[3][1] - 0.1);
vertex(positions.left_eye[2][0], positions.left_eye[2][1] - 0.15);
vertex(positions.left_eye[1][0], positions.left_eye[1][1] - 0.15);
endShape();
//Brows
var truhair = color(255, 206, 10);
var truhair2 = color(255, 246, 140);
var curHairColour = lerpColor(truhair2, truhair, this.hair_colour_value);
fill(curHairColour);
var browArch = map(this.brow_value, 0, 1, -0.23, 0.17);
//R
push();
beginShape();
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[0][1]);//left top
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1] + browArch);//middle top
vertex(positions.right_eyebrow[4][0], positions.right_eyebrow[4][1]);//right top
vertex(positions.right_eyebrow[2][0], positions.right_eyebrow[2][1]+0.2 + browArch);//middle bottom
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[0][1]+0.2);//left bottom
endShape();
pop();
//L
beginShape();
vertex(positions.left_eyebrow[0][0], positions.left_eyebrow[0][1]);//left top
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]);//middle top
vertex(positions.left_eyebrow[4][0], positions.left_eyebrow[4][1]);//right top
vertex(positions.left_eyebrow[4][0], positions.left_eyebrow[4][1]+0.2);
vertex(positions.left_eyebrow[2][0], positions.left_eyebrow[2][1]+0.2);//middle bottom
endShape();
//Hair
fill(curHairColour);
if(faceAngle <= -0.6){ //looking to the left the most (extreme)
push();
translate (-2.8, -4.8);
scale(0.008, 0.0089);
beginShape();
vertex(225,340);//corner
vertex(250,305);
vertex(333,276);
vertex(408,302);
vertex(534,329);
vertex(549,462);
vertex(561,482);
vertex(578,493);
vertex(600,454);
vertex(587,420);
vertex(591,382);
vertex(596,343);
vertex(588,322);
vertex(582,278);
vertex(607,252);
vertex(586,202);
vertex(536,190);
vertex(485,167);
vertex(419,157);//R
vertex(347,154);//highest
vertex(266,174);//L
vertex(198,199);
vertex(142,230);
vertex(142,261);
vertex(163,286);
endShape();
pop();
beginShape();
//hairline
vertex(positions.chin[15][0], positions.chin[15][1]);//face R
vertex(positions.chin[16][0] - 0.5, positions.chin[16][1]); // Face R
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1] - 0.4);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[2][1] - 0.45);
vertex(positions.right_eyebrow[0][0] - 0.7, positions.right_eyebrow[0][1] - 0.8);//mid forehead hair
vertex(positions.left_eyebrow[3][0] - 0.4, positions.right_eyebrow[2][1] - 0.4);
vertex(positions.left_eyebrow[0][0]+0.05, positions.left_eyebrow[0][1] - 0.5);
vertex(positions.chin[0][0], positions.chin[0][1]); //face L
vertex(positions.chin[1][0], positions.chin[1][1]);//face L
vertex(positions.chin[1][0]-0.1, positions.chin[1][1]);
//non-hairline
vertex(positions.chin[1][0] - 0.05, positions.chin[1][1] - 0.2);
vertex(positions.chin[0][0] - 0.15, positions.chin[0][1] - 0.35);
vertex(positions.chin[0][0] - 0.2, positions.chin[0][1] - 0.7);
vertex(positions.chin[0][0] - 0.1, positions.chin[0][1] - 1.4);
vertex(positions.right_eyebrow[2][0]- 1.7, positions.right_eyebrow[2][1] - 1);
vertex(positions.right_eyebrow[2][0]- 1.5, positions.right_eyebrow[2][1] - 1);
vertex(positions.right_eyebrow[2][0]- 1, positions.right_eyebrow[2][1] - 1.5);
vertex(positions.right_eyebrow[2][0] + 1, positions.right_eyebrow[2][1] - 1.3);
vertex(positions.right_eyebrow[2][0] + 1.9, positions.right_eyebrow[2][1] - 0.7);
vertex(positions.right_eyebrow[2][0] + 2, positions.right_eyebrow[2][1] - 0.4);
endShape();
}
else if(faceAngle < -0.5 && faceAngle > -0.6){ //looking to the left the most
push();
translate (-2.8, -4.8);
scale(0.008, 0.0089);
beginShape();
vertex(160,500);
pop();
push();
vertex(positions.chin[1][0] + 180,positions.chin[1][1] + 490);//lowest left
//scale(125, 112.35);
vertex(positions.chin[0][0] + 180,positions.chin[0][1]+490);
pop();
push();
translate (-2.8, -4.8);
scale(0.008, 0.0089);
vertex(210,335);//corner
vertex(250,305);
vertex(333,276);
vertex(408,302);
vertex(534,329);
vertex(549,462);
vertex(561,482);
vertex(578,493);
vertex(600,454);
vertex(587,420);
vertex(591,382);
vertex(596,343);
vertex(588,322);
vertex(582,278);
vertex(607,252);
vertex(586,202);
vertex(536,190);
vertex(485,167);
vertex(419,157);//R
vertex(347,154);//highest
vertex(266,174);//L
vertex(198,199);
vertex(132,230);
vertex(132,261);
vertex(153,286);
vertex(141,308);
vertex(150,337);
vertex(145,378);
vertex(135,427);
endShape();
pop();
beginShape();
//hairline
vertex(positions.chin[15][0], positions.chin[15][1]);//face R
vertex(positions.chin[16][0] - 0.5, positions.chin[16][1]); // Face R
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1] - 0.4);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[2][1] - 0.45);
vertex(positions.right_eyebrow[0][0] - 0.7, positions.right_eyebrow[0][1] - 0.8);//mid forehead hair
vertex(positions.left_eyebrow[3][0] - 0.4, positions.right_eyebrow[2][1] - 0.4);
vertex(positions.left_eyebrow[0][0]+0.05, positions.left_eyebrow[0][1] - 0.5);
vertex(positions.chin[0][0], positions.chin[0][1]); //face L
vertex(positions.chin[1][0], positions.chin[1][1]);//face L
vertex(positions.chin[1][0]-0.1, positions.chin[1][1]);
//non-hairline
vertex(positions.chin[1][0] - 0.05, positions.chin[1][1] - 0.2);
vertex(positions.chin[0][0] - 0.15, positions.chin[0][1] - 0.35);
vertex(positions.chin[0][0] - 0.2, positions.chin[0][1] - 0.7);
vertex(positions.chin[0][0] - 0.1, positions.chin[0][1] - 1.4);
vertex(positions.right_eyebrow[2][0]- 2.35, positions.right_eyebrow[2][1] - 1);
vertex(positions.right_eyebrow[2][0]- 1.5, positions.right_eyebrow[2][1] - 1.6);
vertex(positions.right_eyebrow[2][0]- 1, positions.right_eyebrow[2][1] - 1.5);
vertex(positions.right_eyebrow[2][0] + 1, positions.right_eyebrow[2][1] - 1.3);
vertex(positions.right_eyebrow[2][0] + 1.9, positions.right_eyebrow[2][1] - 0.7);
vertex(positions.right_eyebrow[2][0] + 2, positions.right_eyebrow[2][1] - 0.4);
endShape();
}
else if(faceAngle < -0.14 && faceAngle > -0.35){ //looking to the left smaller amount
push();
translate (-2.9, -4.8);
scale(0.008, 0.0089);
beginShape();
vertex(160,500);
pop();
push();
vertex(positions.chin[1][0] + 180,positions.chin[1][1] + 490);//lowest left
//scale(125, 112.35);
vertex(positions.chin[0][0] + 180,positions.chin[0][1]+490);
pop();
push();
translate (-2.9, -4.8);
scale(0.008, 0.0089);
vertex(210,335);//corner
vertex(250,305);
vertex(333,276);
vertex(408,302);
vertex(534,329);
vertex(549,462);
vertex(561,482);
vertex(578,493);
vertex(600,454);
vertex(587,420);
vertex(591,382);
vertex(596,343);
vertex(588,322);
vertex(582,278);
vertex(607,252);
vertex(586,202);
vertex(536,190);
vertex(485,167);
vertex(419,157);//R
vertex(347,154);//highest
vertex(266,174);//L
vertex(198,199);
vertex(132,230);
vertex(132,261);
vertex(153,286);
vertex(141,308);
vertex(150,337);
vertex(145,378);
vertex(135,427);
endShape();
pop();
beginShape();
//hairline
//vertex(positions.chin[15][0], positions.chin[15][1]);//face R
vertex(positions.chin[16][0], positions.chin[16][1]); // Face R
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1] - 0.4);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[2][1] - 0.45);
vertex(positions.right_eyebrow[0][0] - 0.7, positions.right_eyebrow[0][1] - 0.8);//mid forehead hair
vertex(positions.left_eyebrow[3][0] - 0.4, positions.right_eyebrow[2][1] - 0.4);
vertex(positions.left_eyebrow[0][0]+0.05, positions.left_eyebrow[0][1] - 0.5);
vertex(positions.chin[0][0], positions.chin[0][1]); //face L
vertex(positions.chin[1][0], positions.chin[1][1]);//face L
vertex(positions.chin[1][0]-0.1, positions.chin[1][1]);
//non-hairline
vertex(positions.chin[1][0] - 0.05, positions.chin[1][1] - 0.2);
vertex(positions.chin[0][0] - 0.15, positions.chin[0][1] - 0.35);
vertex(positions.chin[0][0] - 0.2, positions.chin[0][1] - 0.7);
vertex(positions.chin[0][0] - 0.1, positions.chin[0][1] - 1.4);
vertex(positions.right_eyebrow[2][0]- 2.35, positions.right_eyebrow[2][1] - 1);
vertex(positions.right_eyebrow[2][0]- 1.5, positions.right_eyebrow[2][1] - 1.6);
vertex(positions.right_eyebrow[2][0]- 1, positions.right_eyebrow[2][1] - 1.5);
vertex(positions.right_eyebrow[2][0]+ 1, positions.right_eyebrow[2][1]-1);
vertex(positions.right_eyebrow[2][0]+ 1.2, positions.right_eyebrow[2][1]- 0.5);
endShape();
}
else if(faceAngle <= -0.35){ //looking to the left more
push();
translate (-2.6, -4.8);
scale(0.008, 0.0089);
beginShape();
vertex(160,500);
pop();
push();
vertex(positions.chin[1][0] + 180,positions.chin[1][1] + 490);//lowest left
//scale(125, 112.35);
vertex(positions.chin[0][0] + 180,positions.chin[0][1]+490);
pop();
push();
translate (-2.7, -4.8);
scale(0.008, 0.0089);
vertex(210,335);//corner
vertex(250,305);
vertex(333,276);
vertex(408,302);
vertex(534,329);
vertex(549,462);
vertex(561,482);
vertex(578,493);
vertex(600,454);
vertex(587,420);
vertex(591,382);
vertex(596,343);
vertex(588,322);
vertex(582,278);
vertex(607,252);
vertex(586,202);
vertex(536,190);
vertex(485,167);
vertex(419,157);//R
vertex(347,154);//highest
vertex(266,174);//L
vertex(198,199);
vertex(132,230);
vertex(132,261);
vertex(153,286);
vertex(141,308);
vertex(150,337);
vertex(145,378);
vertex(135,427);
endShape();
pop();
beginShape();
//hairline
//vertex(positions.chin[15][0], positions.chin[15][1]);//face R
vertex(positions.chin[16][0], positions.chin[16][1]); // Face R
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1] - 0.4);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[2][1] - 0.45);
vertex(positions.right_eyebrow[0][0] - 0.7, positions.right_eyebrow[0][1] - 0.8);//mid forehead hair
vertex(positions.left_eyebrow[3][0] - 0.4, positions.right_eyebrow[2][1] - 0.4);
vertex(positions.left_eyebrow[0][0]+0.05, positions.left_eyebrow[0][1] - 0.5);
vertex(positions.chin[0][0], positions.chin[0][1]); //face L
vertex(positions.chin[1][0], positions.chin[1][1]);//face L
vertex(positions.chin[1][0]-0.1, positions.chin[1][1]);
//non-hairline
vertex(positions.chin[1][0] - 0.05, positions.chin[1][1] - 0.2);
vertex(positions.chin[0][0] - 0.15, positions.chin[0][1] - 0.35);
vertex(positions.chin[0][0] - 0.2, positions.chin[0][1] - 0.7);
vertex(positions.chin[0][0] - 0.1, positions.chin[0][1] - 1.4);
vertex(positions.right_eyebrow[2][0]- 2.35, positions.right_eyebrow[2][1] - 1);
vertex(positions.right_eyebrow[2][0]- 1.5, positions.right_eyebrow[2][1] - 1.6);
vertex(positions.right_eyebrow[2][0]- 1, positions.right_eyebrow[2][1] - 1.5);
vertex(positions.right_eyebrow[2][0]+ 1.55, positions.right_eyebrow[2][1]-1);
vertex(positions.right_eyebrow[2][0]+ 1.7, positions.right_eyebrow[2][1]- 0.5);
endShape();
}
else if(faceAngle >= -0.14 && faceAngle <= 0.14){ //looking straight on
push();
translate (-3.25, -4.8);
scale(0.0089);
beginShape();
vertex(160,500);
vertex(188,507);
vertex(190,407);
vertex(210,335);
vertex(250,305);
vertex(333,276);
vertex(408,302);
vertex(534,329);
vertex(549,462);
vertex(561,482);
vertex(578,493);
vertex(600,454);
vertex(587,420);
vertex(591,382);
vertex(596,343);
vertex(588,322);
vertex(582,278);
vertex(607,252);
vertex(586,202);
vertex(536,190);
vertex(485,167);
vertex(419,157);//R
vertex(347,154);//highest
vertex(266,174);//L
vertex(198,199);
vertex(132,230);
vertex(132,261);
vertex(153,286);
vertex(141,308);
vertex(138,337);
vertex(138,378);
vertex(135,427);
endShape();
pop();
beginShape();
//hairline
vertex(positions.chin[15][0], positions.chin[15][1]);//face R
vertex(positions.chin[16][0], positions.chin[16][1]); // Face R
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1] - 0.4);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[2][1] - 0.45);
vertex(positions.right_eyebrow[0][0] - 0.7, positions.right_eyebrow[0][1] - 0.8);//mid forehead hair
vertex(positions.left_eyebrow[3][0] - 0.4, positions.right_eyebrow[2][1] - 0.35);
vertex(positions.left_eyebrow[0][0], positions.left_eyebrow[0][1] - 0.5);
vertex(positions.chin[0][0], positions.chin[0][1]); //face L
vertex(positions.chin[1][0], positions.chin[1][1]);//face L
//non-hairline
vertex(positions.chin[1][0] - 0.15, positions.chin[1][1] - 0.2);
vertex(positions.chin[0][0] - 0.25, positions.chin[0][1] - 0.35);
vertex(positions.chin[0][0] - 0.15, positions.chin[0][1] - 0.7);
vertex(positions.chin[0][0] + 0.2, positions.chin[0][1] - 1.3);
vertex(positions.right_eyebrow[2][0]- 2.5, positions.right_eyebrow[2][1] - 1);
vertex(positions.right_eyebrow[2][0]+ 0.6, positions.right_eyebrow[2][1] - 0.9);
endShape();
}
else if (faceAngle > 0.12 && faceAngle <=0.35){ // looking to the right a small amount
push();
translate (-3.35, -4.8);
scale(0.0087, 0.0089);
beginShape();
vertex(160,500);
vertex(188,507);
vertex(190,407);
vertex(210,335);
vertex(250,305);
vertex(333,276);
vertex(408,302);
vertex(534,329);
vertex(549,462);
vertex(561,482);
vertex(578,493);
vertex(600,454);
vertex(587,420);
vertex(591,382);
vertex(596,343);
vertex(588,322);
vertex(582,278);
vertex(607,252);
vertex(586,202);
vertex(536,190);
vertex(485,167);
vertex(419,157);//R
vertex(347,154);//highest
vertex(266,174);//L
vertex(198,199);
vertex(132,230);
vertex(132,261);
vertex(153,286);
vertex(141,308);
vertex(138,337);
vertex(138,378);
vertex(135,427);
endShape();
pop();
beginShape();
//hairline
vertex(positions.chin[15][0], positions.chin[15][1]);//face R
vertex(positions.chin[16][0], positions.chin[16][1]); // Face R
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1] - 0.4);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[2][1] - 0.45);
vertex(positions.right_eyebrow[0][0] - 0.7, positions.right_eyebrow[0][1] - 0.8);//mid forehead hair
vertex(positions.left_eyebrow[3][0] - 0.4, positions.right_eyebrow[2][1] - 0.35);
vertex(positions.left_eyebrow[0][0], positions.left_eyebrow[0][1] - 0.5);
vertex(positions.chin[0][0], positions.chin[0][1]); //face L
vertex(positions.chin[1][0], positions.chin[1][1]);//face L
//non-hairline
vertex(positions.chin[1][0] - 0.15, positions.chin[1][1] - 0.2);
vertex(positions.chin[0][0] - 0.25, positions.chin[0][1] - 0.35);
vertex(positions.chin[0][0] - 0.15, positions.chin[0][1] - 0.7);
vertex(positions.chin[0][0] + 0.2, positions.chin[0][1] - 1.9);
vertex(positions.right_eyebrow[2][0]- 2.5, positions.right_eyebrow[2][1] - 1.4);
vertex(positions.right_eyebrow[2][0]+ 0.6, positions.right_eyebrow[2][1] - 0.9);
endShape();
}
else if(faceAngle >= 0.35 && faceAngle < 0.5){ //looking to right more
push();
translate (-3.6, -4.8);
scale(0.0087, 0.0089);
beginShape();
vertex(160,500);
vertex(188,507);
vertex(190,407);
vertex(210,335);
vertex(250,305);
vertex(333,276);
vertex(408,302);
vertex(534,329);
vertex(549,462);
vertex(561,482);
vertex(578,493);
vertex(600,454);
vertex(587,420);
vertex(591,382);
vertex(596,343);
vertex(588,322);
vertex(582,278);
vertex(607,252);
vertex(586,202);
vertex(536,190);
vertex(485,167);
vertex(419,157);//R
vertex(347,154);//highest
vertex(266,174);//L
vertex(198,199);
vertex(132,230);
vertex(132,261);
vertex(153,286);
vertex(141,308);
vertex(138,337);
vertex(138,378);
vertex(135,427);
endShape();
pop();
beginShape();
//hairline
vertex(positions.chin[15][0], positions.chin[15][1]);//face R
vertex(positions.chin[16][0], positions.chin[16][1]); // Face R
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1] - 0.4);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[2][1] - 0.45);
vertex(positions.right_eyebrow[0][0] - 0.7, positions.right_eyebrow[0][1] - 0.8);//mid forehead hair
vertex(positions.left_eyebrow[3][0] - 0.4, positions.right_eyebrow[2][1] - 0.35);
vertex(positions.left_eyebrow[0][0], positions.left_eyebrow[0][1] - 0.5);
vertex(positions.chin[0][0], positions.chin[0][1]); //face L
vertex(positions.chin[1][0], positions.chin[1][1]);//face L
//non-hairline
vertex(positions.chin[1][0] - 0.15, positions.chin[1][1] - 0.2);
vertex(positions.chin[0][0] - 0.25, positions.chin[0][1] - 0.35);
vertex(positions.chin[0][0] - 0.15, positions.chin[0][1] - 0.7);
vertex(positions.chin[0][0] + 0.2, positions.chin[0][1] - 1.9);
vertex(positions.right_eyebrow[2][0]- 2.5, positions.right_eyebrow[2][1] - 1.4);
vertex(positions.right_eyebrow[2][0]+ 0.2, positions.right_eyebrow[2][1] - 0.5);
endShape();
}
else if(faceAngle>0.5 && faceAngle<0.6){ // looking to the right most
push();
translate (-3.6, -4.8);
scale(0.0087, 0.0089);
beginShape();
vertex(160,500);
vertex(188,507);
vertex(190,407);
vertex(210,335);
vertex(250,305);
vertex(333,276);
vertex(408,302);
vertex(534,329);
vertex(549,462);
vertex(561,482);
vertex(578,493);
vertex(600,454);
vertex(587,420);
vertex(591,382);
vertex(596,343);
vertex(588,322);
vertex(582,278);
vertex(607,252);
vertex(586,202);
vertex(536,190);
vertex(485,167);
vertex(419,157);//R
vertex(347,154);//highest
vertex(266,174);//L
vertex(198,199);
vertex(132,230);
vertex(132,261);
vertex(153,286);
vertex(141,308);
vertex(138,337);
vertex(138,378);
vertex(135,427);
endShape();
pop();
beginShape();
//hairline
vertex(positions.chin[15][0], positions.chin[15][1]);//face R
vertex(positions.chin[16][0], positions.chin[16][1]); // Face R
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1] - 0.4);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[2][1] - 0.45);
vertex(positions.right_eyebrow[0][0] - 0.7, positions.right_eyebrow[0][1] - 0.8);//mid forehead hair
vertex(positions.left_eyebrow[3][0] - 0.4, positions.right_eyebrow[2][1] - 0.35);
vertex(positions.left_eyebrow[0][0], positions.left_eyebrow[0][1] - 0.5);
vertex(positions.chin[0][0], positions.chin[0][1]); //face L
vertex(positions.chin[1][0], positions.chin[1][1]);//face L
//non-hairline
vertex(positions.chin[1][0] - 0.15, positions.chin[1][1] - 0.2);
vertex(positions.chin[0][0] - 0.25, positions.chin[0][1] - 0.35);
vertex(positions.chin[0][0] - 0.15, positions.chin[0][1] - 0.7);
vertex(positions.chin[0][0] + 0.2, positions.chin[0][1] - 1.5);
vertex(positions.right_eyebrow[2][0]- 2.5, positions.right_eyebrow[2][1] - 1.2);
vertex(positions.right_eyebrow[2][0]+ 0.2, positions.right_eyebrow[2][1] - 0.5);
endShape();
}
else { // looking to the right most (extreme)
push();
translate (-3.6, -4.8);
scale(0.0087, 0.0089);
beginShape();
vertex(160,500);
vertex(188,507);
vertex(190,407);
vertex(210,335);
vertex(250,305);
vertex(333,276);
vertex(408,302);
vertex(534,329);
vertex(560,343);
vertex(588,322);
vertex(582,278);
vertex(607,252);
vertex(586,202);
vertex(536,190);
vertex(485,167);
vertex(419,157);//R
vertex(347,154);//highest
vertex(266,174);//L
vertex(198,199);
vertex(132,230);
vertex(132,261);
vertex(153,286);
vertex(141,308);
vertex(138,337);
vertex(138,378);
vertex(135,427);
endShape();
pop();
beginShape();
//hairline
vertex(positions.chin[15][0], positions.chin[15][1]);//face R
vertex(positions.chin[16][0], positions.chin[16][1]); // Face R
vertex(positions.right_eyebrow[3][0], positions.right_eyebrow[3][1] - 0.4);
vertex(positions.right_eyebrow[0][0], positions.right_eyebrow[2][1] - 0.45);
vertex(positions.right_eyebrow[0][0] - 0.7, positions.right_eyebrow[0][1] - 0.8);//mid forehead hair
vertex(positions.left_eyebrow[3][0] - 0.4, positions.right_eyebrow[2][1] - 0.35);
vertex(positions.left_eyebrow[0][0], positions.left_eyebrow[0][1] - 0.5);
vertex(positions.chin[0][0], positions.chin[0][1]); //face L
vertex(positions.chin[1][0], positions.chin[1][1]);//face L
//non-hairline
vertex(positions.chin[1][0] - 0.15, positions.chin[1][1] - 0.2);
vertex(positions.chin[0][0] - 0.25, positions.chin[0][1] - 0.35);
vertex(positions.chin[0][0] - 0.15, positions.chin[0][1] - 0.7);
vertex(positions.chin[0][0] + 0.2, positions.chin[0][1] - 1.5);
vertex(positions.right_eyebrow[2][0]- 2.5, positions.right_eyebrow[2][1] - 1.2);
vertex(positions.right_eyebrow[2][0]+ 0.2, positions.right_eyebrow[2][1] - 0.5);
endShape();
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.wink_value = map(settings[0], 0, 100, 0, 1);
this.colour_value = map(settings[1], 0, 100, 0, 1);
this.hair_colour_value = map(settings[2], 0, 100, 0, 1);
this.eye_colour_value = map(settings[3], 0, 100, 0, 1);
this.brow_value = map(settings[4], 0, 100, 0, 1);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(5);
settings[0] = map(this.wink_value, 0, 1, 0, 100);
settings[1] = map(this.colour_value, 0, 1, 0, 100);
settings[2] = map(this.hair_colour_value, 0, 1, 0, 100);
settings[3] = map(this.eye_colour_value, 0, 1, 0, 100);
settings[4] = map(this.brow_value, 0, 1, 0, 100);
return settings;
}
}
// given an array of [x,y] points, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
0,
17,
56.99999999999999,
98,
0,
null,
null
],
"000002": [
0,
0,
51,
100,
0,
null,
null
],
"000005": [
0,
11,
11,
0,
100,
null,
null
],
"000006": [
0,
100,
80,
100,
62,
null,
null
],
"000007": [
100,
11,
100,
100,
100,
null,
null
],
"000009": [
0,
0,
87,
53,
1,
null,
null
],
"000010": [
0,
0,
0,
0,
69,
null,
null
],
"000013": [
100,
13,
0,
1,
0,
null,
null
],
"000014": [
0,
100,
100,
100,
50,
null,
null
],
"000015": [
100,
0,
100,
22,
90,
null,
null
],
"000016": [
100,
25,
100,
100,
31,
null,
null
],
"000018": [
0,
0,
0,
10,
0,
null,
null
],
"000020": [
100,
17,
100,
39,
89,
null,
null
],
"000023": [
100,
0,
100,
0,
18,
null,
null
],
"000025": [
100,
16,
89,
100,
89,
null,
null
],
"000028": [
0,
39,
62,
100,
1,
null,
null
],
"000029": [
0,
0,
0,
0,
0,
null,
null
],
"000030": [
100,
41,
42,
100,
100,
null,
null
],
"000031": [
0,
0,
70,
0,
0,
null,
null
],
"000032": [
100,
8,
43,
100,
100,
null,
null
],
"000035": [
0,
0,
100,
52,
81,
null,
null
],
"000037": [
100,
100,
100,
100,
100,
null,
null
],
"000038": [
100,
21,
100,
0,
0,
null,
null
],
"000040": [
0,
0,
100,
52,
30,
null,
null
],
"000041": [
100,
32,
100,
100,
0,
null,
null
],
"000042": [
0,
1,
64,
0,
21,
null,
null
],
"000043": [
0,
6,
93,
48,
0,
null,
null
],
"000044": [
0,
100,
100,
100,
51,
null,
null
],
"000045": [
0,
8,
55.00000000000001,
100,
0,
null,
null
],
"000047": [
0,
100,
100,
100,
0,
null,
null
],
"000048": [
100,
0,
100,
22,
100,
null,
null
],
"000050": [
100,
14.000000000000002,
100,
88,
0,
null,
null
],
"000051": [
100,
34,
50,
100,
28.999999999999996,
null,
null
],
"000052": [
100,
39,
91,
0,
39,
null,
null
],
"000054": [
0,
0,
0,
13,
0,
null,
null
],
"000055": [
100,
10,
100,
100,
100,
null,
null
],
"000056": [
100,
0,
100,
26,
52,
null,
null
],
"000058": [
0,
0,
100,
0,
100,
null,
null
],
"000060": [
100,
99,
69,
100,
0,
null,
null
],
"000064": [
100,
0,
100,
0,
51,
null,
null
],
"000065": [
100,
55.00000000000001,
100,
100,
0,
null,
null
],
"000068": [
100,
35,
91,
78,
0,
null,
null
],
"000069": [
100,
9,
100,
87,
100,
null,
null
],
"000071": [
0,
3,
0,
0,
15,
null,
null
],
"000073": [
0,
14.000000000000002,
100,
70,
41,
null,
null
],
"000076": [
100,
10,
100,
100,
78,
null,
null
],
"000077": [
0,
0,
100,
49,
28.000000000000004,
null,
null
],
"000078": [
0,
0,
98,
17,
24,
null,
null
],
"000079": [
100,
22,
56.00000000000001,
100,
31,
null,
null
],
"000080": [
100,
0,
100,
0,
32,
null,
null
],
"000081": [
100,
52,
100,
100,
0,
null,
null
],
"000083": [
0,
1,
66,
16,
31,
null,
null
],
"000085": [
0,
0,
60,
12,
25,
null,
null
],
"000086": [
0,
0,
68,
57.99999999999999,
100,
null,
null
],
"000088": [
0,
0,
49,
100,
100,
null,
null
],
"000091": [
100,
0,
100,
32,
100,
null,
null
],
"000092": [
0,
7.000000000000001,
0,
0,
18,
null,
null
],
"000096": [
0,
18,
100,
100,
100,
null,
null
],
"000097": [
0,
1,
35,
0,
75,
null,
null
],
"000099": [
0,
21,
30,
9,
0,
null,
null
],
"000100": [
0,
1,
26,
100,
51,
null,
null
],
"000103": [
0,
0,
92,
4,
100,
null,
null
],
"000104": [
100,
0,
31,
0,
0,
null,
null
],
"000106": [
0,
39,
77,
100,
0,
null,
null
],
"000108": [
0,
0,
1,
0,
0,
null,
null
],
"000109": [
100,
25,
65,
0,
21,
null,
null
],
"000110": [
0,
0,
62,
0,
0,
null,
null
],
"000111": [
0,
100,
32,
95,
0,
null,
null
],
"000114": [
100,
0,
100,
100,
0,
null,
null
],
"000115": [
100,
0,
41,
2,
50,
null,
null
],
"000116": [
100,
0,
91,
99,
0,
null,
null
],
"000117": [
0,
100,
100,
97,
24,
null,
null
],
"000118": [
0,
85,
100,
85,
28.999999999999996,
null,
null
],
"000121": [
0,
50,
100,
87,
21,
null,
null
],
"000122": [
0,
0,
0,
85,
0,
null,
null
],
"000125": [
100,
36,
52,
1,
73,
null,
null
],
"000126": [
0,
53,
0,
0,
0,
null,
null
],
"000129": [
100,
0,
100,
0,
0,
null,
null
],
"000131": [
0,
86,
100,
100,
0,
null,
null
],
"000132": [
0,
99,
100,
100,
0,
null,
null
],
"000133": [
0,
9,
35,
0,
0,
null,
null
],
"000134": [
100,
100,
100,
100,
0,
null,
null
],
"000135": [
100,
89,
100,
100,
28.999999999999996,
null,
null
],
"000137": [
100,
4,
0,
18,
0,
null,
null
],
"000140": [
0,
50,
1,
0,
100,
null,
null
],
"000142": [
0,
0,
100,
0,
100,
null,
null
],
"000143": [
100,
0,
82,
0,
0,
null,
null
],
"000145": [
0,
5,
100,
87,
0,
null,
null
],
"000146": [
0,
39,
83,
100,
0,
null,
null
],
"000147": [
0,
40,
21,
49,
80,
null,
null
],
"000148": [
0,
0,
100,
2,
89,
null,
null
],
"000150": [
100,
1,
52,
11,
51,
null,
null
],
"000151": [
0,
77,
100,
100,
0,
null,
null
],
"000152": [
100,
11,
49,
9,
0,
null,
null
],
"000153": [
100,
13,
100,
55.00000000000001,
0,
null,
null
],
"000155": [
0,
30,
49,
88,
0,
null,
null
],
"000156": [
0,
0,
0,
0,
0,
null,
null
],
"000157": [
0,
0,
0,
0,
79,
null,
null
],
"000160": [
100,
0,
100,
100,
80,
null,
null
],
"000161": [
0,
0,
100,
0,
0,
null,
null
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// other variables can be in here too
// these control the colors used
const core_colour = [240, 200, 10];
const light_colour = [240, 215, 24];
const shadow_colour = [165, 42, 42, 15];
const hair_light = [255, 204, 0];
function Kelly19Face() {
// these are state variables for a face
// (your variables may be different)
this.eye_type = 1; // defines eye type
this.hair_colour = color(255, 200, 100); // eyebrow colour
this.eyebrow_width = 0.1;
this.eyelid_type = 1;
this.teeth = 50;
this.lip_colour = 0;
this.facial_hair = 0;
this.eye_colour = 255;
this.makeup = 1;
//size variables
this.x_percentage = 1;
this.y_percentage = 1;
let hair_light = color("#fabc37");
let hair_dark = color("#302E23");
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
//shifts face to the left/right to approximate rotation
let face_rotate = map(positions.nose_bridge[3][0], -1, 1, 1.5, -1.5);
//eye values -------------------------------------------------------------------------------------------------------------- //
//eye centers
let left_eye = average_point(positions.left_eye);
let right_eye = average_point(positions.right_eye);
//eye size
let left_eye_size = abs(positions.left_eye[0][0] - positions.left_eye[3][0]);
let right_eye_size = abs(positions.right_eye[0][0] - positions.right_eye[3][0]);
// calculate average eye angle
let left_eye_angle = average_angle(positions.left_eye);
let right_eye_angle = average_angle(positions.right_eye);
//eye squint
let left_eye_squint = constrain(average_distance(positions.left_eye) * 6, 1, 8);
let right_eye_squint = constrain(average_distance(positions.right_eye) * 6, 1, 8);
let hair_colour = lerpColor(hair_light, hair_dark, this.hair_colour);
head(face_rotate, -0.5);
if (this.eye_type <= 1) {
open_eye(left_eye, left_eye_size, left_eye_angle, left_eye_squint, this.eyelid_type, this.eye_colour, this.makeup);
open_eye(right_eye, right_eye_size, right_eye_angle, right_eye_squint, this.eyelid_type, this.eye_colour, this.makeup);
// eye_detail(left_eye, left_eye_size, left_eye_angle, -1);
// eye_detail(right_eye, right_eye_size, right_eye_angle, 1);
eyebrows_flow(positions.left_eyebrow, this.eyebrow_width, hair_colour);
eyebrows_flow(positions.right_eyebrow.reverse(), this.eyebrow_width, hair_colour);
} else if (this.eye_type <= 2) {
classic_eye(left_eye, left_eye_size);
classic_eye(right_eye, right_eye_size);
eyebrows_flow(positions.left_eyebrow, this.eyebrow_width, hair_colour);
eyebrows_flow(positions.right_eyebrow.reverse(), this.eyebrow_width, hair_colour);
} else if (this.eye_type <= 3) {
cross_eye(left_eye, left_eye_size, left_eye_angle);
cross_eye(right_eye, right_eye_size, right_eye_angle);
eyebrows_flow(positions.left_eyebrow, this.eyebrow_width, hair_colour);
eyebrows_flow(positions.right_eyebrow.reverse(), this.eyebrow_width, hair_colour);
} else if (this.eye_type <= 4) {
eyebrows_flow(positions.left_eyebrow, this.eyebrow_width, hair_colour);
eyebrows_flow(positions.right_eyebrow.reverse(), this.eyebrow_width, hair_colour);
heart_eye(left_eye, left_eye_size, left_eye_angle);
heart_eye(right_eye, right_eye_size, right_eye_angle);
}
open_mouth(positions.top_lip, positions.bottom_lip, this.teeth, this.lip_colour);
let left_backup = positions.left_eye;
let eyelid_left = positions.left_eye.slice();
let eyelid_right = positions.right_eye.slice();
let left_removed = eyelid_left.splice(1, 2);
let left_1 = eyelid_left[1];
let left_2 = eyelid_left[3];
let left_3 = eyelid_left[2];
let left_4 = eyelid_left[0];
eyelid_left = [left_1, left_2, left_3, left_4];
eye_shadow(positions.left_eyebrow, eyelid_left);
let right_removed = eyelid_right.splice(1, 2);
let right_1 = eyelid_right[0];
let right_2 = eyelid_right[2];
let right_3 = eyelid_right[3];
let right_4 = eyelid_right[1];
eyelid_right = [right_1, right_2, right_3, right_4];
eye_shadow(positions.right_eyebrow.reverse(), eyelid_right.reverse());
//glasses(left_eye, right_eye, left_eye_angle,right_eye_angle,left_eye_size,right_eye_size);
nose(positions.nose_bridge, positions.nose_tip);
//glasses_bridge(left_eye, right_eye, left_eye_angle,right_eye_angle,left_eye_size,right_eye_size,face_rotate);
//light reflection
push();
noFill();
scale(0.9);
translate(face_rotate, -0.5);
rectMode(CENTER);
scale(0.3);
strokeWeight(0.5);
stroke(255, 70);
arc(-4.5, -4.5, 3, 3, 180, 270);
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.hair_colour = map(settings[0], 0, 100, 0, 1);
this.eyebrow_width = map(settings[1], 0, 100, 0.05, 0.25);
this.eyelid_type = map(settings[2], 0, 100, 0, 4);
this.eye_colour = map(settings[3], 0, 100, 0, 360);
this.lip_colour = map(settings[4], 0, 100, 0, 1);
this.teeth = map(settings[5], 0, 100, 0, 100);
this.makeup = map(settings[6], 0, 100, 0, 5);
this.eye_type = map(settings[7], 0, 100, 0, 4);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(8);
settings[0] = map(this.hair_colour, 0, 1, 0, 100);
settings[1] = map(this.eyebrow_width, 0.05, 0.25, 0, 100);
settings[2] = map(this.eyelid_type, 0, 4, 0, 100);
settings[3] = map(this.eye_colour, 0, 360, 0, 100);
settings[4] = map(this.lip_colour, 0, 1, 0, 100);
settings[5] = map(this.teeth, 0, 100, 0, 100);
settings[6] = map(this.makeup, 0, 5, 0, 100);
settings[7] = map(this.eye_type, 0, 4, 0, 100);
return settings;
}
// given an array of [x,y] points, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for (var i = 0; i < list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
}
function head(center_x, center_y) {
push();
noStroke();
scale(0.9);
translate(center_x, center_y);
this.x_percentage = 1;
this.y_percentage = 1;
rectMode(CENTER);
scale(0.3);
push();
fill(0, 10);
rect(0, 0, 17 * this.x_percentage, 14 * this.y_percentage, 2.5); //core
rect(0, 8, 10 * this.x_percentage, 2 * this.y_percentage); // bottom
rect(0, -8.5, 7 * this.x_percentage, 3 * this.y_percentage, 0.5, 0.5, 0, 0); // top
pop();
//fill core colour
fill(core_colour);
rect(0, 0, 17 * this.x_percentage, 14 * this.y_percentage, 2.5); //core
rect(0, 8, 10 * this.x_percentage, 2 * this.y_percentage); // bottom
rect(0, -8.5, 7 * this.x_percentage, 3 * this.y_percentage, 0.5, 0.5, 0, 0); // top
//fill highlight
fill(light_colour);
rect(0, 0, 17 * 0.8 * this.x_percentage, 14 * this.y_percentage, 2.5); //core
rect(0, 8, 10 * 0.8 * this.x_percentage, 2 * this.y_percentage); // bottom
rect(0, -8.5, 7 * 0.64 * this.x_percentage, 3 * this.y_percentage, 0.5, 0.5, 0, 0); // top
//fill shadow
fill(shadow_colour);
rect(0, 7.5 * this.x_percentage, 10 * this.y_percentage, 1);
pop();
}
function angle(cx, cy, ex, ey) {
var dy = ey - cy;
var dx = ex - cx;
var theta = Math.atan2(dy, dx); // range (-PI, PI]
theta *= 180 / Math.PI; // rads to degs, range (-180, 180]
//if (theta < 0) theta = 360 + theta; // range [0, 360)
theta = theta - 90;
return theta;
}
function average_angle(eye) {
let a1 = angle(eye[1][0], eye[1][1], eye[5][0], eye[5][1]);
let a2 = angle(eye[2][0], eye[2][1], eye[4][0], eye[4][1]);
let average = (a1 + a2) / 2;
return average;
}
function distance(x1, y1, x2, y2) {
var dy = abs(y2 - y1);
var dx = abs(x2 - x1);
var dist = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
return dist;
}
function average_distance(eye) {
let d1 = distance(eye[1][0], eye[1][1], eye[5][0], eye[5][1]);
let d2 = distance(eye[2][0], eye[2][1], eye[4][0], eye[4][1]);
let average = (d1 + d2) / 2;
return average;
}
function eye_shadow(eyebrow, eye) {
push();
fill(0, 10);
noStroke();
beginShape();
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[1][0], eyebrow[1][1]);
curveVertex(eyebrow[2][0], eyebrow[2][1]);
curveVertex(eyebrow[3][0], eyebrow[3][1]);
curveVertex(eyebrow[4][0], eyebrow[4][1]);
curveVertex(eye[0][0], eye[0][1]);
curveVertex(eye[1][0], eye[1][1]);
curveVertex(eye[2][0], eye[2][1]);
curveVertex(eye[3][0], eye[3][1]);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[1][0], eyebrow[1][1]);
endShape(CLOSE);
pop();
}
function nose(nose_bridge, nose_tip) {
let nose_offset = 0.5;
//backing
fill(light_colour);
noStroke();
beginShape()
vertex(nose_bridge[0][0], nose_bridge[0][1] - nose_offset);
vertex(nose_tip[0][0], nose_tip[0][1] - nose_offset);
vertex(nose_tip[nose_tip.length - 1][0], nose_tip[nose_tip.length - 1][1] - nose_offset);
endShape(CLOSE);
//bridge
strokeWeight(0.07);
noFill();
stroke(core_colour);
beginShape();
curveVertex(nose_bridge[0][0], nose_bridge[0][1] - nose_offset);
for (var i = 0; i < nose_bridge.length; i++) {
curveVertex(nose_bridge[i][0], nose_bridge[i][1] - nose_offset);
}
curveVertex(nose_bridge[nose_bridge.length - 1][0], nose_bridge[nose_bridge.length - 1][1] - nose_offset);
endShape();
stroke(core_colour);
beginShape();
curveVertex(nose_bridge[2][0], nose_bridge[2][1] - nose_offset);
for (var i = 2; i < nose_bridge.length; i++) {
curveVertex(nose_bridge[i][0], nose_bridge[i][1] - nose_offset);
}
curveVertex(nose_bridge[nose_bridge.length - 1][0], nose_bridge[nose_bridge.length - 1][1] - nose_offset);
endShape();
//tip
stroke(core_colour);
strokeWeight(0.1);
noFill();
beginShape();
curveVertex(nose_tip[0][0], nose_tip[0][1] - nose_offset);
for (var i = 1; i < nose_tip.length - 1; i++) {
curveVertex(nose_tip[i][0], nose_tip[i][1] - nose_offset);
}
curveVertex(nose_tip[nose_tip.length - 1][0], nose_tip[nose_tip.length - 1][1] - nose_offset);
endShape();
push();
fill(0,20);
noStroke();
ellipse(nose_tip[1][0], nose_tip[1][1] - nose_offset,0.1,0.05);
ellipse(nose_tip[nose_tip.length-2][0], nose_tip[nose_tip.length-2][1] - nose_offset,0.1,0.05);
pop();
push();
ellipseMode(CENTER);
noFill();
stroke(core_colour);
strokeWeight(0.05);
translate(nose_tip[nose_tip.length-2][0], nose_tip[nose_tip.length-2][1] - nose_offset);
//rotate(45);
arc(0, 0, 0.3, 0.3, 315, 0);
pop();
push();
ellipseMode(CENTER);
noFill();
stroke(core_colour);
strokeWeight(0.05);
translate(nose_tip[1][0], nose_tip[1][1] - nose_offset);
//rotate(-45);
arc(0, 0, 0.3, 0.3, 180, 235);
pop();
}
function open_eye(pos, eye_size, eye_angle, eye_squint, eyelid_type, eye_colour, makeup) {
push();
translate(pos[0], pos[1]);
noStroke();
//eye background/tiredness - could be randomised
fill(core_colour);
ellipse(0, 0, eye_size * 1.2, eye_size * 1.2);
push();
fill(255, 100, 20, makeup);
for (let i = 0; i < 20; i++) {
ellipse(0, 0, eye_size * 1 + (0.025 * i), eye_size + 1 * (0.025 * i));
}
pop();
//eye fill - solid black
fill(0);
ellipse(0, 0, eye_size, eye_size);
push();
colorMode(HSL);
if(eye_colour > 0 && eye_colour< 360){
fill(eye_colour, 100, 20);
ellipse(0, 0, eye_size * 0.7, eye_size * 0.7);
}
pop();
//white eye detail
fill(255);
ellipse(-eye_size / 7, -eye_size / 7, eye_size / 2.5, eye_size / 2.5);
rotate(eye_angle);
if (eyelid_type <= 1) {
//none
} else if (eyelid_type > 1 && eyelid_type <= 2) {
//bttm rd
eyelid_bottom_rd(eye_size, eye_squint);
} else if (eyelid_type > 2 && eyelid_type <= 3) {
//top rd
eyelid_top_rd(eye_size, eye_squint);
} else if (eyelid_type > 3 && eyelid_type <= 4) {
//both rd
eyelid_top_rd(eye_size, eye_squint);
eyelid_bottom_rd(eye_size, eye_squint);
}
pop();
}
function closed_eye(pos, eye_size, eye_angle) {
push();
translate(pos[0], pos[1]);
rotate(eye_angle);
stroke(0);
strokeWeight(0.15);
line(-eye_size / 2, 0, eye_size / 2, 0);
pop();
}
function eyelid_top_rd(size, squint) {
push();
noStroke();
fill(light_colour);
translate(0, -size * squint / 2);
scale(1.5);
ellipse(0, 0, size, size / 2);
pop();
}
function eyelid_bottom_rd(size, squint) {
push();
noStroke();
fill(light_colour);
translate(0, size * squint / 2);
scale(1.5);
ellipse(0, 0, size, size / 2);
//highlight_colour.setAlpha(map(squint, 1.3, 1.9, 70, 0));
stroke(255, 20);
strokeWeight(0.05);
noFill();
arc(0, 0, size / 1, size / 2.5, 215, 325);
//highlight_colour.setAlpha(70);
pop();
}
function eyelid_top_sq(size, squint) {
push();
rectMode(CENTER);
noStroke();
fill(light_colour);
translate(0, -size * squint / 2);
scale(1.5);
rect(0, 0, size, size / 2);
pop();
}
function eyelid_bottom_sq(size, squint) {
push();
rectMode(CENTER);
noStroke();
fill(light_colour);
translate(0, size * squint / 2);
scale(1.5);
rect(0, 0, size, size / 2);
//highlight_colour.setAlpha(map(squint, 1.3, 1.9, 70, 0));
stroke(255, 20);
strokeWeight(0.05);
noFill();
//arc(0, 0, size / 1, size / 2.5, 215, 325);
//highlight_colour.setAlpha(70);
pop();
}
function eyebrows(eyebrow, width) {
//eyebrow
push();
curveTightness(0);
strokeJoin(ROUND);
noFill();
stroke(light_colour);
strokeWeight(width * 1.7);
beginShape();
curveVertex(eyebrow[0][0], eyebrow[0][1]);
for (var i = 1; i < eyebrow.length; i++) {
curveVertex(eyebrow[i][0], eyebrow[i][1]);
}
curveVertex(eyebrow[eyebrow.length - 1][0], eyebrow[eyebrow.length - 1][1]);
endShape();
stroke(0, 200);
strokeWeight(width);
beginShape();
curveVertex(eyebrow[0][0], eyebrow[0][1]);
for (var i = 1; i < eyebrow.length; i++) {
curveVertex(eyebrow[i][0], eyebrow[i][1]);
}
curveVertex(eyebrow[eyebrow.length - 1][0], eyebrow[eyebrow.length - 1][1]);
endShape();
pop();
}
function eyebrows_flow(eyebrow, width, colour) {
//eyebrow
push();
fill(light_colour);
stroke(light_colour);
strokeWeight(width);
beginShape();
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[1][0], eyebrow[1][1] - width / 2);
curveVertex(eyebrow[2][0], eyebrow[2][1] - width / 2);
curveVertex(eyebrow[3][0], eyebrow[3][1] - width / 2);
curveVertex(eyebrow[4][0], eyebrow[4][1]);
curveVertex(eyebrow[3][0], eyebrow[3][1] + width / 2)
curveVertex(eyebrow[2][0], eyebrow[2][1] + width / 2);
curveVertex(eyebrow[1][0], eyebrow[1][1] + width / 2);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
endShape();
pop();
push();
noStroke();
fill(colour);
beginShape();
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[1][0], eyebrow[1][1] - width / 2);
curveVertex(eyebrow[2][0], eyebrow[2][1] - width / 2);
curveVertex(eyebrow[3][0], eyebrow[3][1] - width / 2);
curveVertex(eyebrow[4][0], eyebrow[4][1]);
curveVertex(eyebrow[3][0], eyebrow[3][1] + width / 2)
curveVertex(eyebrow[2][0], eyebrow[2][1] + width / 2);
curveVertex(eyebrow[1][0], eyebrow[1][1] + width / 2);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
endShape();
pop();
push();
noStroke();
fill(0, 20);
beginShape();
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[1][0], eyebrow[1][1]);
curveVertex(eyebrow[2][0], eyebrow[2][1]);
curveVertex(eyebrow[3][0], eyebrow[3][1]);
curveVertex(eyebrow[4][0], eyebrow[4][1]);
curveVertex(eyebrow[3][0], eyebrow[3][1] + width / 2)
curveVertex(eyebrow[2][0], eyebrow[2][1] + width / 2);
curveVertex(eyebrow[1][0], eyebrow[1][1] + width / 2);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
curveVertex(eyebrow[0][0], eyebrow[0][1]);
endShape();
pop();
}
function cross_eye(pos, eye_size, eye_angle) {
push();
translate(pos[0], pos[1]);
rotate(eye_angle);
stroke(0);
strokeWeight(0.15);
eye_size = eye_size * 0.5;
line(-eye_size / 2, eye_size / 2, eye_size / 2, -eye_size / 2);
line(-eye_size / 2, -eye_size / 2, eye_size / 2, eye_size / 2);
pop();
}
function classic_eye(pos, eye_size) {
push();
translate(pos[0], pos[1]);
noStroke();
fill(core_colour);
eye_size = eye_size / 1.5;
ellipse(0, 0, eye_size * 1.5, eye_size * 1.5);
fill(0);
ellipse(0, 0, eye_size, eye_size);
pop();
}
function heart_eye(pos, eye_size, angle) {
push();
translate(pos[0], pos[1] - 0.2);
rotate(angle)
scale(0.9);
noStroke();
push();
fill(139, 0, 0, 200);
scale(1.2);
beginShape();
vertex(0, 0);
bezierVertex(-eye_size / 2, -eye_size / 2, -eye_size, eye_size / 3, 0, eye_size);
bezierVertex(eye_size, eye_size / 3, eye_size / 2, -eye_size / 2, 0, 0);
endShape(CLOSE);
pop();
fill('#C91A09');
beginShape();
vertex(0, 0);
bezierVertex(-eye_size / 2, -eye_size / 2, -eye_size, eye_size / 3, 0, eye_size);
bezierVertex(eye_size, eye_size / 3, eye_size / 2, -eye_size / 2, 0, 0);
endShape(CLOSE);
push();
noFill();
strokeWeight(0.1);
stroke(255, 150);
arc(0, eye_size / 4, eye_size, eye_size / 2, 190, 210);
pop();
pop();
}
function eye_detail(pos, eye_size, angle, dir) {
push();
let detail_angle = 30;
let line_num = 3;
translate(pos[0], pos[1]);
rotate(angle);
stroke(core_colour);
strokeWeight(0.07);
//translate(eye_size / 2 * dir, 0);
rotate(-detail_angle / 2);
for (let i = 0; i < line_num; i++) {
line(eye_size / 1.2 * dir, 0, eye_size * 1.2 * dir, 0);
rotate(detail_angle / line_num);
}
pop();
}
function glasses(left_eye, right_eye, left_angle,right_angle,left_size,right_size) {
push();
stroke(0);
strokeCap(SQUARE);
rectMode(CENTER);
noFill();
strokeWeight(0.7);
//line(0, 0, dir * eye_spacing / 2 - dir * eye_size * 1.7 / 2, 0);
strokeWeight(0.12);
push();
translate(left_eye[0],left_eye[1]);
rect(0, 0, left_size * 1.8, left_size * 1.3, 0.2, 0.2, 0.2, 0.2);
pop();
push();
translate(right_eye[0],right_eye[1]);
rect(0, 0, right_size * 1.8, right_size * 1.3, 0.2, 0.2, 0.2, 0.2);
pop();
pop();
}
function glasses_bridge(left_eye, right_eye, left_angle,right_angle,left_size,right_size,face_rotate) {
push();
stroke(0);
strokeCap(SQUARE);
rectMode(CENTER);
noFill();
translate(face_rotate, -0.5);
strokeWeight(0.17);
let y = (left_eye[1] + right_eye[1])/2 - 0.2;
line(left_eye[0]+left_size*0.85 - face_rotate,y+0.5, right_eye[0]-right_size*0.85 - face_rotate,y+0.5);
line(left_eye[0]-left_size*0.85 - face_rotate,y+0.5, -17*0.27/2,y+0.5);
line(right_eye[0]+right_size*0.85 - face_rotate,y+0.5, 17*0.27/2,y+0.5);
pop();
}
function classic_mouth(mouth_width, mouth_height, mouth_emotion) {
push();
noFill();
strokeWeight(0.4);
translate(0, mouth_height);
stroke(0);
arc(0, 0, mouth_width, 1, 0, 180);
pop();
}
function open_mouth(top_lip, bottom_lip, teeth, lip_colour) {
let offset = 0.5;
push();
noStroke();
fill(0);
scale(1.1);
beginShape();
vertex(bottom_lip[11][0], bottom_lip[11][1] - offset);
vertex(bottom_lip[10][0], bottom_lip[10][1] - offset);
vertex(bottom_lip[9][0], bottom_lip[9][1] - offset);
vertex(bottom_lip[8][0], bottom_lip[8][1] - offset);
vertex(top_lip[11][0], top_lip[11][1] - offset);
vertex(top_lip[10][0], top_lip[10][1] - offset);
vertex(top_lip[9][0], top_lip[9][1] - offset);
vertex(top_lip[8][0], top_lip[8][1] - offset);
vertex(top_lip[7][0], top_lip[7][1] - offset);
endShape();
pop();
//let teeth_top = 0.15;
let teeth_top = map(teeth, 0, 100, 0, 0.15);
push();
fill(255);
noStroke();
beginShape();
curveVertex(top_lip[11][0], top_lip[11][1] - offset);
curveVertex(top_lip[11][0], top_lip[11][1] - offset);
curveVertex(top_lip[10][0], top_lip[10][1] - offset);
curveVertex(top_lip[9][0], top_lip[9][1] - offset);
curveVertex(top_lip[8][0], top_lip[8][1] - offset);
curveVertex(top_lip[7][0], top_lip[7][1] - offset);
curveVertex(top_lip[8][0], top_lip[8][1] - offset + teeth_top);
curveVertex(top_lip[9][0], top_lip[9][1] - offset + teeth_top);
curveVertex(top_lip[10][0], top_lip[10][1] - offset + teeth_top);
endShape(CLOSE);
pop();
//let teeth_bottom = 0.1;
if (teeth >= 80) {
let teeth_bottom = map(teeth, 80, 100, 0, 0.1);
push();
fill(255);
noStroke();
beginShape();
curveVertex(bottom_lip[11][0], bottom_lip[11][1] - offset);
curveVertex(bottom_lip[11][0], bottom_lip[11][1] - offset);
curveVertex(bottom_lip[10][0], bottom_lip[10][1] - offset);
curveVertex(bottom_lip[9][0], bottom_lip[9][1] - offset);
curveVertex(bottom_lip[8][0], bottom_lip[8][1] - offset);
curveVertex(bottom_lip[7][0], bottom_lip[7][1] - offset);
curveVertex(bottom_lip[8][0], bottom_lip[8][1] - offset - teeth_bottom);
curveVertex(bottom_lip[9][0], bottom_lip[9][1] - offset - teeth_bottom);
curveVertex(bottom_lip[10][0], bottom_lip[10][1] - offset - teeth_bottom);
endShape(CLOSE);
pop();
}
push();
noStroke();
let c1 = color('#f0c80a');
let c2 = color('#ffc694');
let c3 = color('#ff9494');
let c4 = color('#ff0000');
let c5 = color('#690000');
let lip_fill = color('#f0c80a')
if (lip_colour <= 0.25) {
lip_fill = lerpColor(c1, c2, map(lip_colour, 0, 0.25, 0, 1));
fill(lip_fill);
} else if (lip_colour <= 0.5) {
lip_fill = lerpColor(c2, c3, map(lip_colour, 0.25, 0.5, 0, 1));
fill(lip_fill);
} else if (lip_colour <= 0.75) {
lip_fill = lerpColor(c3, c4, map(lip_colour, 0.5, 0.75, 0, 1));
fill(lip_fill);
} else {
lip_fill = lerpColor(c4, c5, map(lip_colour, 0.75, 1, 0, 1));
fill(lip_fill);
}
beginShape();
curveVertex(top_lip[0][0], top_lip[0][1] - offset);
for (var i = 0; i < top_lip.length; i++) {
curveVertex(top_lip[i][0], top_lip[i][1] - offset);
}
curveVertex(top_lip[top_lip.length - 1][0], top_lip[top_lip.length - 1][1] - offset);
endShape(CLOSE);
beginShape();
curveVertex(bottom_lip[0][0], bottom_lip[0][1] - offset);
for (var i = 0; i < bottom_lip.length; i++) {
curveVertex(bottom_lip[i][0], bottom_lip[i][1] - offset);
}
curveVertex(bottom_lip[bottom_lip.length - 1][0], bottom_lip[bottom_lip.length - 1][1] - offset);
endShape(CLOSE);
pop();
push();
if (lip_colour <= 0.25) {
fill(0, 15);
} else {
fill(0, 50);
}
noStroke();
beginShape();
vertex(bottom_lip[0][0], bottom_lip[0][1] - offset);
vertex(bottom_lip[1][0], bottom_lip[1][1] - offset);
vertex(bottom_lip[2][0], bottom_lip[2][1] - offset);
vertex(bottom_lip[3][0], bottom_lip[3][1] - offset);
vertex(bottom_lip[4][0], bottom_lip[4][1] - offset);
vertex(bottom_lip[5][0], bottom_lip[5][1] - offset);
vertex(bottom_lip[6][0], bottom_lip[6][1] - offset);
vertex(bottom_lip[7][0], bottom_lip[7][1] - offset);
vertex(bottom_lip[8][0], bottom_lip[8][1] - offset + 0.1);
vertex(bottom_lip[9][0], bottom_lip[9][1] - offset + 0.1);
vertex(bottom_lip[10][0], bottom_lip[10][1] - offset + 0.1);
vertex(bottom_lip[11][0], bottom_lip[11][1] - offset + 0.1);
endShape(CLOSE);
beginShape();
vertex(top_lip[0][0], top_lip[0][1] - offset);
vertex(top_lip[1][0], top_lip[1][1] - offset + 0.1);
vertex(top_lip[2][0], top_lip[2][1] - offset + 0.1);
vertex(top_lip[3][0], top_lip[3][1] - offset + 0.1);
vertex(top_lip[4][0], top_lip[4][1] - offset + 0.1);
vertex(top_lip[5][0], top_lip[5][1] - offset + 0.1);
vertex(top_lip[6][0], top_lip[6][1] - offset);
vertex(top_lip[7][0], top_lip[7][1] - offset);
vertex(top_lip[8][0], top_lip[8][1] - offset);
vertex(top_lip[9][0], top_lip[9][1] - offset);
vertex(top_lip[10][0], top_lip[10][1] - offset);
vertex(top_lip[11][0], top_lip[11][1] - offset);
endShape(CLOSE);
pop();
push();
ellipseMode(CENTER);
noFill();
stroke(core_colour);
strokeWeight(0.05);
translate(top_lip[6][0], top_lip[6][1] - offset);
arc(0, 0, 0.3, 0.3, 315, 45);
pop();
push();
ellipseMode(CENTER);
noFill();
stroke(core_colour);
strokeWeight(0.05);
translate(top_lip[0][0], top_lip[0][1] - offset);
arc(0, 0, 0.3, 0.3, 135, 235);
pop();
}
function tongue_out(mouth_width, mouth_height, mouth_emotion) {
push();
noFill();
strokeWeight(0.5);
translate(0, mouth_height);
stroke(0);
arc(0, 0, mouth_width, 1, 0, 180);
pop();
}
function line_mouth(mouth_width, mouth_height, mouth_emotion, dir) {
push();
noFill();
strokeWeight(0.4);
translate(dir * 0.5, mouth_height);
stroke(0);
//line(-mouth_width, 0, mouth_width, 0);
curveTightness(0);
beginShape();
curveVertex(dir * -mouth_width / 1.5, -mouth_emotion / 4);
curveVertex(dir * -mouth_width / 1.5, -mouth_emotion / 4);
curveVertex(dir * mouth_width / 3 / 1.5, -mouth_emotion / 4);
//curveVertex(mouth_width / 2, 0);
curveVertex(dir * mouth_width / 1.5, mouth_emotion / 3);
curveVertex(dir * mouth_width / 1.5, mouth_emotion / 3);
endShape();
strokeWeight(0.2);
stroke('#B58800');
if (dir > 0) {
if (mouth_emotion > 0) {
push();
translate(dir * mouth_width / 1.5, mouth_emotion / 3);
arc(0, 0, 1, 1, 0, 90);
pop();
} else {
push();
translate(dir * mouth_width / 1.5, mouth_emotion / 3);
arc(0, 0, 1.2, 1.2, 270, 0);
pop();
}
} else {
if (mouth_emotion > 0) {
push();
translate(dir * mouth_width / 1.5, mouth_emotion / 3);
arc(0, 0, 1, 1, 90, 180);
pop();
} else {
push();
translate(dir * mouth_width / 1.5, mouth_emotion / 3);
arc(0, 0, 1.2, 1.2, 180, 270);
pop();
}
}
pop();
}
function butt_chin(mouth_width, mouth_height, mouth_emotion) {
push();
noFill();
strokeWeight(0.4);
translate(0, mouth_height);
stroke(0);
arc(0, 0, mouth_width * 2, mouth_emotion * 4, 0, 180);
pop();
}
{
"000001": [
61,
30,
63,
5.999999999999999,
76,
73,
100,
0
],
"000002": [
0,
30,
32,
14.000000000000002,
69,
100,
100,
0
],
"000005": [
2,
98,
37,
50,
63,
19,
100,
0
],
"000006": [
47,
28.000000000000004,
92,
13,
63,
97,
100,
0
],
"000007": [
92,
89.00000000000003,
43,
7.000000000000001,
0,
0,
0,
0
],
"000009": [
77,
65,
39,
16,
63,
100,
100,
0
],
"000010": [
27,
26,
82,
54,
52,
32,
100,
0
],
"000013": [
0,
82.00000000000001,
48,
51,
0,
100,
0,
0
],
"000014": [
75,
32,
31,
0,
69,
100,
100,
0
],
"000015": [
61,
91.00000000000003,
41,
57.99999999999999,
0,
21,
0,
0
],
"000016": [
39,
77.00000000000001,
41,
11.999999999999998,
0,
0,
0,
0
],
"000018": [
33,
26,
36,
18,
49,
100,
100,
35
],
"000020": [
70,
97,
84,
50,
0,
21,
0,
33
],
"000023": [
74,
94,
45,
53,
0,
16,
0,
0
],
"000025": [
78,
100,
69,
5.999999999999999,
0,
17,
0,
0
],
"000028": [
0,
20.999999999999996,
32,
9,
62,
73,
100,
0
],
"000029": [
25,
35.99999999999999,
66,
50,
52,
100,
100,
0
],
"000030": [
36,
100,
50,
28.000000000000004,
0,
0,
0,
32
],
"000031": [
12,
31,
41,
51,
44,
100,
100,
0
],
"000032": [
61,
100,
93,
74,
2,
28.000000000000004,
0,
0
],
"000035": [
100,
17.999999999999993,
42,
15,
62,
18,
100,
0
],
"000037": [
100,
100,
28.000000000000004,
100,
0,
0,
0,
0
],
"000038": [
83,
100,
41,
53,
0,
100,
0,
8
],
"000040": [
100,
17.999999999999993,
71,
9,
70,
0,
100,
0
],
"000041": [
100,
100,
37,
50,
0,
100,
0,
0
],
"000042": [
69,
27,
76,
54,
68,
13,
100,
0
],
"000043": [
68,
28.999999999999996,
80,
14.000000000000002,
60,
100,
100,
0
],
"000044": [
89,
20.999999999999996,
86,
0,
88,
14.000000000000002,
100,
2
],
"000045": [
49,
23,
96,
9,
53,
100,
100,
0
],
"000047": [
100,
15,
91,
0,
53,
100,
100,
0
],
"000048": [
97,
83.00000000000001,
78,
0,
0,
0,
0,
0
],
"000050": [
91,
80.00000000000001,
81,
0,
0,
100,
0,
0
],
"000051": [
89,
78.00000000000001,
86,
23,
0,
0,
0,
30
],
"000052": [
68,
100,
46,
47,
0,
0,
0,
0
],
"000054": [
50,
28.000000000000004,
44,
64,
49,
100,
100,
0
],
"000055": [
88,
86.00000000000001,
67,
11,
0,
0,
0,
0
],
"000056": [
86,
20.000000000000004,
38,
51,
28.999999999999996,
15,
71,
0
],
"000058": [
100,
0,
84,
52,
87,
0,
100,
0
],
"000060": [
71,
81.00000000000001,
28.000000000000004,
15,
0,
86,
0,
0
],
"000064": [
71,
91.00000000000003,
45,
50,
0,
23,
0,
0
],
"000065": [
92,
50.000000000000014,
100,
11.999999999999998,
0,
100,
0,
2
],
"000068": [
89,
80.00000000000001,
86,
13,
0,
100,
42.00000000000001,
26
],
"000069": [
72,
98,
86,
14.000000000000002,
0,
31,
18,
0
],
"000071": [
0,
28.999999999999996,
100,
13,
62,
100,
100,
0
],
"000073": [
38,
24,
86,
17,
50,
100,
100,
0
],
"000076": [
81,
100,
87,
0,
0,
16,
0,
0
],
"000077": [
100,
20.000000000000004,
36,
0,
39,
10,
100,
0
],
"000078": [
94,
24,
32,
13,
69,
30,
100,
0
],
"000079": [
68,
87.00000000000003,
46,
11,
0,
19,
0,
37
],
"000080": [
74,
74.00000000000001,
93,
50,
0,
11,
0,
0
],
"000081": [
100,
80.00000000000001,
41,
7.000000000000001,
0,
100,
0,
0
],
"000083": [
34,
13.000000000000004,
42,
11,
89,
33,
100,
0
],
"000085": [
38,
26,
50,
14.000000000000002,
65,
0,
100,
0
],
"000086": [
33,
6.999999999999999,
95,
50,
72,
100,
100,
0
],
"000088": [
50,
13.000000000000004,
50,
14.000000000000002,
50,
100,
100,
0
],
"000091": [
91,
100,
52,
18,
0,
0,
0,
0
],
"000092": [
18,
43,
30,
15,
71,
100,
100,
0
],
"000096": [
100,
30,
83,
15,
67,
14.000000000000002,
100,
0
],
"000097": [
22,
33,
78,
51,
55.00000000000001,
100,
100,
0
],
"000099": [
50,
12.000000000000004,
50,
50,
46,
68,
100,
0
],
"000100": [
28.999999999999996,
34.99999999999999,
45,
14.000000000000002,
74,
32,
100,
0
],
"000103": [
72,
23,
77,
36,
81,
16,
100,
0
],
"000104": [
50,
59.999999999999986,
35,
50,
0,
100,
0,
0
],
"000106": [
100,
21.999999999999996,
46,
9,
57.99999999999999,
100,
100,
0
],
"000108": [
50,
23,
50,
47.99999999999999,
71,
100,
100,
0
],
"000109": [
41,
69,
36,
50,
0,
100,
0,
0
],
"000110": [
27,
34.99999999999999,
30,
50,
43,
100,
100,
0
],
"000111": [
2,
30,
100,
17,
50,
100,
100,
0
],
"000114": [
44,
100,
39,
17,
0,
87,
0,
0
],
"000115": [
0,
83.00000000000001,
40,
50,
0,
13,
0,
0
],
"000116": [
84,
75.00000000000001,
17,
5.999999999999999,
0,
100,
0,
0
],
"000117": [
100,
4,
11,
0,
72,
100,
100,
0
],
"000118": [
56.99999999999999,
24,
13,
10,
63,
9,
100,
0
],
"000121": [
84,
20.000000000000004,
78,
7.000000000000001,
61,
0,
100,
0
],
"000122": [
50,
20.000000000000004,
50,
11,
67,
100,
100,
32
],
"000125": [
93,
83.00000000000001,
43,
50,
0,
17,
0,
48
],
"000126": [
32,
17.999999999999993,
46,
25,
63,
100,
100,
0
],
"000129": [
100,
87.00000000000003,
28.000000000000004,
18,
18,
100,
46.99999999999999,
0
],
"000131": [
96,
20.999999999999996,
65,
0,
60,
100,
100,
0
],
"000132": [
100,
16,
85,
8,
56.99999999999999,
100,
100,
0
],
"000133": [
17,
30,
36,
49,
54,
100,
100,
0
],
"000134": [
67,
92.00000000000003,
45,
0,
0,
100,
0,
0
],
"000135": [
100,
100,
28.000000000000004,
0,
0,
18,
50,
0
],
"000161": [
78,
17.999999999999993,
41,
23.999999999999996,
59,
100,
100,
0
],
"000160": [
90,
86.00000000000001,
43,
14.000000000000002,
0,
22,
0,
0
],
"000157": [
25,
32,
31,
49,
50,
20,
100,
0
],
"000156": [
5,
27,
50,
50,
50,
50,
50,
0
],
"000155": [
12,
19.000000000000004,
39,
4,
64,
100,
100,
0
],
"000137": [
46,
100,
35,
53,
0,
100,
0,
0
],
"000140": [
14.000000000000002,
40,
50,
47.99999999999999,
51,
0,
100,
0
],
"000143": [
69,
85.00000000000001,
50,
50,
0,
100,
0,
0
],
"000145": [
82,
26,
50,
5.999999999999999,
49,
100,
100,
0
],
"000146": [
12,
58.999999999999986,
42,
8,
70,
93,
100,
0
],
"000147": [
27,
28.999999999999996,
50,
50,
50,
100,
50,
0
],
"000148": [
90,
19.000000000000004,
50,
50,
46,
100,
100,
0
],
"000150": [
0,
100,
55.00000000000001,
36,
0,
35,
69,
0
],
"000151": [
81,
25,
46,
0,
61,
100,
100,
0
],
"000152": [
56.00000000000001,
77.00000000000001,
50,
18,
0,
100,
18,
0
],
"000153": [
70,
78.00000000000001,
46,
11.999999999999998,
0,
100,
0,
0
],
"000142": [
50,
50.000000000000014,
50,
50,
50,
13,
50,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// other variables can be in here too
// these control the colors used
const kelly_bg_color = [225, 206, 187];
const kelly_fg_color = [151, 102, 52];
const kelly_stroke_color = [95, 52, 8];
function KellyFace() {
this.hairColor = 50;
this.wrinkleWeight = 50;
this.skinColor = 50;
this.spots = 50;
this.draw = function(positions) {
var base_tone1 = color("#ffcfaf"); //light color
var base_tone2 = color("#a56e48"); //dark color
var blush_base = color("#701702");
var nose_pos = average_point(positions.nose_bridge);
var eye1_pos = average_point(positions.left_eye);
var eye2_pos = average_point(positions.right_eye);
var half_height = positions.chin[7][1] - nose_pos[1];
var face_width = positions.chin[positions.chin.length - 1][0] - positions.chin[0][0];
//mine
var chin_R = positions.chin[positions.chin.length - 1];
var chin_L = positions.chin[0];
var chin_center = positions.chin[8];
var eyecorner_L = positions.left_eye[0];
var eyecorner_R = positions.right_eye[3];
var x = nose_pos[0];
var y = nose_pos[1];
var w = 2 * face_width;
var h = 2.5 * half_height;
// var curHairLength = map(this.hairLength, 0, 100, 0, 3);
var curHairColor = map(this.hairColor, 0, 120, 255, 20);
var curWrinkleWeight = map(this.wrinkleWeight, 0, 100, 0.0001, 0.065);
var curSpots = map(this.spots, 0, 100, 0, 1);
var curSkincolor = map(this.skinColor, 0, 100, 0, 1);
var skin_tone = lerpColor(base_tone1,base_tone2,curSkincolor);
var blush_color = lerpColor(blush_base,skin_tone,0.55);
var extent = 0;
if (h < w) {
extent = h / 2;
} else {
extent = w / 2;
}
var scale = extent / 220.0;
var eyeShift = 0.35;
for (var i = positions.left_eye.length - 1; i >= 0; i--) {
positions.left_eye[i][1]+=eyeShift;
positions.right_eye[i][1]+=eyeShift;
}
eye1_pos = average_point(positions.left_eye);
eye2_pos = average_point(positions.right_eye);
var eye3_pos = average_point([eye1_pos,eye2_pos]);
//head
var foreheadCenter = average_point([chin_L, chin_R]);
var face_height = distanceBetween(foreheadCenter, chin_center);
push();
noFill();
stroke(blush_color);
fill(skin_tone);
strokeWeight(0.07);
//head outline
beginShape();
curveVertex(-1.5, -2);
curveVertex(chin_L[0], chin_L[1]);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(positions.chin[4][0], positions.chin[4][1]);
curveVertex(positions.chin[6][0], positions.chin[6][1]);
curveVertex(chin_center[0], chin_center[1]);
curveVertex(positions.chin[10][0], positions.chin[10][1]);
curveVertex(positions.chin[12][0], positions.chin[12][1]);
curveVertex(positions.chin[14][0], positions.chin[14][1]);
curveVertex(chin_R[0], chin_R[1]);
//forehead
curveVertex(chin_R[0] - 0.5, chin_R[1] - face_height * 0.45);
curveVertex(foreheadCenter[0], foreheadCenter[1] - face_height * 0.65);
curveVertex(chin_L[0] + 0.5, chin_L[1] - face_height * 0.45);
//close
curveVertex(chin_L[0], chin_L[1]);
curveVertex(positions.chin[1][0], positions.chin[1][1]);
endShape();
pop();
//wrinkels
var wrink_width = face_width*0.2;
var wrink_stroke = curWrinkleWeight;
if (wrink_stroke > 0.0001) {
push();
translate(eye3_pos[0],face_height*-0.65);
rotate(angleBetween(eye1_pos,eye2_pos));
noFill();
stroke(blush_color);
strokeWeight(wrink_stroke);
line(-wrink_width,0,wrink_width , 0);
strokeWeight(wrink_stroke);
beginShape();
curveVertex( - 1, + 0.3 + wrink_stroke);
curveVertex( - wrink_width * 0.8, 0.11 );
curveVertex( + wrink_width * 0.8, 0.11 );
curveVertex( + 1, + 0.3 + wrink_stroke);
endShape();
beginShape();
curveVertex( - 1, - 0.3 - wrink_stroke);
curveVertex( - wrink_width * 0.8, -0.11 );
curveVertex( + wrink_width * 0.8, -0.11);
curveVertex( + 1, - 0.3 - wrink_stroke);
endShape();
pop();
}
//brows
var brow_outer_l = positions.left_eyebrow[0];
var brow_inner_l = positions.left_eyebrow[4];
var brow_upper_l = positions.left_eyebrow[2];
var brow_outer_r = positions.right_eyebrow[4]
var brow_inner_r = positions.right_eyebrow[0];
var brow_upper_r = positions.right_eyebrow[2];
var brow_height_left = (distanceBetween(brow_outer_l, brow_upper_l) + distanceBetween(brow_inner_l, brow_upper_l)) / 4;
var brow_height_right = (distanceBetween(brow_outer_r, brow_upper_r) + distanceBetween(brow_inner_r, brow_upper_r)) / 4;
var brow_width_right = distanceBetween(brow_outer_r, brow_inner_r) * 0.7;
var brow_width_left = distanceBetween(brow_outer_l, brow_inner_l) * 0.7;
// console.log(curHairColor);
var brow_color = curHairColor;
var brow_outline = curHairColor*0.95;
push();
fill(brow_color);
stroke(brow_outline);
//left brow
translate(brow_upper_l[0], brow_upper_l[1]);
rotate(angleBetween(brow_inner_l, brow_outer_l));
ellipse(0, brow_height_left / 4 - eyeShift, brow_width_left, brow_height_left);
pop();
push();
//right brow
fill(brow_color);
stroke(brow_outline);
translate(brow_upper_r[0], brow_upper_r[1]);
rotate(angleBetween(brow_outer_r, brow_inner_r));
ellipse(0, brow_height_right / 4 - eyeShift, brow_width_right, brow_height_left);
pop();
//eyes
//eyes are drawn always closed, with glasses
var blink_weight_L = Math.abs(average_point([positions.left_eye[1], positions.left_eye[2]])[1] - average_point([positions.left_eye[4], positions.left_eye[5]])[1]) / 3;
var blink_weight_R = Math.abs(average_point([positions.right_eye[1], positions.right_eye[2]])[1] - average_point([positions.right_eye[4], positions.right_eye[5]])[1]) / 3;
push();
stroke(blush_color);
noFill();
strokeWeight(blink_weight_L);
beginShape(); //left eye
curveVertex(positions.left_eye[5][0], positions.left_eye[4][1]);
curveVertex(positions.left_eye[0][0], positions.left_eye[0][1]);
curveVertex(positions.left_eye[1][0], positions.left_eye[1][1]);
curveVertex(positions.left_eye[2][0], positions.left_eye[2][1]);
curveVertex(positions.left_eye[3][0], positions.left_eye[3][1]);
curveVertex(positions.left_eye[4][0], positions.left_eye[4][1]);
endShape();
strokeWeight(blink_weight_R);
beginShape(); //right eye
curveVertex(positions.right_eye[5][0], positions.right_eye[4][1]);
curveVertex(positions.right_eye[0][0], positions.right_eye[0][1]);
curveVertex(positions.right_eye[1][0], positions.right_eye[1][1]);
curveVertex(positions.right_eye[2][0], positions.right_eye[2][1]);
curveVertex(positions.right_eye[3][0], positions.right_eye[3][1]);
curveVertex(positions.right_eye[4][0], positions.right_eye[4][1]);
endShape();
pop();
// lens size calculated from average distance between each outer point in positions.eye(l/r) and "eye_pos" center
var l_lens_size;
var r_lens_size;
var frame_color = '#494c56';
var lens_color = color(255, 90);
for (var i = 0; i < positions.left_eye.length; i++) {
l_lens_size = distanceBetween(positions.left_eye[i], eye1_pos);
r_lens_size = distanceBetween(positions.right_eye[i], eye2_pos);
}
l_lens_size /= positions.left_eye.length;
r_lens_size /= positions.right_eye.length;
l_lens_size = 0.4 + l_lens_size * 30;
r_lens_size = 0.4 + r_lens_size * 30;
push();
fill(lens_color);
strokeWeight(0.095);
stroke(frame_color);
//lenses
ellipse(eye1_pos[0], eye1_pos[1], l_lens_size, l_lens_size);
ellipse(eye2_pos[0], eye2_pos[1], r_lens_size, r_lens_size);
//glasses legs (called 'temples')
var temple_connect_angle = -TWO_PI / 32;
var temple_connect_l = rim_vert(eye1_pos, l_lens_size / 2, PI - temple_connect_angle);
var temple_connect_r = rim_vert(eye2_pos, r_lens_size / 2, temple_connect_angle);
noFill();
var bridge_control_offset = distanceBetween(eye1_pos, eye2_pos) - (l_lens_size / 2) - (r_lens_size / 2);
beginShape();
curveVertex(positions.nose_bridge[3][0] * -0.30, (positions.nose_bridge[3][1] + bridge_control_offset) / 2);
curveVertex(eye1_pos[0] + (l_lens_size / 2), eye1_pos[1]);
curveVertex(eye2_pos[0] - (r_lens_size / 2), eye2_pos[1]);
curveVertex(positions.nose_bridge[3][0] * -0.30, (positions.nose_bridge[3][1] + bridge_control_offset) / 2);
endShape();
if (temple_connect_l[0] > chin_L[0]) {
line(chin_L[0], chin_L[1], temple_connect_l[0], temple_connect_l[1]);
}
if (temple_connect_r[0] < chin_R[0]) {
line(chin_R[0], chin_R[1], temple_connect_r[0], temple_connect_r[1]);
}
pop();
//mouth
// for positions.top_lip & positions.bottom_lip: inside = 8,9,10 | outside = 2,3,4 | end = 11
// top_lip[0] is in left mouth corner
// bottom_lip[0] is in right mouth corner
// bottom[0] + top[6] || bottom[6] + top[0] will always intersect
var top_lip_outside = [positions.top_lip[2], positions.top_lip[3], positions.top_lip[4]];
var bottom_lip_outside = [positions.bottom_lip[2], positions.bottom_lip[3], positions.bottom_lip[4]];
var mouthCorner_LT = positions.top_lip[0]; // Left/Top
var mouthCorner_RB = positions.bottom_lip[0]; // Right/Bottom
var top_lip_inside = [positions.top_lip[8], positions.top_lip[9], positions.top_lip[10]];
var bottom_lip_inside = [positions.bottom_lip[8], positions.bottom_lip[9], positions.bottom_lip[10]];
// var mouth_angle = angleBetween(positions.bottom_lip[0], positions.top_lip[0]);
var mouth_width = distanceBetween(positions.bottom_lip[0], positions.top_lip[0]);
var smile;
var lip_thickness = 0;
var mouth_open = 0;
var innverAv = [];
for (var i = 2; i > 0; i--) {
mouth_open += distanceBetween(top_lip_inside[i], bottom_lip_inside[i]);
lip_thickness += distanceBetween(top_lip_inside[i], top_lip_outside[i]);
lip_thickness += distanceBetween(bottom_lip_inside[i], bottom_lip_outside[i]);
innverAv.push(top_lip_inside[i]);
innverAv.push(bottom_lip_inside[i]);
}
innverAv = average_point(innverAv);
cornerAv = average_point([mouthCorner_LT, mouthCorner_RB]);
mouth_open /= 3;
lip_thickness /= 6;
smile = cornerAv[1] - innverAv[1];
push();
strokeWeight(lip_thickness * 0.75);
stroke(blush_color);
noFill();
beginShape();
curveVertex(mouthCorner_LT[0] - smile, mouthCorner_LT[1] + smile * 2);
curveVertex(mouthCorner_LT[0] + mouth_width * 0.15, mouthCorner_LT[1] - smile);
curveVertex(mouthCorner_RB[0] - mouth_width * 0.15, mouthCorner_RB[1] - smile);
curveVertex(mouthCorner_RB[0] - smile, mouthCorner_RB[1] + smile * 2);
endShape();
pop();
fill('red');
stroke('red');
// debugShowPoints(positions.left_eye);
//debugShowPoints(hair_L);
function toms_face() {
// head
stroke(kelly_stroke_color);
fill(kelly_fg_color);
beginShape();
for (var i = 0; i < positions.chin.length; i++) {
vertex(positions.chin[i][0], positions.chin[i][1]);
}
for (var i = positions.right_eyebrow.length - 1; i >= 0; i--) {
vertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
for (var i = positions.left_eyebrow.length - 1; i >= 0; i--) {
vertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
endShape(CLOSE);
// mouth
noStroke();
fill(kelly_bg_color);
beginShape();
for (var i = 0; i < positions.top_lip.length; i++) {
vertex(positions.top_lip[i][0], positions.top_lip[i][1]);
}
endShape(CLOSE);
beginShape();
for (var i = 0; i < positions.bottom_lip.length; i++) {
vertex(positions.bottom_lip[i][0], positions.bottom_lip[i][1]);
}
endShape(CLOSE);
// nose
beginShape();
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]);
for (var i = 0; i < positions.nose_tip.length; i++) {
vertex(positions.nose_tip[i][0], positions.nose_tip[i][1]);
}
endShape(CLOSE);
// eyes
beginShape();
for (var i = 0; i < positions.left_eye.length; i++) {
vertex(positions.left_eye[i][0], positions.left_eye[i][1]);
}
endShape(CLOSE);
beginShape();
for (var i = 0; i < positions.right_eye.length; i++) {
vertex(positions.right_eye[i][0], positions.right_eye[i][1]);
}
endShape(CLOSE);
fill(kelly_fg_color);
ellipse(eye1_pos[0], eye1_pos[1], 16 * scale, 16 * scale);
ellipse(eye2_pos[0], eye2_pos[1], 16 * scale, 16 * scale);
fill(kelly_stroke_color);
beginShape();
for (var i = 0; i < positions.right_eyebrow.length; i++) {
vertex(positions.right_eyebrow[i][0], positions.right_eyebrow[i][1]);
}
endShape(CLOSE);
beginShape();
for (var i = 0; i < positions.left_eyebrow.length; i++) {
vertex(positions.left_eyebrow[i][0], positions.left_eyebrow[i][1]);
}
endShape(CLOSE);
strokeWeight(1);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.hairColor = settings[0];
this.wrinkleWeight = settings[1];
this.skinColor = settings[2];
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
properties = new Array(3);
properties[0] = this.hairColor;
properties[1] = this.wrinkleWeight;
properties[2] = this.skinColor;
return properties;
}
}
// given a point, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for (var i = 0; i < list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
function rim_vert(vert, rad, angl) { //find the co-oridnates for a point on a circle
var x = Math.cos(angl) * rad;
var y = Math.sin(angl) * rad;
return [x + vert[0], y + vert[1]];
}
function angleBetween(p1, p2) {
//angle given with reference to horizon line
var c;
c = Math.atan2(p2[1] - p1[1], p2[0] - p1[0]) * 180 / Math.PI;
return c;
}
function distanceBetween(p1, p2) {
var a = p1[0] - p2[0];
var b = p1[1] - p2[1];
var c = Math.abs(Math.sqrt(a * a + b * b));
return c;
}
function debugShowPoints(arr, txtsiz) {
push();
textSize(0.25);
if (txtsiz) {
textSize(txtsiz);
}
noStroke();
for (var i = arr.length - 1; i >= 0; i--) {
text(i, arr[i][0], arr[i][1]);
}
pop();
}
{
"000001": [
83,
0,
17
],
"000002": [
54,
41
],
"000058": [
100,
7,
4
],
"000005": [
18,
0,
18
],
"000006": [
45,
27,
57
],
"000007": [
94,
67,
34
],
"000009": [
66,
31,
9
],
"000010": [
20,
40,
20
],
"000013": [
0,
71,
0
],
"000014": [
100,
17,
71
],
"000015": [
74,
64,
36
],
"000016": [
80,
40,
27
],
"000018": [
11,
36,
4
],
"000020": [
76,
47,
17
],
"000023": [
87,
70,
20
],
"000025": [
71,
32,
16
],
"000028": [
59,
66,
21
],
"000029": [
5,
6,
13
],
"000030": [
14,
61,
15
],
"000031": [
29,
93,
0
],
"000032": [
9,
60,
23
],
"000035": [
100,
0,
0
],
"000037": [
100,
16,
67
],
"000038": [
87,
100,
7
],
"000040": [
93,
7,
14
],
"000041": [
98,
100,
19
],
"000042": [
23,
34,
0
],
"000043": [
74,
45,
20
],
"000044": [
100,
0,
93
],
"000045": [
69,
17,
14
],
"000047": [
100,
55,
17
],
"000048": [
90,
7,
0
],
"000050": [
78,
100,
17
],
"000051": [
0,
100,
30
],
"000052": [
70,
100,
22
],
"000054": [
12,
72,
10
],
"000055": [
97,
64,
8
],
"000056": [
100,
23,
7
],
"000060": [
72,
80,
96
],
"000064": [
74,
49,
2
],
"000065": [
80,
25,
9
],
"000068": [
42,
100,
21
],
"000069": [
100,
69,
7
],
"000071": [
5,
39,
14
],
"000073": [
79,
12,
29
],
"000076": [
100,
75,
9
],
"000077": [
100,
0,
0
],
"000078": [
84,
18,
5
],
"000079": [
0,
59,
21
],
"000080": [
98,
21,
0
],
"000081": [
98,
87,
0
],
"000083": [
64,
14,
4
],
"000085": [
71,
18,
6
],
"000086": [
50,
4,
7
],
"000088": [
70,
0,
7
],
"000091": [
94,
22,
5
],
"000092": [
17,
69,
8
],
"000096": [
77,
0,
17
],
"000097": [
31,
21,
19
],
"000099": [
57,
21,
8
],
"000100": [
27,
34,
5
],
"000103": [
67,
0,
5
],
"000104": [
10,
82,
3
],
"000106": [
38,
23,
21
],
"000108": [
2,
36,
4
],
"000109": [
11,
50,
28
],
"000110": [
73,
40,
17
],
"000111": [
34,
13,
65
],
"000114": [
92,
34,
14
],
"000115": [
0,
17,
0
],
"000116": [
59,
85,
36
],
"000117": [
100,
0,
67
],
"000118": [
91,
15,
69
],
"000121": [
91,
67,
37
],
"000122": [
0,
81,
0
],
"000125": [
20,
100,
18
],
"000126": [
0,
35,
21
],
"000129": [
90,
41,
31
],
"000131": [
91,
29,
14
],
"000132": [
100,
33,
59
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 6;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
// example of a global function
// given a segment, this returns the average point [x, y]
// This where you define your own face object
function LeeFace() {
// these are state variables for a face
// (your variables should be different!)
this.mouth_value= 4;
this.petal_colour = 1;
this.petal_layer = 1;
this.petal_length = 2;
this.eye_size_y = 1.5;
this.eye_colour = 1;
this.face_colour =1;
/* Slider 1 - Hair colour - blue for dark hair, cyan for lgiht hair or no hair, red for red hair
Slider 2 - Petal Layers - 1 for feminine, 2 for masculine
Slider 3 - Petal Shape - Pointy for short hair, rounded for long hair
Slider 4 - Eye size
Slider 5 -Eye colour - purple for blue eyes, green for green eyes, brown for brown eyes
Slider 6 -Skin Colour - light for lighter skin, dark for darker skin.
*/
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw = function(positions) {
//VARIABLES
const blue = color(83, 40, 237,180);
const cyan_bonus = color(48, 252, 255, 220);
const red = color(227, 29, 23,180);
const red_stroke = color(235, 62, 56 );
const blue_stroke = color(68, 21, 171);
const cyan_b_stroke = color(48, 252, 255);
const purple_eyes = color(92, 0, 163);
const green_eyes = color(0, 122, 104);
const brown_eyes = color(166, 91, 0);
const darker = color(255, 131, 8);
const lighter = color(255, 166, 0);
let bottom_lip3 = positions.bottom_lip[2];
let bottom_lip4 = positions.bottom_lip[3];
let bottom_lip5 = positions.bottom_lip[4];
let top_lip1 = positions.top_lip[1];
let top_lip2 = positions.top_lip[2];
let top_lip3 = positions.top_lip[3];
let top_lip4 = positions.top_lip[4];
let top_lip6 = positions.top_lip[5];
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos= segment_average(positions.right_eye);
let nose_pos = positions.nose_bridge[0];
let mouth_top = positions.top_lip[3];
let mouth_bottom = positions.bottom_lip[3];
let right_eyebrow = positions.right_eyebrow;
let left_eyebrow = positions.left_eyebrow;
let right_brow_0 = positions.right_eyebrow[0];
let right_brow_1 = positions.right_eyebrow[1];
let right_brow_2 = positions.right_eyebrow[2];
let right_brow_3 = positions.right_eyebrow[3];
let right_brow_4 = positions.right_eyebrow[4];
let left_brow_0 = positions.left_eyebrow[0];
let left_brow_1 = positions.left_eyebrow[1];
let left_brow_2 = positions.left_eyebrow[2];
let left_brow_3 = positions.left_eyebrow[3];
let left_brow_4 = positions.left_eyebrow[4];
// rotation in degrees
angleMode(DEGREES);
//rotate(tilt_value);
strokeWeight(0.05);
//PETAL COLOURS--BLUE, CYAN OR RED------------------------------
if(this.petal_colour == 1) {
fill(blue);
stroke(blue_stroke);
}
else if(this.petal_colour ==2) {
fill(cyan_bonus);
stroke(cyan_b_stroke);
}
else if(this.petal_colour ==3) {
fill(red);
stroke(red_stroke);
}
//PETAL LAYERS -- ONE OR TWO------------------------------
if(this.petal_layer == 1) {
beginShape();
curveVertex(0,0);
curveVertex(0, 0);
curveVertex(-2.8, 1.2);
curveVertex(-this.petal_length,-0.8);
curveVertex(-2.8, -2.8);
curveVertex(0,-1.6);
curveVertex(0,-1.6);
endShape();
beginShape();
curveVertex(0,-1.6);
curveVertex(0, -1.6);
curveVertex(2.8, -2.8);
curveVertex(this.petal_length,-0.8);
curveVertex(2.8, 1.2);
curveVertex(0,0);
curveVertex(0,0);
endShape();
beginShape();
curveVertex(-0.8,-0.8);
curveVertex(-0.8,-0.8);
curveVertex(-2, -3.6);
curveVertex(0, -this.petal_length-0.8);
curveVertex(2, -3.6);
curveVertex(0.8, -0.8);
curveVertex(0.8,-0.8);
endShape();
beginShape();
curveVertex(-0.8,-0.8);
curveVertex(-0.8,-0.8);
curveVertex(-2, 2);
curveVertex(0, this.petal_length-0.8);
curveVertex(2, 2);
curveVertex(0.8, -0.8);
curveVertex(0.8,-0.8);
endShape();
}
else if(this.petal_layer ==2){
beginShape();
curveVertex(0,0);
curveVertex(0, 0);
curveVertex(-2.8, 1.2);
curveVertex(-this.petal_length,-0.8);
curveVertex(-2.8, -2.8);
curveVertex(0,-1.6);
curveVertex(0,-1.6);
endShape();
beginShape();
curveVertex(0,-1.6);
curveVertex(0, -1.6);
curveVertex(2.8, -2.8);
curveVertex(this.petal_length,-0.8);
curveVertex(2.8, 1.2);
curveVertex(0,0);
curveVertex(0,0);
endShape();
beginShape();
curveVertex(-0.8,-0.8);
curveVertex(-0.8,-0.8);
curveVertex(-2, -3.6);
curveVertex(0, -this.petal_length-0.8);
curveVertex(2, -3.6);
curveVertex(0.8, -0.8);
curveVertex(0.8,-0.8);
endShape();
beginShape();
curveVertex(-0.8,-0.8);
curveVertex(-0.8,-0.8);
curveVertex(-2, 2);
curveVertex(0, this.petal_length-0.8);
curveVertex(2, 2);
curveVertex(0.8, -0.8);
curveVertex(0.8,-0.8);
endShape();
fill(174, 82, 255, 170);
//SECOND LAYER OF PETALS
beginShape();
curveVertex(-0.8, 0);
curveVertex(-0.8, 0);
curveVertex(-2, 0.4);
curveVertex(-this.petal_length/1.2, -0.8);
curveVertex(-2, -2);
curveVertex(-0.8, -1.6);
curveVertex(-0.8, -1.6);
endShape();
beginShape();
curveVertex(0.8, 0);
curveVertex(0.8, 0);
curveVertex(2, 0.4);
curveVertex(this.petal_length/1.2, -0.8);
curveVertex(2, -2);
curveVertex(0.8, -1.6);
curveVertex(0.8, -1.6);
endShape();
beginShape();
curveVertex(0.8, 0);
curveVertex(0.8, 0);
curveVertex(1.2, 1.2);
curveVertex(0, this.petal_length/1.2 -0.8);
curveVertex(-1.2, 1.2);
curveVertex(-0.8, 0);
curveVertex(-0.8, 0);
endShape();
beginShape();
curveVertex(0.8, -1.6);
curveVertex(0.8, -1.6);
curveVertex(1.2, -2.8);
curveVertex(0, -this.petal_length/1.2 -0.8);
curveVertex(-1.2, -2.8);
curveVertex(-0.8, -1.6);
curveVertex(-0.8, -1.6);
endShape();
}
//FACE COLOUR--LIGHTER OR DARKER----------------------------------------------------------------------
if(this.face_colour ==1){
fill(lighter);
stroke(255, 83, 3);
}
else if(this.face_colour ==2){
fill(darker);
stroke(255, 83, 3);
}
//HEAD
ellipse(0, -0.8, 2.4);
//EYES
//WHITE
fill(255);
strokeWeight(0.05);
stroke(255, 224, 153);
noStroke();
ellipse(left_eye_pos[0], left_eye_pos[1]+0.05,0.6, this.eye_size_y);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.05, 0.6, this.eye_size_y);
//EYE COLOUR
if (this.eye_colour == 1){
fill(purple_eyes);
}
else if(this.eye_colour ==2){
fill(green_eyes);
}
else if( this.eye_colour ==3){
fill(brown_eyes);
}
//IRIS
noStroke();
ellipse(left_eye_pos[0],left_eye_pos[1]+0.05,0.4,this.eye_size_y/2);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.05,0.4,this.eye_size_y/2);
//HIGHLIGHTS------------------
noStroke();
fill(255);
//left hl
ellipse(left_eye_pos[0]+0.1,left_eye_pos[1],this.eye_size_y/6);
//right hl
ellipse(right_eye_pos[0]+0.1,right_eye_pos[1],this.eye_size_y/6);
//MOUTH
noStroke();
if(this.face_colour ==1){
fill(224, 108, 0);
}
else if(this.face_colour ==2){
fill(184, 61, 0);
}
push();
scale(0.8);
translate(0, -0.8);
beginShape();
curveVertex(top_lip1[0], top_lip1[1]);
curveVertex(top_lip1[0], top_lip1[1]);
curveVertex(bottom_lip3[0] - 0.4, bottom_lip3[1] );
curveVertex(bottom_lip4[0], bottom_lip4[1] +0.02);
curveVertex(bottom_lip5[0] + 0.4, bottom_lip5[1]);
curveVertex(top_lip6[0], top_lip6[1]);
curveVertex(top_lip4[0], top_lip4[1]-0.1);
curveVertex(top_lip3[0]+0.1, top_lip3[1]-0.15);
curveVertex(top_lip3[0]-0.1, top_lip3[1]-0.15);
curveVertex(top_lip2[0], top_lip2[1]-0.1);
curveVertex(top_lip2[0], top_lip2[1]-0.1);
endShape();
endShape();
pop();
//EYEBROWS --------------------------
stroke(15, 33, 92);
strokeWeight(0.3);
noFill();
beginShape();
curveVertex(left_brow_0[0], left_brow_0[1]),
curveVertex(left_brow_1[0], left_brow_1[1]),
curveVertex(left_brow_2[0], left_brow_2[1]),
curveVertex(left_brow_3[0], left_brow_3[1]),
curveVertex(left_brow_4[0], left_brow_4[1]),
endShape();
beginShape();
curveVertex(right_brow_0[0], right_brow_0[1]),
curveVertex(right_brow_1[0], right_brow_1[1]),
curveVertex(right_brow_2[0], right_brow_2[1]),
curveVertex(right_brow_3[0], right_brow_3[1]),
curveVertex(right_brow_4[0], right_brow_4[1]),
endShape();
//NOSE -----------------------------
//NOSE COLOUR -- BASED ON SKIN COLOUR
if(this.face_colour ==1){
fill(224, 108, 0);
}
else if (this.face_colour ==2){
fill(194, 78, 0);
}
//DRAW NOSE
noStroke();
ellipse(nose_pos[0], nose_pos[1]+0.4, 0.2, 0.1);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.petal_colour = int(map(settings[0], 0, 100, 1, 3));
this.petal_layer = int(map(settings[1], 0, 100, 1, 2));
this.petal_length = map(settings[2], 0, 100, 2, 3);
this.eye_size_y = map(settings[3], 0, 100, 0.4, 1);
this.eye_colour = int(map(settings[4], 0, 100, 1, 3));
this.face_colour = int(map(settings[5], 0, 100, 1, 2));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(6);
settings[0] = map(this.petal_colour, 1,3, 0, 100);
settings[1] = map(this.petal_layer, 1, 2, 0, 100);
settings[2] = map(this.petal_length, 2, 3, 0, 100);
settings[3] = map(this.eye_size_y, 0.4, 1, 0, 100);
settings[4] = map(this.eye_colour, 1, 3, 0, 100);
settings[5] = map(this.face_colour, 1, 2, 0, 100);
return settings;
}
}
{
"000001": [
50,
0,
100,
100,
100,
0
],
"000002": [
100,
0,
100,
100,
100,
0
],
"000005": [
50,
0,
100,
81,
50,
0
],
"000006": [
0,
0,
100,
100,
100,
100
],
"000007": [
0,
100,
0,
27.000000000000007,
100,
0
],
"000009": [
100,
0,
100,
100,
100,
0
],
"000010": [
50,
0,
100,
100,
0,
0
],
"000013": [
50,
100,
0,
12.000000000000002,
50,
0
],
"000014": [
0,
0,
100,
100,
100,
100
],
"000015": [
0,
100,
0,
0,
100,
0
],
"000016": [
0,
100,
0,
0,
100,
0
],
"000018": [
50,
0,
100,
51.99999999999999,
50,
0
],
"000020": [
0,
100,
0,
19,
100,
0
],
"000023": [
0,
100,
0,
14.999999999999996,
0,
0
],
"000025": [
0,
100,
0,
25.000000000000007,
100,
0
],
"000028": [
100,
0,
100,
100,
100,
0
],
"000029": [
50,
0,
100,
100,
50,
0
],
"000030": [
50,
100,
0,
93.00000000000001,
50,
0
],
"000031": [
50,
0,
100,
61,
0,
0
],
"000032": [
0,
100,
0,
61,
100,
0
],
"000035": [
0,
0,
100,
100,
100,
0
],
"000037": [
0,
100,
0,
33.000000000000014,
100,
100
],
"000038": [
0,
100,
0,
12.000000000000002,
50,
0
],
"000040": [
0,
0,
100,
100,
100,
0
],
"000041": [
0,
100,
0,
20,
100,
100
],
"000042": [
50,
0,
100,
64,
50,
0
],
"000043": [
0,
0,
100,
100,
100,
0
],
"000044": [
0,
0,
100,
100,
100,
100
],
"000045": [
100,
0,
100,
34.000000000000014,
100,
0
],
"000047": [
0,
0,
100,
0,
100,
100
],
"000048": [
0,
100,
0,
9,
100,
0
],
"000050": [
0,
100,
0,
9,
100,
0
],
"000051": [
50,
100,
0,
78,
100,
0
],
"000052": [
0,
100,
0,
45.00000000000001,
50,
0
],
"000054": [
50,
0,
100,
30.00000000000001,
50,
0
],
"000055": [
0,
100,
0,
13.000000000000004,
100,
0
],
"000056": [
0,
100,
39.000000000000014,
13.000000000000004,
100,
0
],
"000058": [
0,
0,
100,
85.00000000000001,
0,
0
],
"000060": [
100,
100,
0,
20,
100,
100
],
"000064": [
0,
100,
0,
0,
50,
0
],
"000065": [
0,
100,
0,
0,
100,
100
],
"000068": [
0,
100,
0,
0,
100,
0
],
"000069": [
0,
100,
0,
100,
100,
0
],
"000071": [
50,
0,
100,
100,
50,
0
],
"000073": [
0,
0,
100,
52.99999999999999,
100,
0
],
"000076": [
0,
100,
25,
52.99999999999999,
100,
100
],
"000077": [
0,
0,
100,
100,
100,
0
],
"000078": [
0,
0,
100,
100,
100,
0
],
"000079": [
50,
100,
0,
36,
100,
100
],
"000080": [
0,
100,
0,
0,
50,
0
],
"000081": [
0,
100,
0,
0,
100,
100
],
"000083": [
100,
0,
100,
100,
50,
0
],
"000085": [
100,
0,
100,
100,
50,
0
],
"000086": [
100,
0,
100,
100,
50,
0
],
"000088": [
100,
0,
100,
68,
100,
0
],
"000091": [
0,
100,
0,
0,
100,
0
],
"000092": [
50,
0,
100,
78,
50,
0
],
"000096": [
0,
0,
100,
100,
100,
100
],
"000097": [
50,
0,
100,
100,
0,
0
],
"000099": [
50,
0,
100,
100,
50,
0
],
"000100": [
50,
0,
100,
100,
100,
0
],
"000103": [
0,
0,
100,
100,
50,
0
],
"000104": [
50,
100,
0,
0,
0,
0
],
"000106": [
100,
0,
100,
100,
100,
0
],
"000108": [
50,
0,
100,
100,
0,
0
],
"000109": [
50,
100,
0,
48.999999999999986,
50,
0
],
"000110": [
0,
0,
100,
17,
50,
0
],
"000111": [
50,
0,
100,
0,
100,
100
],
"000114": [
0,
100,
0,
100,
100,
0
],
"000115": [
50,
100,
0,
0,
50,
0
],
"000116": [
0,
100,
0,
37,
100,
0
],
"000117": [
0,
0,
100,
100,
100,
100
],
"000118": [
0,
0,
100,
100,
100,
100
],
"000121": [
0,
0,
100,
100,
100,
100
],
"000122": [
50,
0,
100,
81.99999999999999,
100,
0
],
"000125": [
0,
100,
0,
55.99999999999999,
50,
100
],
"000126": [
50,
0,
100,
100,
50,
100
],
"000129": [
0,
100,
0,
32.000000000000014,
100,
0
],
"000131": [
0,
0,
100,
72.00000000000001,
100,
100
],
"000132": [
0,
0,
100,
44.00000000000001,
100,
100
],
"000133": [
50,
0,
100,
100,
0,
0
],
"000134": [
0,
100,
0,
73.00000000000001,
100,
100
],
"000135": [
0,
100,
0,
43.00000000000001,
100,
100
],
"000137": [
0,
100,
0,
0,
100,
0
],
"000140": [
50,
0,
100,
100,
0,
0
],
"000142": [
0,
0,
100,
100,
0,
0
],
"000143": [
50,
100,
0,
32.000000000000014,
50,
0
],
"000145": [
0,
0,
100,
0,
100,
0
],
"000146": [
100,
0,
100,
65,
100,
100
],
"000147": [
50,
0,
100,
100,
50,
0
],
"000148": [
0,
0,
100,
30.00000000000001,
50,
0
],
"000150": [
100,
100,
0,
85.00000000000001,
50,
0
],
"000151": [
0,
0,
100,
26.000000000000007,
100,
100
],
"000152": [
0,
100,
0,
25.000000000000007,
50,
0
],
"000153": [
0,
100,
0,
25.000000000000007,
100,
0
],
"000155": [
100,
0,
100,
100,
100,
0
],
"000156": [
50,
0,
100,
62,
0,
0
],
"000157": [
50,
0,
100,
68,
50,
0
],
"000160": [
0,
100,
0,
42.00000000000001,
100,
0
],
"000161": [
0,
0,
100,
0,
50,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 5;
// other variables can be in here too
// these control the colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
function LuoFace() {
// these are state variables for a face
// (your variables may be different)
this.face = 4; // 1-5
this.spot = 5; // 0-10
this.shape = 1;
/*
* Draw a face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
let face = this.face;
let mouth = 5;
let blush = 5;
let spot = this.spot;
let spot_col = 5;
let spot_size = 1;
let eyebrows_rotate = 50;
let glasses = 5;
// Colour Sets
let face1 = '#ffe3fc'; //white
let face2 = '#f5ad8e'; //pink
let face3 = '#fcf06a'; //yellow
let face4 = '#d9764c'; //brown
let face5 = '#66756a'; //grey
let face6 = '#315070'; //blue
let face7 = '#8a5189'; //purple
let face8 = '#a65561'; //red
let face9 = '#5b8a5a'; //green
let face10 = '#de4e26'; //orange
let faceColour;
let left_eye = average_point(positions.left_eye);
let right_eye = average_point(positions.right_eye);
let left_eyebrow = average_point(positions.left_eyebrow);
let right_eyebrow = average_point(positions.right_eyebrow);
let left_d = dist(left_eye[0], left_eye[1], left_eyebrow[0], left_eyebrow[1]);
let right_d = dist(right_eye[0], right_eye[1], right_eyebrow[0], right_eyebrow[1]);
let left_eb_move = map(left_d, 0.4, 0.7, 0, 2, true);
let right_eb_move = map(right_d, 0.4, 0.7, 0, 2, true);
// print(left_d);
left_eye[0] *= 3;
left_eye[1] *= 3;
right_eye[0] *= 3;
right_eye[1] *= 3;
push();
scale(0.33);
// Rabbit (Brown)
//fill(221,168,128);
strokeWeight(0.3);
stroke(0);
beginShape();
endShape();
if(this.shape <2){
//soft SHAPES
noStroke();
// Face Colour
if(face == 1){
faceColour = face1; //***WHITE***//
}else if (face == 2){
faceColour = face2; //***dark***//
}else if (face == 3){
faceColour = face3; //***Yellow***//
}else if (face == 4){
faceColour = face4; //***Brown***//
}else{
faceColour = face5; //***Grey***//
}
fill(faceColour);
strokeWeight(0.3);
stroke(0);
ellipse(-0.5, 1.8, 15, 11);
push();
angleMode(RADIANS);
arc(-3.9, -3, 4.5, 16, -4, -0.4);//ear left
arc(2.4, -3.2, 5, 16, -2.8, 0.65);//ear right
pop();
} else {
//unsoft shape
if(face == 1){
faceColour = face6; //***WHITE***//
}else if (face == 2){
faceColour = face8; //***dark***//
}else if (face == 3){
faceColour = face7; //***Yellow***//
}else if (face == 4){
faceColour = face9; //***Brown***//
}else{
faceColour = face10; //***Grey***//
}
fill(faceColour);
strokeWeight(0.2);
stroke(0);
rect(-8, -4, 15, 11);
push();
angleMode(RADIANS);
rect(-3, -4, -2.5, -9.5);
rect(5, -4, -3, -6.5);
//arc(-3.9, -3, 4.5, 16, -4, -0.4);//ear left
//arc(2.4, -3.2, 5, 16, -2.8, 0.65);//ear right
pop();
}
// spot (Colour, Spot)
let amount = map(spot_col, 0, 10, 0, 1);
let colourWhite = color('#dbdbdb');
let colourDark = color('#e6655c');
let spotColour = lerpColor(colourWhite, colourDark, amount);
let spotFace = map(spot, 0, 100, 0, 100);
let spotS = map(spot_size, 0, 100, 1.3, 15);
strokeWeight(spotS);
stroke(spotColour);
if (spotFace == 0){
}
if (spotFace >= 2){
line(-0.5, -3, -0.5, -2);
}
if (spotFace >=4){
line(-6.5, 3, -3, 3);
}
if (spotFace >=6){
line(2.5, 2, 5.5, 2);
}
if (spotFace >=8){
line(3, 0, 5.5, 0);
}
if (spotFace >=10){
line(-6.5, 0.5, -4.5, 0.5);
}
// Mouth
strokeWeight(0.4);
stroke(0);
line(-1.55, -1, -0.05, -1);
let top_lip_point = positions.top_lip[9];
let bottom_lip_point = positions.bottom_lip[9];
// fill(255, 0, 0);
let d = dist(top_lip_point[0], top_lip_point[1], bottom_lip_point[0], bottom_lip_point[1])
// print(d);
// Mouth Open
if(d < 0.1) {
d = 0;
}
mouth = map(d, 0, 0.5, 0, 10);
let mouth_size = map(mouth, 0, 10, 0, 3.5);
strokeWeight(0.3);
fill('#fffcf7');
rect(-1.6, 2, 1.6, mouth_size, 0.08);
// Blush
noStroke();
if (blush > 3 && blush < 6){
fill('#ed4415'); //red
ellipse(-3.6, 0.5, 1.5, 1);
ellipse(2.3, 0.5, 1.5, 1);
}
// Eyes
noStroke();
fill(0);
// ellipse(-2.2, -2, 1.1, 1.1);
// ellipse(0.5, -2, 1.1, 1.1);
ellipse(left_eye[0], left_eye[1]+ 1.5, 2, 2); //eye size left
ellipse(right_eye[0] - 1.6, right_eye[1] + 1.7, 2, 2);
// Eyebrows
strokeWeight(0.5);
stroke(0);
push();
angleMode(DEGREES);
//translate(left_eye[0]-0.1, left_eye[1]-1);
//translate(0, -left_eb_move);
//rotate(eyebrows_rotate);
line(0.5, -2.5, 2.5, -2.5);
pop();
push();
angleMode(DEGREES);
//translate(right_eye[0]-0.2, right_eye[1]-1);
//translate(0, -right_eb_move);
//rotate(-eyebrows_rotate);
line(-3.5, -2.5, -1.5, -2.5);
pop();
// Glasses
if (glasses > 5 && glasses < 8){
stroke(0);
strokeWeight(0.35);
noFill();
ellipse(-2.3, -2.4, 2.6, 2.6);
ellipse(0.6, -2.4, 2.6, 2.6);
}
// Sunglasses
else if (glasses > 7 && glasses <= 10){
stroke(0);
strokeWeight(0.3);
fill('white');
ellipse(-2.6, -2.4, 3, 2.6);
ellipse(1, -2.4, 3, 2.6);
noStroke();
fill('black');
ellipse(-2.6, -2.37, 2.4, 2);
ellipse(1, -2.37, 2.4, 2);
stroke(0);
strokeWeight(0.3);
line(-1.1, -2.5, -0.65, -2.5);
}
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.face = int(map(settings[0], 0, 100, 1, 5));
this.spot = int(map(settings[1], 0, 100, 0, 10));
this.shape = map(settings[2],0,100,1,2);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(2);
settings[0] = map(this.face, 1, 5, 0, 100);
settings[1] = map(this.spot, 0, 10, 0, 100);
settings[82] = map(this.shape, 1, 2, 0, 100);
return settings;
}
}
// given an array of [x,y] points, return the average
function average_point(list) {
var sum_x = 0;
var sum_y = 0;
var num_points = 0;
for(var i=0; i<list.length; i++) {
sum_x += list[i][0];
sum_y += list[i][1];
num_points += 1;
}
return [sum_x / num_points, sum_y / num_points];
}
{
"000001": [
0,
100,
50
],
"000002": [
0,
100
],
"000005": [
20,
100
],
"000006": [
50,
100,
50
],
"000007": [
25,
0
],
"000009": [
25,
100
],
"000010": [
25,
100,
50
],
"000013": [
25,
0
],
"000014": [
75,
100
],
"000015": [
25,
0,
50
],
"000016": [
25,
0
],
"000018": [
75,
100,
50
],
"000020": [
25,
0
],
"000023": [
55,
0
],
"000025": [
10,
0,
50
],
"000028": [
25,
100
],
"000029": [
75,
100,
50
],
"000030": [
25,
0
],
"000031": [
80,
100,
50
],
"000032": [
90,
0
],
"000035": [
40,
100
],
"000037": [
50,
0
],
"000038": [
0,
70,
50
],
"000040": [
0,
90
],
"000041": [
30,
50,
50
],
"000042": [
0,
100,
50
],
"000043": [
10,
100,
50
],
"000044": [
50,
100
],
"000045": [
20,
100
],
"000047": [
50,
100,
50
],
"000048": [
20,
0,
50
],
"000050": [
20,
0
],
"000051": [
0,
20
],
"000052": [
60,
50,
50
],
"000054": [
0,
100
],
"000055": [
90,
40
],
"000056": [
50,
100
],
"000058": [
20,
100,
50
],
"000060": [
100,
0
],
"000064": [
0,
0
],
"000065": [
50,
0
],
"000068": [
0,
30,
50
],
"000069": [
20,
0,
50
],
"000071": [
50,
100
],
"000073": [
40,
100,
50
],
"000076": [
50,
0,
50
],
"000077": [
0,
100
],
"000078": [
50,
100
],
"000079": [
0,
0
],
"000080": [
0,
0
],
"000081": [
0,
0
],
"000083": [
0,
100
],
"000085": [
0,
100
],
"000086": [
25,
100
],
"000088": [
0,
100
],
"000091": [
0,
0
],
"000092": [
0,
100
],
"000096": [
0,
100
],
"000097": [
0,
100
],
"000099": [
25,
100
],
"000100": [
0,
100
],
"000103": [
25,
100
],
"000104": [
25,
0
],
"000106": [
25,
0
],
"000108": [
25,
100
],
"000109": [
0,
0
],
"000110": [
25,
100
],
"000111": [
50,
100
],
"000114": [
0,
0
],
"000115": [
25,
0
],
"000116": [
0,
0
],
"000117": [
100,
100
],
"000118": [
25,
100
],
"000121": [
25,
100
],
"000122": [
0,
100
],
"000125": [
0,
0
],
"000126": [
0,
100
],
"000129": [
0,
0
],
"000131": [
25,
100
],
"000132": [
50,
100
],
"000133": [
0,
100
],
"000134": [
100,
0
],
"000135": [
75,
0
],
"000137": [
0,
0
],
"000140": [
0,
100
],
"000142": [
0,
100
],
"000143": [
0,
0
],
"000145": [
0,
100
],
"000146": [
0,
100
],
"000147": [
0,
100
],
"000148": [
0,
100
],
"000150": [
0,
0
],
"000151": [
50,
70
],
"000152": [
0,
0
],
"000153": [
0,
0
],
"000155": [
25,
100
],
"000156": [
0,
100
],
"000157": [
0,
100
],
"000160": [
0,
0
],
"000161": [
0,
90
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = false;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 9;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i = 0; i < s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len, sum_y / s_len];
}
// This where you define your own face object
function McKendryFace() {
//colours:
this.purple = color(210, 160, 200, 200);
this.pink = color(250, 225, 250, 200);
this.light_red = color(240, 180, 170, 200);
this.dark_red = color(185, 120, 115, 200);
this.orange = color(240, 190, 145, 200);
this.yellow = color(255, 250, 210, 200);
this.light_green = color(230, 250, 220, 200);
this.dark_green = color(150, 175, 135, 200);
this.dark_blue = color(135, 135, 180, 200);
this.light_blue = color(200, 230, 245, 200);
this.other_turq = color(195, 245, 225, 200);
//positions/states:
this.mouthX = 0;
this.mouthY = 0;
this.male_female = 1;
this.chinX = 0;
this.chinY = 0;
this.shapeScale = 1;
this.eye_height = .25;
this.faceColor = 1;
this.eyesX = 0;
this.mouth_OpenClose = 2
this.show_points = function(segment) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
var number = i.toString();
textAlign(CENTER, CENTER);
textSize(0.2);
fill(0);
text(number, px, py, 0.1);
}
}
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if (i < segment.length - 1) {
let nx = segment[i + 1][0];
let ny = segment[i + 1][1];
line(px, py, nx, ny);
} else if (do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
//this array takes the colours called in the variables above, then I get a random colour from the array to be the fill for the background shapes
this.colourFillArray = [this.purple, this.pink, this.light_red, this.dark_red, this.orange, this.yellow, this.light_green, this.dark_green, this.dark_blue, this.light_blue, this.other_turq];
this.colourFill = random(this.colourFillArray);
//If statement decides if the face is male or female, dictated by slider5.
if (this.male_female < 2) {
//FEMALE SHAPES
fill(this.colourFill);
noStroke();
push();
//scales shapes to size of the face
scale(this.shapeScale);
ellipse(0, 0, 2, 3);
ellipse(0, .5, 3.75, 3.25);
ellipse(-1.25, -1.5, 2, 4);
ellipse(.75, -2.5, 2.5, 2);
ellipse(-.5, 1.75, 2.5, 2);
ellipse(1, -1.5, 2, 2.5);
ellipse(-.75, -2.5, 2, 3);
//HAIRLINE
noFill();
stroke(0);
strokeWeight(0.035);
beginShape();
vertex(-.3, -2.9);
quadraticVertex(1.5, -4, 1.9, -2.5);
endShape();
pop();
//FEMALE MOUTH
//if-else statement decides if the mouth is closed (only a line, no fill) or open (area of mouth filled)
if (this.mouth_OpenClose == 1) {
stroke(0);
noFill();
strokeWeight(0.03);
beginShape();
vertex(positions.bottom_lip[7][0], positions.bottom_lip[7][1]);
quadraticVertex(positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
endShape();
} else {
stroke(0);
fill(200, 200, 200, 100);
strokeWeight(0.03);
beginShape();
vertex(positions.bottom_lip[7][0], positions.bottom_lip[7][1]);
quadraticVertex(positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
endShape();
strokeWeight(0.01);
line(positions.bottom_lip[7][0], positions.bottom_lip[7][1], positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
}
//FEMALE JAWLINE
stroke(0);
strokeWeight(0.035);
//if statement decides what side of the jaw the face is on, using the tip of the nose as a center point to figure out if the person is looking left or right
if (positions.nose_tip[2][0] < 0) {
beginShape();
noFill();
vertex(positions.chin[8][0], positions.chin[8][1])
quadraticVertex(positions.chin[12][0] + this.chinX, positions.chin[12][1] + this.chinY, positions.chin[16][0], positions.chin[16][1])
endShape();
} else {
beginShape();
noFill();
vertex(positions.chin[0][0], positions.chin[0][1])
quadraticVertex(positions.chin[4][0] + this.chinX, positions.chin[5][1] + this.chinY, positions.chin[8][0], positions.chin[8][1])
endShape();
}
//FEMALE EYEBROWS
noFill();
stroke(0);
strokeWeight(0.02);
beginShape();
vertex(positions.left_eyebrow[1][0], positions.left_eyebrow[1][1]);
quadraticVertex(positions.nose_bridge[1][0], positions.nose_bridge[1][1] - 1.2, positions.right_eyebrow[3][0], positions.right_eyebrow[3][1])
endShape();
//FEMALE NOSE
noFill();
stroke(0);
strokeWeight(0.03);
//same as the jawline if statement- decides which way the nose should be pointing
if (positions.nose_tip[2][0] < 0) {
beginShape();
vertex(positions.nose_bridge[1][0], positions.nose_bridge[1][1])
quadraticVertex(positions.nose_tip[1][0], positions.nose_tip[1][1] + .5, positions.nose_tip[4][0], positions.nose_tip[4][1])
endShape();
} else {
beginShape();
vertex(positions.nose_bridge[1][0], positions.nose_bridge[1][1])
quadraticVertex(positions.nose_tip[3][0], positions.nose_tip[3][1] + .5, positions.nose_tip[1][0], positions.nose_tip[1][1])
endShape();
}
} else {
////MALE FACE////
//MALE SHAPES
this.colourFillArray = [this.purple, this.pink, this.light_red, this.dark_red, this.orange, this.yellow, this.light_green, this.dark_green, this.dark_blue, this.light_blue, this.other_turq];
this.colourFill = random(this.colourFillArray);
noStroke();
fill(this.colourFill);
push();
//scales shapes to size of the face
scale(this.shapeScale);
rect(.75, -2.25, 2, 3.5);
rect(-2.25, -3.25, 2.5, 1.5);
rect(-.75, -2, 2, 2);
rect(-1.75, -1.25, 3, 3.5);
rect(-1.25, -2.75, 1, 5.5);
rect(0, -3.5, 1.5, 1.5);
//HAIRLINE
stroke(0);
strokeWeight(0.035);
line(-1.75, -1.75, -1.75, -2.9);
line(-1.9, -2.75, 1.5, -2.75);
noStroke();
pop();
//MALE MOUTH
if (this.mouth_OpenClose == 1) {
stroke(0);
noFill();
strokeWeight(0.03);
line(positions.bottom_lip[7][0], positions.bottom_lip[7][1], positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY);
line(positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
} else {
stroke(0);
fill(200, 200, 200, 100);
stroke(0);
strokeWeight(0.02);
triangle(positions.bottom_lip[7][0], positions.bottom_lip[7][1], positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
strokeWeight(0.03);
line(positions.bottom_lip[7][0], positions.bottom_lip[7][1], positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY);
line(positions.bottom_lip[3][0] + this.mouthX, positions.bottom_lip[3][1] + this.mouthY, positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
}
//MALE JAWLINE
stroke(0);
strokeWeight(0.035);
if (positions.nose_tip[2][0] < 0) {
line(positions.chin[8][0], positions.chin[8][1], positions.chin[12][0] + this.chinX, positions.chin[12][1] + this.chinY);
line(positions.chin[12][0] + this.chinX, positions.chin[12][1] + this.chinY, positions.chin[16][0], positions.chin[16][1]);
} else {
line(positions.chin[0][0], positions.chin[0][1], positions.chin[4][0] + this.chinX, positions.chin[4][1] + this.chinY);
line(positions.chin[4][0] + this.chinX, positions.chin[4][1] + this.chinY, positions.chin[8][0], positions.chin[8][1]);
}
//MALE EYEBROWS
stroke(0);
strokeWeight(0.02);
line(positions.left_eyebrow[1][0], positions.left_eyebrow[1][1], positions.right_eyebrow[3][0], positions.right_eyebrow[3][1]);
//MALE NOSE
noFill();
stroke(0);
strokeWeight(0.03);
if (positions.nose_tip[2][0] < 0) {
line(positions.nose_bridge[1][0], positions.nose_bridge[1][1], positions.nose_tip[1][0], positions.nose_tip[1][1]);
line(positions.nose_tip[1][0], positions.nose_tip[1][1], positions.nose_tip[3][0], positions.nose_tip[3][1])
} else {
line(positions.nose_bridge[1][0], positions.nose_bridge[1][1], positions.nose_tip[3][0], positions.nose_tip[3][1]);
line(positions.nose_tip[3][0], positions.nose_tip[3][1], positions.nose_tip[1][0], positions.nose_tip[1][1])
}
}
//EYES//
fill(240, 240, 240, 100);
stroke(0)
strokeWeight(0.025);
if (positions.nose_tip[2][0] < 0) {
rect(positions.left_eye[0][0] + this.eyesX, positions.left_eye[0][1], 1, this.eye_height)
ellipse(positions.right_eye[4][0] + this.eyesX, positions.right_eye[4][1], 1.25, .25 + this.eye_height);
} else {
rect(positions.left_eye[0][0] + this.eyesX, positions.left_eye[0][1], 1, this.eye_height)
ellipse(positions.right_eye[4][0] + this.eyesX, positions.right_eye[4][1], 1.25, .25 + this.eye_height);
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.mouthX = map(settings[0], 0, 100, -1.25, 1.25);
this.mouthY = map(settings[1], 0, 100, -1.25, 1.25);
this.eyesX = map(settings[2], 0, 100, -1, 1);
this.eye_height = map(settings[3], 0, 100, 0, .75);
this.chinX = map(settings[4], 0, 100, -1.5, 1.5);
this.chinY = map(settings[5], 0, 100, -1.5, 1.5);
this.mouth_OpenClose = int(map(settings[6], 0, 100, 1, 3));
this.shapeScale = map(settings[7], 0, 100, .5, 1.25);
this.male_female = map(settings[8], 0, 100, 1, 3);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(3);
settings[0] = map(this.mouthX, -1.25, 1.25, 0, 100);
settings[1] = map(this.mouthY, -1.25, 1.25, 0, 100);
settings[2] = map(this.eyesX, -1, 1, 0, 100);
settings[3] = map(this.eye_height, 0, .75, 0, 100);
settings[4] = map(this.chinX, -1.5, 1.5, 0, 100);
settings[5] = map(this.chinY, -1.5, 1.5, 0, 100);
settings[6] = int(map(this.mouth_OpenClose, 1, 3, 0, 100));
settings[7] = map(this.shapeScale, .5, 1.25, 0, 100);
settings[8] = map(this.male_female, 1, 3, 0, 100);
return settings;
}
}
{
"000001": [
48,
40,
34,
22,
57,
50,
52,
49,
100
],
"000002": [
34,
66,
26,
50,
54,
68,
100,
34.99999999999999,
0
],
"000005": [
46.99999999999999,
33,
44,
28.999999999999996,
69,
82,
100,
38.99999999999999,
17.999999999999993
],
"000006": [
61,
40,
54,
34.99999999999999,
54,
69,
100,
30,
37.999999999999986
],
"000007": [
46.00000000000001,
43,
46,
51,
44,
69,
0,
54,
100
],
"000009": [
51,
52,
33,
47,
36.99999999999999,
51,
100,
66,
0
],
"000010": [
50,
57.99999999999999,
45,
22,
51,
66,
60,
40.00000000000001,
27
],
"000013": [
50,
44.00000000000001,
55.00000000000001,
23,
54,
62,
100,
73.99999999999999,
100
],
"000014": [
48,
53,
41,
40.00000000000001,
63,
68,
0,
52.99999999999999,
47
],
"000015": [
56.00000000000001,
34,
46,
7.000000000000001,
64,
71,
100,
62,
100
],
"000016": [
46.99999999999999,
45,
61,
27,
57.99999999999999,
53,
0,
56.99999999999999,
100
],
"000018": [
49.00000000000001,
53,
40,
25,
40.00000000000001,
56.99999999999999,
100,
38.00000000000001,
30.000000000000004
],
"000020": [
51,
32,
45,
9.000000000000002,
53,
47,
100,
46,
100
],
"000023": [
49.00000000000001,
45,
48,
16,
56.00000000000001,
53,
100,
51.000000000000014,
100
],
"000025": [
41,
41,
45,
23,
64,
47,
0,
62,
100
],
"000028": [
50,
64,
46,
23,
41,
87,
100,
51.000000000000014,
44.99999999999999
],
"000029": [
50,
49.00000000000001,
44,
31,
41,
48,
100,
54,
44.99999999999999
],
"000030": [
57.99999999999999,
38,
37,
34.99999999999999,
72.00000000000001,
72.00000000000001,
0,
61,
100
],
"000031": [
45,
56.99999999999999,
37,
16,
38.99999999999999,
60,
100,
54,
0
],
"000032": [
48,
27,
41,
36.99999999999999,
52,
62,
100,
61,
100
],
"000035": [
48,
42.00000000000001,
41,
38.99999999999999,
40.00000000000001,
46,
100,
47,
0
],
"000037": [
56.00000000000001,
34,
66,
28.000000000000004,
54,
52,
0,
61,
100
],
"000038": [
46.99999999999999,
44.00000000000001,
45,
23,
46,
47,
100,
69,
100
],
"000040": [
53,
55.00000000000001,
49,
30,
31,
59,
0,
62,
42.99999999999999
],
"000041": [
42.00000000000001,
41,
25,
21,
56.99999999999999,
48,
100,
65,
100
],
"000042": [
50,
60,
40,
36.00000000000001,
43,
57.99999999999999,
0,
46,
0
],
"000043": [
46.99999999999999,
63,
40,
33,
36.99999999999999,
53,
100,
46,
0
],
"000044": [
49.00000000000001,
51,
43,
25,
57.99999999999999,
50,
0,
36.99999999999999,
0
],
"000045": [
46.99999999999999,
63,
43,
17,
69.99999999999999,
52,
100,
36.99999999999999,
0
],
"000047": [
46.99999999999999,
56.99999999999999,
43,
12,
69.99999999999999,
64,
100,
45,
0
],
"000048": [
60,
40,
55.00000000000001,
10.000000000000002,
63,
72.00000000000001,
0,
38.99999999999999,
100
],
"000050": [
54,
43,
55.00000000000001,
21,
77.99999999999999,
77.99999999999999,
100,
47,
100
],
"000051": [
64,
46.99999999999999,
48,
41,
41,
72.00000000000001,
0,
82,
100
],
"000052": [
42.00000000000001,
45,
40,
30,
59,
57.99999999999999,
0,
64,
100
],
"000054": [
45,
64,
44,
16,
59,
67,
100,
44.000000000000014,
0
],
"000055": [
48,
42.00000000000001,
42,
18.000000000000004,
53,
55.00000000000001,
0,
60,
100
],
"000056": [
38,
48,
35,
14.000000000000002,
67,
77,
0,
36.99999999999999,
0
],
"000058": [
56.99999999999999,
51,
35,
26,
41,
53,
20,
36.99999999999999,
0
],
"000060": [
46.00000000000001,
45,
12,
16,
61,
34,
100,
34,
100
],
"000064": [
46.00000000000001,
48,
44,
14.000000000000002,
53,
60,
0,
47,
100
],
"000065": [
46.99999999999999,
45,
44,
21,
62,
56.99999999999999,
100,
55.000000000000014,
100
],
"000068": [
51,
49.00000000000001,
44,
24,
59,
53,
100,
46,
100
],
"000069": [
50,
37,
43,
36.00000000000001,
43,
54,
100,
56.99999999999999,
100
],
"000071": [
46.99999999999999,
53,
43,
36.00000000000001,
64,
73,
100,
43,
0
],
"000073": [
38,
46.99999999999999,
14.000000000000002,
21,
41,
85,
100,
48.99999999999999,
0
],
"000076": [
45,
49.00000000000001,
34,
14.000000000000002,
50,
61,
0,
48.99999999999999,
100
],
"000077": [
49.00000000000001,
46.00000000000001,
48,
28.999999999999996,
69.99999999999999,
64,
0,
38.00000000000001,
0
],
"000078": [
42.00000000000001,
44.00000000000001,
40,
30,
46,
60,
0,
44.000000000000014,
0
],
"000079": [
46.00000000000001,
45,
48,
30,
30,
84,
0,
56.99999999999999,
100
],
"000080": [
44.00000000000001,
43,
37,
22,
42,
28.999999999999996,
0,
56.00000000000001,
100
],
"000081": [
52,
48,
52,
22,
43,
54,
100,
61,
100
],
"000083": [
48,
56.00000000000001,
43,
21,
56.00000000000001,
82,
0,
50,
0
],
"000085": [
41,
55.00000000000001,
43,
46,
65,
73,
0,
50,
0
],
"000086": [
30,
33,
37,
40.00000000000001,
34.99999999999999,
52,
0,
55.000000000000014,
0
],
"000088": [
40,
42.00000000000001,
50,
41,
73,
61,
100,
44.000000000000014,
0
],
"000091": [
44.00000000000001,
41,
41,
13,
56.99999999999999,
66,
0,
55.000000000000014,
100
],
"000092": [
39,
53,
41,
22,
66,
69,
0,
45,
0
],
"000096": [
54,
32,
47,
28.000000000000004,
38.99999999999999,
66,
0,
30.99999999999999,
0
],
"000097": [
46.00000000000001,
31,
42,
25,
68,
51,
100,
36.99999999999999,
0
],
"000099": [
53,
55.00000000000001,
42,
16,
52,
79,
100,
46,
0
],
"000100": [
63,
48,
56.99999999999999,
21,
38.00000000000001,
46,
30,
43,
0
],
"000103": [
41,
38,
44,
23,
43,
69.99999999999999,
40,
34,
0
],
"000104": [
55.00000000000001,
46.00000000000001,
48,
16,
31,
80.00000000000001,
100,
46,
100
],
"000106": [
61,
55.00000000000001,
43,
26,
33,
42,
100,
47,
0
],
"000108": [
43,
55.00000000000001,
43,
36.99999999999999,
55.00000000000001,
63,
100,
40.00000000000001,
0
],
"000109": [
49.00000000000001,
38,
43,
24,
56.99999999999999,
56.99999999999999,
100,
55.000000000000014,
100
],
"000110": [
46.00000000000001,
50,
43,
23,
38.00000000000001,
55.00000000000001,
100,
54,
49
],
"000111": [
36,
54,
48,
13,
61,
57.99999999999999,
100,
48,
0
],
"000114": [
50,
44.00000000000001,
48,
46,
56.00000000000001,
56.99999999999999,
100,
55.000000000000014,
100
],
"000115": [
50,
42.00000000000001,
42,
31,
61,
53,
10,
51.000000000000014,
100
],
"000116": [
46.00000000000001,
44.00000000000001,
42,
27,
50,
53,
100,
50,
100
],
"000117": [
57.99999999999999,
46.00000000000001,
42,
34.99999999999999,
50,
77,
100,
50,
0
],
"000118": [
65,
46.99999999999999,
33,
38.99999999999999,
44,
60,
40,
51.000000000000014,
0
],
"000121": [
46.00000000000001,
48,
43,
34.99999999999999,
33,
64,
50,
48.99999999999999,
0
],
"000122": [
46.00000000000001,
53,
43,
36.99999999999999,
69,
69.99999999999999,
100,
40.00000000000001,
0
],
"000125": [
57.99999999999999,
41,
46,
28.000000000000004,
55.00000000000001,
53,
0,
61,
100
],
"000126": [
38,
46.00000000000001,
54,
28.000000000000004,
66,
69,
100,
48,
0
],
"000129": [
44.00000000000001,
46.00000000000001,
46,
18.000000000000004,
59,
55.00000000000001,
100,
48,
100
],
"000131": [
34,
50,
66,
25,
69.99999999999999,
75,
100,
36.99999999999999,
0
],
"000132": [
46.99999999999999,
56.00000000000001,
40,
17,
63,
48,
100,
36.99999999999999,
0
],
"000133": [
48,
55.00000000000001,
45,
25,
36.00000000000001,
54,
100,
46,
0
],
"000134": [
41,
39,
18,
14.000000000000002,
53,
64,
100,
51.000000000000014,
100
],
"000135": [
53,
42.00000000000001,
56.99999999999999,
17,
49,
46,
0,
50,
100
],
"000137": [
51,
36,
65,
10.000000000000002,
46,
54,
100,
33.00000000000001,
100
],
"000140": [
61,
37,
48,
38.99999999999999,
46,
60,
0,
34.99999999999999,
0
],
"000142": [
61,
31,
48,
19.000000000000004,
61,
72.00000000000001,
100,
43,
0
],
"000143": [
61,
41,
41,
21,
59,
63,
100,
55.000000000000014,
100
],
"000145": [
55.00000000000001,
59,
49,
10.000000000000002,
40.00000000000001,
61,
100,
46,
0
],
"000146": [
68,
46.99999999999999,
66,
24,
30,
71,
100,
41,
0
],
"000147": [
62,
49.00000000000001,
51,
36.99999999999999,
38.99999999999999,
61,
100,
47,
0
],
"000148": [
54,
43,
70,
18.000000000000004,
54,
71,
100,
40.00000000000001,
0
],
"000150": [
52,
43,
48,
24,
50,
38.00000000000001,
10,
48,
100
],
"000151": [
45,
56.00000000000001,
43,
12,
36.00000000000001,
52,
100,
40.00000000000001,
0
],
"000152": [
48,
44.00000000000001,
44,
16,
54,
50,
100,
51.000000000000014,
100
],
"000153": [
48,
40,
44,
21,
42,
36.99999999999999,
100,
48,
100
],
"000155": [
41,
56.99999999999999,
44,
32,
63,
63,
100,
46,
0
],
"000156": [
37,
51,
50,
26,
66,
68,
100,
46,
0
],
"000157": [
46.99999999999999,
42.00000000000001,
44,
27,
28.000000000000004,
62,
70,
45,
0
],
"000160": [
43,
42.00000000000001,
40,
34.99999999999999,
52,
50,
80,
56.99999999999999,
100
],
"000161": [
48,
52,
35,
17,
71,
56.99999999999999,
100,
38.00000000000001,
0
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 4;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i = 0; i < s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len, sum_y / s_len];
}
// This where you define your own face object
function McSweeneyFace() {
//frameRate(1);
// these are state variables for a face
// (your variables should be different!)
this.num_eyes = 2; // can be either 1 (cyclops) or 2 (two eyes)
this.eye_shift = -1; // range is -10 to 10
this.mouth_value = 4; // range is 0.5 to 8
//variables between 0-100;
this.jaw = 50;
this.eyes = 50;
this.cheek1 = 50;
this.mouth = 50;
this.cheek2 = 50;
this.colour_picker = 80;
this.horn_size = 50;
this.jaw_ang = 50;
this.eye_evil = 50;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for (let i = 0; i < segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if (i < segment.length - 1) {
let nx = segment[i + 1][0];
let ny = segment[i + 1][1];
line(px, py, nx, ny);
} else if (do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
// fill(255);
// ellipse(0, 0, 4);
// return;
/*
// draw segments of face using points
fill(128);
stroke(128);
this.draw_segment(positions.chin);
fill(100, 0, 100);
stroke(100, 0, 100);
this.draw_segment(positions.nose_bridge);
this.draw_segment(positions.nose_tip);
strokeWeight(0.03);
fill(200, 0, 0);
stroke(200, 0, 0);
this.draw_segment(positions.top_lip);
this.draw_segment(positions.bottom_lip);
fill(255);
stroke(255);
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye); */
//---------------------------------------------------------------------------
//scale(4/10);
let colour_pic = int(map(this.colour_picker, 0, 100, 1, 3))
let colour = [];
let strokeCol = [];
if (colour_pic == 1) {
colour = [165, 146, 126];
strokeCol = [20];
} else if (colour_pic == 2) {
colour = [227, 218, 201];
strokeCol = [150];
} else if (colour_pic == 3) {
colour = [222, 202, 176];
strokeCol = [255];
}
// head
let cheek = 5;
let cheek_dist = 4;
let cheek_out = 5.5;
let cheek_height = map(this.cheek1, 0, 100, -1.5, -0.7, true);
let cheek_end_x = 4;
let cheek_end_y = 2;
var jaw_width = map(this.jaw, 0, 100, 3, 5);
var jaw_height = 3.5;
var chin_width = 1.5;
var chin_height = 6;
let mouthweight = 0.1;
let genstroke = 0.15;
let eyeposL = segment_average(positions.left_eye);
let eyeposR = segment_average(positions.right_eye);
let eyesizeL = (positions.left_eye[3][0] - positions.left_eye[0][0]);
let eyesizeR = (positions.right_eye[3][0] - positions.right_eye[0][0]);
let eyesizeRV = ((positions.right_eye[2][1] - positions.right_eye[4][1])) * 3;
let eyesizeLV = ((positions.right_eye[1][1] - positions.right_eye[5][1])) * 3;
//fill(colour);
stroke(strokeCol);
//stroke(145,136,116);
strokeCap(ROUND);
smooth();
strokeJoin(ROUND);
strokeWeight(genstroke);
//Crainium ------------------------------------------------------
//Horns ------------------------------------------------------
push();
noFill();
let nosl = positions.nose_bridge[0][1] - positions.nose_bridge[3][1];
let hornpos = ((eyeposR[1] + eyeposL[1])/2) + (nosl)
let horn_height =(map(this.horn_size, 0, 100, 0.75, 2));
//Fill -----
push();
fill(strokeCol);
stroke(strokeCol);
strokeWeight(genstroke/3)
triangle(positions.right_eyebrow[1][0],hornpos*1.1, positions.right_eyebrow[3][0],hornpos,
positions.chin[12][0]*0.95, hornpos + (nosl*horn_height ) );
triangle(positions.left_eyebrow[1][0],hornpos, positions.left_eyebrow[3][0],hornpos*1.1,
positions.chin[4][0]*0.95, (hornpos + (nosl*horn_height)) );
/*//if (horn_desc ==)
fill(255,0,0);
stroke(255,0,0);
triangle(positions.right_eyebrow[1][0]*1.4,hornpos*1.9, positions.right_eyebrow[3][0],hornpos*1.8,
positions.chin[12][0]*0.95, hornpos + (nosl*horn_height ) );
triangle(positions.left_eyebrow[1][0],hornpos*1.8, positions.left_eyebrow[3][0]*1.4,hornpos*1.9,
positions.chin[4][0]*0.95, (hornpos + (nosl*horn_height)) );
*/
pop();
//Top Horn --------
noFill();
beginShape();
curveVertex(positions.right_eyebrow[3][0]*0.8, eyeposR[1]); //
curveVertex(positions.right_eyebrow[3][0],hornpos);
curveVertex(positions.chin[12][0], hornpos + (nosl*horn_height ));
curveVertex(positions.chin[12][0]*1.5, hornpos + (nosl*horn_height)); //
endShape();
beginShape();
curveVertex(positions.right_eyebrow[1][0]*0.8, eyeposR[1]); //
curveVertex(positions.right_eyebrow[1][0],hornpos*1.1);
curveVertex(positions.chin[12][0], hornpos + (nosl*horn_height));
curveVertex(positions.chin[12][0]*2, hornpos + (nosl*horn_height)); //
endShape();
//Bottom horn ----
beginShape();
curveVertex(positions.right_eyebrow[1][0]*0.6,hornpos*1.5); //
curveVertex(positions.right_eyebrow[1][0],hornpos*1.1);
curveVertex(positions.right_eyebrow[3][0],hornpos);
curveVertex(positions.right_eyebrow[3][0]*1.4,hornpos*1.4); //
endShape();
//Left
beginShape();
curveVertex(positions.left_eyebrow[1][0]*0.8, eyeposL[1]); //
curveVertex(positions.left_eyebrow[1][0],hornpos);
curveVertex(positions.chin[4][0], hornpos + (nosl*horn_height));
curveVertex(positions.chin[4][0]*1.5, hornpos + (nosl*horn_height)); //
endShape();
beginShape();
curveVertex(positions.left_eyebrow[3][0]*0.8 , eyeposL[1]); //
curveVertex(positions.left_eyebrow[3][0],hornpos*1.1);
curveVertex(positions.chin[4][0], hornpos + (nosl*horn_height) );
curveVertex(positions.chin[4][0]*2, hornpos + (nosl*horn_height)); //
endShape();
//Bottom horn ----
beginShape();
curveVertex(positions.left_eyebrow[1][0]*1.4,hornpos*1.4); //
curveVertex(positions.left_eyebrow[1][0],hornpos);
curveVertex(positions.left_eyebrow[3][0],hornpos*1.1);
curveVertex(positions.left_eyebrow[3][0]*0.6,hornpos*1.5); //
endShape();
pop();
//Chin
//Chin
push();
let jaw_stroke = 0.3;
strokeWeight(genstroke);
noFill();
let jawrightx = (positions.chin[12][0] * 1.2)
let jawrighty = (positions.chin[12][1] * 1.1)
let jawleftx = (positions.chin[4][0] * 1.2)
let jawlefty = (positions.chin[4][1] * 1.1)
let jaw_angle = int(map(this.jaw_ang, 0, 100, 1, 2));
beginShape();
curveVertex(jawrightx + 1 * jaw_angle, jawrighty * jaw_angle);
curveVertex(jawrightx, jawrighty);
curveVertex(positions.chin[9][0], positions.chin[8][1]);
curveVertex(positions.chin[7][0], positions.chin[8][1]);
curveVertex(jawleftx, jawlefty);
curveVertex(jawleftx - 1* jaw_angle, jawlefty * jaw_angle);
endShape();
//Jaw Side Left ----
beginShape();
curveVertex(positions.chin[2][0] - 1, positions.chin[2][1] - 1);
curveVertex(positions.chin[2][0], positions.chin[2][1]);
curveVertex(jawleftx, jawlefty);
curveVertex(jawleftx - 1, jawlefty + 1);
endShape();
//Jaw Side Right ----
beginShape();
curveVertex(positions.chin[14][0] + 1, positions.chin[14][1] - 1);
curveVertex(positions.chin[14][0], positions.chin[14][1]);
curveVertex(jawrightx, jawrighty);
curveVertex(jawrightx + 1, jawrighty + 1);
endShape();
pop();
//Cheeks-------------------------
strokeWeight(genstroke);
noFill();
let cheekinnerY = (positions.chin[14][1] - positions.chin[15][1]) + positions.chin[15][1]
let cheekinnerX = (positions.chin[14][0] - (positions.chin[14][0] - positions.chin[12][0]));
beginShape();
curveVertex(positions.chin[16][0] - 1, positions.chin[16][1] - 1);
curveVertex(positions.chin[16][0] * 0.9, positions.chin[16][1]);
curveVertex(positions.chin[15][0] * 1.1, positions.chin[15][1]);
curveVertex(positions.chin[14][0] * 1.05, positions.chin[14][1]);
curveVertex(cheekinnerX, cheekinnerY);
curveVertex(cheekinnerX - 1, cheekinnerY + 0.5);
endShape();
let cheekinnerLY = (positions.chin[14][1] - positions.chin[1][1]) + positions.chin[1][1]
let cheekinnerLX = (positions.chin[2][0] - (positions.chin[2][0] - positions.chin[4][0]));
beginShape();
curveVertex(positions.chin[0][0] + 1, positions.chin[0][1] - 1);
curveVertex(positions.chin[0][0] * 0.9, positions.chin[0][1]);
curveVertex(positions.chin[1][0] * 1.1, positions.chin[1][1]);
curveVertex(positions.chin[2][0] * 1.05, positions.chin[2][1]);
curveVertex(cheekinnerLX, cheekinnerLY);
curveVertex(cheekinnerLX + 1, cheekinnerLY + 0.5);
endShape();
//Eyes-----------------------------------------------
push();
let eye_evil2 = map(this.eye_evil,0,100,0,3);
let smalleyeS = 4;
fill(200/eye_evil2,0,0);
strokeWeight(genstroke);
stroke('black');
ellipse(eyeposR[0],eyeposR[1], eyesizeR, eyesizeRV);
ellipse(eyeposL[0],eyeposL[1], eyesizeL, eyesizeLV);
noStroke();
fill(255,33*eye_evil2);
ellipse(eyeposR[0],eyeposR[1], eyesizeR/smalleyeS, eyesizeRV/smalleyeS);
ellipse(eyeposL[0],eyeposL[1], eyesizeL/smalleyeS, eyesizeLV/smalleyeS);
pop();
//mouth ------------------------------
let mouthcurveRy = positions.bottom_lip[0][1] - (positions.bottom_lip[10][1] - positions.bottom_lip[0][1])*3
let mouthcurveLy = positions.bottom_lip[6][1] - (positions.bottom_lip[8][1] - positions.bottom_lip[6][1])*3
let mouthfracLX = (positions.bottom_lip[2][0] + positions.top_lip[4][0]) / 2;
let mouthfracRX = (positions.bottom_lip[4][0] + positions.top_lip[2][0]) / 2;
let mouthfracRX2 = (positions.bottom_lip[6][0] + mouthfracRX) / 2
let mouthfracLX2 = (positions.bottom_lip[0][0] + mouthfracLX) / 2
let mouthheight = (positions.bottom_lip[3][1] - positions.top_lip[3][1])/2;
let mouthcenterheight = positions.bottom_lip[9][1] - ((positions.bottom_lip[9][1] - positions.top_lip[9][1])/2);
push();
noFill();
let check = 6;
translate(0,mouthweight*1/3)
stroke(200,0,0)
strokeWeight(mouthweight)
beginShape();
curveVertex(positions.bottom_lip[0][0] + 0.5, mouthcurveRy);
curveVertex(positions.bottom_lip[0][0], positions.bottom_lip[0][1]);
curveVertex(positions.bottom_lip[6][0], positions.bottom_lip[6][1]);
curveVertex(positions.bottom_lip[6][0] - 0.5, mouthcurveLy);
endShape();
line(mouthfracRX,mouthcenterheight-mouthheight, mouthfracRX, mouthcenterheight+mouthheight);
line(mouthfracRX2,mouthcenterheight-mouthheight, mouthfracRX2, mouthcenterheight+mouthheight);
line(mouthfracLX,mouthcenterheight-mouthheight, mouthfracLX, mouthcenterheight+mouthheight);
line(mouthfracLX2,mouthcenterheight-mouthheight, mouthfracLX2, mouthcenterheight+mouthheight);
pop();
//inner -----
push();
strokeWeight(mouthweight);
stroke(0);
beginShape();
curveVertex(positions.bottom_lip[0][0]+0.5, mouthcurveRy);
curveVertex(positions.bottom_lip[0][0],positions.bottom_lip[0][1]);
curveVertex(positions.bottom_lip[6][0], positions.bottom_lip[6][1]);
curveVertex(positions.bottom_lip[6][0]-0.5, mouthcurveLy);
endShape();
line(mouthfracRX,mouthcenterheight-mouthheight, mouthfracRX, mouthcenterheight+mouthheight);
line(mouthfracRX2,mouthcenterheight-mouthheight, mouthfracRX2, mouthcenterheight+mouthheight);
line(mouthfracLX,mouthcenterheight-mouthheight, mouthfracLX, mouthcenterheight+mouthheight);
line(mouthfracLX2,mouthcenterheight-mouthheight, mouthfracLX2, mouthcenterheight+mouthheight);
pop();
//Nose -------------
push();
fill(colour);
//fill(strokeCol);
strokeWeight(genstroke);
let nose_width = map(jaw_width, 3, 5, 0.5, 1);
let nose_top = positions.nose_bridge[1][1] - positions.nose_bridge[0][1];
triangle(positions.nose_bridge[0][0], positions.nose_bridge[1][1] - nose_top / 2, positions.nose_tip[0][0], positions.nose_tip[0][1], positions.nose_tip[4][0], positions.nose_tip[4][1])
pop();
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.colour_picker = int(map(settings[0], 0, 100, 0, 100));
this.horn_size = map(settings[1], 0, 100, 0, 100);
this.jaw_ang = map(settings[2], 0, 100, 0, 100);
this.eye_evil = map(settings[3], 0, 100, 0, 100);
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(0);
settings[0] = map(this.colour_picker, 0, 100, 0, 100);
settings[1] = map(this.horn_size, 0,100, 0, 100);
settings[2] = map(this.jaw_ang, 0, 100, 0, 100);
settings[3] = map(this.eye_evil, 0, 100, 0, 100);
return settings;
}
}
{
"000001": [
0,
0,
100,
0
],
"000002": [
0,
33,
100,
100
],
"000005": [
70,
53,
100,
54
],
"000006": [
78,
41,
100,
79
],
"000007": [
68,
77,
10,
79
],
"000009": [
0,
22,
100,
50
],
"000010": [
0,
0,
100,
0
],
"000013": [
0,
85,
0,
79
],
"000014": [
76,
19,
100,
32
],
"000015": [
0,
93,
0,
78
],
"000016": [
0,
77,
0,
30
],
"000018": [
0,
22,
100,
54
],
"000020": [
0,
62,
0,
22
],
"000023": [
0,
79,
0,
18
],
"000025": [
0,
67,
0,
100
],
"000028": [
56.99999999999999,
22,
100,
73
],
"000029": [
0,
0,
100,
16
],
"000030": [
0,
56.00000000000001,
0,
37
],
"000031": [
0,
37,
100,
18
],
"000032": [
0,
57.99999999999999,
0,
87
],
"000035": [
0,
57.99999999999999,
100,
65
],
"000037": [
77,
100,
0,
66
],
"000038": [
0,
76,
0,
33
],
"000040": [
54,
0,
100,
0
],
"000041": [
54,
73,
0,
24
],
"000042": [
0,
34,
100,
48
],
"000043": [
0,
13,
100,
30
],
"000044": [
94,
13,
100,
30
],
"000045": [
0,
10,
100,
7.000000000000001
],
"000047": [
0,
10,
100,
44
],
"000048": [
0,
69,
0,
71
],
"000050": [
53,
84,
0,
39
],
"000051": [
53,
69,
0,
100
],
"000052": [
0,
87,
0,
39
],
"000054": [
0,
87,
1,
54
],
"000055": [
56.00000000000001,
87,
0,
69
],
"000056": [
0,
56.99999999999999,
0,
84
],
"000058": [
0,
8,
100,
70
],
"000060": [
83,
68,
0,
62
],
"000064": [
0,
67,
0,
62
],
"000065": [
56.99999999999999,
78,
0,
91
],
"000068": [
0,
89,
0,
100
],
"000069": [
0,
75,
0,
100
],
"000071": [
0,
28.000000000000004,
100,
100
],
"000073": [
0,
0,
100,
0
],
"000076": [
0,
100,
0,
0
],
"000077": [
0,
0,
100,
0
],
"000078": [
0,
3,
100,
62
],
"000079": [
0,
81,
0,
62
],
"000080": [
0,
100,
0,
39
],
"000081": [
60,
90,
0,
60
],
"000083": [
0,
12,
100,
60
],
"000085": [
0,
0,
100,
0
],
"000086": [
0,
0,
100,
0
],
"000088": [
64,
0,
100,
12
],
"000091": [
0,
89,
0,
26
],
"000092": [
0,
12,
100,
14.000000000000002
],
"000096": [
0,
0,
100,
26
],
"000097": [
0,
0,
100,
0
],
"000099": [
0,
7.000000000000001,
100,
28.999999999999996
],
"000100": [
0,
31,
100,
37
],
"000103": [
0,
0,
100,
18
],
"000104": [
0,
71,
0,
32
],
"000106": [
0,
10,
100,
14.000000000000002
],
"000108": [
0,
10,
100,
14.000000000000002
],
"000109": [
0,
68,
0,
46
],
"000110": [
0,
4,
100,
16
],
"000111": [
75,
15,
100,
22
],
"000114": [
0,
75,
0,
52
],
"000115": [
0,
100,
0,
76
],
"000116": [
0,
84,
0,
25
],
"000117": [
80,
19,
100,
16
],
"000118": [
64,
0,
100,
0
],
"000121": [
64,
6,
100,
7.000000000000001
],
"000122": [
0,
13,
100,
100
],
"000125": [
0,
81,
0,
64
],
"000126": [
0,
0,
100,
0
],
"000129": [
0,
82,
0,
83
],
"000131": [
66,
10,
100,
31
],
"000132": [
79,
10,
100,
31
],
"000133": [
0,
4,
100,
14.000000000000002
],
"000134": [
84,
77,
0,
62
],
"000135": [
67,
63,
0,
35
],
"000137": [
0,
70,
0,
35
],
"000140": [
0,
0,
100,
13
],
"000142": [
0,
6,
100,
48
],
"000143": [
0,
81,
0,
79
],
"000145": [
0,
4,
100,
18
],
"000146": [
0,
0,
100,
0
],
"000147": [
0,
0,
100,
0
],
"000148": [
0,
9,
100,
38
],
"000150": [
0,
67,
0,
77
],
"000151": [
66,
8,
100,
22
],
"000152": [
0,
68,
0,
11
],
"000153": [
0,
85,
0,
25
],
"000155": [
0,
0,
100,
25
],
"000156": [
0,
8,
100,
41
],
"000157": [
0,
0,
100,
9
],
"000160": [
0,
83,
0,
60
],
"000161": [
0,
10,
100,
12
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
//var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 7;
// other variables can be in here too
// here's some examples for colors used
// const bg_color = [225, 206, 187];
// const fg_color = [151, 102, 52];
// const stroke_color = [95, 52, 8];
let cluster = new Cluster();
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i = 0; i < s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len, sum_y / s_len];
}
// This where you define your own face object
function NgFace() {
// these are state variables for a face
// (your variables should be different!)
this.numOfSq = 7;
this.numOfTri = focusedRandom(0, 15);
this.numOfEll = 7;
this.hairColorSelector = 5;
this.faceColorSelector = 5;
this.eyeColorSelector = 5;
this.eye_shift = -1;
this.makeUp = 0;
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
//
this.draw_segment = function (segment, scaleX, scaleY) {
for (let i = 0; i < segment.length; i += 1) {
let px = segment[i][0];
let py = segment[i][1];
push()
translate(px, py);
scale(scaleX, scaleY);
rotate(focusedRandom(10, 350));
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function (positions) {
//Colour initialization
let faceColor = 0;
let faceShad = 0;
let hairColor = 0;
let eyeColor = 0;
let eyeBallColor = 255;
let mouthColor = 255;
//Hair colour range using lerpColor() function
let fromHair = color(0, 0, 0);
let toHair = color(252, 226, 91);
let interHair = lerpColor(fromHair, toHair, this.hairColorSelector);
//Face colour range using lerpColor() function
let fromFace = color(105, 64, 29);
let toFace = color(255, 219, 172);
let interFace = lerpColor(fromFace, toFace, this.faceColorSelector);
//FaceShad colour range using lerpColor() function
let fromFaceShad = color(64, 39, 17);
let toFaceShad = color(227, 195, 154);
let interFaceShad = lerpColor(fromFaceShad, toFaceShad, this.faceColorSelector);
//Eye colour range using lerpColor() function
let fromEye = color(0, 0, 0);
let toEye = color(0, 255, 247);
let interEye = lerpColor(fromEye, toEye, this.eyeColorSelector);
//Shared Variable
let left_eye_pos = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
let top_mouth_pos = segment_average(positions.top_lip);
let bottom_mouth_pos = segment_average(positions.bottom_lip);
let avgBrowLine = (positions.left_eyebrow[2][1] + positions.right_eyebrow[2][1]) / 2
const makeupThreshold = 0.475;
noStroke()
//face
let faceback_midpt_x = ((positions.chin[16][0] - positions.chin[0][0]) / 2) + positions.chin[0][0];
let faceback_midpt_y = ((positions.chin[8][1] - avgBrowLine) / 2) + avgBrowLine;
let faceback_height = dist(positions.chin[8][0], avgBrowLine, positions.chin[8][0], positions.chin[8][1]);
let faceback_y_scale = map(faceback_height, 0.01, 3.78, 0.01, 1.85);
let faceback_width = dist(positions.chin[0][0], positions.chin[0][1], positions.chin[16][0], positions.chin[16][1]);
let faceback_x_scale = map(faceback_width, 0.01, 3.31, 0.1, 1.25);
//Cheeks to show face direction
push()
translate(faceback_midpt_x + 0, faceback_midpt_y - 0.55);
scale(faceback_x_scale, faceback_y_scale);
fill(interFaceShad);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop()
let faceMidPtX = ((right_eye_pos[0] - left_eye_pos[0]) / 2) + left_eye_pos[0];
let faceMidPtY = ((positions.chin[8][1] - avgBrowLine) / 2) + avgBrowLine;
let face_height = dist(positions.chin[8][0], avgBrowLine, positions.chin[8][0], positions.chin[8][1]);
let face_y_scale = map(face_height, 0.01, 3.5, 0.01, 1.3);
let face_width = dist(left_eye_pos[0], left_eye_pos[1], right_eye_pos[0], right_eye_pos[1]);
let face_x_scale = map(face_width, 0.01, 1.4, 0.1, 0.8);
push()
fill(interFace)
translate(faceMidPtX, faceMidPtY + 0.1);
scale(face_x_scale, face_y_scale);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);//Lower face
translate(0, -1);
scale(1.2, 1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);//Upper face
pop()
//eyeball
//Eye shadow
if (this.makeUp > makeupThreshold) {
fill(50, 50);
//Left Eye
push();
translate(left_eye_pos[0], left_eye_pos[1] - 0.1);
scale(0.2, 0.1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
//Right Eye
push();
translate(right_eye_pos[0], right_eye_pos[1] - 0.1);
scale(0.2, 0.1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
}
//Eyes
fill(255);
push();
translate(left_eye_pos[0], left_eye_pos[1]);
scale(0.2, 0.1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
push();
translate(right_eye_pos[0], right_eye_pos[1]);
scale(0.2, 0.1);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
//eyebrow
fill(interHair);
//Left Eyebrow
for (let j = 0; j < positions.left_eyebrow.length - 1; j++) {
let v1 = createVector(positions.left_eyebrow[j][0], positions.left_eyebrow[j][1]);
let v2 = createVector(positions.left_eyebrow[j + 1][0], positions.left_eyebrow[j + 1][1]);
let angleBetweenL = v1.angleBetween(v2);
push();
translate(positions.left_eyebrow[j][0], positions.left_eyebrow[j][1]);
rotate(-angleBetweenL);
scale(0.15, 0.05);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
}
//Right Eyebrow
for (let k = 0; k < positions.right_eyebrow.length - 1; k++) {
let v3 = createVector(positions.right_eyebrow[k][0], positions.right_eyebrow[k][1]);
let v4 = createVector(positions.right_eyebrow[k + 1][0], positions.right_eyebrow[k + 1][1]);
let angleBetweenR = v3.angleBetween(v4);
push();
translate(positions.right_eyebrow[k][0], positions.right_eyebrow[k][1]);
rotate(angleBetweenR);
scale(0.15, 0.05);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop()
}
// pupils
let curEyeShift = 0.04 * this.eye_shift;
fill(interEye);
//Left pupil
push()
translate(left_eye_pos[0] + curEyeShift, left_eye_pos[1]);
scale(0.07);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
//Right pupil
push();
translate(right_eye_pos[0] + curEyeShift, right_eye_pos[1]);
scale(0.07);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
//mouth
let mouth_midpt_y = ((positions.bottom_lip[9][1] - positions.top_lip[9][1]) / 2) + positions.top_lip[9][1];
let mouth_midpt_x = ((positions.top_lip[6][0] - positions.top_lip[0][0]) / 2) + positions.top_lip[0][0];
let mouth_height = dist(positions.top_lip[9][0], positions.top_lip[9][1], positions.bottom_lip[9][0], positions.bottom_lip[9][1]);
let mouth_y_scale = map(mouth_height, 0.1, 0.35, 0.005, 0.1);
let mouth_width = dist(positions.top_lip[0][0], positions.top_lip[0][1], positions.top_lip[6][0], positions.top_lip[6][1]);
let mouth_x_scale = map(mouth_width, 0.01, 1.5, 0.01, 0.35);
//Turn mouth black when it is "closed"
if (mouth_height <= 0.1) {
mouthColor = 0;
}
//lipstick
if (this.makeUp > makeupThreshold) {
push()
translate(mouth_midpt_x, mouth_midpt_y);
scale(mouth_x_scale + 0.05, mouth_y_scale + 0.05);
fill(235, 64, 52);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop()
}
push()
translate(mouth_midpt_x, mouth_midpt_y);
scale(mouth_x_scale, mouth_y_scale);
fill(mouthColor);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop()
//nose
blendMode(MULTIPLY)
fill(100, 0, 100);
let noseq1 = color(150);
let noseq2 = color(50);
if (positions.nose_bridge[3][0] <= positions.nose_tip[2][0]) {
noseq1 = color(50);
noseq2 = color(150);
}
fill(noseq1);
beginShape();
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]);
vertex(positions.nose_tip[0][0], positions.nose_tip[0][1]);
vertex(positions.nose_tip[2][0], positions.nose_tip[2][1]);
vertex(positions.nose_bridge[3][0], positions.nose_bridge[3][1]);
endShape(CLOSE);
fill(noseq2);
beginShape();
vertex(positions.nose_bridge[0][0], positions.nose_bridge[0][1]);
vertex(positions.nose_bridge[3][0], positions.nose_bridge[3][1]);
vertex(positions.nose_tip[2][0], positions.nose_tip[2][1]);
vertex(positions.nose_tip[4][0], positions.nose_tip[4][1]);
endShape(CLOSE);
//Blush
if (this.makeUp > makeupThreshold) {
push();
fill(255, 233, 232, 20);
translate(left_eye_pos[0], positions.nose_bridge[3][1] + 0.2);
scale(0.3, 0.5);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
push();
fill(255, 233, 232, 15);
translate(right_eye_pos[0], positions.nose_bridge[3][1] + 0.2);
scale(0.3, 0.5);
cluster.draw(this.numOfSq, this.numOfTri, this.numOfEll);
pop();
}
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function (settings) {
this.faceColorSelector = map(settings[0], 0, 100, 0, 1);
this.eye_shift = map(settings[1], 0, 100, -4, 4);
this.eyeColorSelector = map(settings[2], 0, 100, 0, 1);
this.hairColorSelector = map(settings[3], 0, 100, 0, 1);
this.makeUp = map(settings[4], 0, 100, 0, 1);
this.numOfSq = int(map(settings[5], 0, 100, 0, 15));
this.numOfEll = int(map(settings[6], 0, 100, 0, 15));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function () {
let settings = new Array(6)
settings[0] = map(this.faceColorSelector, 0, 1, 0, 100);
settings[1] = map(this.eye_shift, -4, 4, 0, 100);
settings[2] = map(this.eyeColorSelector, 0, 1, 0, 100);
settings[3] = map(this.hairColorSelector, 0, 1, 0, 100);
settings[4] = map(this.makeUp, 0, 1, 0, 100);
settings[5] = map(this.numOfSq, 0, 15, 0, 100);
settings[6] = map(this.numOfEll, 0, 15, 0, 100);
return settings;
}
}
function Cluster() {
this.arrayXSq = [];
this.arrayYSq = [];
this.arraySSq = [];
this.arrayXTri = [];
this.arrayYTri = [];
this.arraySTri = [];
this.arrayXEll = [];
this.arrayYEll = [];
this.arraySEll = [];
for (let i = 0; i < 20; i++) {
this.xPosSq = focusedRandom(-3, 3) * 0.4;
this.yPosSq = focusedRandom(-3, 3) * 0.4;
this.sSizeSq = focusedRandom(4, 7) * 0.3;
this.arrayXSq.push(this.xPosSq);
this.arrayYSq.push(this.yPosSq);
this.arraySSq.push(this.sSizeSq);
this.xPosTri = focusedRandom(-3, 3) * 0.4;
this.yPosTri = focusedRandom(-3, 3) * 0.4;
this.sSizeTri = focusedRandom(4, 7) * 0.2;
this.arrayXTri.push(this.xPosTri);
this.arrayYTri.push(this.yPosTri);
this.arraySTri.push(this.sSizeTri);
this.xPosEll = focusedRandom(-3, 3) * 0.4;
this.yPosEll = focusedRandom(-3, 3) * 0.4;
this.sSizeEll = focusedRandom(4, 7) * 0.3;
this.arrayXEll.push(this.xPosEll);
this.arrayYEll.push(this.yPosEll);
this.arraySEll.push(this.sSizeEll);
}
this.draw = function (testValue1, testValue2, testValue3) {
rectMode(CENTER);
noStroke();
beginShape();
for (let j = 0; j < testValue1; j++) {
let x = this.arrayXSq[j];
let y = this.arrayYSq[j];
if (x < 0 && y < 0) {
x += ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
} else if (x < 0 && y > 0) {
x += ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y > 0) {
x -= ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y < 0) {
x -= ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
}
push();
translate(x, y);
//vertex(x, y);
square(0, 0, this.arraySSq[j]);
pop();
}
endShape(CLOSE);
beginShape();
for (let k = 0; k < testValue2; k++) {
let x = this.arrayXTri[k];
let y = this.arrayYTri[k];
if (x < 0 && y < 0) {
x += ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
} else if (x < 0 && y > 0) {
x += ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y > 0) {
x -= ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y < 0) {
x -= ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
}
push();
translate(x, y);
//vertex(x, y);
cusTriangle(0, 0, this.arraySTri[k]);
pop();
}
endShape(CLOSE);
beginShape();
for (let l = 0; l < testValue3; l++) {
let x = this.arrayXEll[l];
let y = this.arrayYEll[l];
if (x < 0 && y < 0) {
x += ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
} else if (x < 0 && y > 0) {
x += ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y > 0) {
x -= ((5 / 3) * 0.4);
y -= ((5 / 4) * 0.4);
} else if (x > 0 && y < 0) {
x -= ((5 / 3) * 0.4);
y += ((5 / 4) * 0.4);
}
push();
translate(x, y);
//vertex(x, y);
ellipse(0, 0, this.arraySEll[l]);
pop();
}
endShape(CLOSE);
};
}
function cusTriangle(x, y, radius) {
let angle = 360 / 3;
beginShape();
for (let a = 0; a < 360; a += angle) {
let sx = x + cos(a) * radius;
let sy = y + sin(a) * radius;
vertex(sx, sy);
}
endShape(CLOSE);
}
{
"000001": [
98,
77,
0,
82,
100,
0,
100
],
"000002": [
100,
54,
0,
0,
100,
0,
100
],
"000005": [
100,
55.00000000000001,
0,
89,
100,
0,
100
],
"000006": [
72,
55.00000000000001,
0,
76,
100,
0,
100
],
"000007": [
48,
55.00000000000001,
0,
0,
0,
100,
0
],
"000009": [
94,
42,
0,
0,
100,
0,
100
],
"000010": [
94,
63,
60,
65,
100,
0,
100
],
"000013": [
94,
63,
74,
73,
0,
100,
0
],
"000014": [
39,
54,
0,
0,
100,
0,
100
],
"000015": [
94,
54,
30,
45,
0,
100,
0
],
"000016": [
94,
78,
0,
0,
0,
100,
0
],
"000018": [
100,
61,
64,
81,
100,
0,
100
],
"000020": [
95,
61,
0,
0,
0,
100,
0
],
"000023": [
95,
99,
96,
0,
0,
100,
0
],
"000025": [
95,
54,
0,
0,
0,
100,
0
],
"000028": [
57.99999999999999,
54,
0,
37,
100,
0,
100
],
"000029": [
91,
69,
100,
100,
100,
0,
100
],
"000030": [
100,
69,
35,
43,
0,
100,
0
],
"000031": [
93,
69,
93,
74,
100,
0,
100
],
"000032": [
93,
57.99999999999999,
0,
23,
0,
100,
0
],
"000035": [
100,
72,
0,
23,
100,
0,
100
],
"000037": [
44,
72,
0,
0,
0,
100,
0
],
"000038": [
100,
54,
62,
25,
0,
100,
0
],
"000040": [
77,
62,
0,
14.000000000000002,
100,
0,
100
],
"000041": [
85,
62,
0,
14.000000000000002,
0,
100,
0
],
"000042": [
100,
62,
80,
54,
100,
0,
100
],
"000043": [
100,
62,
0,
0,
100,
0,
100
],
"000044": [
42,
62,
0,
0,
100,
0,
100
],
"000045": [
74,
73,
0,
0,
100,
0,
100
],
"000047": [
44,
86,
0,
0,
100,
0,
100
],
"000048": [
100,
71,
0,
0,
0,
100,
0
],
"000050": [
87,
42,
0,
0,
0,
100,
0
],
"000051": [
87,
59,
0,
0,
0,
100,
0
],
"000052": [
92,
59,
78,
30,
0,
100,
0
],
"000054": [
100,
70,
55.00000000000001,
38,
100,
0,
100
],
"000055": [
100,
50,
0,
0,
0,
100,
0
],
"000056": [
100,
50,
0,
0,
0,
100,
0
],
"000058": [
100,
74,
76,
0,
100,
0,
100
],
"000060": [
17,
28.000000000000004,
0,
0,
0,
100,
0
],
"000064": [
79,
52,
41,
0,
0,
100,
0
],
"000065": [
80,
52,
0,
0,
0,
100,
0
],
"000068": [
100,
52,
37,
0,
0,
100,
0
],
"000069": [
100,
36,
0,
0,
0,
100,
0
],
"000071": [
100,
55.00000000000001,
38,
71,
100,
0,
100
],
"000073": [
74,
61,
6,
71,
100,
0,
100
],
"000076": [
90,
44,
0,
0,
0,
100,
0
],
"000077": [
72,
75,
0,
0,
100,
0,
100
],
"000078": [
96,
59,
65,
0,
100,
0,
100
],
"000079": [
96,
62,
0,
13,
0,
100,
0
],
"000080": [
100,
38,
61,
13,
0,
100,
0
],
"000081": [
60,
71,
0,
13,
0,
100,
0
],
"000083": [
100,
71,
33,
12,
100,
0,
100
],
"000085": [
100,
71,
46,
12,
100,
0,
100
],
"000086": [
100,
48,
0,
0,
100,
0,
100
],
"000088": [
97,
76,
20,
0,
100,
0,
100
],
"000091": [
100,
47,
1,
0,
0,
100,
0
],
"000092": [
100,
73,
46,
56.00000000000001,
100,
0,
100
],
"000096": [
84,
52,
0,
0,
100,
0,
100
],
"000097": [
84,
68,
57.99999999999999,
63,
100,
0,
100
],
"000099": [
84,
68,
57.99999999999999,
63,
100,
0,
100
],
"000100": [
100,
85,
3,
28.000000000000004,
100,
0,
100
],
"000103": [
100,
52,
71,
19,
100,
0,
100
],
"000104": [
100,
52,
71,
48,
0,
100,
0
],
"000106": [
100,
59,
0,
22,
100,
0,
100
],
"000108": [
100,
59,
84,
84,
100,
0,
100
],
"000109": [
94,
61,
56.00000000000001,
84,
0,
100,
0
],
"000110": [
94,
70,
45,
25,
100,
0,
100
],
"000111": [
48,
73,
12,
55.00000000000001,
100,
0,
100
],
"000114": [
100,
51,
0,
0,
0,
100,
0
],
"000115": [
100,
50,
53,
56.99999999999999,
0,
100,
0
],
"000116": [
100,
46,
4,
21,
0,
100,
0
],
"000117": [
42,
76,
4,
21,
100,
0,
100
],
"000118": [
73,
57.99999999999999,
4,
21,
100,
0,
100
],
"000121": [
64,
73,
4,
21,
100,
0,
100
],
"000122": [
100,
73,
36,
88,
100,
0,
100
],
"000125": [
100,
48,
57.99999999999999,
5,
0,
100,
0
],
"000126": [
81,
51,
92,
91,
100,
0,
100
],
"000129": [
100,
51,
25,
0,
0,
100,
0
],
"000131": [
67,
66,
0,
0,
100,
0,
100
],
"000132": [
50,
66,
0,
0,
100,
0,
100
],
"000133": [
100,
66,
100,
93,
100,
0,
100
],
"000134": [
8,
14.000000000000002,
0,
0,
0,
100,
0
],
"000135": [
37,
71,
0,
0,
0,
100,
0
],
"000137": [
100,
71,
56.00000000000001,
0,
0,
100,
0
],
"000140": [
97,
64,
94,
93,
100,
0,
100
],
"000142": [
84,
67,
0,
0,
100,
0,
100
],
"000143": [
98,
45,
56.99999999999999,
31,
0,
100,
0
],
"000145": [
89,
82,
11,
10,
100,
0,
100
],
"000146": [
60,
82,
11,
10,
100,
0,
100
],
"000147": [
100,
86,
85,
80,
100,
0,
100
],
"000148": [
100,
86,
77,
18,
100,
0,
100
],
"000150": [
100,
39,
63,
18,
0,
100,
0
],
"000151": [
80,
67,
0,
18,
100,
0,
100
],
"000152": [
80,
67,
53,
22,
0,
100,
0
],
"000153": [
80,
35,
0,
0,
0,
100,
0
],
"000155": [
84,
66,
0,
0,
100,
0,
100
],
"000156": [
100,
66,
62,
86,
100,
0,
100
],
"000157": [
100,
68,
87,
94,
100,
0,
100
],
"000160": [
54,
54,
0,
0,
0,
100,
0
],
"000161": [
100,
77,
86,
0,
100,
0,
100
]
}
/*
* FaceMap class - holds all informaiton about one mapped
* face and is able to draw itself.
*/
// remove this or set to false to enable full program (load will be slower)
// var DEBUG_MODE = true;
// this can be used to set the number of sliders to show
// var NUM_SLIDERS = 6;
// example of a global function
// given a segment, this returns the average point [x, y]
function segment_average(segment) {
let sum_x = 0;
let sum_y = 0;
let s_len = segment.length;
for (let i=0; i<s_len; i++) {
sum_x = sum_x + segment[i][0];
sum_y = sum_y + segment[i][1];
}
return [sum_x / s_len , sum_y / s_len ];
}
// This where you define your own face object
function NuescaFace() {
const female_col = color(189,125,106);
const male_col = color(80, 119, 122);
const light_col = color(247, 240, 244);
const med_col = color(221,148,192);
const dark_col = color(13, 32, 33);
const eye_light = color(153, 201, 196);
const eye_med = color(237, 185, 126);
const eye_dark = color(54, 29, 1);
// these are state variables for a face
this.nose_value = 1; // range is 0.8 to 1.5
this.lash_brow_value = 1; //range is 0 to 1
this.eye_size = 1; //range is 0.8 to 1
this.ear_color = 1; // range is 0 to 1
this.skin_color =1; //range is 0 to 2
this.eye_color =1; //range is 0 to 2
// example of a function *inside* the face object.
// this draws a segment, and do_loop will connect the ends if true
this.draw_segment = function(segment, do_loop) {
for(let i=0; i<segment.length; i++) {
let px = segment[i][0];
let py = segment[i][1];
ellipse(px, py, 0.1);
if(i < segment.length - 1) {
let nx = segment[i+1][0];
let ny = segment[i+1][1];
line(px, py, nx, ny);
}
else if(do_loop) {
let nx = segment[0][0];
let ny = segment[0][1];
line(px, py, nx, ny);
}
}
};
/*
* Draw the face with position lists that include:
* chin, right_eye, left_eye, right_eyebrow, left_eyebrow
* bottom_lip, top_lip, nose_tip, nose_bridge,
*/
this.draw = function(positions) {
//ears
if (this.ear_color == 0){
fill(female_col);
}
else{
fill(male_col);
}
strokeWeight(0.05);
triangle(-1.6, -1.6, -2.3, -3.2, -0.28, -2.2);
triangle(1.6, -1.6, 2.3, -3.2, 0.28, -2.2);
//inner ear
if (this.skin_color == 0){
fill(light_col);
}
else if (this.skin_color == 1){
fill(med_col);
}
else{
fill(dark_col);
}
triangle(-1.4, -1.7, -1.9, -2.8, -0.6, -2.1);
triangle(1.4, -1.7, 1.9, -2.8, 0.6, -2.1);
stroke(0);
strokeWeight(0.05);
if(this.lash_brow_value == 0){
//brows
let left_brow_pos = positions.left_eyebrow[0];
let left_brow_pos2 = positions.left_eyebrow[4];
let right_brow_pos = positions.right_eyebrow[0];
let right_brow_pos2 = positions.right_eyebrow[4];
stroke(0);
strokeWeight(0.2);
line(left_brow_pos[0], left_brow_pos[1] + 0.1, left_brow_pos2[0], left_brow_pos2[1] + 0.1);
line(right_brow_pos[0], right_brow_pos[1] + 0.1, right_brow_pos2[0], right_brow_pos2[1] + 0.1);
}
//eyes
let left_eye_pos = segment_average(positions.left_eye);
let left_eye_pos2 = segment_average(positions.left_eye);
let right_eye_pos = segment_average(positions.right_eye);
let right_eye_pos2 = segment_average(positions.right_eye);
//eyelashes
stroke(0);
if(this.lash_brow_value == 0){
strokeWeight(0);
}
else if(this.lash_brow_value == 1){
strokeWeight(0.1);
}
//left
line(left_eye_pos[0]- 0.3, left_eye_pos[1] + 0.3, left_eye_pos2[0] -0.5, left_eye_pos2[1]- 0.3);
line(left_eye_pos[0], left_eye_pos[1] + 0.2, left_eye_pos2[0], left_eye_pos2[1]- 0.4);
line(left_eye_pos[0]+ 0.3, left_eye_pos[1] + 0.3, left_eye_pos2[0] +0.5, left_eye_pos2[1]- 0.3);
//right
line(right_eye_pos[0]- 0.3, right_eye_pos[1] + 0.3, right_eye_pos2[0] -0.5, right_eye_pos2[1]- 0.3);
line(right_eye_pos[0], right_eye_pos[1] + 0.2, right_eye_pos2[0], right_eye_pos2[1]- 0.4);
line(right_eye_pos[0]+ 0.3, right_eye_pos[1] + 0.3, right_eye_pos2[0] +0.5, right_eye_pos2[1]- 0.3);
//eye_shape
fill(255);
strokeWeight(0.05);
ellipse(left_eye_pos[0], left_eye_pos[1]+0.3, 1, this.eye_size);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.3, 1, this.eye_size);
//eyeColour
noStroke();
if (this.eye_color == 0){
fill(eye_light);
}
else if (this.eye_color == 1){
fill(eye_med);
}
else{
fill(eye_dark);
}
ellipse(left_eye_pos[0], left_eye_pos[1]+0.3, 0.5, this.eye_size);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.3, 0.5, this.eye_size);
//pupil
fill(0);
ellipse(left_eye_pos[0], left_eye_pos[1]+0.3, 0.2, this.eye_size - 0.2);
ellipse(right_eye_pos[0], right_eye_pos[1]+0.3, 0.2, this.eye_size - 0.2);
// nose setup
let nose_center = positions.nose_tip[2];
//mouth setup
let inner_left_lip = positions.top_lip[2];
let outer_left_lip = positions.top_lip[0];
let inner_right_lip = positions.top_lip[4];
let outer_right_lip = positions.top_lip[7];
let right_bottom_lip = positions.bottom_lip[2];
let center_bottom_lip = positions.bottom_lip[4];
let left_bottom_lip = positions.bottom_lip[7];
//mouth draw
fill(0);
stroke(0);
beginShape();
vertex(outer_left_lip[0], outer_left_lip[1]);
vertex(inner_left_lip[0] - 0.1, inner_left_lip[1] + 0.2);
vertex(nose_center[0], nose_center[1] + 0.4);
vertex(nose_center[0], nose_center[1] + 0.1);
vertex(nose_center[0], nose_center[1] + 0.4);
vertex(inner_right_lip[0] + 0.1, inner_right_lip[1] +0.2);
vertex(outer_right_lip[0] - 0.1, outer_right_lip[1]);
vertex(right_bottom_lip[0], right_bottom_lip[1]);
vertex(center_bottom_lip[0], center_bottom_lip[1]);
vertex(left_bottom_lip[0], left_bottom_lip[1]);
endShape(CLOSE);
//teeth
fill(255);
noStroke();
ellipse(inner_left_lip[0], inner_left_lip[1] + 0.32, 0.1, 0.34);
ellipse(inner_right_lip[0], inner_right_lip[1] + 0.32, 0.1, 0.34);
//nose draw
stroke(0);
strokeWeight(0.05);
if (this.skin_color == 0){
fill(light_col);
}
else if (this.skin_color == 1){
fill(med_col);
}
else{
fill(dark_col);
}
ellipse(nose_center[0], nose_center[1], 0.5 * this.nose_value, 0.25 * this.nose_value);
//whiskers
noFill();
strokeWeight(0.04);
line(left_eye_pos[0] - 1.8, left_eye_pos[1] + 1, left_eye_pos2[0], nose_center[1] + 0.04);
line(left_eye_pos[0] - 1.8, left_eye_pos[1] + 1.4, left_eye_pos2[0], nose_center[1] + 0.04);
line(right_eye_pos[0] + 1.8, left_eye_pos[1] + 1, right_eye_pos2[0], nose_center[1] + 0.04);
line(right_eye_pos[0] + 1.8, left_eye_pos[1] + 1.4, right_eye_pos2[0], nose_center[1] + 0.04);
}
/* set internal properties based on list numbers 0-100 */
this.setProperties = function(settings) {
this.nose_value = map(settings[0], 0, 100, 1, 1.5);
this.lash_brow_value=int(map(settings[1], 0, 100, 0, 1));
this.eye_size = map(settings[2], 0, 100, 0.6, 1);
this.ear_color=int(map(settings[3], 0, 100, 0, 1));
this.skin_color=int(map(settings[4], 0, 100, 0, 2));
this.eye_color=int(map(settings[5], 0, 100, 0, 2));
}
/* get internal properties as list of numbers 0-100 */
this.getProperties = function() {
let settings = new Array(6);
settings[0] = map(this.nose_value, 1, 1.5, 0, 100);
settings[1] = int(map(this.lash_brow_value, 0, 1, 0, 100));
settings[2] = map(this.eye_size, 0.6, 1, 0, 100);
settings[3] = int(map(this.ear_color, 0, 1, 0, 100));
settings[4] = int(map(this.skin_color, 0, 2, 0, 100));
settings[5] = int(map(this.eye_color, 0, 2, 0, 100));
return settings;
}
}
{
"000001": [
0,
100,
49.000000000000014,
0,
0,
0
],
"000002": [
0,
100,
100,
0,
0,
0
],
"000005": [
0,
100,
45.000000000000014,
0,
0,
0
],
"000006": [
0,
100,
0,
0,
50,
100
],
"000007": [
100,
0,
45.000000000000014,
100,
0,
50
],
"000009": [
0,
100,
45.000000000000014,
0,
0,
50
],
"000010": [
0,
100,
0,
0,
0,
0
],
"000013": [
100,
0,
0,
100,
0,
0
],
"000014": [
0,
100,
0,
0,
50,
100
],
"000015": [
100,
0,
0,
100,
0,
0
],
"000016": [
100,
0,
51.000000000000014,
100,
50,
50
],
"000018": [
0,
100,
0,
0,
0,
0
],
"000020": [
100,
0,
0,
100,
0,
50
],
"000023": [
100,
0,
47.000000000000014,
100,
0,
0
],
"000025": [
100,
0,
0,
100,
50,
50
],
"000028": [
0,
100,
0,
0,
50,
100
],
"000029": [
0,
100,
47.000000000000014,
0,
0,
0
],
"000030": [
100,
0,
100,
100,
50,
50
],
"000031": [
0,
100,
0,
0,
0,
0
],
"000032": [
100,
0,
45.000000000000014,
100,
50,
0
],
"000035": [
0,
100,
45.000000000000014,
0,
0,
50
],
"000037": [
100,
0,
45.000000000000014,
100,
50,
100
],
"000038": [
100,
0,
0,
100,
0,
0
],
"000040": [
0,
100,
46.000000000000014,
0,
0,
50
],
"000041": [
100,
0,
0,
100,
50,
50
],
"000042": [
0,
100,
50.000000000000014,
0,
0,
0
],
"000043": [
0,
100,
100,
0,
50,
50
],
"000044": [
0,
100,
52.000000000000014,
0,
100,
100
],
"000045": [
0,
100,
0,
0,
50,
100
],
"000047": [
0,
100,
0,
0,
50,
100
],
"000048": [
100,
0,
51.000000000000014,
100,
50,
50
],
"000050": [
100,
0,
51.000000000000014,
100,
0,
50
],
"000051": [
100,
0,
51.000000000000014,
100,
0,
50
],
"000052": [
100,
0,
88.99999999999999,
100,
50,
0
],
"000054": [
0,
100,
50.000000000000014,
0,
0,
0
],
"000055": [
100,
0,
50.000000000000014,
100,
0,
50
],
"000056": [
100,
0,
0,
100,
0,
0
],
"000058": [
0,
100,
52.000000000000014,
0,
0,
0
],
"000060": [
100,
0,
0,
100,
100,
100
],
"000064": [
100,
0,
0,
100,
0,
0
],
"000065": [
100,
0,
0,
100,
50,
100
],
"000068": [
100,
0,
47.000000000000014,
100,
0,
50
],
"000069": [
100,
0,
92,
100,
0,
50
],
"000071": [
0,
100,
100,
0,
0,
0
],
"000073": [
0,
100,
100,
0,
50,
50
],
"000076": [
100,
0,
48.000000000000014,
100,
50,
50
],
"000077": [
0,
100,
48.000000000000014,
0,
50,
100
],
"000078": [
0,
100,
48.000000000000014,
0,
50,
50
],
"000079": [
100,
0,
48.000000000000014,
100,
0,
50
],
"000080": [
100,
0,
0,
100,
0,
0
],
"000081": [
100,
0,
49.000000000000014,
100,
50,
50
],
"000083": [
0,
100,
0,
0,
0,
0
],
"000085": [
0,
100,
100,
0,
0,
0
],
"000086": [
0,
100,
53.000000000000014,
0,
0,
50
],
"000088": [
0,
100,
54.000000000000014,
0,
50,
50
],
"000091": [
100,
0,
0,
100,
0,
0
],
"000092": [
0,
100,
0,
0,
0,
0
],
"000096": [
0,
100,
79.00000000000001,
0,
50,
100
],
"000097": [
0,
100,
66,
0,
0,
0
],
"000099": [
0,
100,
0,
0,
0,
0
],
"000100": [
0,
100,
49.000000000000014,
0,
0,
50
],
"000103": [
0,
100,
89.99999999999999,
0,
0,
50
],
"000104": [
100,
0,
0,
100,
0,
0
],
"000106": [
0,
100,
0,
0,
0,
50
],
"000108": [
0,
100,
52.000000000000014,
0,
0,
0
],
"000109": [
100,
0,
52.000000000000014,
100,
50,
0
],
"000110": [
0,
100,
52.000000000000014,
0,
0,
0
],
"000111": [
0,
100,
0,
0,
100,
100
],
"000114": [
100,
0,
48.000000000000014,
100,
0,
50
],
"000115": [
100,
0,
0,
100,
0,
0
],
"000116": [
100,
0,
0,
100,
0,
50
],
"000117": [
0,
100,
84.99999999999999,
0,
100,
100
],
"000118": [
0,
100,
51.000000000000014,
0,
50,
50
],
"000121": [
0,
100,
51.000000000000014,
0,
0,
50
],
"000122": [
0,
100,
51.000000000000014,
0,
0,
0
],
"000125": [
100,
0,
0,
100,
0,
0
],
"000126": [
0,
100,
53.000000000000014,
0,
0,
0
],
"000129": [
100,
0,
0,
100,
0,
0
],
"000131": [
0,
100,
51.000000000000014,
0,
0,
50
],
"000132": [
0,
100,
0,
0,
50,
100
],
"000133": [
0,
100,
52.000000000000014,
0,
0,
0
],
"000134": [
100,
0,
52.000000000000014,
100,
100,
100
],
"000135": [
100,
0,
52.000000000000014,
100,
50,
100
],
"000137": [
100,
0,
0,
100,
0,
0
],
"000140": [
0,
100,
100,
0,
0,
0
],
"000142": [
0,
100,
0,
0,
0,
0
],
"000143": [
100,
0,
53.000000000000014,
100,
0,
0
],
"000145": [
0,
100,
0,
0,
50,
50
],
"000146": [
0,
100,
50.000000000000014,
0,
50,
50
],
"000147": [
0,
100,
50.000000000000014,
0,
0,
0
],
"000148": [
0,
100,
0,
0,
0,
0
],
"000150": [
100,
0,
45.000000000000014,
100,
0,
0
],
"000151": [
0,
100,
0,
0,
50,
100
],
"000152": [
100,
0,
0,
100,
0,
0
],
"000153": [
100,
0,
49.000000000000014,
100,
0,
50
],
"000155": [
0,
100,
45.000000000000014,
0,
50,
100
],
"000156": [
0,
100,
0,
0,
0,
0
],
"000157": [
0,
100,
0,
0,
0,
0
],
"000160": [
100,
0,
48.000000000000014,
100,
0,
50
],
"000161": [
0,
100,
0,
0,
0,
0
]
}
This file has been truncated, but you can view the full file.
/*! p5.js v1.1.9 July 22, 2020 */
(function(f) {
if (typeof exports === 'object' && typeof module !== 'undefined') {
module.exports = f();
} else if (typeof define === 'function' && define.amd) {
define([], f);
} else {
var g;
if (typeof window !== 'undefined') {
g = window;
} else if (typeof global !== 'undefined') {
g = global;
} else if (typeof self !== 'undefined') {
g = self;
} else {
g = this;
}
g.p5 = f();
}
})(function() {
var define, module, exports;
return (function() {
function r(e, n, t) {
function o(i, f) {
if (!n[i]) {
if (!e[i]) {
var c = 'function' == typeof require && require;
if (!f && c) return c(i, !0);
if (u) return u(i, !0);
var a = new Error("Cannot find module '" + i + "'");
throw ((a.code = 'MODULE_NOT_FOUND'), a);
}
var p = (n[i] = { exports: {} });
e[i][0].call(
p.exports,
function(r) {
var n = e[i][1][r];
return o(n || r);
},
p,
p.exports,
r,
e,
n,
t
);
}
return n[i].exports;
}
for (var u = 'function' == typeof require && require, i = 0; i < t.length; i++)
o(t[i]);
return o;
}
return r;
})()(
{
1: [
function(_dereq_, module, exports) {
module.exports = {
p5: {
alpha: {
name: 'alpha',
params: [
{
name: 'color',
description:
'<p><a href="#/p5.Color">p5.Color</a> object, color components,\n or CSS color</p>\n',
type: 'p5.Color|Number[]|String'
}
],
class: 'p5',
module: 'Color'
},
blue: {
name: 'blue',
params: [
{
name: 'color',
description:
'<p><a href="#/p5.Color">p5.Color</a> object, color components,\n or CSS color</p>\n',
type: 'p5.Color|Number[]|String'
}
],
class: 'p5',
module: 'Color'
},
brightness: {
name: 'brightness',
params: [
{
name: 'color',
description:
'<p><a href="#/p5.Color">p5.Color</a> object, color components,\n or CSS color</p>\n',
type: 'p5.Color|Number[]|String'
}
],
class: 'p5',
module: 'Color'
},
color: {
name: 'color',
class: 'p5',
module: 'Color',
overloads: [
{
params: [
{
name: 'gray',
description:
'<p>number specifying value between white and black.</p>\n',
type: 'Number'
},
{
name: 'alpha',
description:
'<p>alpha value relative to current color range\n (default is 0-255)</p>\n',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'v1',
description:
'<p>red or hue value relative to\n the current color range</p>\n',
type: 'Number'
},
{
name: 'v2',
description:
'<p>green or saturation value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'v3',
description:
'<p>blue or brightness value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'alpha',
description: '',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'value',
description: '<p>a color string</p>\n',
type: 'String'
}
]
},
{
params: [
{
name: 'values',
description:
'<p>an array containing the red,green,blue &\n and alpha components of the color</p>\n',
type: 'Number[]'
}
]
},
{
params: [
{
name: 'color',
description: '',
type: 'p5.Color'
}
]
}
]
},
green: {
name: 'green',
params: [
{
name: 'color',
description:
'<p><a href="#/p5.Color">p5.Color</a> object, color components,\n or CSS color</p>\n',
type: 'p5.Color|Number[]|String'
}
],
class: 'p5',
module: 'Color'
},
hue: {
name: 'hue',
params: [
{
name: 'color',
description:
'<p><a href="#/p5.Color">p5.Color</a> object, color components,\n or CSS color</p>\n',
type: 'p5.Color|Number[]|String'
}
],
class: 'p5',
module: 'Color'
},
lerpColor: {
name: 'lerpColor',
params: [
{
name: 'c1',
description: '<p>interpolate from this color</p>\n',
type: 'p5.Color'
},
{
name: 'c2',
description: '<p>interpolate to this color</p>\n',
type: 'p5.Color'
},
{
name: 'amt',
description: '<p>number between 0 and 1</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Color'
},
lightness: {
name: 'lightness',
params: [
{
name: 'color',
description:
'<p><a href="#/p5.Color">p5.Color</a> object, color components,\n or CSS color</p>\n',
type: 'p5.Color|Number[]|String'
}
],
class: 'p5',
module: 'Color'
},
red: {
name: 'red',
params: [
{
name: 'color',
description:
'<p><a href="#/p5.Color">p5.Color</a> object, color components,\n or CSS color</p>\n',
type: 'p5.Color|Number[]|String'
}
],
class: 'p5',
module: 'Color'
},
saturation: {
name: 'saturation',
params: [
{
name: 'color',
description:
'<p><a href="#/p5.Color">p5.Color</a> object, color components,\n or CSS color</p>\n',
type: 'p5.Color|Number[]|String'
}
],
class: 'p5',
module: 'Color'
},
background: {
name: 'background',
class: 'p5',
module: 'Color',
overloads: [
{
params: [
{
name: 'color',
description:
'<p>any value created by the <a href="#/p5/color">color()</a> function</p>\n',
type: 'p5.Color'
}
],
chainable: 1
},
{
params: [
{
name: 'colorstring',
description:
'<p>color string, possible formats include: integer\n rgb() or rgba(), percentage rgb() or rgba(),\n 3-digit hex, 6-digit hex</p>\n',
type: 'String'
},
{
name: 'a',
description:
'<p>opacity of the background relative to current\n color range (default is 0-255)</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'gray',
description: '<p>specifies a value between white and black</p>\n',
type: 'Number'
},
{
name: 'a',
description: '',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'v1',
description:
'<p>red or hue value (depending on the current color\n mode)</p>\n',
type: 'Number'
},
{
name: 'v2',
description:
'<p>green or saturation value (depending on the current\n color mode)</p>\n',
type: 'Number'
},
{
name: 'v3',
description:
'<p>blue or brightness value (depending on the current\n color mode)</p>\n',
type: 'Number'
},
{
name: 'a',
description: '',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'values',
description:
'<p>an array containing the red, green, blue\n and alpha components of the color</p>\n',
type: 'Number[]'
}
],
chainable: 1
},
{
params: [
{
name: 'image',
description:
'<p>image created with <a href="#/p5/loadImage">loadImage()</a> or <a href="#/p5/createImage">createImage()</a>,\n to set as background\n (must be same size as the sketch window)</p>\n',
type: 'p5.Image'
},
{
name: 'a',
description: '',
type: 'Number',
optional: true
}
],
chainable: 1
}
]
},
clear: {
name: 'clear',
class: 'p5',
module: 'Color'
},
colorMode: {
name: 'colorMode',
class: 'p5',
module: 'Color',
overloads: [
{
params: [
{
name: 'mode',
description:
'<p>either RGB, HSB or HSL, corresponding to\n Red/Green/Blue and Hue/Saturation/Brightness\n (or Lightness)</p>\n',
type: 'Constant'
},
{
name: 'max',
description: '<p>range for all values</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'mode',
description: '',
type: 'Constant'
},
{
name: 'max1',
description:
'<p>range for the red or hue depending on the\n current color mode</p>\n',
type: 'Number'
},
{
name: 'max2',
description:
'<p>range for the green or saturation depending\n on the current color mode</p>\n',
type: 'Number'
},
{
name: 'max3',
description:
'<p>range for the blue or brightness/lightness\n depending on the current color mode</p>\n',
type: 'Number'
},
{
name: 'maxA',
description: '<p>range for the alpha</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
}
]
},
fill: {
name: 'fill',
class: 'p5',
module: 'Color',
overloads: [
{
params: [
{
name: 'v1',
description:
'<p>red or hue value relative to\n the current color range</p>\n',
type: 'Number'
},
{
name: 'v2',
description:
'<p>green or saturation value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'v3',
description:
'<p>blue or brightness value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'alpha',
description: '',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'value',
description: '<p>a color string</p>\n',
type: 'String'
}
],
chainable: 1
},
{
params: [
{
name: 'gray',
description: '<p>a gray value</p>\n',
type: 'Number'
},
{
name: 'alpha',
description: '',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'values',
description:
'<p>an array containing the red,green,blue &\n and alpha components of the color</p>\n',
type: 'Number[]'
}
],
chainable: 1
},
{
params: [
{
name: 'color',
description: '<p>the fill color</p>\n',
type: 'p5.Color'
}
],
chainable: 1
}
]
},
noFill: {
name: 'noFill',
class: 'p5',
module: 'Color'
},
noStroke: {
name: 'noStroke',
class: 'p5',
module: 'Color'
},
stroke: {
name: 'stroke',
class: 'p5',
module: 'Color',
overloads: [
{
params: [
{
name: 'v1',
description:
'<p>red or hue value relative to\n the current color range</p>\n',
type: 'Number'
},
{
name: 'v2',
description:
'<p>green or saturation value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'v3',
description:
'<p>blue or brightness value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'alpha',
description: '',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'value',
description: '<p>a color string</p>\n',
type: 'String'
}
],
chainable: 1
},
{
params: [
{
name: 'gray',
description: '<p>a gray value</p>\n',
type: 'Number'
},
{
name: 'alpha',
description: '',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'values',
description:
'<p>an array containing the red,green,blue &\n and alpha components of the color</p>\n',
type: 'Number[]'
}
],
chainable: 1
},
{
params: [
{
name: 'color',
description: '<p>the stroke color</p>\n',
type: 'p5.Color'
}
],
chainable: 1
}
]
},
erase: {
name: 'erase',
params: [
{
name: 'strengthFill',
description:
"<p>A number (0-255) for the strength of erasing for a shape's fill.\n This will default to 255 when no argument is given, which\n is full strength.</p>\n",
type: 'Number',
optional: true
},
{
name: 'strengthStroke',
description:
"<p>A number (0-255) for the strength of erasing for a shape's stroke.\n This will default to 255 when no argument is given, which\n is full strength.</p>\n",
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Color'
},
noErase: {
name: 'noErase',
class: 'p5',
module: 'Color'
},
arc: {
name: 'arc',
params: [
{
name: 'x',
description: "<p>x-coordinate of the arc's ellipse</p>\n",
type: 'Number'
},
{
name: 'y',
description: "<p>y-coordinate of the arc's ellipse</p>\n",
type: 'Number'
},
{
name: 'w',
description: "<p>width of the arc's ellipse by default</p>\n",
type: 'Number'
},
{
name: 'h',
description: "<p>height of the arc's ellipse by default</p>\n",
type: 'Number'
},
{
name: 'start',
description: '<p>angle to start the arc, specified in radians</p>\n',
type: 'Number'
},
{
name: 'stop',
description: '<p>angle to stop the arc, specified in radians</p>\n',
type: 'Number'
},
{
name: 'mode',
description:
'<p>optional parameter to determine the way of drawing\n the arc. either CHORD, PIE or OPEN</p>\n',
type: 'Constant',
optional: true
},
{
name: 'detail',
description:
'<p>optional parameter for WebGL mode only. This is to\n specify the number of vertices that makes up the\n perimeter of the arc. Default value is 25.</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
ellipse: {
name: 'ellipse',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x',
description: '<p>x-coordinate of the center of ellipse.</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate of the center of ellipse.</p>\n',
type: 'Number'
},
{
name: 'w',
description: '<p>width of the ellipse.</p>\n',
type: 'Number'
},
{
name: 'h',
description: '<p>height of the ellipse.</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'x',
description: '',
type: 'Number'
},
{
name: 'y',
description: '',
type: 'Number'
},
{
name: 'w',
description: '',
type: 'Number'
},
{
name: 'h',
description: '',
type: 'Number'
},
{
name: 'detail',
description:
'<p>number of radial sectors to draw (for WebGL mode)</p>\n',
type: 'Integer'
}
]
}
]
},
circle: {
name: 'circle',
params: [
{
name: 'x',
description: '<p>x-coordinate of the centre of the circle.</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate of the centre of the circle.</p>\n',
type: 'Number'
},
{
name: 'd',
description: '<p>diameter of the circle.</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
line: {
name: 'line',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x1',
description: '<p>the x-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'y1',
description: '<p>the y-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '<p>the x-coordinate of the second point</p>\n',
type: 'Number'
},
{
name: 'y2',
description: '<p>the y-coordinate of the second point</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'x1',
description: '',
type: 'Number'
},
{
name: 'y1',
description: '',
type: 'Number'
},
{
name: 'z1',
description: '<p>the z-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '',
type: 'Number'
},
{
name: 'y2',
description: '',
type: 'Number'
},
{
name: 'z2',
description: '<p>the z-coordinate of the second point</p>\n',
type: 'Number'
}
],
chainable: 1
}
]
},
point: {
name: 'point',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x',
description: '<p>the x-coordinate</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>the y-coordinate</p>\n',
type: 'Number'
},
{
name: 'z',
description: '<p>the z-coordinate (for WebGL mode)</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'coordinate_vector',
description: '<p>the coordinate vector</p>\n',
type: 'p5.Vector'
}
],
chainable: 1
}
]
},
quad: {
name: 'quad',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x1',
description: '<p>the x-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'y1',
description: '<p>the y-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '<p>the x-coordinate of the second point</p>\n',
type: 'Number'
},
{
name: 'y2',
description: '<p>the y-coordinate of the second point</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '<p>the x-coordinate of the third point</p>\n',
type: 'Number'
},
{
name: 'y3',
description: '<p>the y-coordinate of the third point</p>\n',
type: 'Number'
},
{
name: 'x4',
description: '<p>the x-coordinate of the fourth point</p>\n',
type: 'Number'
},
{
name: 'y4',
description: '<p>the y-coordinate of the fourth point</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'x1',
description: '',
type: 'Number'
},
{
name: 'y1',
description: '',
type: 'Number'
},
{
name: 'z1',
description: '<p>the z-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '',
type: 'Number'
},
{
name: 'y2',
description: '',
type: 'Number'
},
{
name: 'z2',
description: '<p>the z-coordinate of the second point</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '',
type: 'Number'
},
{
name: 'y3',
description: '',
type: 'Number'
},
{
name: 'z3',
description: '<p>the z-coordinate of the third point</p>\n',
type: 'Number'
},
{
name: 'x4',
description: '',
type: 'Number'
},
{
name: 'y4',
description: '',
type: 'Number'
},
{
name: 'z4',
description: '<p>the z-coordinate of the fourth point</p>\n',
type: 'Number'
}
],
chainable: 1
}
]
},
rect: {
name: 'rect',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x',
description: '<p>x-coordinate of the rectangle.</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate of the rectangle.</p>\n',
type: 'Number'
},
{
name: 'w',
description: '<p>width of the rectangle.</p>\n',
type: 'Number'
},
{
name: 'h',
description: '<p>height of the rectangle.</p>\n',
type: 'Number',
optional: true
},
{
name: 'tl',
description: '<p>optional radius of top-left corner.</p>\n',
type: 'Number',
optional: true
},
{
name: 'tr',
description: '<p>optional radius of top-right corner.</p>\n',
type: 'Number',
optional: true
},
{
name: 'br',
description: '<p>optional radius of bottom-right corner.</p>\n',
type: 'Number',
optional: true
},
{
name: 'bl',
description: '<p>optional radius of bottom-left corner.</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'x',
description: '',
type: 'Number'
},
{
name: 'y',
description: '',
type: 'Number'
},
{
name: 'w',
description: '',
type: 'Number'
},
{
name: 'h',
description: '',
type: 'Number'
},
{
name: 'detailX',
description:
'<p>number of segments in the x-direction (for WebGL mode)</p>\n',
type: 'Integer',
optional: true
},
{
name: 'detailY',
description:
'<p>number of segments in the y-direction (for WebGL mode)</p>\n',
type: 'Integer',
optional: true
}
],
chainable: 1
}
]
},
square: {
name: 'square',
params: [
{
name: 'x',
description: '<p>x-coordinate of the square.</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate of the square.</p>\n',
type: 'Number'
},
{
name: 's',
description: '<p>side size of the square.</p>\n',
type: 'Number'
},
{
name: 'tl',
description: '<p>optional radius of top-left corner.</p>\n',
type: 'Number',
optional: true
},
{
name: 'tr',
description: '<p>optional radius of top-right corner.</p>\n',
type: 'Number',
optional: true
},
{
name: 'br',
description: '<p>optional radius of bottom-right corner.</p>\n',
type: 'Number',
optional: true
},
{
name: 'bl',
description: '<p>optional radius of bottom-left corner.</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
triangle: {
name: 'triangle',
params: [
{
name: 'x1',
description: '<p>x-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'y1',
description: '<p>y-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '<p>x-coordinate of the second point</p>\n',
type: 'Number'
},
{
name: 'y2',
description: '<p>y-coordinate of the second point</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '<p>x-coordinate of the third point</p>\n',
type: 'Number'
},
{
name: 'y3',
description: '<p>y-coordinate of the third point</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
ellipseMode: {
name: 'ellipseMode',
params: [
{
name: 'mode',
description: '<p>either CENTER, RADIUS, CORNER, or CORNERS</p>\n',
type: 'Constant'
}
],
class: 'p5',
module: 'Shape'
},
noSmooth: {
name: 'noSmooth',
class: 'p5',
module: 'Shape'
},
rectMode: {
name: 'rectMode',
params: [
{
name: 'mode',
description: '<p>either CORNER, CORNERS, CENTER, or RADIUS</p>\n',
type: 'Constant'
}
],
class: 'p5',
module: 'Shape'
},
smooth: {
name: 'smooth',
class: 'p5',
module: 'Shape'
},
strokeCap: {
name: 'strokeCap',
params: [
{
name: 'cap',
description: '<p>either ROUND, SQUARE or PROJECT</p>\n',
type: 'Constant'
}
],
class: 'p5',
module: 'Shape'
},
strokeJoin: {
name: 'strokeJoin',
params: [
{
name: 'join',
description: '<p>either MITER, BEVEL, ROUND</p>\n',
type: 'Constant'
}
],
class: 'p5',
module: 'Shape'
},
strokeWeight: {
name: 'strokeWeight',
params: [
{
name: 'weight',
description: '<p>the weight of the stroke (in pixels)</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
bezier: {
name: 'bezier',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x1',
description: '<p>x-coordinate for the first anchor point</p>\n',
type: 'Number'
},
{
name: 'y1',
description: '<p>y-coordinate for the first anchor point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '<p>x-coordinate for the first control point</p>\n',
type: 'Number'
},
{
name: 'y2',
description: '<p>y-coordinate for the first control point</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '<p>x-coordinate for the second control point</p>\n',
type: 'Number'
},
{
name: 'y3',
description: '<p>y-coordinate for the second control point</p>\n',
type: 'Number'
},
{
name: 'x4',
description: '<p>x-coordinate for the second anchor point</p>\n',
type: 'Number'
},
{
name: 'y4',
description: '<p>y-coordinate for the second anchor point</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'x1',
description: '',
type: 'Number'
},
{
name: 'y1',
description: '',
type: 'Number'
},
{
name: 'z1',
description: '<p>z-coordinate for the first anchor point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '',
type: 'Number'
},
{
name: 'y2',
description: '',
type: 'Number'
},
{
name: 'z2',
description: '<p>z-coordinate for the first control point</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '',
type: 'Number'
},
{
name: 'y3',
description: '',
type: 'Number'
},
{
name: 'z3',
description: '<p>z-coordinate for the second control point</p>\n',
type: 'Number'
},
{
name: 'x4',
description: '',
type: 'Number'
},
{
name: 'y4',
description: '',
type: 'Number'
},
{
name: 'z4',
description: '<p>z-coordinate for the second anchor point</p>\n',
type: 'Number'
}
],
chainable: 1
}
]
},
bezierDetail: {
name: 'bezierDetail',
params: [
{
name: 'detail',
description: '<p>resolution of the curves</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
bezierPoint: {
name: 'bezierPoint',
params: [
{
name: 'a',
description: '<p>coordinate of first point on the curve</p>\n',
type: 'Number'
},
{
name: 'b',
description: '<p>coordinate of first control point</p>\n',
type: 'Number'
},
{
name: 'c',
description: '<p>coordinate of second control point</p>\n',
type: 'Number'
},
{
name: 'd',
description: '<p>coordinate of second point on the curve</p>\n',
type: 'Number'
},
{
name: 't',
description: '<p>value between 0 and 1</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
bezierTangent: {
name: 'bezierTangent',
params: [
{
name: 'a',
description: '<p>coordinate of first point on the curve</p>\n',
type: 'Number'
},
{
name: 'b',
description: '<p>coordinate of first control point</p>\n',
type: 'Number'
},
{
name: 'c',
description: '<p>coordinate of second control point</p>\n',
type: 'Number'
},
{
name: 'd',
description: '<p>coordinate of second point on the curve</p>\n',
type: 'Number'
},
{
name: 't',
description: '<p>value between 0 and 1</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
curve: {
name: 'curve',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x1',
description:
'<p>x-coordinate for the beginning control point</p>\n',
type: 'Number'
},
{
name: 'y1',
description:
'<p>y-coordinate for the beginning control point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '<p>x-coordinate for the first point</p>\n',
type: 'Number'
},
{
name: 'y2',
description: '<p>y-coordinate for the first point</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '<p>x-coordinate for the second point</p>\n',
type: 'Number'
},
{
name: 'y3',
description: '<p>y-coordinate for the second point</p>\n',
type: 'Number'
},
{
name: 'x4',
description: '<p>x-coordinate for the ending control point</p>\n',
type: 'Number'
},
{
name: 'y4',
description: '<p>y-coordinate for the ending control point</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'x1',
description: '',
type: 'Number'
},
{
name: 'y1',
description: '',
type: 'Number'
},
{
name: 'z1',
description:
'<p>z-coordinate for the beginning control point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '',
type: 'Number'
},
{
name: 'y2',
description: '',
type: 'Number'
},
{
name: 'z2',
description: '<p>z-coordinate for the first point</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '',
type: 'Number'
},
{
name: 'y3',
description: '',
type: 'Number'
},
{
name: 'z3',
description: '<p>z-coordinate for the second point</p>\n',
type: 'Number'
},
{
name: 'x4',
description: '',
type: 'Number'
},
{
name: 'y4',
description: '',
type: 'Number'
},
{
name: 'z4',
description: '<p>z-coordinate for the ending control point</p>\n',
type: 'Number'
}
],
chainable: 1
}
]
},
curveDetail: {
name: 'curveDetail',
params: [
{
name: 'resolution',
description: '<p>resolution of the curves</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
curveTightness: {
name: 'curveTightness',
params: [
{
name: 'amount',
description:
'<p>amount of deformation from the original vertices</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
curvePoint: {
name: 'curvePoint',
params: [
{
name: 'a',
description: '<p>coordinate of first control point of the curve</p>\n',
type: 'Number'
},
{
name: 'b',
description: '<p>coordinate of first point</p>\n',
type: 'Number'
},
{
name: 'c',
description: '<p>coordinate of second point</p>\n',
type: 'Number'
},
{
name: 'd',
description: '<p>coordinate of second control point</p>\n',
type: 'Number'
},
{
name: 't',
description: '<p>value between 0 and 1</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
curveTangent: {
name: 'curveTangent',
params: [
{
name: 'a',
description: '<p>coordinate of first control point</p>\n',
type: 'Number'
},
{
name: 'b',
description: '<p>coordinate of first point on the curve</p>\n',
type: 'Number'
},
{
name: 'c',
description: '<p>coordinate of second point on the curve</p>\n',
type: 'Number'
},
{
name: 'd',
description: '<p>coordinate of second conrol point</p>\n',
type: 'Number'
},
{
name: 't',
description: '<p>value between 0 and 1</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Shape'
},
beginContour: {
name: 'beginContour',
class: 'p5',
module: 'Shape'
},
beginShape: {
name: 'beginShape',
params: [
{
name: 'kind',
description:
'<p>either POINTS, LINES, TRIANGLES, TRIANGLE_FAN\n TRIANGLE_STRIP, QUADS, QUAD_STRIP or TESS</p>\n',
type: 'Constant',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
bezierVertex: {
name: 'bezierVertex',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x2',
description: '<p>x-coordinate for the first control point</p>\n',
type: 'Number'
},
{
name: 'y2',
description: '<p>y-coordinate for the first control point</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '<p>x-coordinate for the second control point</p>\n',
type: 'Number'
},
{
name: 'y3',
description: '<p>y-coordinate for the second control point</p>\n',
type: 'Number'
},
{
name: 'x4',
description: '<p>x-coordinate for the anchor point</p>\n',
type: 'Number'
},
{
name: 'y4',
description: '<p>y-coordinate for the anchor point</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'x2',
description: '',
type: 'Number'
},
{
name: 'y2',
description: '',
type: 'Number'
},
{
name: 'z2',
description:
'<p>z-coordinate for the first control point (for WebGL mode)</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '',
type: 'Number'
},
{
name: 'y3',
description: '',
type: 'Number'
},
{
name: 'z3',
description:
'<p>z-coordinate for the second control point (for WebGL mode)</p>\n',
type: 'Number'
},
{
name: 'x4',
description: '',
type: 'Number'
},
{
name: 'y4',
description: '',
type: 'Number'
},
{
name: 'z4',
description:
'<p>z-coordinate for the anchor point (for WebGL mode)</p>\n',
type: 'Number'
}
],
chainable: 1
}
]
},
curveVertex: {
name: 'curveVertex',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x',
description: '<p>x-coordinate of the vertex</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate of the vertex</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'x',
description: '',
type: 'Number'
},
{
name: 'y',
description: '',
type: 'Number'
},
{
name: 'z',
description: '<p>z-coordinate of the vertex (for WebGL mode)</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
}
]
},
endContour: {
name: 'endContour',
class: 'p5',
module: 'Shape'
},
endShape: {
name: 'endShape',
params: [
{
name: 'mode',
description: '<p>use CLOSE to close the shape</p>\n',
type: 'Constant',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
quadraticVertex: {
name: 'quadraticVertex',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'cx',
description: '<p>x-coordinate for the control point</p>\n',
type: 'Number'
},
{
name: 'cy',
description: '<p>y-coordinate for the control point</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '<p>x-coordinate for the anchor point</p>\n',
type: 'Number'
},
{
name: 'y3',
description: '<p>y-coordinate for the anchor point</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'cx',
description: '',
type: 'Number'
},
{
name: 'cy',
description: '',
type: 'Number'
},
{
name: 'cz',
description:
'<p>z-coordinate for the control point (for WebGL mode)</p>\n',
type: 'Number'
},
{
name: 'x3',
description: '',
type: 'Number'
},
{
name: 'y3',
description: '',
type: 'Number'
},
{
name: 'z3',
description:
'<p>z-coordinate for the anchor point (for WebGL mode)</p>\n',
type: 'Number'
}
],
chainable: 1
}
]
},
vertex: {
name: 'vertex',
class: 'p5',
module: 'Shape',
overloads: [
{
params: [
{
name: 'x',
description: '<p>x-coordinate of the vertex</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate of the vertex</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'x',
description: '',
type: 'Number'
},
{
name: 'y',
description: '',
type: 'Number'
},
{
name: 'z',
description: '<p>z-coordinate of the vertex</p>\n',
type: 'Number'
},
{
name: 'u',
description: "<p>the vertex's texture u-coordinate</p>\n",
type: 'Number',
optional: true
},
{
name: 'v',
description: "<p>the vertex's texture v-coordinate</p>\n",
type: 'Number',
optional: true
}
],
chainable: 1
}
]
},
P2D: {
name: 'P2D',
class: 'p5',
module: 'Constants'
},
WEBGL: {
name: 'WEBGL',
class: 'p5',
module: 'Constants'
},
ARROW: {
name: 'ARROW',
class: 'p5',
module: 'Constants'
},
CROSS: {
name: 'CROSS',
class: 'p5',
module: 'Constants'
},
HAND: {
name: 'HAND',
class: 'p5',
module: 'Constants'
},
MOVE: {
name: 'MOVE',
class: 'p5',
module: 'Constants'
},
TEXT: {
name: 'TEXT',
class: 'p5',
module: 'Constants'
},
WAIT: {
name: 'WAIT',
class: 'p5',
module: 'Constants'
},
HALF_PI: {
name: 'HALF_PI',
class: 'p5',
module: 'Constants'
},
PI: {
name: 'PI',
class: 'p5',
module: 'Constants'
},
QUARTER_PI: {
name: 'QUARTER_PI',
class: 'p5',
module: 'Constants'
},
TAU: {
name: 'TAU',
class: 'p5',
module: 'Constants'
},
TWO_PI: {
name: 'TWO_PI',
class: 'p5',
module: 'Constants'
},
DEGREES: {
name: 'DEGREES',
class: 'p5',
module: 'Constants'
},
RADIANS: {
name: 'RADIANS',
class: 'p5',
module: 'Constants'
},
CORNER: {
name: 'CORNER',
class: 'p5',
module: 'Constants'
},
CORNERS: {
name: 'CORNERS',
class: 'p5',
module: 'Constants'
},
RADIUS: {
name: 'RADIUS',
class: 'p5',
module: 'Constants'
},
RIGHT: {
name: 'RIGHT',
class: 'p5',
module: 'Constants'
},
LEFT: {
name: 'LEFT',
class: 'p5',
module: 'Constants'
},
CENTER: {
name: 'CENTER',
class: 'p5',
module: 'Constants'
},
TOP: {
name: 'TOP',
class: 'p5',
module: 'Constants'
},
BOTTOM: {
name: 'BOTTOM',
class: 'p5',
module: 'Constants'
},
BASELINE: {
name: 'BASELINE',
class: 'p5',
module: 'Constants'
},
POINTS: {
name: 'POINTS',
class: 'p5',
module: 'Constants'
},
LINES: {
name: 'LINES',
class: 'p5',
module: 'Constants'
},
LINE_STRIP: {
name: 'LINE_STRIP',
class: 'p5',
module: 'Constants'
},
LINE_LOOP: {
name: 'LINE_LOOP',
class: 'p5',
module: 'Constants'
},
TRIANGLES: {
name: 'TRIANGLES',
class: 'p5',
module: 'Constants'
},
TRIANGLE_FAN: {
name: 'TRIANGLE_FAN',
class: 'p5',
module: 'Constants'
},
TRIANGLE_STRIP: {
name: 'TRIANGLE_STRIP',
class: 'p5',
module: 'Constants'
},
QUADS: {
name: 'QUADS',
class: 'p5',
module: 'Constants'
},
QUAD_STRIP: {
name: 'QUAD_STRIP',
class: 'p5',
module: 'Constants'
},
TESS: {
name: 'TESS',
class: 'p5',
module: 'Constants'
},
CLOSE: {
name: 'CLOSE',
class: 'p5',
module: 'Constants'
},
OPEN: {
name: 'OPEN',
class: 'p5',
module: 'Constants'
},
CHORD: {
name: 'CHORD',
class: 'p5',
module: 'Constants'
},
PIE: {
name: 'PIE',
class: 'p5',
module: 'Constants'
},
PROJECT: {
name: 'PROJECT',
class: 'p5',
module: 'Constants'
},
SQUARE: {
name: 'SQUARE',
class: 'p5',
module: 'Constants'
},
ROUND: {
name: 'ROUND',
class: 'p5',
module: 'Constants'
},
BEVEL: {
name: 'BEVEL',
class: 'p5',
module: 'Constants'
},
MITER: {
name: 'MITER',
class: 'p5',
module: 'Constants'
},
RGB: {
name: 'RGB',
class: 'p5',
module: 'Constants'
},
HSB: {
name: 'HSB',
class: 'p5',
module: 'Constants'
},
HSL: {
name: 'HSL',
class: 'p5',
module: 'Constants'
},
AUTO: {
name: 'AUTO',
class: 'p5',
module: 'Constants'
},
ALT: {
name: 'ALT',
class: 'p5',
module: 'Constants'
},
BACKSPACE: {
name: 'BACKSPACE',
class: 'p5',
module: 'Constants'
},
CONTROL: {
name: 'CONTROL',
class: 'p5',
module: 'Constants'
},
DELETE: {
name: 'DELETE',
class: 'p5',
module: 'Constants'
},
DOWN_ARROW: {
name: 'DOWN_ARROW',
class: 'p5',
module: 'Constants'
},
ENTER: {
name: 'ENTER',
class: 'p5',
module: 'Constants'
},
ESCAPE: {
name: 'ESCAPE',
class: 'p5',
module: 'Constants'
},
LEFT_ARROW: {
name: 'LEFT_ARROW',
class: 'p5',
module: 'Constants'
},
OPTION: {
name: 'OPTION',
class: 'p5',
module: 'Constants'
},
RETURN: {
name: 'RETURN',
class: 'p5',
module: 'Constants'
},
RIGHT_ARROW: {
name: 'RIGHT_ARROW',
class: 'p5',
module: 'Constants'
},
SHIFT: {
name: 'SHIFT',
class: 'p5',
module: 'Constants'
},
TAB: {
name: 'TAB',
class: 'p5',
module: 'Constants'
},
UP_ARROW: {
name: 'UP_ARROW',
class: 'p5',
module: 'Constants'
},
BLEND: {
name: 'BLEND',
class: 'p5',
module: 'Constants'
},
REMOVE: {
name: 'REMOVE',
class: 'p5',
module: 'Constants'
},
ADD: {
name: 'ADD',
class: 'p5',
module: 'Constants'
},
DARKEST: {
name: 'DARKEST',
class: 'p5',
module: 'Constants'
},
LIGHTEST: {
name: 'LIGHTEST',
class: 'p5',
module: 'Constants'
},
DIFFERENCE: {
name: 'DIFFERENCE',
class: 'p5',
module: 'Constants'
},
SUBTRACT: {
name: 'SUBTRACT',
class: 'p5',
module: 'Constants'
},
EXCLUSION: {
name: 'EXCLUSION',
class: 'p5',
module: 'Constants'
},
MULTIPLY: {
name: 'MULTIPLY',
class: 'p5',
module: 'Constants'
},
SCREEN: {
name: 'SCREEN',
class: 'p5',
module: 'Constants'
},
REPLACE: {
name: 'REPLACE',
class: 'p5',
module: 'Constants'
},
OVERLAY: {
name: 'OVERLAY',
class: 'p5',
module: 'Constants'
},
HARD_LIGHT: {
name: 'HARD_LIGHT',
class: 'p5',
module: 'Constants'
},
SOFT_LIGHT: {
name: 'SOFT_LIGHT',
class: 'p5',
module: 'Constants'
},
DODGE: {
name: 'DODGE',
class: 'p5',
module: 'Constants'
},
BURN: {
name: 'BURN',
class: 'p5',
module: 'Constants'
},
THRESHOLD: {
name: 'THRESHOLD',
class: 'p5',
module: 'Constants'
},
GRAY: {
name: 'GRAY',
class: 'p5',
module: 'Constants'
},
OPAQUE: {
name: 'OPAQUE',
class: 'p5',
module: 'Constants'
},
INVERT: {
name: 'INVERT',
class: 'p5',
module: 'Constants'
},
POSTERIZE: {
name: 'POSTERIZE',
class: 'p5',
module: 'Constants'
},
DILATE: {
name: 'DILATE',
class: 'p5',
module: 'Constants'
},
ERODE: {
name: 'ERODE',
class: 'p5',
module: 'Constants'
},
BLUR: {
name: 'BLUR',
class: 'p5',
module: 'Constants'
},
NORMAL: {
name: 'NORMAL',
class: 'p5',
module: 'Constants'
},
ITALIC: {
name: 'ITALIC',
class: 'p5',
module: 'Constants'
},
BOLD: {
name: 'BOLD',
class: 'p5',
module: 'Constants'
},
BOLDITALIC: {
name: 'BOLDITALIC',
class: 'p5',
module: 'Constants'
},
LINEAR: {
name: 'LINEAR',
class: 'p5',
module: 'Constants'
},
QUADRATIC: {
name: 'QUADRATIC',
class: 'p5',
module: 'Constants'
},
BEZIER: {
name: 'BEZIER',
class: 'p5',
module: 'Constants'
},
CURVE: {
name: 'CURVE',
class: 'p5',
module: 'Constants'
},
STROKE: {
name: 'STROKE',
class: 'p5',
module: 'Constants'
},
FILL: {
name: 'FILL',
class: 'p5',
module: 'Constants'
},
TEXTURE: {
name: 'TEXTURE',
class: 'p5',
module: 'Constants'
},
IMMEDIATE: {
name: 'IMMEDIATE',
class: 'p5',
module: 'Constants'
},
IMAGE: {
name: 'IMAGE',
class: 'p5',
module: 'Constants'
},
NEAREST: {
name: 'NEAREST',
class: 'p5',
module: 'Constants'
},
REPEAT: {
name: 'REPEAT',
class: 'p5',
module: 'Constants'
},
CLAMP: {
name: 'CLAMP',
class: 'p5',
module: 'Constants'
},
MIRROR: {
name: 'MIRROR',
class: 'p5',
module: 'Constants'
},
LANDSCAPE: {
name: 'LANDSCAPE',
class: 'p5',
module: 'Constants'
},
PORTRAIT: {
name: 'PORTRAIT',
class: 'p5',
module: 'Constants'
},
GRID: {
name: 'GRID',
class: 'p5',
module: 'Constants'
},
AXES: {
name: 'AXES',
class: 'p5',
module: 'Constants'
},
print: {
name: 'print',
params: [
{
name: 'contents',
description:
'<p>any combination of Number, String, Object, Boolean,\n Array to print</p>\n',
type: 'Any'
}
],
class: 'p5',
module: 'Environment'
},
frameCount: {
name: 'frameCount',
class: 'p5',
module: 'Environment'
},
deltaTime: {
name: 'deltaTime',
class: 'p5',
module: 'Environment'
},
focused: {
name: 'focused',
class: 'p5',
module: 'Environment'
},
cursor: {
name: 'cursor',
params: [
{
name: 'type',
description:
"<p>Built-In: either ARROW, CROSS, HAND, MOVE, TEXT and WAIT\n Native CSS properties: 'grab', 'progress', 'cell' etc.\n External: path for cursor's images\n (Allowed File extensions: .cur, .gif, .jpg, .jpeg, .png)\n For more information on Native CSS cursors and url visit:\n <a href=\"https://developer.mozilla.org/en-US/docs/Web/CSS/cursor\">https://developer.mozilla.org/en-US/docs/Web/CSS/cursor</a></p>\n",
type: 'String|Constant'
},
{
name: 'x',
description:
'<p>the horizontal active spot of the cursor (must be less than 32)</p>\n',
type: 'Number',
optional: true
},
{
name: 'y',
description:
'<p>the vertical active spot of the cursor (must be less than 32)</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Environment'
},
frameRate: {
name: 'frameRate',
class: 'p5',
module: 'Environment',
overloads: [
{
params: [
{
name: 'fps',
description:
'<p>number of frames to be displayed every second</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: []
}
]
},
noCursor: {
name: 'noCursor',
class: 'p5',
module: 'Environment'
},
displayWidth: {
name: 'displayWidth',
class: 'p5',
module: 'Environment'
},
displayHeight: {
name: 'displayHeight',
class: 'p5',
module: 'Environment'
},
windowWidth: {
name: 'windowWidth',
class: 'p5',
module: 'Environment'
},
windowHeight: {
name: 'windowHeight',
class: 'p5',
module: 'Environment'
},
windowResized: {
name: 'windowResized',
class: 'p5',
module: 'Environment'
},
width: {
name: 'width',
class: 'p5',
module: 'Environment'
},
height: {
name: 'height',
class: 'p5',
module: 'Environment'
},
fullscreen: {
name: 'fullscreen',
params: [
{
name: 'val',
description:
'<p>whether the sketch should be in fullscreen mode\nor not</p>\n',
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'Environment'
},
pixelDensity: {
name: 'pixelDensity',
class: 'p5',
module: 'Environment',
overloads: [
{
params: [
{
name: 'val',
description: '<p>whether or how much the sketch should scale</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: []
}
]
},
displayDensity: {
name: 'displayDensity',
class: 'p5',
module: 'Environment'
},
getURL: {
name: 'getURL',
class: 'p5',
module: 'Environment'
},
getURLPath: {
name: 'getURLPath',
class: 'p5',
module: 'Environment'
},
getURLParams: {
name: 'getURLParams',
class: 'p5',
module: 'Environment'
},
preload: {
name: 'preload',
class: 'p5',
module: 'Structure'
},
setup: {
name: 'setup',
class: 'p5',
module: 'Structure'
},
draw: {
name: 'draw',
class: 'p5',
module: 'Structure'
},
remove: {
name: 'remove',
class: 'p5',
module: 'Structure'
},
disableFriendlyErrors: {
name: 'disableFriendlyErrors',
class: 'p5',
module: 'Structure'
},
let: {
name: 'let',
class: 'p5',
module: 'Foundation'
},
const: {
name: 'const',
class: 'p5',
module: 'Foundation'
},
'===': {
name: '===',
class: 'p5',
module: 'Foundation'
},
'>': {
name: '>',
class: 'p5',
module: 'Foundation'
},
'>=': {
name: '>=',
class: 'p5',
module: 'Foundation'
},
'<': {
name: '<',
class: 'p5',
module: 'Foundation'
},
'<=': {
name: '<=',
class: 'p5',
module: 'Foundation'
},
'if-else': {
name: 'if-else',
class: 'p5',
module: 'Foundation'
},
function: {
name: 'function',
class: 'p5',
module: 'Foundation'
},
return: {
name: 'return',
class: 'p5',
module: 'Foundation'
},
boolean: {
name: 'boolean',
params: [
{
name: 'n',
description: '<p>value to parse</p>\n',
type: 'String|Boolean|Number|Array'
}
],
class: 'p5',
module: 'Data'
},
string: {
name: 'string',
class: 'p5',
module: 'Foundation'
},
number: {
name: 'number',
class: 'p5',
module: 'Foundation'
},
object: {
name: 'object',
class: 'p5',
module: 'Foundation'
},
class: {
name: 'class',
class: 'p5',
module: 'Foundation'
},
for: {
name: 'for',
class: 'p5',
module: 'Foundation'
},
while: {
name: 'while',
class: 'p5',
module: 'Foundation'
},
createCanvas: {
name: 'createCanvas',
params: [
{
name: 'w',
description: '<p>width of the canvas</p>\n',
type: 'Number'
},
{
name: 'h',
description: '<p>height of the canvas</p>\n',
type: 'Number'
},
{
name: 'renderer',
description: '<p>either P2D or WEBGL</p>\n',
type: 'Constant',
optional: true
}
],
class: 'p5',
module: 'Rendering'
},
resizeCanvas: {
name: 'resizeCanvas',
params: [
{
name: 'w',
description: '<p>width of the canvas</p>\n',
type: 'Number'
},
{
name: 'h',
description: '<p>height of the canvas</p>\n',
type: 'Number'
},
{
name: 'noRedraw',
description: "<p>don't redraw the canvas immediately</p>\n",
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'Rendering'
},
noCanvas: {
name: 'noCanvas',
class: 'p5',
module: 'Rendering'
},
createGraphics: {
name: 'createGraphics',
params: [
{
name: 'w',
description: '<p>width of the offscreen graphics buffer</p>\n',
type: 'Number'
},
{
name: 'h',
description: '<p>height of the offscreen graphics buffer</p>\n',
type: 'Number'
},
{
name: 'renderer',
description:
'<p>either P2D or WEBGL\n undefined defaults to p2d</p>\n',
type: 'Constant',
optional: true
}
],
class: 'p5',
module: 'Rendering'
},
blendMode: {
name: 'blendMode',
params: [
{
name: 'mode',
description:
'<p>blend mode to set for canvas.\n either BLEND, DARKEST, LIGHTEST, DIFFERENCE, MULTIPLY,\n EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n SOFT_LIGHT, DODGE, BURN, ADD, REMOVE or SUBTRACT</p>\n',
type: 'Constant'
}
],
class: 'p5',
module: 'Rendering'
},
drawingContext: {
name: 'drawingContext',
class: 'p5',
module: 'Rendering'
},
noLoop: {
name: 'noLoop',
class: 'p5',
module: 'Structure'
},
loop: {
name: 'loop',
class: 'p5',
module: 'Structure'
},
isLooping: {
name: 'isLooping',
class: 'p5',
module: 'Structure'
},
push: {
name: 'push',
class: 'p5',
module: 'Structure'
},
pop: {
name: 'pop',
class: 'p5',
module: 'Structure'
},
redraw: {
name: 'redraw',
params: [
{
name: 'n',
description: '<p>Redraw for n-times. The default value is 1.</p>\n',
type: 'Integer',
optional: true
}
],
class: 'p5',
module: 'Structure'
},
p5: {
name: 'p5',
params: [
{
name: 'sketch',
description: '<p>a function containing a p5.js sketch</p>\n',
type: 'Object'
},
{
name: 'node',
description:
'<p>ID or pointer to HTML DOM node to contain sketch in</p>\n',
type: 'String|Object'
}
],
class: 'p5',
module: 'Structure'
},
applyMatrix: {
name: 'applyMatrix',
params: [
{
name: 'a',
description:
'<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
type: 'Number'
},
{
name: 'b',
description:
'<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
type: 'Number'
},
{
name: 'c',
description:
'<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
type: 'Number'
},
{
name: 'd',
description:
'<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
type: 'Number'
},
{
name: 'e',
description:
'<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
type: 'Number'
},
{
name: 'f',
description:
'<p>numbers which define the 2x3 matrix to be multiplied</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Transform'
},
resetMatrix: {
name: 'resetMatrix',
class: 'p5',
module: 'Transform'
},
rotate: {
name: 'rotate',
params: [
{
name: 'angle',
description:
'<p>the angle of rotation, specified in radians\n or degrees, depending on current angleMode</p>\n',
type: 'Number'
},
{
name: 'axis',
description: '<p>(in 3d) the axis to rotate around</p>\n',
type: 'p5.Vector|Number[]',
optional: true
}
],
class: 'p5',
module: 'Transform'
},
rotateX: {
name: 'rotateX',
params: [
{
name: 'angle',
description:
'<p>the angle of rotation, specified in radians\n or degrees, depending on current angleMode</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Transform'
},
rotateY: {
name: 'rotateY',
params: [
{
name: 'angle',
description:
'<p>the angle of rotation, specified in radians\n or degrees, depending on current angleMode</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Transform'
},
rotateZ: {
name: 'rotateZ',
params: [
{
name: 'angle',
description:
'<p>the angle of rotation, specified in radians\n or degrees, depending on current angleMode</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Transform'
},
scale: {
name: 'scale',
class: 'p5',
module: 'Transform',
overloads: [
{
params: [
{
name: 's',
description:
'<p>percent to scale the object, or percentage to\n scale the object in the x-axis if multiple arguments\n are given</p>\n',
type: 'Number|p5.Vector|Number[]'
},
{
name: 'y',
description: '<p>percent to scale the object in the y-axis</p>\n',
type: 'Number',
optional: true
},
{
name: 'z',
description:
'<p>percent to scale the object in the z-axis (webgl only)</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'scales',
description: '<p>per-axis percents to scale the object</p>\n',
type: 'p5.Vector|Number[]'
}
],
chainable: 1
}
]
},
shearX: {
name: 'shearX',
params: [
{
name: 'angle',
description:
'<p>angle of shear specified in radians or degrees,\n depending on current angleMode</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Transform'
},
shearY: {
name: 'shearY',
params: [
{
name: 'angle',
description:
'<p>angle of shear specified in radians or degrees,\n depending on current angleMode</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Transform'
},
translate: {
name: 'translate',
class: 'p5',
module: 'Transform',
overloads: [
{
params: [
{
name: 'x',
description: '<p>left/right translation</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>up/down translation</p>\n',
type: 'Number'
},
{
name: 'z',
description: '<p>forward/backward translation (webgl only)</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'vector',
description: '<p>the vector to translate by</p>\n',
type: 'p5.Vector'
}
],
chainable: 1
}
]
},
storeItem: {
name: 'storeItem',
params: [
{
name: 'key',
description: '',
type: 'String'
},
{
name: 'value',
description: '',
type: 'String|Number|Object|Boolean|p5.Color|p5.Vector'
}
],
class: 'p5',
module: 'Data'
},
getItem: {
name: 'getItem',
params: [
{
name: 'key',
description:
'<p>name that you wish to use to store in local storage</p>\n',
type: 'String'
}
],
class: 'p5',
module: 'Data'
},
clearStorage: {
name: 'clearStorage',
class: 'p5',
module: 'Data'
},
removeItem: {
name: 'removeItem',
params: [
{
name: 'key',
description: '',
type: 'String'
}
],
class: 'p5',
module: 'Data'
},
createStringDict: {
name: 'createStringDict',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'key',
description: '',
type: 'String'
},
{
name: 'value',
description: '',
type: 'String'
}
]
},
{
params: [
{
name: 'object',
description: '<p>object</p>\n',
type: 'Object'
}
]
}
]
},
createNumberDict: {
name: 'createNumberDict',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'key',
description: '',
type: 'Number'
},
{
name: 'value',
description: '',
type: 'Number'
}
]
},
{
params: [
{
name: 'object',
description: '<p>object</p>\n',
type: 'Object'
}
]
}
]
},
select: {
name: 'select',
params: [
{
name: 'selectors',
description: '<p>CSS selector string of element to search for</p>\n',
type: 'String'
},
{
name: 'container',
description:
'<p>CSS selector string, <a href="#/p5.Element">p5.Element</a>, or\n HTML element to search within</p>\n',
type: 'String|p5.Element|HTMLElement',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
selectAll: {
name: 'selectAll',
params: [
{
name: 'selectors',
description: '<p>CSS selector string of elements to search for</p>\n',
type: 'String'
},
{
name: 'container',
description:
'<p>CSS selector string, <a href="#/p5.Element">p5.Element</a>\n , or HTML element to search within</p>\n',
type: 'String|p5.Element|HTMLElement',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
removeElements: {
name: 'removeElements',
class: 'p5',
module: 'DOM'
},
changed: {
name: 'changed',
params: [
{
name: 'fxn',
description:
'<p>function to be fired when the value of\n an element changes.\n if <code>false</code> is passed instead, the previously\n firing function will no longer fire.</p>\n',
type: 'Function|Boolean'
}
],
class: 'p5',
module: 'DOM'
},
input: {
name: 'input',
params: [
{
name: 'fxn',
description:
'<p>function to be fired when any user input is\n detected within the element.\n if <code>false</code> is passed instead, the previously\n firing function will no longer fire.</p>\n',
type: 'Function|Boolean'
}
],
class: 'p5',
module: 'DOM'
},
createDiv: {
name: 'createDiv',
params: [
{
name: 'html',
description: '<p>inner HTML for element created</p>\n',
type: 'String',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createP: {
name: 'createP',
params: [
{
name: 'html',
description: '<p>inner HTML for element created</p>\n',
type: 'String',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createSpan: {
name: 'createSpan',
params: [
{
name: 'html',
description: '<p>inner HTML for element created</p>\n',
type: 'String',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createImg: {
name: 'createImg',
class: 'p5',
module: 'DOM',
overloads: [
{
params: [
{
name: 'src',
description: '<p>src path or url for image</p>\n',
type: 'String'
},
{
name: 'alt',
description:
'<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/Img#Attributes">alternate text</a> to be used if image does not load. You can use also an empty string (<code>""</code>) if that an image is not intended to be viewed.</p>\n',
type: 'String'
}
]
},
{
params: [
{
name: 'src',
description: '',
type: 'String'
},
{
name: 'alt',
description: '',
type: 'String'
},
{
name: 'crossOrigin',
description:
'<p><a href="https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_settings_attributes">crossOrigin property</a> of the <code>img</code> element; use either \'anonymous\' or \'use-credentials\' to retrieve the image with cross-origin access (for later use with <code>canvas</code>. if an empty string(<code>""</code>) is passed, CORS is not used</p>\n',
type: 'String'
},
{
name: 'successCallback',
description:
'<p>callback to be called once image data is loaded with the <a href="#/p5.Element">p5.Element</a> as argument</p>\n',
type: 'Function',
optional: true
}
]
}
]
},
createA: {
name: 'createA',
params: [
{
name: 'href',
description: '<p>url of page to link to</p>\n',
type: 'String'
},
{
name: 'html',
description: '<p>inner html of link element to display</p>\n',
type: 'String'
},
{
name: 'target',
description:
'<p>target where new link should open,\n could be _blank, _self, _parent, _top.</p>\n',
type: 'String',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createSlider: {
name: 'createSlider',
params: [
{
name: 'min',
description: '<p>minimum value of the slider</p>\n',
type: 'Number'
},
{
name: 'max',
description: '<p>maximum value of the slider</p>\n',
type: 'Number'
},
{
name: 'value',
description: '<p>default value of the slider</p>\n',
type: 'Number',
optional: true
},
{
name: 'step',
description:
'<p>step size for each tick of the slider (if step is set to 0, the slider will move continuously from the minimum to the maximum value)</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createButton: {
name: 'createButton',
params: [
{
name: 'label',
description: '<p>label displayed on the button</p>\n',
type: 'String'
},
{
name: 'value',
description: '<p>value of the button</p>\n',
type: 'String',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createCheckbox: {
name: 'createCheckbox',
params: [
{
name: 'label',
description: '<p>label displayed after checkbox</p>\n',
type: 'String',
optional: true
},
{
name: 'value',
description:
'<p>value of the checkbox; checked is true, unchecked is false</p>\n',
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createSelect: {
name: 'createSelect',
class: 'p5',
module: 'DOM',
overloads: [
{
params: [
{
name: 'multiple',
description:
'<p>true if dropdown should support multiple selections</p>\n',
type: 'Boolean',
optional: true
}
]
},
{
params: [
{
name: 'existing',
description: '<p>DOM select element</p>\n',
type: 'Object'
}
]
}
]
},
createRadio: {
name: 'createRadio',
class: 'p5',
module: 'DOM',
overloads: [
{
params: [
{
name: 'containerElement',
description:
'<p>An container HTML Element either a div\nor span inside which all existing radio inputs will be considered as options.</p>\n',
type: 'Object'
},
{
name: 'name',
description: '<p>A name parameter for each Input Element.</p>\n',
type: 'String',
optional: true
}
]
},
{
params: [
{
name: 'name',
description: '',
type: 'String'
}
]
},
{
params: []
}
]
},
createColorPicker: {
name: 'createColorPicker',
params: [
{
name: 'value',
description: '<p>default color of element</p>\n',
type: 'String|p5.Color',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createInput: {
name: 'createInput',
class: 'p5',
module: 'DOM',
overloads: [
{
params: [
{
name: 'value',
description: '<p>default value of the input box</p>\n',
type: 'String'
},
{
name: 'type',
description:
'<p>type of text, ie text, password etc. Defaults to text.\n Needs a value to be specified first.</p>\n',
type: 'String',
optional: true
}
]
},
{
params: [
{
name: 'value',
description: '',
type: 'String',
optional: true
}
]
}
]
},
createFileInput: {
name: 'createFileInput',
params: [
{
name: 'callback',
description: '<p>callback function for when a file is loaded</p>\n',
type: 'Function'
},
{
name: 'multiple',
description:
'<p>optional, to allow multiple files to be selected</p>\n',
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createVideo: {
name: 'createVideo',
params: [
{
name: 'src',
description:
'<p>path to a video file, or array of paths for\n supporting different browsers</p>\n',
type: 'String|String[]'
},
{
name: 'callback',
description:
"<p>callback function to be called upon\n 'canplaythrough' event fire, that is, when the\n browser can play the media, and estimates that\n enough data has been loaded to play the media\n up to its end without having to stop for\n further buffering of content</p>\n",
type: 'Function',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createAudio: {
name: 'createAudio',
params: [
{
name: 'src',
description:
'<p>path to an audio file, or array of paths\n for supporting different browsers</p>\n',
type: 'String|String[]',
optional: true
},
{
name: 'callback',
description:
"<p>callback function to be called upon\n 'canplaythrough' event fire, that is, when the\n browser can play the media, and estimates that\n enough data has been loaded to play the media\n up to its end without having to stop for\n further buffering of content</p>\n",
type: 'Function',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
VIDEO: {
name: 'VIDEO',
class: 'p5',
module: 'DOM'
},
AUDIO: {
name: 'AUDIO',
class: 'p5',
module: 'DOM'
},
createCapture: {
name: 'createCapture',
params: [
{
name: 'type',
description:
'<p>type of capture, either VIDEO or\n AUDIO if none specified, default both,\n or a Constraints object</p>\n',
type: 'String|Constant|Object'
},
{
name: 'callback',
description:
'<p>function to be called once\n stream has loaded</p>\n',
type: 'Function',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
createElement: {
name: 'createElement',
params: [
{
name: 'tag',
description: '<p>tag for the new element</p>\n',
type: 'String'
},
{
name: 'content',
description: '<p>html content to be inserted into the element</p>\n',
type: 'String',
optional: true
}
],
class: 'p5',
module: 'DOM'
},
deviceOrientation: {
name: 'deviceOrientation',
class: 'p5',
module: 'Events'
},
accelerationX: {
name: 'accelerationX',
class: 'p5',
module: 'Events'
},
accelerationY: {
name: 'accelerationY',
class: 'p5',
module: 'Events'
},
accelerationZ: {
name: 'accelerationZ',
class: 'p5',
module: 'Events'
},
pAccelerationX: {
name: 'pAccelerationX',
class: 'p5',
module: 'Events'
},
pAccelerationY: {
name: 'pAccelerationY',
class: 'p5',
module: 'Events'
},
pAccelerationZ: {
name: 'pAccelerationZ',
class: 'p5',
module: 'Events'
},
rotationX: {
name: 'rotationX',
class: 'p5',
module: 'Events'
},
rotationY: {
name: 'rotationY',
class: 'p5',
module: 'Events'
},
rotationZ: {
name: 'rotationZ',
class: 'p5',
module: 'Events'
},
pRotationX: {
name: 'pRotationX',
class: 'p5',
module: 'Events'
},
pRotationY: {
name: 'pRotationY',
class: 'p5',
module: 'Events'
},
pRotationZ: {
name: 'pRotationZ',
class: 'p5',
module: 'Events'
},
turnAxis: {
name: 'turnAxis',
class: 'p5',
module: 'Events'
},
setMoveThreshold: {
name: 'setMoveThreshold',
params: [
{
name: 'value',
description: '<p>The threshold value</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Events'
},
setShakeThreshold: {
name: 'setShakeThreshold',
params: [
{
name: 'value',
description: '<p>The threshold value</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Events'
},
deviceMoved: {
name: 'deviceMoved',
class: 'p5',
module: 'Events'
},
deviceTurned: {
name: 'deviceTurned',
class: 'p5',
module: 'Events'
},
deviceShaken: {
name: 'deviceShaken',
class: 'p5',
module: 'Events'
},
keyIsPressed: {
name: 'keyIsPressed',
class: 'p5',
module: 'Events'
},
key: {
name: 'key',
class: 'p5',
module: 'Events'
},
keyCode: {
name: 'keyCode',
class: 'p5',
module: 'Events'
},
keyPressed: {
name: 'keyPressed',
class: 'p5',
module: 'Events'
},
keyReleased: {
name: 'keyReleased',
class: 'p5',
module: 'Events'
},
keyTyped: {
name: 'keyTyped',
class: 'p5',
module: 'Events'
},
keyIsDown: {
name: 'keyIsDown',
params: [
{
name: 'code',
description: '<p>The key to check for.</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Events'
},
movedX: {
name: 'movedX',
class: 'p5',
module: 'Events'
},
movedY: {
name: 'movedY',
class: 'p5',
module: 'Events'
},
mouseX: {
name: 'mouseX',
class: 'p5',
module: 'Events'
},
mouseY: {
name: 'mouseY',
class: 'p5',
module: 'Events'
},
pmouseX: {
name: 'pmouseX',
class: 'p5',
module: 'Events'
},
pmouseY: {
name: 'pmouseY',
class: 'p5',
module: 'Events'
},
winMouseX: {
name: 'winMouseX',
class: 'p5',
module: 'Events'
},
winMouseY: {
name: 'winMouseY',
class: 'p5',
module: 'Events'
},
pwinMouseX: {
name: 'pwinMouseX',
class: 'p5',
module: 'Events'
},
pwinMouseY: {
name: 'pwinMouseY',
class: 'p5',
module: 'Events'
},
mouseButton: {
name: 'mouseButton',
class: 'p5',
module: 'Events'
},
mouseIsPressed: {
name: 'mouseIsPressed',
class: 'p5',
module: 'Events'
},
mouseMoved: {
name: 'mouseMoved',
params: [
{
name: 'event',
description: '<p>optional MouseEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
mouseDragged: {
name: 'mouseDragged',
params: [
{
name: 'event',
description: '<p>optional MouseEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
mousePressed: {
name: 'mousePressed',
params: [
{
name: 'event',
description: '<p>optional MouseEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
mouseReleased: {
name: 'mouseReleased',
params: [
{
name: 'event',
description: '<p>optional MouseEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
mouseClicked: {
name: 'mouseClicked',
params: [
{
name: 'event',
description: '<p>optional MouseEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
doubleClicked: {
name: 'doubleClicked',
params: [
{
name: 'event',
description: '<p>optional MouseEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
mouseWheel: {
name: 'mouseWheel',
params: [
{
name: 'event',
description: '<p>optional WheelEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
requestPointerLock: {
name: 'requestPointerLock',
class: 'p5',
module: 'Events'
},
exitPointerLock: {
name: 'exitPointerLock',
class: 'p5',
module: 'Events'
},
touches: {
name: 'touches',
class: 'p5',
module: 'Events'
},
touchStarted: {
name: 'touchStarted',
params: [
{
name: 'event',
description: '<p>optional TouchEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
touchMoved: {
name: 'touchMoved',
params: [
{
name: 'event',
description: '<p>optional TouchEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
touchEnded: {
name: 'touchEnded',
params: [
{
name: 'event',
description: '<p>optional TouchEvent callback argument.</p>\n',
type: 'Object',
optional: true
}
],
class: 'p5',
module: 'Events'
},
createImage: {
name: 'createImage',
params: [
{
name: 'width',
description: '<p>width in pixels</p>\n',
type: 'Integer'
},
{
name: 'height',
description: '<p>height in pixels</p>\n',
type: 'Integer'
}
],
class: 'p5',
module: 'Image'
},
saveCanvas: {
name: 'saveCanvas',
class: 'p5',
module: 'Image',
overloads: [
{
params: [
{
name: 'selectedCanvas',
description:
'<p>a variable\n representing a specific html5 canvas (optional)</p>\n',
type: 'p5.Element|HTMLCanvasElement'
},
{
name: 'filename',
description: '',
type: 'String',
optional: true
},
{
name: 'extension',
description: "<p>'jpg' or 'png'</p>\n",
type: 'String',
optional: true
}
]
},
{
params: [
{
name: 'filename',
description: '',
type: 'String',
optional: true
},
{
name: 'extension',
description: '',
type: 'String',
optional: true
}
]
}
]
},
saveFrames: {
name: 'saveFrames',
params: [
{
name: 'filename',
description: '',
type: 'String'
},
{
name: 'extension',
description: "<p>'jpg' or 'png'</p>\n",
type: 'String'
},
{
name: 'duration',
description: '<p>Duration in seconds to save the frames for.</p>\n',
type: 'Number'
},
{
name: 'framerate',
description: '<p>Framerate to save the frames in.</p>\n',
type: 'Number'
},
{
name: 'callback',
description:
'<p>A callback function that will be executed\n to handle the image data. This function\n should accept an array as argument. The\n array will contain the specified number of\n frames of objects. Each object has three\n properties: imageData - an\n image/octet-stream, filename and extension.</p>\n',
type: 'Function(Array)',
optional: true
}
],
class: 'p5',
module: 'Image'
},
loadImage: {
name: 'loadImage',
params: [
{
name: 'path',
description: '<p>Path of the image to be loaded</p>\n',
type: 'String'
},
{
name: 'successCallback',
description:
'<p>Function to be called once\n the image is loaded. Will be passed the\n <a href="#/p5.Image">p5.Image</a>.</p>\n',
type: 'function(p5.Image)',
optional: true
},
{
name: 'failureCallback',
description:
'<p>called with event error if\n the image fails to load.</p>\n',
type: 'Function(Event)',
optional: true
}
],
class: 'p5',
module: 'Image'
},
image: {
name: 'image',
class: 'p5',
module: 'Image',
overloads: [
{
params: [
{
name: 'img',
description: '<p>the image to display</p>\n',
type: 'p5.Image|p5.Element'
},
{
name: 'x',
description:
'<p>the x-coordinate of the top-left corner of the image</p>\n',
type: 'Number'
},
{
name: 'y',
description:
'<p>the y-coordinate of the top-left corner of the image</p>\n',
type: 'Number'
},
{
name: 'width',
description: '<p>the width to draw the image</p>\n',
type: 'Number',
optional: true
},
{
name: 'height',
description: '<p>the height to draw the image</p>\n',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'img',
description: '',
type: 'p5.Image|p5.Element'
},
{
name: 'dx',
description:
'<p>the x-coordinate of the destination\n rectangle in which to draw the source image</p>\n',
type: 'Number'
},
{
name: 'dy',
description:
'<p>the y-coordinate of the destination\n rectangle in which to draw the source image</p>\n',
type: 'Number'
},
{
name: 'dWidth',
description: '<p>the width of the destination rectangle</p>\n',
type: 'Number'
},
{
name: 'dHeight',
description: '<p>the height of the destination rectangle</p>\n',
type: 'Number'
},
{
name: 'sx',
description:
'<p>the x-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n',
type: 'Number'
},
{
name: 'sy',
description:
'<p>the y-coordinate of the subsection of the source\nimage to draw into the destination rectangle</p>\n',
type: 'Number'
},
{
name: 'sWidth',
description:
'<p>the width of the subsection of the\n source image to draw into the destination\n rectangle</p>\n',
type: 'Number',
optional: true
},
{
name: 'sHeight',
description:
'<p>the height of the subsection of the\n source image to draw into the destination rectangle</p>\n',
type: 'Number',
optional: true
}
]
}
]
},
tint: {
name: 'tint',
class: 'p5',
module: 'Image',
overloads: [
{
params: [
{
name: 'v1',
description:
'<p>red or hue value relative to\n the current color range</p>\n',
type: 'Number'
},
{
name: 'v2',
description:
'<p>green or saturation value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'v3',
description:
'<p>blue or brightness value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'alpha',
description: '',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'value',
description: '<p>a color string</p>\n',
type: 'String'
}
]
},
{
params: [
{
name: 'gray',
description: '<p>a gray value</p>\n',
type: 'Number'
},
{
name: 'alpha',
description: '',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'values',
description:
'<p>an array containing the red,green,blue &\n and alpha components of the color</p>\n',
type: 'Number[]'
}
]
},
{
params: [
{
name: 'color',
description: '<p>the tint color</p>\n',
type: 'p5.Color'
}
]
}
]
},
noTint: {
name: 'noTint',
class: 'p5',
module: 'Image'
},
imageMode: {
name: 'imageMode',
params: [
{
name: 'mode',
description: '<p>either CORNER, CORNERS, or CENTER</p>\n',
type: 'Constant'
}
],
class: 'p5',
module: 'Image'
},
pixels: {
name: 'pixels',
class: 'p5',
module: 'Image'
},
blend: {
name: 'blend',
class: 'p5',
module: 'Image',
overloads: [
{
params: [
{
name: 'srcImage',
description: '<p>source image</p>\n',
type: 'p5.Image'
},
{
name: 'sx',
description:
"<p>X coordinate of the source's upper left corner</p>\n",
type: 'Integer'
},
{
name: 'sy',
description:
"<p>Y coordinate of the source's upper left corner</p>\n",
type: 'Integer'
},
{
name: 'sw',
description: '<p>source image width</p>\n',
type: 'Integer'
},
{
name: 'sh',
description: '<p>source image height</p>\n',
type: 'Integer'
},
{
name: 'dx',
description:
"<p>X coordinate of the destination's upper left corner</p>\n",
type: 'Integer'
},
{
name: 'dy',
description:
"<p>Y coordinate of the destination's upper left corner</p>\n",
type: 'Integer'
},
{
name: 'dw',
description: '<p>destination image width</p>\n',
type: 'Integer'
},
{
name: 'dh',
description: '<p>destination image height</p>\n',
type: 'Integer'
},
{
name: 'blendMode',
description:
'<p>the blend mode. either\n BLEND, DARKEST, LIGHTEST, DIFFERENCE,\n MULTIPLY, EXCLUSION, SCREEN, REPLACE, OVERLAY, HARD_LIGHT,\n SOFT_LIGHT, DODGE, BURN, ADD or NORMAL.</p>\n',
type: 'Constant'
}
]
},
{
params: [
{
name: 'sx',
description: '',
type: 'Integer'
},
{
name: 'sy',
description: '',
type: 'Integer'
},
{
name: 'sw',
description: '',
type: 'Integer'
},
{
name: 'sh',
description: '',
type: 'Integer'
},
{
name: 'dx',
description: '',
type: 'Integer'
},
{
name: 'dy',
description: '',
type: 'Integer'
},
{
name: 'dw',
description: '',
type: 'Integer'
},
{
name: 'dh',
description: '',
type: 'Integer'
},
{
name: 'blendMode',
description: '',
type: 'Constant'
}
]
}
]
},
copy: {
name: 'copy',
class: 'p5',
module: 'Image',
overloads: [
{
params: [
{
name: 'srcImage',
description: '<p>source image</p>\n',
type: 'p5.Image|p5.Element'
},
{
name: 'sx',
description:
"<p>X coordinate of the source's upper left corner</p>\n",
type: 'Integer'
},
{
name: 'sy',
description:
"<p>Y coordinate of the source's upper left corner</p>\n",
type: 'Integer'
},
{
name: 'sw',
description: '<p>source image width</p>\n',
type: 'Integer'
},
{
name: 'sh',
description: '<p>source image height</p>\n',
type: 'Integer'
},
{
name: 'dx',
description:
"<p>X coordinate of the destination's upper left corner</p>\n",
type: 'Integer'
},
{
name: 'dy',
description:
"<p>Y coordinate of the destination's upper left corner</p>\n",
type: 'Integer'
},
{
name: 'dw',
description: '<p>destination image width</p>\n',
type: 'Integer'
},
{
name: 'dh',
description: '<p>destination image height</p>\n',
type: 'Integer'
}
]
},
{
params: [
{
name: 'sx',
description: '',
type: 'Integer'
},
{
name: 'sy',
description: '',
type: 'Integer'
},
{
name: 'sw',
description: '',
type: 'Integer'
},
{
name: 'sh',
description: '',
type: 'Integer'
},
{
name: 'dx',
description: '',
type: 'Integer'
},
{
name: 'dy',
description: '',
type: 'Integer'
},
{
name: 'dw',
description: '',
type: 'Integer'
},
{
name: 'dh',
description: '',
type: 'Integer'
}
]
}
]
},
filter: {
name: 'filter',
params: [
{
name: 'filterType',
description:
'<p>either THRESHOLD, GRAY, OPAQUE, INVERT,\n POSTERIZE, BLUR, ERODE, DILATE or BLUR.\n See Filters.js for docs on\n each available filter</p>\n',
type: 'Constant'
},
{
name: 'filterParam',
description:
'<p>an optional parameter unique\n to each filter, see above</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Image'
},
get: {
name: 'get',
class: 'p5',
module: 'Image',
overloads: [
{
params: [
{
name: 'x',
description: '<p>x-coordinate of the pixel</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate of the pixel</p>\n',
type: 'Number'
},
{
name: 'w',
description: '<p>width</p>\n',
type: 'Number'
},
{
name: 'h',
description: '<p>height</p>\n',
type: 'Number'
}
]
},
{
params: []
},
{
params: [
{
name: 'x',
description: '',
type: 'Number'
},
{
name: 'y',
description: '',
type: 'Number'
}
]
}
]
},
loadPixels: {
name: 'loadPixels',
class: 'p5',
module: 'Image'
},
set: {
name: 'set',
params: [
{
name: 'x',
description: '<p>x-coordinate of the pixel</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate of the pixel</p>\n',
type: 'Number'
},
{
name: 'c',
description:
'<p>insert a grayscale value | a pixel array |\n a <a href="#/p5.Color">p5.Color</a> object | a <a href="#/p5.Image">p5.Image</a> to copy</p>\n',
type: 'Number|Number[]|Object'
}
],
class: 'p5',
module: 'Image'
},
updatePixels: {
name: 'updatePixels',
params: [
{
name: 'x',
description:
'<p>x-coordinate of the upper-left corner of region\n to update</p>\n',
type: 'Number',
optional: true
},
{
name: 'y',
description:
'<p>y-coordinate of the upper-left corner of region\n to update</p>\n',
type: 'Number',
optional: true
},
{
name: 'w',
description: '<p>width of region to update</p>\n',
type: 'Number',
optional: true
},
{
name: 'h',
description: '<p>height of region to update</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Image'
},
loadJSON: {
name: 'loadJSON',
class: 'p5',
module: 'IO',
overloads: [
{
params: [
{
name: 'path',
description: '<p>name of the file or url to load</p>\n',
type: 'String'
},
{
name: 'jsonpOptions',
description: '<p>options object for jsonp related settings</p>\n',
type: 'Object',
optional: true
},
{
name: 'datatype',
description: '<p>"json" or "jsonp"</p>\n',
type: 'String',
optional: true
},
{
name: 'callback',
description:
'<p>function to be executed after\n <a href="#/p5/loadJSON">loadJSON()</a> completes, data is passed\n in as first argument</p>\n',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description:
'<p>function to be executed if\n there is an error, response is passed\n in as first argument</p>\n',
type: 'Function',
optional: true
}
]
},
{
params: [
{
name: 'path',
description: '',
type: 'String'
},
{
name: 'datatype',
description: '',
type: 'String'
},
{
name: 'callback',
description: '',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description: '',
type: 'Function',
optional: true
}
]
},
{
params: [
{
name: 'path',
description: '',
type: 'String'
},
{
name: 'callback',
description: '',
type: 'Function'
},
{
name: 'errorCallback',
description: '',
type: 'Function',
optional: true
}
]
}
]
},
loadStrings: {
name: 'loadStrings',
params: [
{
name: 'filename',
description: '<p>name of the file or url to load</p>\n',
type: 'String'
},
{
name: 'callback',
description:
'<p>function to be executed after <a href="#/p5/loadStrings">loadStrings()</a>\n completes, Array is passed in as first\n argument</p>\n',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description:
'<p>function to be executed if\n there is an error, response is passed\n in as first argument</p>\n',
type: 'Function',
optional: true
}
],
class: 'p5',
module: 'IO'
},
loadTable: {
name: 'loadTable',
params: [
{
name: 'filename',
description: '<p>name of the file or URL to load</p>\n',
type: 'String'
},
{
name: 'extension',
description:
'<p>parse the table by comma-separated values "csv", semicolon-separated\n values "ssv", or tab-separated values "tsv"</p>\n',
type: 'String',
optional: true
},
{
name: 'header',
description: '<p>"header" to indicate table has header row</p>\n',
type: 'String',
optional: true
},
{
name: 'callback',
description:
'<p>function to be executed after\n <a href="#/p5/loadTable">loadTable()</a> completes. On success, the\n <a href="#/p5.Table">Table</a> object is passed in as the\n first argument.</p>\n',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description:
'<p>function to be executed if\n there is an error, response is passed\n in as first argument</p>\n',
type: 'Function',
optional: true
}
],
class: 'p5',
module: 'IO'
},
loadXML: {
name: 'loadXML',
params: [
{
name: 'filename',
description: '<p>name of the file or URL to load</p>\n',
type: 'String'
},
{
name: 'callback',
description:
'<p>function to be executed after <a href="#/p5/loadXML">loadXML()</a>\n completes, XML object is passed in as\n first argument</p>\n',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description:
'<p>function to be executed if\n there is an error, response is passed\n in as first argument</p>\n',
type: 'Function',
optional: true
}
],
class: 'p5',
module: 'IO'
},
loadBytes: {
name: 'loadBytes',
params: [
{
name: 'file',
description: '<p>name of the file or URL to load</p>\n',
type: 'String'
},
{
name: 'callback',
description:
'<p>function to be executed after <a href="#/p5/loadBytes">loadBytes()</a>\n completes</p>\n',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description:
'<p>function to be executed if there\n is an error</p>\n',
type: 'Function',
optional: true
}
],
class: 'p5',
module: 'IO'
},
httpGet: {
name: 'httpGet',
class: 'p5',
module: 'IO',
overloads: [
{
params: [
{
name: 'path',
description: '<p>name of the file or url to load</p>\n',
type: 'String'
},
{
name: 'datatype',
description:
'<p>"json", "jsonp", "binary", "arrayBuffer",\n "xml", or "text"</p>\n',
type: 'String',
optional: true
},
{
name: 'data',
description: '<p>param data passed sent with request</p>\n',
type: 'Object|Boolean',
optional: true
},
{
name: 'callback',
description:
'<p>function to be executed after\n <a href="#/p5/httpGet">httpGet()</a> completes, data is passed in\n as first argument</p>\n',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description:
'<p>function to be executed if\n there is an error, response is passed\n in as first argument</p>\n',
type: 'Function',
optional: true
}
]
},
{
params: [
{
name: 'path',
description: '',
type: 'String'
},
{
name: 'data',
description: '',
type: 'Object|Boolean'
},
{
name: 'callback',
description: '',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description: '',
type: 'Function',
optional: true
}
]
},
{
params: [
{
name: 'path',
description: '',
type: 'String'
},
{
name: 'callback',
description: '',
type: 'Function'
},
{
name: 'errorCallback',
description: '',
type: 'Function',
optional: true
}
]
}
]
},
httpPost: {
name: 'httpPost',
class: 'p5',
module: 'IO',
overloads: [
{
params: [
{
name: 'path',
description: '<p>name of the file or url to load</p>\n',
type: 'String'
},
{
name: 'datatype',
description:
'<p>"json", "jsonp", "xml", or "text".\n If omitted, <a href="#/p5/httpPost">httpPost()</a> will guess.</p>\n',
type: 'String',
optional: true
},
{
name: 'data',
description: '<p>param data passed sent with request</p>\n',
type: 'Object|Boolean',
optional: true
},
{
name: 'callback',
description:
'<p>function to be executed after\n <a href="#/p5/httpPost">httpPost()</a> completes, data is passed in\n as first argument</p>\n',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description:
'<p>function to be executed if\n there is an error, response is passed\n in as first argument</p>\n',
type: 'Function',
optional: true
}
]
},
{
params: [
{
name: 'path',
description: '',
type: 'String'
},
{
name: 'data',
description: '',
type: 'Object|Boolean'
},
{
name: 'callback',
description: '',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description: '',
type: 'Function',
optional: true
}
]
},
{
params: [
{
name: 'path',
description: '',
type: 'String'
},
{
name: 'callback',
description: '',
type: 'Function'
},
{
name: 'errorCallback',
description: '',
type: 'Function',
optional: true
}
]
}
]
},
httpDo: {
name: 'httpDo',
class: 'p5',
module: 'IO',
overloads: [
{
params: [
{
name: 'path',
description: '<p>name of the file or url to load</p>\n',
type: 'String'
},
{
name: 'method',
description:
'<p>either "GET", "POST", or "PUT",\n defaults to "GET"</p>\n',
type: 'String',
optional: true
},
{
name: 'datatype',
description: '<p>"json", "jsonp", "xml", or "text"</p>\n',
type: 'String',
optional: true
},
{
name: 'data',
description: '<p>param data passed sent with request</p>\n',
type: 'Object',
optional: true
},
{
name: 'callback',
description:
'<p>function to be executed after\n <a href="#/p5/httpGet">httpGet()</a> completes, data is passed in\n as first argument</p>\n',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description:
'<p>function to be executed if\n there is an error, response is passed\n in as first argument</p>\n',
type: 'Function',
optional: true
}
]
},
{
params: [
{
name: 'path',
description: '',
type: 'String'
},
{
name: 'options',
description:
'<p>Request object options as documented in the\n "fetch" API\n<a href="https://developer.mozilla.org/en/docs/Web/API/Fetch_API">reference</a></p>\n',
type: 'Object'
},
{
name: 'callback',
description: '',
type: 'Function',
optional: true
},
{
name: 'errorCallback',
description: '',
type: 'Function',
optional: true
}
]
}
]
},
createWriter: {
name: 'createWriter',
params: [
{
name: 'name',
description: '<p>name of the file to be created</p>\n',
type: 'String'
},
{
name: 'extension',
description: '',
type: 'String',
optional: true
}
],
class: 'p5',
module: 'IO'
},
save: {
name: 'save',
params: [
{
name: 'objectOrFilename',
description:
'<p>If filename is provided, will\n save canvas as an image with\n either png or jpg extension\n depending on the filename.\n If object is provided, will\n save depending on the object\n and filename (see examples\n above).</p>\n',
type: 'Object|String',
optional: true
},
{
name: 'filename',
description:
'<p>If an object is provided as the first\n parameter, then the second parameter\n indicates the filename,\n and should include an appropriate\n file extension (see examples above).</p>\n',
type: 'String',
optional: true
},
{
name: 'options',
description:
'<p>Additional options depend on\n filetype. For example, when saving JSON,\n <code>true</code> indicates that the\n output will be optimized for filesize,\n rather than readability.</p>\n',
type: 'Boolean|String',
optional: true
}
],
class: 'p5',
module: 'IO'
},
saveJSON: {
name: 'saveJSON',
params: [
{
name: 'json',
description: '',
type: 'Array|Object'
},
{
name: 'filename',
description: '',
type: 'String'
},
{
name: 'optimize',
description:
'<p>If true, removes line breaks\n and spaces from the output\n file to optimize filesize\n (but not readability).</p>\n',
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'IO'
},
saveStrings: {
name: 'saveStrings',
params: [
{
name: 'list',
description: '<p>string array to be written</p>\n',
type: 'String[]'
},
{
name: 'filename',
description: '<p>filename for output</p>\n',
type: 'String'
},
{
name: 'extension',
description: "<p>the filename's extension</p>\n",
type: 'String',
optional: true
},
{
name: 'isCRLF',
description: '<p>if true, change line-break to CRLF</p>\n',
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'IO'
},
saveTable: {
name: 'saveTable',
params: [
{
name: 'Table',
description:
'<p>the <a href="#/p5.Table">Table</a> object to save to a file</p>\n',
type: 'p5.Table'
},
{
name: 'filename',
description: '<p>the filename to which the Table should be saved</p>\n',
type: 'String'
},
{
name: 'options',
description: '<p>can be one of "tsv", "csv", or "html"</p>\n',
type: 'String',
optional: true
}
],
class: 'p5',
module: 'IO'
},
abs: {
name: 'abs',
params: [
{
name: 'n',
description: '<p>number to compute</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
ceil: {
name: 'ceil',
params: [
{
name: 'n',
description: '<p>number to round up</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
constrain: {
name: 'constrain',
params: [
{
name: 'n',
description: '<p>number to constrain</p>\n',
type: 'Number'
},
{
name: 'low',
description: '<p>minimum limit</p>\n',
type: 'Number'
},
{
name: 'high',
description: '<p>maximum limit</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
dist: {
name: 'dist',
class: 'p5',
module: 'Math',
overloads: [
{
params: [
{
name: 'x1',
description: '<p>x-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'y1',
description: '<p>y-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '<p>x-coordinate of the second point</p>\n',
type: 'Number'
},
{
name: 'y2',
description: '<p>y-coordinate of the second point</p>\n',
type: 'Number'
}
]
},
{
params: [
{
name: 'x1',
description: '',
type: 'Number'
},
{
name: 'y1',
description: '',
type: 'Number'
},
{
name: 'z1',
description: '<p>z-coordinate of the first point</p>\n',
type: 'Number'
},
{
name: 'x2',
description: '',
type: 'Number'
},
{
name: 'y2',
description: '',
type: 'Number'
},
{
name: 'z2',
description: '<p>z-coordinate of the second point</p>\n',
type: 'Number'
}
]
}
]
},
exp: {
name: 'exp',
params: [
{
name: 'n',
description: '<p>exponent to raise</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
floor: {
name: 'floor',
params: [
{
name: 'n',
description: '<p>number to round down</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
lerp: {
name: 'lerp',
params: [
{
name: 'start',
description: '<p>first value</p>\n',
type: 'Number'
},
{
name: 'stop',
description: '<p>second value</p>\n',
type: 'Number'
},
{
name: 'amt',
description: '<p>number</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
log: {
name: 'log',
params: [
{
name: 'n',
description: '<p>number greater than 0</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
mag: {
name: 'mag',
params: [
{
name: 'a',
description: '<p>first value</p>\n',
type: 'Number'
},
{
name: 'b',
description: '<p>second value</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
map: {
name: 'map',
params: [
{
name: 'value',
description: '<p>the incoming value to be converted</p>\n',
type: 'Number'
},
{
name: 'start1',
description: "<p>lower bound of the value's current range</p>\n",
type: 'Number'
},
{
name: 'stop1',
description: "<p>upper bound of the value's current range</p>\n",
type: 'Number'
},
{
name: 'start2',
description: "<p>lower bound of the value's target range</p>\n",
type: 'Number'
},
{
name: 'stop2',
description: "<p>upper bound of the value's target range</p>\n",
type: 'Number'
},
{
name: 'withinBounds',
description: '<p>constrain the value to the newly mapped range</p>\n',
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'Math'
},
max: {
name: 'max',
class: 'p5',
module: 'Math',
overloads: [
{
params: [
{
name: 'n0',
description: '<p>Number to compare</p>\n',
type: 'Number'
},
{
name: 'n1',
description: '<p>Number to compare</p>\n',
type: 'Number'
}
]
},
{
params: [
{
name: 'nums',
description: '<p>Numbers to compare</p>\n',
type: 'Number[]'
}
]
}
]
},
min: {
name: 'min',
class: 'p5',
module: 'Math',
overloads: [
{
params: [
{
name: 'n0',
description: '<p>Number to compare</p>\n',
type: 'Number'
},
{
name: 'n1',
description: '<p>Number to compare</p>\n',
type: 'Number'
}
]
},
{
params: [
{
name: 'nums',
description: '<p>Numbers to compare</p>\n',
type: 'Number[]'
}
]
}
]
},
norm: {
name: 'norm',
params: [
{
name: 'value',
description: '<p>incoming value to be normalized</p>\n',
type: 'Number'
},
{
name: 'start',
description: "<p>lower bound of the value's current range</p>\n",
type: 'Number'
},
{
name: 'stop',
description: "<p>upper bound of the value's current range</p>\n",
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
pow: {
name: 'pow',
params: [
{
name: 'n',
description: '<p>base of the exponential expression</p>\n',
type: 'Number'
},
{
name: 'e',
description: '<p>power by which to raise the base</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
round: {
name: 'round',
params: [
{
name: 'n',
description: '<p>number to round</p>\n',
type: 'Number'
},
{
name: 'decimals',
description:
'<p>number of decimal places to round to, default is 0</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Math'
},
sq: {
name: 'sq',
params: [
{
name: 'n',
description: '<p>number to square</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
sqrt: {
name: 'sqrt',
params: [
{
name: 'n',
description: '<p>non-negative number to square root</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
fract: {
name: 'fract',
params: [
{
name: 'num',
description:
'<p>Number whose fractional part needs to be found out</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
createVector: {
name: 'createVector',
params: [
{
name: 'x',
description: '<p>x component of the vector</p>\n',
type: 'Number',
optional: true
},
{
name: 'y',
description: '<p>y component of the vector</p>\n',
type: 'Number',
optional: true
},
{
name: 'z',
description: '<p>z component of the vector</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Math'
},
noise: {
name: 'noise',
params: [
{
name: 'x',
description: '<p>x-coordinate in noise space</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate in noise space</p>\n',
type: 'Number',
optional: true
},
{
name: 'z',
description: '<p>z-coordinate in noise space</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Math'
},
noiseDetail: {
name: 'noiseDetail',
params: [
{
name: 'lod',
description: '<p>number of octaves to be used by the noise</p>\n',
type: 'Number'
},
{
name: 'falloff',
description: '<p>falloff factor for each octave</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
noiseSeed: {
name: 'noiseSeed',
params: [
{
name: 'seed',
description: '<p>the seed value</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
randomSeed: {
name: 'randomSeed',
params: [
{
name: 'seed',
description: '<p>the seed value</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
random: {
name: 'random',
class: 'p5',
module: 'Math',
overloads: [
{
params: [
{
name: 'min',
description: '<p>the lower bound (inclusive)</p>\n',
type: 'Number',
optional: true
},
{
name: 'max',
description: '<p>the upper bound (exclusive)</p>\n',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'choices',
description: '<p>the array to choose from</p>\n',
type: 'Array'
}
]
}
]
},
randomGaussian: {
name: 'randomGaussian',
params: [
{
name: 'mean',
description: '<p>the mean</p>\n',
type: 'Number'
},
{
name: 'sd',
description: '<p>the standard deviation</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
acos: {
name: 'acos',
params: [
{
name: 'value',
description: '<p>the value whose arc cosine is to be returned</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
asin: {
name: 'asin',
params: [
{
name: 'value',
description: '<p>the value whose arc sine is to be returned</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
atan: {
name: 'atan',
params: [
{
name: 'value',
description: '<p>the value whose arc tangent is to be returned</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
atan2: {
name: 'atan2',
params: [
{
name: 'y',
description: '<p>y-coordinate of the point</p>\n',
type: 'Number'
},
{
name: 'x',
description: '<p>x-coordinate of the point</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
cos: {
name: 'cos',
params: [
{
name: 'angle',
description: '<p>the angle</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
sin: {
name: 'sin',
params: [
{
name: 'angle',
description: '<p>the angle</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
tan: {
name: 'tan',
params: [
{
name: 'angle',
description: '<p>the angle</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
degrees: {
name: 'degrees',
params: [
{
name: 'radians',
description: '<p>the radians value to convert to degrees</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
radians: {
name: 'radians',
params: [
{
name: 'degrees',
description: '<p>the degree value to convert to radians</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Math'
},
angleMode: {
name: 'angleMode',
params: [
{
name: 'mode',
description: '<p>either RADIANS or DEGREES</p>\n',
type: 'Constant'
}
],
class: 'p5',
module: 'Math'
},
textAlign: {
name: 'textAlign',
class: 'p5',
module: 'Typography',
overloads: [
{
params: [
{
name: 'horizAlign',
description:
'<p>horizontal alignment, either LEFT,\n CENTER, or RIGHT</p>\n',
type: 'Constant'
},
{
name: 'vertAlign',
description:
'<p>vertical alignment, either TOP,\n BOTTOM, CENTER, or BASELINE</p>\n',
type: 'Constant',
optional: true
}
],
chainable: 1
},
{
params: []
}
]
},
textLeading: {
name: 'textLeading',
class: 'p5',
module: 'Typography',
overloads: [
{
params: [
{
name: 'leading',
description:
'<p>the size in pixels for spacing between lines</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: []
}
]
},
textSize: {
name: 'textSize',
class: 'p5',
module: 'Typography',
overloads: [
{
params: [
{
name: 'theSize',
description: '<p>the size of the letters in units of pixels</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: []
}
]
},
textStyle: {
name: 'textStyle',
class: 'p5',
module: 'Typography',
overloads: [
{
params: [
{
name: 'theStyle',
description:
'<p>styling for text, either NORMAL,\n ITALIC, BOLD or BOLDITALIC</p>\n',
type: 'Constant'
}
],
chainable: 1
},
{
params: []
}
]
},
textWidth: {
name: 'textWidth',
params: [
{
name: 'theText',
description: '<p>the String of characters to measure</p>\n',
type: 'String'
}
],
class: 'p5',
module: 'Typography'
},
textAscent: {
name: 'textAscent',
class: 'p5',
module: 'Typography'
},
textDescent: {
name: 'textDescent',
class: 'p5',
module: 'Typography'
},
loadFont: {
name: 'loadFont',
params: [
{
name: 'path',
description: '<p>name of the file or url to load</p>\n',
type: 'String'
},
{
name: 'callback',
description:
'<p>function to be executed after\n <a href="#/p5/loadFont">loadFont()</a> completes</p>\n',
type: 'Function',
optional: true
},
{
name: 'onError',
description:
'<p>function to be executed if\n an error occurs</p>\n',
type: 'Function',
optional: true
}
],
class: 'p5',
module: 'Typography'
},
text: {
name: 'text',
params: [
{
name: 'str',
description:
'<p>the alphanumeric\n symbols to be displayed</p>\n',
type: 'String|Object|Array|Number|Boolean'
},
{
name: 'x',
description: '<p>x-coordinate of text</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y-coordinate of text</p>\n',
type: 'Number'
},
{
name: 'x2',
description:
'<p>by default, the width of the text box,\n see <a href="#/p5/rectMode">rectMode()</a> for more info</p>\n',
type: 'Number',
optional: true
},
{
name: 'y2',
description:
'<p>by default, the height of the text box,\n see <a href="#/p5/rectMode">rectMode()</a> for more info</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Typography'
},
textFont: {
name: 'textFont',
class: 'p5',
module: 'Typography',
overloads: [
{
params: []
},
{
params: [
{
name: 'font',
description:
'<p>a font loaded via <a href="#/p5/loadFont">loadFont()</a>,\nor a String representing a <a href="https://mzl.la/2dOw8WD">web safe font</a>\n(a font that is generally available across all systems)</p>\n',
type: 'Object|String'
},
{
name: 'size',
description: '<p>the font size to use</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
}
]
},
append: {
name: 'append',
params: [
{
name: 'array',
description: '<p>Array to append</p>\n',
type: 'Array'
},
{
name: 'value',
description: '<p>to be added to the Array</p>\n',
type: 'Any'
}
],
class: 'p5',
module: 'Data'
},
arrayCopy: {
name: 'arrayCopy',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'src',
description: '<p>the source Array</p>\n',
type: 'Array'
},
{
name: 'srcPosition',
description: '<p>starting position in the source Array</p>\n',
type: 'Integer'
},
{
name: 'dst',
description: '<p>the destination Array</p>\n',
type: 'Array'
},
{
name: 'dstPosition',
description: '<p>starting position in the destination Array</p>\n',
type: 'Integer'
},
{
name: 'length',
description: '<p>number of Array elements to be copied</p>\n',
type: 'Integer'
}
]
},
{
params: [
{
name: 'src',
description: '',
type: 'Array'
},
{
name: 'dst',
description: '',
type: 'Array'
},
{
name: 'length',
description: '',
type: 'Integer',
optional: true
}
]
}
]
},
concat: {
name: 'concat',
params: [
{
name: 'a',
description: '<p>first Array to concatenate</p>\n',
type: 'Array'
},
{
name: 'b',
description: '<p>second Array to concatenate</p>\n',
type: 'Array'
}
],
class: 'p5',
module: 'Data'
},
reverse: {
name: 'reverse',
params: [
{
name: 'list',
description: '<p>Array to reverse</p>\n',
type: 'Array'
}
],
class: 'p5',
module: 'Data'
},
shorten: {
name: 'shorten',
params: [
{
name: 'list',
description: '<p>Array to shorten</p>\n',
type: 'Array'
}
],
class: 'p5',
module: 'Data'
},
shuffle: {
name: 'shuffle',
params: [
{
name: 'array',
description: '<p>Array to shuffle</p>\n',
type: 'Array'
},
{
name: 'bool',
description: '<p>modify passed array</p>\n',
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'Data'
},
sort: {
name: 'sort',
params: [
{
name: 'list',
description: '<p>Array to sort</p>\n',
type: 'Array'
},
{
name: 'count',
description: '<p>number of elements to sort, starting from 0</p>\n',
type: 'Integer',
optional: true
}
],
class: 'p5',
module: 'Data'
},
splice: {
name: 'splice',
params: [
{
name: 'list',
description: '<p>Array to splice into</p>\n',
type: 'Array'
},
{
name: 'value',
description: '<p>value to be spliced in</p>\n',
type: 'Any'
},
{
name: 'position',
description: '<p>in the array from which to insert data</p>\n',
type: 'Integer'
}
],
class: 'p5',
module: 'Data'
},
subset: {
name: 'subset',
params: [
{
name: 'list',
description: '<p>Array to extract from</p>\n',
type: 'Array'
},
{
name: 'start',
description: '<p>position to begin</p>\n',
type: 'Integer'
},
{
name: 'count',
description: '<p>number of values to extract</p>\n',
type: 'Integer',
optional: true
}
],
class: 'p5',
module: 'Data'
},
float: {
name: 'float',
params: [
{
name: 'str',
description: '<p>float string to parse</p>\n',
type: 'String'
}
],
class: 'p5',
module: 'Data'
},
int: {
name: 'int',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'n',
description: '<p>value to parse</p>\n',
type: 'String|Boolean|Number'
},
{
name: 'radix',
description: '<p>the radix to convert to (default: 10)</p>\n',
type: 'Integer',
optional: true
}
]
},
{
params: [
{
name: 'ns',
description: '<p>values to parse</p>\n',
type: 'Array'
}
]
}
]
},
str: {
name: 'str',
params: [
{
name: 'n',
description: '<p>value to parse</p>\n',
type: 'String|Boolean|Number|Array'
}
],
class: 'p5',
module: 'Data'
},
byte: {
name: 'byte',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'n',
description: '<p>value to parse</p>\n',
type: 'String|Boolean|Number'
}
]
},
{
params: [
{
name: 'ns',
description: '<p>values to parse</p>\n',
type: 'Array'
}
]
}
]
},
char: {
name: 'char',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'n',
description: '<p>value to parse</p>\n',
type: 'String|Number'
}
]
},
{
params: [
{
name: 'ns',
description: '<p>values to parse</p>\n',
type: 'Array'
}
]
}
]
},
unchar: {
name: 'unchar',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'n',
description: '<p>value to parse</p>\n',
type: 'String'
}
]
},
{
params: [
{
name: 'ns',
description: '<p>values to parse</p>\n',
type: 'Array'
}
]
}
]
},
hex: {
name: 'hex',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'n',
description: '<p>value to parse</p>\n',
type: 'Number'
},
{
name: 'digits',
description: '',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'ns',
description: '<p>array of values to parse</p>\n',
type: 'Number[]'
},
{
name: 'digits',
description: '',
type: 'Number',
optional: true
}
]
}
]
},
unhex: {
name: 'unhex',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'n',
description: '<p>value to parse</p>\n',
type: 'String'
}
]
},
{
params: [
{
name: 'ns',
description: '<p>values to parse</p>\n',
type: 'Array'
}
]
}
]
},
join: {
name: 'join',
params: [
{
name: 'list',
description: '<p>array of Strings to be joined</p>\n',
type: 'Array'
},
{
name: 'separator',
description: '<p>String to be placed between each item</p>\n',
type: 'String'
}
],
class: 'p5',
module: 'Data'
},
match: {
name: 'match',
params: [
{
name: 'str',
description: '<p>the String to be searched</p>\n',
type: 'String'
},
{
name: 'regexp',
description: '<p>the regexp to be used for matching</p>\n',
type: 'String'
}
],
class: 'p5',
module: 'Data'
},
matchAll: {
name: 'matchAll',
params: [
{
name: 'str',
description: '<p>the String to be searched</p>\n',
type: 'String'
},
{
name: 'regexp',
description: '<p>the regexp to be used for matching</p>\n',
type: 'String'
}
],
class: 'p5',
module: 'Data'
},
nf: {
name: 'nf',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'num',
description: '<p>the Number to format</p>\n',
type: 'Number|String'
},
{
name: 'left',
description:
'<p>number of digits to the left of the\n decimal point</p>\n',
type: 'Integer|String',
optional: true
},
{
name: 'right',
description:
'<p>number of digits to the right of the\n decimal point</p>\n',
type: 'Integer|String',
optional: true
}
]
},
{
params: [
{
name: 'nums',
description: '<p>the Numbers to format</p>\n',
type: 'Array'
},
{
name: 'left',
description: '',
type: 'Integer|String',
optional: true
},
{
name: 'right',
description: '',
type: 'Integer|String',
optional: true
}
]
}
]
},
nfc: {
name: 'nfc',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'num',
description: '<p>the Number to format</p>\n',
type: 'Number|String'
},
{
name: 'right',
description:
'<p>number of digits to the right of the\n decimal point</p>\n',
type: 'Integer|String',
optional: true
}
]
},
{
params: [
{
name: 'nums',
description: '<p>the Numbers to format</p>\n',
type: 'Array'
},
{
name: 'right',
description: '',
type: 'Integer|String',
optional: true
}
]
}
]
},
nfp: {
name: 'nfp',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'num',
description: '<p>the Number to format</p>\n',
type: 'Number'
},
{
name: 'left',
description:
'<p>number of digits to the left of the decimal\n point</p>\n',
type: 'Integer',
optional: true
},
{
name: 'right',
description:
'<p>number of digits to the right of the\n decimal point</p>\n',
type: 'Integer',
optional: true
}
]
},
{
params: [
{
name: 'nums',
description: '<p>the Numbers to format</p>\n',
type: 'Number[]'
},
{
name: 'left',
description: '',
type: 'Integer',
optional: true
},
{
name: 'right',
description: '',
type: 'Integer',
optional: true
}
]
}
]
},
nfs: {
name: 'nfs',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'num',
description: '<p>the Number to format</p>\n',
type: 'Number'
},
{
name: 'left',
description:
'<p>number of digits to the left of the decimal\n point</p>\n',
type: 'Integer',
optional: true
},
{
name: 'right',
description:
'<p>number of digits to the right of the\n decimal point</p>\n',
type: 'Integer',
optional: true
}
]
},
{
params: [
{
name: 'nums',
description: '<p>the Numbers to format</p>\n',
type: 'Array'
},
{
name: 'left',
description: '',
type: 'Integer',
optional: true
},
{
name: 'right',
description: '',
type: 'Integer',
optional: true
}
]
}
]
},
split: {
name: 'split',
params: [
{
name: 'value',
description: '<p>the String to be split</p>\n',
type: 'String'
},
{
name: 'delim',
description: '<p>the String used to separate the data</p>\n',
type: 'String'
}
],
class: 'p5',
module: 'Data'
},
splitTokens: {
name: 'splitTokens',
params: [
{
name: 'value',
description: '<p>the String to be split</p>\n',
type: 'String'
},
{
name: 'delim',
description:
'<p>list of individual Strings that will be used as\n separators</p>\n',
type: 'String',
optional: true
}
],
class: 'p5',
module: 'Data'
},
trim: {
name: 'trim',
class: 'p5',
module: 'Data',
overloads: [
{
params: [
{
name: 'str',
description: '<p>a String to be trimmed</p>\n',
type: 'String'
}
]
},
{
params: [
{
name: 'strs',
description: '<p>an Array of Strings to be trimmed</p>\n',
type: 'Array'
}
]
}
]
},
day: {
name: 'day',
class: 'p5',
module: 'IO'
},
hour: {
name: 'hour',
class: 'p5',
module: 'IO'
},
minute: {
name: 'minute',
class: 'p5',
module: 'IO'
},
millis: {
name: 'millis',
class: 'p5',
module: 'IO'
},
month: {
name: 'month',
class: 'p5',
module: 'IO'
},
second: {
name: 'second',
class: 'p5',
module: 'IO'
},
year: {
name: 'year',
class: 'p5',
module: 'IO'
},
plane: {
name: 'plane',
params: [
{
name: 'width',
description: '<p>width of the plane</p>\n',
type: 'Number',
optional: true
},
{
name: 'height',
description: '<p>height of the plane</p>\n',
type: 'Number',
optional: true
},
{
name: 'detailX',
description:
'<p>Optional number of triangle\n subdivisions in x-dimension</p>\n',
type: 'Integer',
optional: true
},
{
name: 'detailY',
description:
'<p>Optional number of triangle\n subdivisions in y-dimension</p>\n',
type: 'Integer',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
box: {
name: 'box',
params: [
{
name: 'width',
description: '<p>width of the box</p>\n',
type: 'Number',
optional: true
},
{
name: 'Height',
description: '<p>height of the box</p>\n',
type: 'Number',
optional: true
},
{
name: 'depth',
description: '<p>depth of the box</p>\n',
type: 'Number',
optional: true
},
{
name: 'detailX',
description:
'<p>Optional number of triangle\n subdivisions in x-dimension</p>\n',
type: 'Integer',
optional: true
},
{
name: 'detailY',
description:
'<p>Optional number of triangle\n subdivisions in y-dimension</p>\n',
type: 'Integer',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
sphere: {
name: 'sphere',
params: [
{
name: 'radius',
description: '<p>radius of circle</p>\n',
type: 'Number',
optional: true
},
{
name: 'detailX',
description: '<p>optional number of subdivisions in x-dimension</p>\n',
type: 'Integer',
optional: true
},
{
name: 'detailY',
description: '<p>optional number of subdivisions in y-dimension</p>\n',
type: 'Integer',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
cylinder: {
name: 'cylinder',
params: [
{
name: 'radius',
description: '<p>radius of the surface</p>\n',
type: 'Number',
optional: true
},
{
name: 'height',
description: '<p>height of the cylinder</p>\n',
type: 'Number',
optional: true
},
{
name: 'detailX',
description:
'<p>number of subdivisions in x-dimension;\n default is 24</p>\n',
type: 'Integer',
optional: true
},
{
name: 'detailY',
description:
'<p>number of subdivisions in y-dimension;\n default is 1</p>\n',
type: 'Integer',
optional: true
},
{
name: 'bottomCap',
description: '<p>whether to draw the bottom of the cylinder</p>\n',
type: 'Boolean',
optional: true
},
{
name: 'topCap',
description: '<p>whether to draw the top of the cylinder</p>\n',
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
cone: {
name: 'cone',
params: [
{
name: 'radius',
description: '<p>radius of the bottom surface</p>\n',
type: 'Number',
optional: true
},
{
name: 'height',
description: '<p>height of the cone</p>\n',
type: 'Number',
optional: true
},
{
name: 'detailX',
description:
'<p>number of segments,\n the more segments the smoother geometry\n default is 24</p>\n',
type: 'Integer',
optional: true
},
{
name: 'detailY',
description:
'<p>number of segments,\n the more segments the smoother geometry\n default is 1</p>\n',
type: 'Integer',
optional: true
},
{
name: 'cap',
description: '<p>whether to draw the base of the cone</p>\n',
type: 'Boolean',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
ellipsoid: {
name: 'ellipsoid',
params: [
{
name: 'radiusx',
description: '<p>x-radius of ellipsoid</p>\n',
type: 'Number',
optional: true
},
{
name: 'radiusy',
description: '<p>y-radius of ellipsoid</p>\n',
type: 'Number',
optional: true
},
{
name: 'radiusz',
description: '<p>z-radius of ellipsoid</p>\n',
type: 'Number',
optional: true
},
{
name: 'detailX',
description:
'<p>number of segments,\n the more segments the smoother geometry\n default is 24. Avoid detail number above\n 150, it may crash the browser.</p>\n',
type: 'Integer',
optional: true
},
{
name: 'detailY',
description:
'<p>number of segments,\n the more segments the smoother geometry\n default is 16. Avoid detail number above\n 150, it may crash the browser.</p>\n',
type: 'Integer',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
torus: {
name: 'torus',
params: [
{
name: 'radius',
description: '<p>radius of the whole ring</p>\n',
type: 'Number',
optional: true
},
{
name: 'tubeRadius',
description: '<p>radius of the tube</p>\n',
type: 'Number',
optional: true
},
{
name: 'detailX',
description:
'<p>number of segments in x-dimension,\n the more segments the smoother geometry\n default is 24</p>\n',
type: 'Integer',
optional: true
},
{
name: 'detailY',
description:
'<p>number of segments in y-dimension,\n the more segments the smoother geometry\n default is 16</p>\n',
type: 'Integer',
optional: true
}
],
class: 'p5',
module: 'Shape'
},
orbitControl: {
name: 'orbitControl',
params: [
{
name: 'sensitivityX',
description: '<p>sensitivity to mouse movement along X axis</p>\n',
type: 'Number',
optional: true
},
{
name: 'sensitivityY',
description: '<p>sensitivity to mouse movement along Y axis</p>\n',
type: 'Number',
optional: true
},
{
name: 'sensitivityZ',
description: '<p>sensitivity to scroll movement along Z axis</p>\n',
type: 'Number',
optional: true
}
],
class: 'p5',
module: 'Lights, Camera'
},
debugMode: {
name: 'debugMode',
class: 'p5',
module: 'Lights, Camera',
overloads: [
{
params: []
},
{
params: [
{
name: 'mode',
description: '<p>either GRID or AXES</p>\n',
type: 'Constant'
}
]
},
{
params: [
{
name: 'mode',
description: '',
type: 'Constant'
},
{
name: 'gridSize',
description: '<p>size of one side of the grid</p>\n',
type: 'Number',
optional: true
},
{
name: 'gridDivisions',
description: '<p>number of divisions in the grid</p>\n',
type: 'Number',
optional: true
},
{
name: 'xOff',
description: '<p>X axis offset from origin (0,0,0)</p>\n',
type: 'Number',
optional: true
},
{
name: 'yOff',
description: '<p>Y axis offset from origin (0,0,0)</p>\n',
type: 'Number',
optional: true
},
{
name: 'zOff',
description: '<p>Z axis offset from origin (0,0,0)</p>\n',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'mode',
description: '',
type: 'Constant'
},
{
name: 'axesSize',
description: '<p>size of axes icon</p>\n',
type: 'Number',
optional: true
},
{
name: 'xOff',
description: '',
type: 'Number',
optional: true
},
{
name: 'yOff',
description: '',
type: 'Number',
optional: true
},
{
name: 'zOff',
description: '',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'gridSize',
description: '',
type: 'Number',
optional: true
},
{
name: 'gridDivisions',
description: '',
type: 'Number',
optional: true
},
{
name: 'gridXOff',
description: '',
type: 'Number',
optional: true
},
{
name: 'gridYOff',
description: '',
type: 'Number',
optional: true
},
{
name: 'gridZOff',
description: '',
type: 'Number',
optional: true
},
{
name: 'axesSize',
description: '',
type: 'Number',
optional: true
},
{
name: 'axesXOff',
description: '',
type: 'Number',
optional: true
},
{
name: 'axesYOff',
description: '',
type: 'Number',
optional: true
},
{
name: 'axesZOff',
description: '',
type: 'Number',
optional: true
}
]
}
]
},
noDebugMode: {
name: 'noDebugMode',
class: 'p5',
module: 'Lights, Camera'
},
ambientLight: {
name: 'ambientLight',
class: 'p5',
module: 'Lights, Camera',
overloads: [
{
params: [
{
name: 'v1',
description:
'<p>red or hue value relative to\n the current color range</p>\n',
type: 'Number'
},
{
name: 'v2',
description:
'<p>green or saturation value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'v3',
description:
'<p>blue or brightness value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'alpha',
description: '<p>the alpha value</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'value',
description: '<p>a color string</p>\n',
type: 'String'
}
],
chainable: 1
},
{
params: [
{
name: 'gray',
description: '<p>a gray value</p>\n',
type: 'Number'
},
{
name: 'alpha',
description: '',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'values',
description:
'<p>an array containing the red,green,blue &\n and alpha components of the color</p>\n',
type: 'Number[]'
}
],
chainable: 1
},
{
params: [
{
name: 'color',
description: '<p>the ambient light color</p>\n',
type: 'p5.Color'
}
],
chainable: 1
}
]
},
specularColor: {
name: 'specularColor',
class: 'p5',
module: 'Lights, Camera',
overloads: [
{
params: [
{
name: 'v1',
description:
'<p>red or hue value relative to\n the current color range</p>\n',
type: 'Number'
},
{
name: 'v2',
description:
'<p>green or saturation value\n relative to the current color range</p>\n',
type: 'Number'
},
{
name: 'v3',
description:
'<p>blue or brightness value\n relative to the current color range</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'value',
description: '<p>a color string</p>\n',
type: 'String'
}
],
chainable: 1
},
{
params: [
{
name: 'gray',
description: '<p>a gray value</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'values',
description:
'<p>an array containing the red,green,blue &\n and alpha components of the color</p>\n',
type: 'Number[]'
}
],
chainable: 1
},
{
params: [
{
name: 'color',
description: '<p>the ambient light color</p>\n',
type: 'p5.Color'
}
],
chainable: 1
}
]
},
directionalLight: {
name: 'directionalLight',
class: 'p5',
module: 'Lights, Camera',
overloads: [
{
params: [
{
name: 'v1',
description:
'<p>red or hue value (depending on the current\ncolor mode),</p>\n',
type: 'Number'
},
{
name: 'v2',
description: '<p>green or saturation value</p>\n',
type: 'Number'
},
{
name: 'v3',
description: '<p>blue or brightness value</p>\n',
type: 'Number'
},
{
name: 'position',
description: '<p>the direction of the light</p>\n',
type: 'p5.Vector'
}
],
chainable: 1
},
{
params: [
{
name: 'color',
description:
'<p>color Array, CSS color string,\n or <a href="#/p5.Color">p5.Color</a> value</p>\n',
type: 'Number[]|String|p5.Color'
},
{
name: 'x',
description: '<p>x axis direction</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y axis direction</p>\n',
type: 'Number'
},
{
name: 'z',
description: '<p>z axis direction</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'color',
description: '',
type: 'Number[]|String|p5.Color'
},
{
name: 'position',
description: '',
type: 'p5.Vector'
}
],
chainable: 1
},
{
params: [
{
name: 'v1',
description: '',
type: 'Number'
},
{
name: 'v2',
description: '',
type: 'Number'
},
{
name: 'v3',
description: '',
type: 'Number'
},
{
name: 'x',
description: '',
type: 'Number'
},
{
name: 'y',
description: '',
type: 'Number'
},
{
name: 'z',
description: '',
type: 'Number'
}
],
chainable: 1
}
]
},
pointLight: {
name: 'pointLight',
class: 'p5',
module: 'Lights, Camera',
overloads: [
{
params: [
{
name: 'v1',
description:
'<p>red or hue value (depending on the current\ncolor mode),</p>\n',
type: 'Number'
},
{
name: 'v2',
description: '<p>green or saturation value</p>\n',
type: 'Number'
},
{
name: 'v3',
description: '<p>blue or brightness value</p>\n',
type: 'Number'
},
{
name: 'x',
description: '<p>x axis position</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y axis position</p>\n',
type: 'Number'
},
{
name: 'z',
description: '<p>z axis position</p>\n',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'v1',
description: '',
type: 'Number'
},
{
name: 'v2',
description: '',
type: 'Number'
},
{
name: 'v3',
description: '',
type: 'Number'
},
{
name: 'position',
description: '<p>the position of the light</p>\n',
type: 'p5.Vector'
}
],
chainable: 1
},
{
params: [
{
name: 'color',
description:
'<p>color Array, CSS color string,\nor <a href="#/p5.Color">p5.Color</a> value</p>\n',
type: 'Number[]|String|p5.Color'
},
{
name: 'x',
description: '',
type: 'Number'
},
{
name: 'y',
description: '',
type: 'Number'
},
{
name: 'z',
description: '',
type: 'Number'
}
],
chainable: 1
},
{
params: [
{
name: 'color',
description: '',
type: 'Number[]|String|p5.Color'
},
{
name: 'position',
description: '',
type: 'p5.Vector'
}
],
chainable: 1
}
]
},
lights: {
name: 'lights',
class: 'p5',
module: 'Lights, Camera'
},
lightFalloff: {
name: 'lightFalloff',
params: [
{
name: 'constant',
description: '<p>constant value for determining falloff</p>\n',
type: 'Number'
},
{
name: 'linear',
description: '<p>linear value for determining falloff</p>\n',
type: 'Number'
},
{
name: 'quadratic',
description: '<p>quadratic value for determining falloff</p>\n',
type: 'Number'
}
],
class: 'p5',
module: 'Lights, Camera'
},
spotLight: {
name: 'spotLight',
class: 'p5',
module: 'Lights, Camera',
overloads: [
{
params: [
{
name: 'v1',
description:
'<p>red or hue value (depending on the current\ncolor mode),</p>\n',
type: 'Number'
},
{
name: 'v2',
description: '<p>green or saturation value</p>\n',
type: 'Number'
},
{
name: 'v3',
description: '<p>blue or brightness value</p>\n',
type: 'Number'
},
{
name: 'x',
description: '<p>x axis position</p>\n',
type: 'Number'
},
{
name: 'y',
description: '<p>y axis position</p>\n',
type: 'Number'
},
{
name: 'z',
description: '<p>z axis position</p>\n',
type: 'Number'
},
{
name: 'rx',
description: '<p>x axis direction of light</p>\n',
type: 'Number'
},
{
name: 'ry',
description: '<p>y axis direction of light</p>\n',
type: 'Number'
},
{
name: 'rz',
description: '<p>z axis direction of light</p>\n',
type: 'Number'
},
{
name: 'angle',
description:
'<p>optional parameter for angle. Defaults to PI/3</p>\n',
type: 'Number',
optional: true
},
{
name: 'conc',
description:
'<p>optional parameter for concentration. Defaults to 100</p>\n',
type: 'Number',
optional: true
}
],
chainable: 1
},
{
params: [
{
name: 'color',
description:
'<p>color Array, CSS color string,\nor <a href="#/p5.Color">p5.Color</a> value</p>\n',
type: 'Number[]|String|p5.Color'
},
{
name: 'position',
description: '<p>the position of the light</p>\n',
type: 'p5.Vector'
},
{
name: 'direction',
description: '<p>the direction of the light</p>\n',
type: 'p5.Vector'
},
{
name: 'angle',
description: '',
type: 'Number',
optional: true
},
{
name: 'conc',
description: '',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'v1',
description: '',
type: 'Number'
},
{
name: 'v2',
description: '',
type: 'Number'
},
{
name: 'v3',
description: '',
type: 'Number'
},
{
name: 'position',
description: '',
type: 'p5.Vector'
},
{
name: 'direction',
description: '',
type: 'p5.Vector'
},
{
name: 'angle',
description: '',
type: 'Number',
optional: true
},
{
name: 'conc',
description: '',
type: 'Number',
optional: true
}
]
},
{
params: [
{
name: 'color',
description: '',
type: 'Number[]|String|p5.Color'
},
{
name: 'x',
description: '',
type: 'Number'
},
View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment