Rubik's cube 5x5x5 edgeswap added.
[zzandy.git] / tiling.html
blob60a7123b2ec5c57f5094af63649324c6866d6992
1 <!DOCTYPE html>
3 <html lang="en" xmlns="http://www.w3.org/1999/xhtml">
4 <head>
5 <meta charset="utf-8" />
6 <title></title>
7 <style type="text/css">
8 html {
9 background-color: #262926;
12 </style>
13 </head>
14 <body>
15 <!-- Fullscreen canvas -->
16 <script type="text/javascript">
17 function fullscreenCanvas() {
18 var c = window.document.createElement('canvas');
19 window.document.body.appendChild(c);
21 var ctx = c.getContext('2d');
23 ctx.canvas.width = window.innerWidth;
24 ctx.canvas.height = window.innerHeight;
25 ctx.canvas.style.position = 'absolute';
26 ctx.canvas.style.top = 0;
27 ctx.canvas.style.left = 0;
29 return ctx;
31 </script>
33 <script type="text/javascript">
34 var r = .3;
35 var g = .59;
36 var b = .11;
38 // hue Chroma luma
39 function hcy2rgb(h, c, y) {
40 h0 = h;
41 h /= 60;
43 var k = (1 - Math.abs((h % 2) - 1));
45 var K = h < 1 ? r + k * g
46 : h < 2 ? g + k * r
47 : h < 3 ? g + k * b
48 : h < 4 ? b + k * g
49 : h < 5 ? b + k * r
50 : r + k * b;
52 var cmax = 1;
54 if (y <= 0 || y >= 1) cmax = 0;
55 else cmax *= K < y ? (y - 1) / (K - 1) : K > y ? y / K : 1;
56 c = Math.min(c, cmax);
58 var x = c * k;
59 var rgb = h < 1 ? [c, x, 0]
60 : h < 2 ? [x, c, 0]
61 : h < 3 ? [0, c, x]
62 : h < 4 ? [0, x, c]
63 : h < 5 ? [x, 0, c]
64 : [c, 0, x];
66 var m = y - (r * rgb[0] + g * rgb[1] + b * rgb[2]);
68 return [rgb[0] + m, rgb[1] + m, rgb[2] + m];
71 function hcyCol(h, c, y)
73 var col = hcy2rgb(h % 360, c, y);
74 ctx.fillStyle = 'rgb(' + (255 * col[0] | 0) + ', ' + (255 * col[1] | 0) + ',' + (255 * col[2] | 0) + ')';
77 </script>
79 <script type="text/javascript">
81 function Point(x, y)
83 this.x = x; this.y = y;
86 function DerivedPoint(p, dx, dy)
88 this.point = p;
89 this.dx = dx;
90 this.dy = dy;
93 Object.defineProperty(DerivedPoint.prototype, 'x', {
94 get: function () { return this.point.x + this.dx; },
95 set: function (v) { this.point.x = v - this.dx }
96 });
98 Object.defineProperty(DerivedPoint.prototype, 'y', {
99 get: function () { return this.point.y + this.dy; },
100 set: function (v) { this.point.y = v - this.dy}
103 Point.prototype.distanceLessThan = function (maxdist) {
104 maxdist *= maxdist;
105 var p1 = this;
107 return function(p) {
108 var distSq = (p.x - p1.x) * (p.x - p1.x) + (p.y - p1.y) * (p.y - p1.y);
109 return distSq < maxdist;
113 function Line(p1, p2) {
114 this.nodes = [p1, p2];
117 </script>
119 <script type="text/javascript">
121 var ctx = fullscreenCanvas();
123 var extent = 25;
124 var zoom = ctx.canvas.width < ctx.canvas.height
125 ? ctx.canvas.width / extent
126 : ctx.canvas.height / extent;
128 ctx.translate(ctx.canvas.width / 2, ctx.canvas.height / 2);
129 ctx.scale(zoom, -zoom);
130 ctx.lineJoin = 'round';
131 ctx.strokeStyle = '#999';
132 ctx.fillStyle = '#777';
133 ctx.lineWidth = 1 / zoom;
135 var a = 5;
136 var w2 = a / Math.sqrt(3);
138 var pa = new Point(w2, 0);
139 var pb = new Point(w2 / 2, a / 2);
141 var p1 = pa;
142 var p2 = pb;
143 var p3 = new DerivedPoint(pa, -3 * w2 / 2, a / 2);
144 var p4 = new DerivedPoint(pb, -3 * w2 / 2, -a / 2);
145 var p5 = new DerivedPoint(pa, -3 * w2 / 2, -a / 2);
146 var p6 = new DerivedPoint(pb, 0, -a);
148 var lines = [
149 new Line(p1, p2),
150 new Line(p2, p3),
151 new Line(p3, p4),
152 new Line(p4, p5),
153 new Line(p5, p6),
154 new Line(p6, p1)
157 var cursor = new Point(-extent*2, -extent*2);
158 var selected = null;
159 var prevClickTime = 0;
160 var lastClickTime = 0;
161 var dblClickTime = 250;
163 function onmousemove(e) {
164 cursor = new Point(cursor.x = (e.clientX - ctx.canvas.width / 2) / zoom, (ctx.canvas.height / 2 - e.clientY) / zoom);
166 if (selected) {
167 var p = lines[selected[0]].nodes[selected[1]];
170 p.x = cursor.x;
171 p.y = cursor.y;
175 function findNode(cursor)
177 for (var i = 0; i < lines.length; ++i)
179 var node = findIndex(lines[i].nodes, cursor.distanceLessThan(10 / zoom));
180 if (node >= 0) {
181 return [i, node];
185 return null;
188 function onmousedown(e) {
189 var node = findNode(cursor);
191 if (e.button == 1 && node && lines[node[0]].nodes.length > 2 && node[1]!=0 && node[1]!=lines[node[0]].nodes.lenght) {
192 lines[node[0]].nodes.splice(node[1], 1);
193 selected = null;
195 return;
198 prevClickTime = lastClickTime;
199 lastClickTime = (new Date()).getTime();
201 selected = node;
204 function onmouseup() {
205 selected = null;
207 var time = (new Date()).getTime();
208 var dbclick = (time - prevClickTime) < dblClickTime;
210 if (dbclick) {
211 var node = findNode(cursor);
213 if (node) {
214 console.log(node);
216 var line = lines[node[0]];
217 var i = node[1] == 0 ? 1 : node[1];
219 var newNode = new Point(line.nodes[i].x - (line.nodes[i].x - line.nodes[i-1].x) / 2,
220 line.nodes[i].y - (line.nodes[i ].y - line.nodes[i-1].y) / 2);
222 line.nodes.splice(i, 0, newNode);
227 function findIndex(array, predicate) {
228 for(var i=0;i<array.length;++i)
229 if (predicate(array[i], i, array))
230 return i;
233 function drawLine(line) {
234 var k = 10;
236 for (var n = 0; n < k; ++n) {
237 for (var m = 0; m < k; ++m) {
238 var dx = (n - k / 2) * 3 * w2 / 2;
239 var dy = (m - k / 2) * a + ((1 + n) % 2) * a / 2;
241 ctx.beginPath();
242 ctx.moveTo(line.nodes[0].x + dx, line.nodes[0].y + dy);
244 for (var i = 1; i < line.nodes.length; ++i)
245 ctx.lineTo(line.nodes[i].x + dx, line.nodes[i].y + dy);
247 ctx.stroke();
252 function frame() {
253 ctx.clearRect(-extent*2, -extent*2, extent * 4, extent * 4);
255 ctx.strokeStyle = '#777';
256 ctx.fillStyle = 'rgba(200, 20,20,.3)';
258 var m = 10;
259 var n = 10;
260 for (var i = 0; i < n; ++i) {
261 for (var j = 0; j < m; ++j)
263 ctx.save();
264 var dx = (i - n / 2) * 3 * w2 / 2;
265 var dy = (j - m / 2) * a + ((1 + i) % 2) * a / 2;
267 ctx.fillStyle= hcyCol(i*50+j*10, .5, .5);
269 ctx.translate(dx, dy);
271 ctx.beginPath();
273 var first = true;
274 lines.forEach(function (line) {
275 if (first) {
276 ctx.moveTo(line.nodes[0].x, line.nodes[0].y);
277 first = false;
280 for (var k = first ? 1 : 0; k < line.nodes.length; ++k)
281 ctx.lineTo(line.nodes[k].x, line.nodes[k].y);
285 ctx.closePath();
286 ctx.fill();
288 ctx.restore();
293 ctx.strokeStyle = 'white';
294 ctx.fillStyle = 'white';
295 lines.forEach(function (line) {
297 ctx.beginPath();
298 ctx.moveTo(line.nodes[0].x, line.nodes[0].y);
299 for (var i = 1; i < line.nodes.length; ++i)
300 ctx.lineTo(line.nodes[i].x, line.nodes[i].y);
302 ctx.stroke();
304 line.nodes.forEach(function(node) {
305 ctx.fillRect(node.x - 1.5 / zoom, node.y - 1.5 / zoom, 3 / zoom, 3 / zoom);
309 var node = findNode(cursor);
311 if (selected) {
312 ctx.fillRect(lines[selected[0]].nodes[selected[1]].x - 5 / zoom, lines[selected[0]].nodes[selected[1]].y - 5 / zoom, 10 / zoom, 10 / zoom);
315 if (node) {
316 ctx.strokeRect(lines[node[0]].nodes[node[1]].x - 5 / zoom, lines[node[0]].nodes[node[1]].y - 5 / zoom, 10 / zoom, 10 / zoom);
319 window.requestAnimationFrame(frame);
322 ctx.canvas.addEventListener('mousemove', onmousemove);
323 ctx.canvas.addEventListener('mousedown', onmousedown);
325 ctx.canvas.addEventListener('mouseup', onmouseup);
327 window.requestAnimationFrame(frame);
329 </script>
331 </body>
332 </html>