blob: 2078396bad0ac0ab516841ac8f5a980aa4c0c996 [file] [log] [blame]
caryclark@google.com752b60e2012-03-22 21:11:17 +00001<html>
2<head>
3<div style="height:0">
4<div id="test_1div">
5path.moveTo(213.673737, 413.292938);
6path.lineTo(225.200134, 343.616821);
7path.lineTo(236.726532, 273.940704);
8path.lineTo(219.386414, 231.373322);
9path.lineTo(213.673737, 413.292938);
10path.close();
11path.moveTo(43.485352, 308.984497);
12path.lineTo(122.610657, 305.950134);
13path.lineTo(201.735962, 302.915802);
14path.lineTo(280.861267, 299.881470);
15path.lineTo(43.485352, 308.984497);
16path.close();
17</div>
caryclark@google.comd88e0892012-03-27 13:23:51 +000018<div id="test_2div">
19path.moveTo(-177.878387, 265.368988);
20path.lineTo(-254.415771, 303.709961);
21path.lineTo(-317.465363, 271.325562);
22path.lineTo(-374.520386, 207.507660);
23path.lineTo(-177.878387, 265.368988);
24path.close();
25path.moveTo(-63.582489, -3.679123);
26path.lineTo(-134.496841, 26.434566);
27path.lineTo(-205.411209, 56.548256);
28path.lineTo(-276.325562, 86.661942);
29path.lineTo(-63.582489, -3.679123);
30path.close();
31path.moveTo(-57.078423, 162.633453);
32path.lineTo(-95.963928, 106.261139);
33path.lineTo(-134.849457, 49.888824);
34path.lineTo(-173.734955, -6.483480);
35path.lineTo(-57.078423, 162.633453);
36path.close();
37</div>
38<div id="test_3div">
39path.moveTo(98.666489, -94.295059);
40path.lineTo(156.584320, -61.939133);
41path.lineTo(174.672974, -12.343765);
42path.lineTo(158.622345, 52.028267);
43path.lineTo(98.666489, -94.295059);
44path.close();
45path.moveTo(-133.225616, -48.622055);
46path.lineTo(-73.855499, -10.375397);
47path.lineTo(-14.485367, 27.871277);
48path.lineTo(44.884750, 66.117935);
49path.lineTo(-133.225616, -48.622055);
50path.close();
51path.moveTo( 9.030045, -163.413132);
52path.lineTo(-19.605331, -89.588760);
53path.lineTo(-48.240707, -15.764404);
54path.lineTo(-76.876053, 58.059944);
55path.lineTo( 9.030045, -163.413132);
56path.close();
57</div>
58<div id="test_4div">
caryclark@google.coma5764232012-03-28 16:20:21 +000059path.moveTo(340.41568, -170.97171);
60path.lineTo(418.846893, -142.428329);
61path.lineTo(497.278107, -113.884933);
62path.lineTo(449.18222, -45.6723022);
63path.lineTo(340.41568, -170.97171);
caryclark@google.comd88e0892012-03-27 13:23:51 +000064path.close();
caryclark@google.coma5764232012-03-28 16:20:21 +000065path.moveTo(326.610535, 34.0393639);
66path.lineTo(371.334595, -14.9620667);
67path.lineTo(416.058624, -63.9634857);
68path.lineTo(460.782654, -112.96492);
69path.lineTo(326.610535, 34.0393639);
caryclark@google.comd88e0892012-03-27 13:23:51 +000070path.close();
71</div>
caryclark@google.comfb173422012-04-10 18:28:55 +000072<div id="test_5div">
73original:
74path.moveTo(0, 0);
75path.quadTo(20, 0, 20, 20);
76path.lineTo(0, 0);
77path.close();
78path.moveTo(0, 20);
79path.quadTo(0, 0, 20, 0);
80path.lineTo(0, 20);
81path.close();
82simplified:
83path.moveTo(0, 0);
84path.lineTo(5, 5);
85path.quadTo(0, 10, 0, 20);
86path.lineTo(20, 20);
87path.quadTo(20, 10, 15, 5);
88path.lineTo(20, 0);
89path.quadTo(14.1421356, 0, 10, 1.71572876);
90path.quadTo(5.85786438, 0, 0, 0);
91path.close();
92</div>
93<div id="test_6div">
94original:
95path.moveTo(0, 20);
96path.quadTo(20, 0, 40, 20);
97path.lineTo(0, 20);
98path.close();
99path.moveTo(40, 10);
100path.quadTo(20, 30, 0, 10);
101path.lineTo(40, 10);
102path.close();
103simplified:
104path.moveTo(0, 10);
105path.quadTo(2.92893219, 12.9289322, 5.85786438, 15);
106path.quadTo(2.92893219, 17.0710678, 0, 20);
107path.lineTo(40, 20);
108path.quadTo(37.0710678, 17.0710678, 34.1421356, 15);
109path.quadTo(37.0710678, 12.9289322, 40, 10);
110path.lineTo(0, 10);
111path.close();
112</div>
113
caryclark@google.com752b60e2012-03-22 21:11:17 +0000114</div>
115
116<script type="text/javascript">
117
118var testDivs = [
caryclark@google.comfb173422012-04-10 18:28:55 +0000119 test_5div,
120 test_6div,
caryclark@google.comd88e0892012-03-27 13:23:51 +0000121 test_4div,
122 test_3div,
123 test_2div,
caryclark@google.com752b60e2012-03-22 21:11:17 +0000124 test_1div,
125];
126
127var scale, columns, rows, xStart, yStart;
128
129var ticks = 0.1;
130var at_x = 13 + 0.5;
131var at_y = 13 + 0.5;
132
133var tests = [];
134var testIndex = 0;
135
136var ctx;
137
138function parse(test) {
139 var contours = [];
140 var contourStrs = test.split("path.close();");
caryclark@google.comd88e0892012-03-27 13:23:51 +0000141 var pattern = /-?\d+\.*\d*/g;
caryclark@google.com752b60e2012-03-22 21:11:17 +0000142 for (var c in contourStrs) {
caryclark@google.comfb173422012-04-10 18:28:55 +0000143 var contour = contourStrs[c];
144 var verbStrs = contour.split("path");
145 var verbs = [];
146 for (var v in verbStrs) {
147 var verbStr = verbStrs[v];
148 var points = verbStr.match(pattern);
149 var pts = [];
150 for (var wd in points) {
151 var num = parseFloat(points[wd]);
152 if (isNaN(num)) continue;
153 pts.push(num);
154 }
155 if (pts.length > 0)
156 verbs.push(pts);
caryclark@google.com752b60e2012-03-22 21:11:17 +0000157 }
caryclark@google.comfb173422012-04-10 18:28:55 +0000158 if (verbs.length > 0)
159 contours.push(verbs);
caryclark@google.com752b60e2012-03-22 21:11:17 +0000160 }
caryclark@google.comfb173422012-04-10 18:28:55 +0000161 if (contours.length > 0)
162 tests.push(contours);
caryclark@google.com752b60e2012-03-22 21:11:17 +0000163}
164
165function init(test) {
166 var canvas = document.getElementById('canvas');
167 if (!canvas.getContext) return;
168 ctx = canvas.getContext('2d');
169 var xmin = Infinity;
170 var xmax = -Infinity;
171 var ymin = Infinity;
172 var ymax = -Infinity;
caryclark@google.comfb173422012-04-10 18:28:55 +0000173 for (var contours in test) {
174 var contour = test[contours];
175 for (var verbs in contour) {
176 var verb = contour[verbs];
177 var last = verb.length;
178 xmin = Math.min(xmin, verb[0]);
179 ymin = Math.min(ymin, verb[1]);
180 xmax = Math.max(xmax, verb[last - 2]);
181 ymax = Math.max(ymax, verb[last - 1]);
caryclark@google.com752b60e2012-03-22 21:11:17 +0000182 }
183 }
184 var subscale = 1;
185 while ((xmax - xmin) * subscale < 0.1 && (ymax - ymin) * subscale < 0.1) {
186 subscale *= 10;
187 }
188 columns = Math.ceil(xmax) - Math.floor(xmin) + 1;
189 rows = Math.ceil(ymax) - Math.floor(ymin) + 1;
190 xStart = Math.floor(xmin);
191 yStart = Math.floor(ymin);
192 var hscale = ctx.canvas.width / columns / ticks;
193 var vscale = ctx.canvas.height / rows / ticks;
194 scale = Math.floor(Math.min(hscale, vscale)) * subscale;
195}
196
197function drawPoint(px, py, xoffset, yoffset, unit) {
caryclark@google.comd88e0892012-03-27 13:23:51 +0000198 var label = px.toFixed(3) + ", " + py.toFixed(3);
caryclark@google.com752b60e2012-03-22 21:11:17 +0000199 var _px = px * unit + xoffset;
200 var _py = py * unit + yoffset;
201 ctx.beginPath();
202 ctx.arc(_px, _py, 3, 0, Math.PI*2, true);
203 ctx.closePath();
204 ctx.fill();
205 ctx.fillText(label, _px + 5, _py);
206}
207
208function draw(test, _at_x, _at_y, scale) {
209 var unit = scale * ticks;
210 ctx.lineWidth = 1;
211 var i;
212 for (i = 0; i <= rows * ticks; ++i) {
213 ctx.strokeStyle = (i % ticks) != 0 ? "rgb(160,160,160)" : "black";
214 ctx.beginPath();
215 ctx.moveTo(_at_x + 0, _at_y + i * scale);
216 ctx.lineTo(_at_x + unit * columns, _at_y + i * scale);
217 ctx.stroke();
218 }
219 for (i = 0; i <= columns * ticks; ++i) {
220 ctx.strokeStyle = (i % ticks) != 0 ? "rgb(160,160,160)" : "black";
221 ctx.beginPath();
222 ctx.moveTo(_at_x + i * scale, _at_y + 0);
223 ctx.lineTo(_at_x + i * scale, _at_y + unit * rows);
224 ctx.stroke();
225 }
226
227 var xoffset = xStart * -unit + _at_x;
228 var yoffset = yStart * -unit + _at_y;
229
230 ctx.fillStyle = "rgb(40,80,60)"
231 for (i = 0; i <= columns; i += (1 / ticks))
232 {
233 num = (xoffset - _at_x) / -unit + i;
234 ctx.fillText(num.toFixed(0), i * unit + _at_y - 5, 10);
235 }
236 for (i = 0; i <= rows; i += (1 / ticks))
237 {
238 num = (yoffset - _at_x) / -unit + i;
239 ctx.fillText(num.toFixed(0), 0, i * unit + _at_y + 0);
240 }
241 ctx.strokeStyle = "red";
caryclark@google.comfb173422012-04-10 18:28:55 +0000242 var contours, verbs, pts;
243 for (contours in test) {
244 var contour = test[contours];
245 if (contours == 2) ctx.strokeStyle = "blue";
caryclark@google.com752b60e2012-03-22 21:11:17 +0000246 ctx.beginPath();
caryclark@google.comfb173422012-04-10 18:28:55 +0000247 var first = true;
248 for (verbs in contour) {
249 var verb = contour[verbs];
250 switch (verb.length) {
251 case 2:
252 if (first) {
253 ctx.moveTo(xoffset + verb[0] * unit, yoffset + verb[1] * unit);
254 first = false;
255 } else
256 ctx.lineTo(xoffset + verb[0] * unit, yoffset + verb[1] * unit);
257 break;
258 case 4:
259 ctx.quadraticCurveTo(xoffset + verb[0] * unit, yoffset + verb[1] * unit,
260 xoffset + verb[2] * unit, yoffset + verb[3] * unit);
261 break;
262 case 6:
263 ctx.bezierCurveTo(xoffset + verb[0] * unit, yoffset + verb[1] * unit,
264 xoffset + verb[2] * unit, yoffset + verb[3] * unit,
265 xoffset + verb[4] * unit, yoffset + verb[5] * unit);
266 break;
267 }
caryclark@google.com752b60e2012-03-22 21:11:17 +0000268 }
269 ctx.stroke();
270 }
271
272 ctx.fillStyle="blue";
caryclark@google.comfb173422012-04-10 18:28:55 +0000273 for (contours in test) {
274 var contour = test[contours];
275 for (verbs in contour) {
276 var verb = contour[verbs];
277 for (i = 0; i < verb.length; i += 2) {
278 x = verb[i];
279 y = verb[i + 1];
280 drawPoint(x, y, xoffset, yoffset, unit);
281 }
caryclark@google.com752b60e2012-03-22 21:11:17 +0000282 }
283 }
284}
285
286var mouseX = Infinity, mouseY;
287
288function calcXY() {
289 var e = window.event;
290 var tgt = e.target || e.srcElement;
291 var left = tgt.offsetLeft;
292 var top = tgt.offsetTop;
293 var unit = scale * ticks;
294 mouseX = (e.clientX - left - Math.ceil(at_x) + 1) / unit + xStart;
295 mouseY = (e.clientY - top - Math.ceil(at_y)) / unit + yStart;
296}
297
298function handleMouseOver() {
299 calcXY();
300 var num = mouseX.toFixed(3) + ", " + mouseY.toFixed(3);
301 ctx.beginPath();
302 ctx.rect(300,100,200,10);
303 ctx.fillStyle="white";
304 ctx.fill();
305 ctx.fillStyle="black";
306 ctx.fillText(num, 300, 108);
307}
308
309function handleMouseClick() {
310 calcXY();
311// drawInset();
312}
313
314function drawTop() {
315 init(tests[testIndex]);
316 redraw();
317}
318
319function redraw() {
320 ctx.beginPath();
321 ctx.rect(0, 0, ctx.canvas.width, ctx.canvas.height);
322 ctx.fillStyle="white";
323 ctx.fill();
324 draw(tests[testIndex], at_x, at_y, scale);
325// if (insetScale != scale && mouseX != Infinity)
326// drawInset();
327}
328
329function doKeyPress(evt) {
330 var char = String.fromCharCode(evt.charCode);
331 switch (char) {
332 case 'N':
333 case 'n':
334 if (++testIndex >= tests.length)
335 testIndex = 0;
336 // insetScale = scale;
337 mouseX = Infinity;
338 drawTop();
339 break;
340 case 'T':
341 case 't':
342 // drawTs(testIndex);
343 break;
344 case '-':
345 // if (--insetScale < 1)
346 // insetScale = 1;
347 // else
348 redraw();
349 break;
350 case '=':
351 case '+':
352 // ++insetScale;
353 redraw();
354 break;
355 }
356}
357
358function start() {
359 for (i = 0; i < testDivs.length; ++i) {
360 var str = testDivs[i].firstChild.data;
361 parse(str);
362 }
363 drawTop();
364 window.addEventListener('keypress', doKeyPress, true);
365}
366
367</script>
368</head>
369
370<body onLoad="start();">
371<canvas id="canvas" width="1500" height="1000"
372 onmousemove="handleMouseOver()"
373 onclick="handleMouseClick()"
374 ></canvas >
375</body>
376</html>