-
Notifications
You must be signed in to change notification settings - Fork 0
/
celebrity-editor.html
144 lines (144 loc) · 7.91 KB
/
celebrity-editor.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
<!DOCTYPE html>
<html>
<head>
<title>Celebrity Face Editor</title>
<link rel="shortcut icon" type="image/x-icon" href="favicon.ico">
<style>
body {background-color: #222; position: relative; left: 10px; width: 90vw; height: 90vh; overflow: hidden;}
a, h1, p, span {color: #fff; font-family: verdana;}
input {width: 1355px; font-size: 120%; font-family: consolas;}
canvas {display: block; margin: 8px 0px;}
.pca {width: 150px;}
span {padding: 0px 54px; display: inline-block; position: relative; left: 1px;}
button {font-size: 150%; padding: 0px 15px; margin: 8px 0px; position: relative; top: 8px;}
#myCanvas {position: relative; left: 340px; bottom: 520px;}
.dd {left: -3px;}
.dd2 {left: -13px;}
#invert {padding: 0px 123px;}
</style>
</head>
<body>
<h1>Celebrity Face Editor</h1>
<p>Based on carykh's celebrity face editor.</p>
<p>Why did I make this? It's too difficult to download the real thing, so I made my own version.</p>
<span>PCA 1</span><span>PCA 2</span>
<br>
<input type="range" id="pca1" class="pca" title="Lighting">
<input type="range" id="pca2" class="pca" title="Skin tone">
<br>
<span>PCA 3</span><span>PCA 4</span>
<br>
<input type="range" id="pca3" class="pca" title="Horizontal shading">
<input type="range" id="pca4" class="pca" title="Horiz shading again">
<br>
<span>PCA 5</span><span>PCA 6</span>
<br>
<input type="range" id="pca5" class="pca" title="Vertical shading">
<input type="range" id="pca6" class="pca" title="Temperature">
<br>
<span>PCA 7</span><span>PCA 8</span>
<br>
<input type="range" id="pca7" class="pca" title="Horiz shading again">
<input type="range" id="pca8" class="pca" title="Ambient occlusion">
<br>
<span>PCA 9</span><span class="dd">PCA 10</span>
<br>
<input type="range" id="pca9" class="pca" title="Perimeter shading">
<input type="range" id="pca10" class="pca" title="Eyebrow height">
<br>
<span class="dd">PCA 11</span><span class="dd2">PCA 12</span>
<br>
<input type="range" id="pca11" class="pca" title="Horiz shading again">
<input type="range" id="pca12" class="pca" title="Makeup">
<br>
<span class="dd">PCA 13</span><span class="dd2">PCA 14</span>
<br>
<input type="range" id="pca13" class="pca" title="Horiz shading again">
<input type="range" id="pca14" class="pca" title="Head width">
<br>
<span class="dd">PCA 15</span><span class="dd2">PCA 16</span>
<br>
<input type="range" id="pca15" class="pca" title="Smile">
<input type="range" id="pca16" class="pca" title="Vertical rotation">
<br>
<button onclick=randomize()>Randomize</button>
<button onclick=gotomean()>Go To Mean</button>
<br>
<button id="invert" onclick="invert()">Invert</button>
<canvas id="myCanvas" width="512" height="512"></canvas>
<script>
let c = document.getElementById("myCanvas");
let ctx = c.getContext("2d");
setInterval(function() {
let brightness = 50 - Number(pca1.value);
let skin = Number(pca2.value) - 50;
let horizontal = (Number(pca3.value) - 50) - (Number(pca4.value) - 50) + (Number(pca7.value) - 50) / 1.5 + (Number(pca11.value) - 50) / 3 - (Number(pca13.value) - 50) / 3;
let vertical = 50 - Number(pca5.value) + (50 - Number(pca16.value)) / 2;
let temperature = Number(pca6.value) - 50;
let occlusion = Number(pca8.value) - 50;
let perimeter = Number(pca9.value) - 50;
let browHeight = Number(pca10.value) - 50;
let makeup = 50 - Number(pca12.value);
let headWidth = Number(pca14.value) - 50;
ctx.clearRect(0, 0, c.width, c.height);
ctx.fillStyle = "hsl(" + (temperature > 0 ? 20 : 200) + ", " + Math.abs(temperature) + "%, " + (50 + brightness - skin / 2 + (Number(pca3.value) - 50) / 2.5 + (Number(pca4.value) - 50) / 2 - perimeter / 8) + "%)";
ctx.fillRect(0, 0, 512, 512);
ctx.fillStyle = "hsl(25, " + (50 + Math.abs(skin / 2) + temperature / 2) + "%, " + (50 + brightness / 4 + skin / 2) + "%)";
ctx.beginPath();
ctx.arc(256, 256, 224 + headWidth / 4, 0, 2 * Math.PI);
ctx.fill();
ctx.fillRect(160 - horizontal / 3, 256, 192, 256);
ctx.fillStyle = "hsl(25, " + (50 + Math.abs(skin / 2) + temperature / 2) + "%, " + (45 + occlusion / 10 + brightness / 4 + skin / 2) + "%)";
ctx.beginPath();
ctx.arc(160 + horizontal / 3 + perimeter / 8, 240 + vertical / 3, 48, 0, 2 * Math.PI);
ctx.arc(352 + horizontal / 3 - perimeter / 8, 240 + vertical / 3, 48, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle = "#fff";
ctx.beginPath();
ctx.arc(160 + horizontal / 3 + perimeter / 8, 224 + vertical / 3, 48, 0, 2 * Math.PI);
ctx.arc(352 + horizontal / 3 - perimeter / 8, 224 + vertical / 3, 48, 0, 2 * Math.PI);
ctx.fill();
ctx.fillStyle = "#000";
ctx.beginPath();
ctx.arc(160 + horizontal / 6 + perimeter / 8, 224 + vertical / 6, 8, 0, 2 * Math.PI);
ctx.arc(352 + horizontal / 6 - perimeter / 8, 224 + vertical / 6, 8, 0, 2 * Math.PI);
ctx.fill();
ctx.strokeStyle = "#000";
ctx.lineWidth = 6 + makeup / 20;
ctx.beginPath();
ctx.arc(160 + horizontal / 3 + perimeter / 8, 200 + vertical / 3 - browHeight / 4, 64, 1.25 * Math.PI, 1.75 * Math.PI);
ctx.stroke();
ctx.beginPath();
ctx.arc(352 + horizontal / 3 - perimeter / 8, 200 + vertical / 3 - browHeight / 4, 64, 1.25 * Math.PI, 1.75 * Math.PI);
ctx.stroke();
let smileHorizontal = (50 - Number(pca3.value)) / 8 + (50 - Number(pca4.value)) / 6 + (50 - Number(pca15.value)) / 3;
ctx.strokeStyle = "hsl(25, " + (50 + Math.abs(skin / 2) + temperature / 2) + "%, " + (45 + occlusion / 10 + brightness / 4 + skin / 2) + "%)";
ctx.beginPath();
ctx.moveTo(192 + horizontal / 3, 358 - smileHorizontal / 2 + vertical / 3 + makeup / 20);
ctx.quadraticCurveTo(256 + horizontal / 3, 390 + smileHorizontal + vertical / 3 + makeup / 20, 320 + horizontal / 3, 358 - smileHorizontal / 2 + vertical / 3 + makeup / 20);
ctx.stroke();
ctx.strokeStyle = "hsl(350, " + (50 + Math.abs(skin / 2) + temperature / 2) + "%, " + (45 + occlusion / 10 + brightness / 4 + skin / 2) + "%)";
ctx.beginPath();
ctx.moveTo(192 + horizontal / 3, 352 - smileHorizontal / 2 + vertical / 3);
ctx.quadraticCurveTo(256 + horizontal / 3, 384 + smileHorizontal + vertical / 3, 320 + horizontal / 3, 352 - smileHorizontal / 2 + vertical / 3);
ctx.stroke();
});
function randomize() {
for (i = 1; i <= 16; i++) {
random = ((Math.random() - 0.5) * Math.cbrt(400)) ** 3 + 50;
document.getElementById("pca" + i).value = random;
}
}
function gotomean() {
for (i = 1; i <= 16; i++) {
document.getElementById("pca" + i).value = 50;
}
}
function invert() {
for (i = 1; i <= 16; i++) {
document.getElementById("pca" + i).value = 100 - document.getElementById("pca" + i).value;
}
}
</script>
</body>
</html>