浏览代码

Refactoring the code to streamline all the sates to a single function

Patrick Augusto 4 年之前
父节点
当前提交
8fa4eb9e3e
共有 2 个文件被更改,包括 141 次插入160 次删除
  1. 1 1
      Pixel.html
  2. 140 159
      Pixel.js

+ 1 - 1
Pixel.html

@@ -10,6 +10,6 @@
         <button id="closer">Zoom +</button>
         <button id="farther">Zoom -</button>
         <span id="level">0</span>
-        <script>init();</script>
+        <script>main();</script>
     </body>
 </html>

+ 140 - 159
Pixel.js

@@ -1,184 +1,165 @@
-var canvas = {};
-
 const dotProduct = function(U, V) {
     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))
         && (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});
+    }
 };