|
@@ -1,184 +1,165 @@
|
|
-var canvas = {};
|
|
|
|
-
|
|
|
|
const dotProduct = function(U, V) {
|
|
const dotProduct = function(U, V) {
|
|
return U.x * V.x + U.y * V.y;
|
|
return U.x * V.x + U.y * V.y;
|
|
};
|
|
};
|
|
|
|
|
|
-const isInside = function(vertex) {
|
|
|
|
- const AB = { x: canvas.vertex.b.x - canvas.vertex.a.x, y: canvas.vertex.b.y - canvas.vertex.a.y };
|
|
|
|
- const AM = { x: vertex.x - canvas.vertex.a.x, y: vertex.y - canvas.vertex.a.y };
|
|
|
|
- const BC = { x: canvas.vertex.c.x - canvas.vertex.b.x, y: canvas.vertex.c.y - canvas.vertex.b.y };
|
|
|
|
- const BM = { x: vertex.x - canvas.vertex.b.x, y: vertex.y - canvas.vertex.b.y };
|
|
|
|
|
|
+const isInside = function(vertex, square) {
|
|
|
|
+ const AB = { x: square.b.x - square.a.x, y: square.b.y - square.a.y };
|
|
|
|
+ const AM = { x: vertex.x - square.a.x, y: vertex.y - square.a.y };
|
|
|
|
+ const BC = { x: square.c.x - square.b.x, y: square.c.y - square.b.y };
|
|
|
|
+ const BM = { x: vertex.x - square.b.x, y: vertex.y - square.b.y };
|
|
|
|
|
|
return (0 <= dotProduct(AB, AM) && dotProduct(AB, AM) <= dotProduct(AB, AB))
|
|
return (0 <= dotProduct(AB, AM) && dotProduct(AB, AM) <= dotProduct(AB, AB))
|
|
&& (0 <= dotProduct(BC, BM) && dotProduct(BC, BM) <= dotProduct(BC, BC));
|
|
&& (0 <= dotProduct(BC, BM) && dotProduct(BC, BM) <= dotProduct(BC, BC));
|
|
};
|
|
};
|
|
|
|
|
|
-const draw = function(ctx, source, coords) {
|
|
|
|
- if (!coords) {
|
|
|
|
- ctx.clearRect(0, 0, canvas.element.width, canvas.element.height);
|
|
|
|
- coords = { x: 0, y: 0 };
|
|
|
|
-
|
|
|
|
- canvas.quadrants.images = canvas.quadrants.images.filter(i => {
|
|
|
|
- return isInside({ x: i.x, y: i.y })
|
|
|
|
- || isInside({ x: (i.x + i.image.width) * 2, y: i.y })
|
|
|
|
- || isInside({ x: (i.x + i.image.width) * 2, y: (i.y + i.image.height) * 2 })
|
|
|
|
- || isInside({ x: i.x, y: (i.y + i.image.height) * 2 });
|
|
|
|
- });
|
|
|
|
- canvas.quadrants.images.forEach(i => i.drawn = false);
|
|
|
|
- }
|
|
|
|
|
|
+const toBinary = function(decimal, padding) {
|
|
|
|
+ return decimal.toString(2).padStart(padding, 0);
|
|
|
|
+};
|
|
|
|
|
|
- const imgQ1 = new Image();
|
|
|
|
- imgQ1.src = canvas.url + source + "00";
|
|
|
|
- const imgQ2 = new Image();
|
|
|
|
- imgQ2.src = canvas.url + source + "01";
|
|
|
|
- const imgQ3 = new Image();
|
|
|
|
- imgQ3.src = canvas.url + source + "10";
|
|
|
|
- const imgQ4 = new Image();
|
|
|
|
- imgQ4.src = canvas.url + source + "11";
|
|
|
|
-
|
|
|
|
- const imgIndex = canvas.quadrants.images.findIndex(i => imgQ1.src == i.image.src);
|
|
|
|
- var img = canvas.quadrants.images[imgIndex] || {};
|
|
|
|
-
|
|
|
|
- if (!!imgIndex || !img.naturalWidth) {
|
|
|
|
- imgQ1.onload = () => {
|
|
|
|
- ctx.drawImage(imgQ1, coords.x, coords.y);
|
|
|
|
- imgQ2.onload = () => ctx.drawImage(imgQ2, coords.x + imgQ1.width, coords.y);
|
|
|
|
- imgQ3.onload = () => ctx.drawImage(imgQ3, coords.x, coords.y + imgQ1.height);
|
|
|
|
- imgQ4.onload = () => ctx.drawImage(imgQ4, coords.x + imgQ1.width, coords.y + imgQ1.height);
|
|
|
|
-
|
|
|
|
- let newImg = {
|
|
|
|
- drawn: true,
|
|
|
|
- image: imgQ1,
|
|
|
|
- images: [imgQ1, imgQ2, imgQ3, imgQ4],
|
|
|
|
- x: coords.x,
|
|
|
|
- y: coords.y
|
|
|
|
- };
|
|
|
|
|
|
+const canvas = {
|
|
|
|
+ get boundary() { return document.getElementById("canvas").getBoundingClientRect() },
|
|
|
|
+ vertices: {
|
|
|
|
+ get a() { return { x: 0, y: 0 }; },
|
|
|
|
+ get b() { return { x: 0, y: canvas.boundary.width }; },
|
|
|
|
+ get c() { return { x: canvas.boundary.height, y: canvas.boundary.width }; },
|
|
|
|
+ get d() { return { x: canvas.boundary.height, y: 0 }; }
|
|
|
|
+ },
|
|
|
|
+
|
|
|
|
+ url: "http://127.0.0.1:5000/image/",
|
|
|
|
+ images: [],
|
|
|
|
+ level: 3
|
|
|
|
+};
|
|
|
|
|
|
- canvas.quadrants.images.push(newImg);
|
|
|
|
- Object.assign(img, newImg);
|
|
|
|
- };
|
|
|
|
- } else {
|
|
|
|
- const vector = { x: canvas.mouse.x - canvas.mouse.prevX, y: canvas.mouse.y - canvas.mouse.prevY };
|
|
|
|
- ctx.drawImage(imgQ1, img.x + vector.x, img.y + vector.y);
|
|
|
|
- ctx.drawImage(imgQ2, img.x + imgQ1.width + vector.x, img.y + vector.y);
|
|
|
|
- ctx.drawImage(imgQ3, img.x, img.y + imgQ1.height + vector.y);
|
|
|
|
- ctx.drawImage(imgQ4, img.x + imgQ1.width + vector.x, img.y + imgQ1.height + vector.y);
|
|
|
|
-
|
|
|
|
- canvas.quadrants.images.splice(imgIndex, 1, Object.assign(img, {
|
|
|
|
- drawn: true,
|
|
|
|
- x: img.x + vector.x,
|
|
|
|
- y: img.x + vector.y
|
|
|
|
- }));
|
|
|
|
- }
|
|
|
|
|
|
+const mouse = {
|
|
|
|
+ prevX: 0,
|
|
|
|
+ prevY: 0
|
|
|
|
+};
|
|
|
|
|
|
- if (parseInt(source + "00", 2) >= 2 ** (canvas.level + 1) * 2) {
|
|
|
|
- draw(ctx, (parseInt(source, 2) - (2 ** (canvas.level + 1) * 2)).toString(2).padStart(source.length, 0),
|
|
|
|
- { x: img.x, y: img.y - img.height * 2 });
|
|
|
|
- }
|
|
|
|
|
|
|
|
- if ((parseInt(source + "00", 2) + 4) % (2 ** (canvas.level + 1) * 2)) {
|
|
|
|
- draw(ctx, (parseInt(source, 2) + 4).toString(2).padStart(source.length, 0),
|
|
|
|
- { x: img.x + img.width * 2, y: img.y });
|
|
|
|
- }// } else {
|
|
|
|
- // draw(ctx, (parseInt(source, 2) + 2 ** (canvas.level + 1) * 2).toString(2).padStart(source.length, 0),
|
|
|
|
- // { x: img.x + img.width * 2, y: img.y });
|
|
|
|
- // }
|
|
|
|
-
|
|
|
|
- if (parseInt(source + "00", 2) < 4 ** (canvas.level + 1) - 2 ** (canvas.level + 1) * 2) {
|
|
|
|
- draw(ctx, (parseInt(source, 2) + (2 ** (canvas.level + 1) * 2)).toString(2).padStart(source.length, 0),
|
|
|
|
- { x: img.x, y: img.y + img.height * 2 });
|
|
|
|
- }
|
|
|
|
|
|
|
|
- if (parseInt(source + "00", 2) % (2 ** (canvas.level + 1) * 2)) {
|
|
|
|
- draw(ctx, (parseInt(source, 2) - 4).toString(2).padStart(source.length, 0),
|
|
|
|
- { x: img.x - img.width * 2, y: img.y });
|
|
|
|
- }// } else {
|
|
|
|
- // draw(ctx, (parseInt(source, 2) + 2 ** (canvas.level + 1) * 2).toString(2).padStart(source.length, 0),
|
|
|
|
- // { x: img.x - img.width * 2, y: img.y });
|
|
|
|
- // }
|
|
|
|
-};
|
|
|
|
|
|
|
|
-const mouseMove = function(e) {
|
|
|
|
- canvas.mouse.x = e.clientX;
|
|
|
|
- canvas.mouse.y = e.clientY;
|
|
|
|
|
|
|
|
- console.log("Dragging: " + canvas.isDragging);
|
|
|
|
- console.log(canvas);
|
|
|
|
|
|
+const draw = function(ctx, csize, isize, url, level, images, coords) {
|
|
|
|
+ ctx.clearRect(0, 0, csize.width, csize.height);
|
|
|
|
|
|
- if (canvas.isDragging) {
|
|
|
|
- draw(canvas.context, "");
|
|
|
|
- }
|
|
|
|
|
|
+ return draw_(ctx, isize, url, level, images.map((i) => {
|
|
|
|
+ return Object.assign(i, {drawn: false});
|
|
|
|
+ }), "0".repeat((level + 1) * 2), coords);
|
|
|
|
+}
|
|
|
|
|
|
- canvas.mouse.prevX = e.clientX;
|
|
|
|
- canvas.mouse.prevY = e.clientY;
|
|
|
|
-};
|
|
|
|
|
|
+const draw_ = function(ctx, isize, url, level, images, id, coords) {
|
|
|
|
+ if (!isInside(coords, canvas.vertices)) {
|
|
|
|
+ return images;
|
|
|
|
+ } else {
|
|
|
|
+ const decimal = parseInt(id, 2);
|
|
|
|
+
|
|
|
|
+ const index = images.findIndex((i) => (url + id) === i.image.src);
|
|
|
|
+ const target = images[index];
|
|
|
|
+ if (target) {
|
|
|
|
+ if (target.drawn) {
|
|
|
|
+ return images;
|
|
|
|
+ } else {
|
|
|
|
+ if (target.image.naturalWidth) {
|
|
|
|
+ ctx.drawImage(target.image, target.x + coords.x, target.y + coords.y);
|
|
|
|
+ } else {
|
|
|
|
+ target.image.onload = () => ctx.drawImage(target.image, target.x + coords.x, target.y + coords.y);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ images.push({
|
|
|
|
+ image: target.image,
|
|
|
|
+ x: target.x + coords.x,
|
|
|
|
+ y: target.y + coords.y,
|
|
|
|
+ drawn: true
|
|
|
|
+ });
|
|
|
|
+ images.splice(index);
|
|
|
|
+ }
|
|
|
|
+ } else {
|
|
|
|
+ const image = new Image();
|
|
|
|
+ image.src = url + id;
|
|
|
|
+ console.log(decimal);
|
|
|
|
+
|
|
|
|
+ image.onload = () => ctx.drawImage(image, coords.x, coords.y);
|
|
|
|
+ images.push({
|
|
|
|
+ image: image,
|
|
|
|
+ x: coords.x,
|
|
|
|
+ y: coords.y,
|
|
|
|
+ drawn: true
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
|
|
-const mouseDown = function(e) {
|
|
|
|
- if (canvas.element === document.activeElement) {
|
|
|
|
- canvas.isDragging = true;
|
|
|
|
- }
|
|
|
|
-};
|
|
|
|
|
|
+ switch (decimal % 4) {
|
|
|
|
+ case 0:
|
|
|
|
+ if (decimal >= 2 ** (level + 1) * 2)
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal - 2 ** (level + 1) * 2 + 2, id.length), { x: coords.x, y: coords.y - isize.height });
|
|
|
|
+ if (![0, 2].includes((decimal + 3) % (2 ** (level + 1) * 2)))
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal + 1, id.length), { x: coords.x + isize.width, y: coords.y });
|
|
|
|
+ if (decimal < 4 ** (level + 1) - 2 ** (level + 1) * 2)
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal + 2, id.length), { x: coords.x, y: coords.y + isize.height });
|
|
|
|
+ if (![0, 2].includes(decimal % (2 ** (level + 1) * 2)))
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal - 3, id.length), { x: coords.x - isize.width, y: coords.y });
|
|
|
|
+ break;
|
|
|
|
+ case 1:
|
|
|
|
+ if (decimal >= 2 ** (level + 1) * 2)
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal - 2 ** (level + 1) * 2 + 2, id.length), { x: coords.x, y: coords.y - isize.height });
|
|
|
|
+ if (![0, 2].includes((decimal + 3) % (2 ** (level + 1) * 2)))
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal + 3, id.length), { x: coords.x + isize.width, y: coords.y });
|
|
|
|
+ if (decimal < 4 ** (level + 1) - 2 ** (level + 1) * 2)
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal + 2, id.length), { x: coords.x, y: coords.y + isize.height });
|
|
|
|
+ if (![0, 2].includes(decimal % (2 ** (level + 1) * 2)))
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal - 1, id.length), { x: coords.x - isize.width, y: coords.y });
|
|
|
|
+ break;
|
|
|
|
+ case 2:
|
|
|
|
+ if (decimal >= 2 ** (level + 1) * 2)
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal - 2, id.length), { x: coords.x, y: coords.y - isize.height });
|
|
|
|
+ if (![0, 2].includes((decimal + 3) % (2 ** (level + 1) * 2)))
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal + 1, id.length), { x: coords.x + isize.width, y: coords.y });
|
|
|
|
+ if (decimal < 4 ** (level + 1) - 2 ** (level + 1) * 2)
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal + 2 ** (level + 1) * 2 - 2, id.length), { x: coords.x, y: coords.y + isize.height });
|
|
|
|
+ if (![0, 2].includes(decimal % (2 ** (level + 1) * 2)))
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal - 3, id.length), { x: coords.x - isize.width, y: coords.y });
|
|
|
|
+ break;
|
|
|
|
+ case 3:
|
|
|
|
+ if (decimal >= 2 ** (level + 1) * 2)
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal - 2, id.length), { x: coords.x, y: coords.y - isize.height });
|
|
|
|
+ if (![0, 2].includes((decimal + 3) % (2 ** (level + 1) * 2)))
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal + 3, id.length), { x: coords.x + isize.width, y: coords.y });
|
|
|
|
+ if (decimal < 4 ** (level + 1) - 2 ** (level + 1) * 2)
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal + 2 ** (level + 1) * 2 - 2, id.length), { x: coords.x, y: coords.y + isize.height });
|
|
|
|
+ if (![0, 2].includes(decimal % (2 ** (level + 1) * 2)))
|
|
|
|
+ images = draw_(ctx, isize, url, level, images, toBinary(decimal - 1, id.length), { x: coords.x - isize.width, y: coords.y });
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
|
|
-const mouseUp = function(e) {
|
|
|
|
- canvas.isDragging = false;
|
|
|
|
|
|
+ return images;
|
|
|
|
+ }
|
|
};
|
|
};
|
|
|
|
|
|
-const init = function() {
|
|
|
|
- canvas = {
|
|
|
|
- url: "http://localhost:5000/image/",
|
|
|
|
- element: document.getElementById("canvas"),
|
|
|
|
- get context() { return canvas.element.getContext("2d"); },
|
|
|
|
- isDragging: false,
|
|
|
|
-
|
|
|
|
- mouse: {
|
|
|
|
- x: 0,
|
|
|
|
- y: 0,
|
|
|
|
- prevX: 0,
|
|
|
|
- prevY: 0
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- get boundary() { return canvas.element.getBoundingClientRect(); },
|
|
|
|
- vertex: {
|
|
|
|
- get a() { return { x: canvas.boundary.top + window.scrollY, y: canvas.boundary.left + window.scrollX }; },
|
|
|
|
- get b() { return { x: canvas.boundary.top + window.scrollY, y: canvas.boundary.right }; },
|
|
|
|
- get c() { return { x: canvas.boundary.bottom, y: canvas.boundary.right }; },
|
|
|
|
- get d() { return { x: canvas.boundary.bottom, y: canvas.boundary.left + window.scrollX }; }
|
|
|
|
- },
|
|
|
|
-
|
|
|
|
- level: 0,
|
|
|
|
- quadrants: {
|
|
|
|
- width: 0,
|
|
|
|
- height: 0,
|
|
|
|
- images: []
|
|
|
|
-
|
|
|
|
- /*{
|
|
|
|
- drawn: false,
|
|
|
|
- image: null,
|
|
|
|
- images: [],
|
|
|
|
- x: 0,
|
|
|
|
- y: 0
|
|
|
|
- }*/
|
|
|
|
-
|
|
|
|
- }
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- canvas.element.setAttribute("width", 500); // window.getComputedStyle(document.body).getPropertyValue("width"));
|
|
|
|
- canvas.element.setAttribute("height", 500); // window.getComputedStyle(document.body).getPropertyValue("height"));
|
|
|
|
-
|
|
|
|
- document.addEventListener("mousemove", mouseMove);
|
|
|
|
- document.addEventListener("mouseup", mouseUp);
|
|
|
|
- document.addEventListener("mousedown", mouseDown);
|
|
|
|
-
|
|
|
|
- document.getElementById("closer").addEventListener("click", () => {
|
|
|
|
- canvas.level++;
|
|
|
|
- document.getElementById("level").innerText = canvas.level;
|
|
|
|
- });
|
|
|
|
- document.getElementById("farther").addEventListener("click", () => {
|
|
|
|
- if (canvas.level > 0)
|
|
|
|
- canvas.level--;
|
|
|
|
- document.getElementById("level").innerText = canvas.level;
|
|
|
|
|
|
+const main = function() {
|
|
|
|
+ const c = document.getElementById("canvas");
|
|
|
|
+ c.setAttribute("width", 1000); // window.getComputedStyle(document.body).getPropertyValue("width"));
|
|
|
|
+ c.setAttribute("height", 1000); // window.getComputedStyle(document.body).getPropertyValue("height"));
|
|
|
|
+
|
|
|
|
+ document.addEventListener("mousemove", (e) => {
|
|
|
|
+ const image = new Image();
|
|
|
|
+ image.src = canvas.url + "0".repeat((canvas.level + 1) * 2)
|
|
|
|
+
|
|
|
|
+ image.onload = () => {
|
|
|
|
+ if (c === document.activeElement && e.buttons === 1) {
|
|
|
|
+ canvas.images = draw(c.getContext("2d"), canvas.boundary, {width: image.width, height: image.height},
|
|
|
|
+ canvas.url, canvas.level, canvas.images,
|
|
|
|
+ {x: e.clientX - mouse.prevX, y: e.clientY - mouse.prevY});
|
|
|
|
+
|
|
|
|
+ mouse.prevX = e.clientX;
|
|
|
|
+ mouse.prevY = e.clientY;
|
|
|
|
+ }
|
|
|
|
+ };
|
|
});
|
|
});
|
|
|
|
|
|
- draw(canvas.context, "");
|
|
|
|
|
|
+ const image = new Image();
|
|
|
|
+ image.src = canvas.url + "0".repeat((canvas.level + 1) * 2)
|
|
|
|
+
|
|
|
|
+ image.onload = () => {
|
|
|
|
+ canvas.images = draw(c.getContext("2d"), canvas.boundary, {width: image.width, height: image.height},
|
|
|
|
+ canvas.url, canvas.level, canvas.images, {x: 0, y: 0});
|
|
|
|
+ }
|
|
};
|
|
};
|