OSDN Git Service

commit the part that makes the map work snapshot
authorThe Grand Dog <alex.h@me.com>
Thu, 4 Jun 2020 00:00:29 +0000 (20:00 -0400)
committerThe Grand Dog <alex.h@me.com>
Thu, 4 Jun 2020 00:00:29 +0000 (20:00 -0400)
Automap/MapSRC/build.js
Automap/MapSRC/src/ViewFrame.js
Automap/MapSRC/src/ViewFrameUtils.js
Automap/MapSRC/src/index.js
Automap/assets/automap/config/automap.html

index c5e0fb2..9c60009 100755 (executable)
@@ -8,15 +8,15 @@ fs.readFile(__dirname + '/src/Automap.html', 'utf8', (err, d) => {
        if (err) console.log(err);
        let outD = d.replace(/<link rel=\"stylesheet\" href=\"(.*)\">/g, (match, name, offset, string) => {
                        return '<style>' + fs.readFileSync(__dirname + '/src/' + name, 'utf8')
-                               .replace(/\/\/.*\n?/g, '')
+                               // .replace(/\/\/.*\n?/g, '')
                                + '</style>';
                })
                .replace(/<script type=\"text\/javascript\" src=\"(.*)\">/g, (match, name, offset, string) => {
                        return '<script type=\"text\/javascript\">' + fs.readFileSync(__dirname + '/src/' + name, 'utf8')
-                               .replace(/\/\/.*\n?/g, '')
+                               // .replace(/\/\/.*\n?/g, '')
                                + '</script>';
-               })
-               .replace(/[\t\n]/g, '');
+               });
+       //      .replace(/[\t\n]/g, '');
        fs.writeFile(__dirname + '/../assets/automap/config/automap.html', outD, err => {
                if (err) console.log(err);
        });
index 663a50f..2e286b9 100644 (file)
@@ -40,7 +40,7 @@ function ViewFrame() {
 
        this.x = -1;
        this.y = -1; // can be fractional
-       this.zoom = 32; // pixels wide the images are to be
+       this.zoom = 32; // pixels wide the shards are to be
        this.updateEdges();
 }
 // prototypes, some less... notable? methods are
@@ -107,7 +107,7 @@ ViewFrame.prototype.render = function () {
                        const img = new Image(32, 32);
                        const name = round.value.join('_');
 
-                       img.src = name + '.png';
+                       img.src = 'Chunks/' + name + '.png';
 
                        decode(img, loadedImage => {
                                this.place(img, round.value[0], round.value[1]);
index dc35335..7693516 100644 (file)
@@ -1,5 +1,5 @@
 ViewFrame.initInfobox = function (ibox, iboxSlots) {
-
+       // TODO: make faster
        ViewFrame.chunks
                .chunkMetadataNames.forEach((item, i) => {
                        const slot = document.createElement('tr');
@@ -34,16 +34,31 @@ ViewFrame.prototype.updateEdges = function () {
        this.southChunk = Math.floor(this.south);
 };
 
+/**
+* dx and dy are the distances in chunks
+*/
 ViewFrame.prototype.moveCenter = function (dx, dy) {
        // to pan when we click on the map!
        this.x += (dx - this.width / 2) / this.zoom;
        this.y += (dy - this.height / 2) / this.zoom;
 };
+
+/**
+* x and y are positions in chunks
+*/
 ViewFrame.prototype.setCenter = function (x, y) {
        this.x = x;
        this.y = y;
 };
 
+/**
+* x and y are positions in BLOCKS!!!!
+*/
+ViewFrame.prototype.setBlockwiseCenter = function (x, y) {
+       this.x = x / this.zoom;
+       this.y = y / this.zoom;
+};
+
 ViewFrame.prototype.clear = function () {
        this.loadedChunksByName.clear();
        this.loadedChunksByCoords.clear();
index 5b8dc9e..55abc93 100644 (file)
@@ -25,7 +25,6 @@ vf.reloadChunkList();
        });
 }());
 
-
 // #### CONTROLS ####
 // hovering
 (function () {
@@ -49,10 +48,17 @@ vf.reloadChunkList();
        var id;
        vf.map.canvas.addEventListener('wheel', event => {
                clearTimeout(id);
-               vf.zoom += -Math.sign(event.deltaY)*2;
                id = setTimeout(() => {
                        vf.render();
                }, 250);
+               // this makes it so zooming out is faster
+               let dir = -Math.sign(event.deltaY);
+               if (vf.zoom < 16) // arbitrary value
+                       vf.zoom += dir;
+               else
+                       vf.zoom += dir * 4;
+               if (vf.zoom <= 0)
+                       vf.zoom += 1; // make sure it doesnt go to negative values
        });
 }());
 
index ad5ec0b..03f3d26 100644 (file)
 <head>
        <meta charset="utf-8">
        <title>Automap</title>
-       <style media="screen">.m,body,html{width:100%;height:100%;margin:0;outline:1px dotted #000}.m img{position:absolute;image-rendering:pixelated}.i{width:15em;background-color:rgba(200,200,200,.5);left:0;top:0;font-family:sans-serif;position:absolute;z-index:1}h1{font-size:22px;margin:.6em 1em;text-align:center}.t{margin:.3em auto;width:90%;outline:1px solid #333}.t th{width:30%}.t td{text-align:right}</style>
+       <style>html, body, .map {
+       width: 100%;
+       height: 100%;
+       margin: 0;
+       overflow: hidden;
+       outline: 1px dotted black;
+}
+
+.infobox {
+       width: 15em;
+       /* height: 15em; */
+       background-color: rgba(200, 200, 200, 0.5);
+       left: 0;
+       top: 0;
+       font-family: sans-serif;
+       position: absolute;
+       z-index: 1;
+}
+
+h1 {
+       font-size: 22px;
+       margin: .6em 1em;
+       text-align: center;
+}
+
+.infoboxTable {
+       margin: .3em auto;
+       width: 90%;
+       outline: 1px solid #333;
+}
+
+.infoboxTable th {
+       width: 30%;
+}
+
+.infoboxTable td {
+       text-align: right;
+}</style>
 </head>
 
 <body>
-       <div class="i">
-               <h1>Chunk Info</h1>
-               <table class="t"></table>
-       </div>
-       <script type="text/javascript">
-               function ViewFrame() {
-                       this.map = document.createElement("div"), this.map.className = "m", this.infobox = document.getElementsByClassName("t")[0], this.infoboxSlots = new Map, ViewFrame.initInfobox(this.infobox, this.infoboxSlots), document.getElementsByTagName("body")[
-                                       0].append(this.map), this.loadedChunksByName = new Map, this.loadedChunksByCoords = new Map, this.availableChunks = null, this.chunkScript = null, this.renderOnReload = !0, this.dirty = !1, this.rendering = !1, this.x = null, this.y = null,
-                               this._zoom = 32, this.updateEdges()
-               }
+       <script type="text/javascript">function ViewFrame() {
+       // dom stuff
+       const map = document.createElement('canvas'); // the map we see
+       map.className = 'map';
+       map.height = window.innerHeight;
+       map.width = window.innerWidth;
+       document.getElementsByTagName('body')[0].append(map);
+       // this is the map that we actually draw on
+       this.map = map.getContext('2d', {
+               alpha: false
+       });
+       this.map.imageSmoothingEnabled = false;
+
+       // the info box in the corner
+       this.infobox = document.getElementsByClassName('infoboxTable')[0];
+       this.infoboxSlots = new Array();
+
+       // load the metadata!
+       this.chunkScript = document.createElement('script');
+       this.chunkScript.type = 'text/javascript';
+       this.chunkScript.src = 'Metadata.js';
+       document.getElementsByTagName('body')[0].append(this.chunkScript);
+       this.chunkScript.addEventListener('load', () => {
+               ViewFrame.initInfobox(this.infobox, this.infoboxSlots);
+               this.x = ViewFrame.chunks.startCoords[0];
+               this.y = ViewFrame.chunks.startCoords[1];
+               this.availableChunks = ViewFrame.chunks.chunkMetadata;
+               this.render();
+       }, {
+               once: true
+       });
 
-               function decode(t, e) {
-                       t.decode().then(() => {
-                               e(t)
-                       }).catch(() => {})
+       // Tracks images that have been loaded and are on the map
+       this.loadedChunksByName = new Map();
+       // this is needed because [1, 2] != [1, 2] and thats how we store coords.
+       this.loadedChunksByCoords = new Map();
+       this.availableChunks = null; // the chunks in ./Metadata.js
+       // so that we dont render twice at the same time
+       this.rendering = false;
+
+       this.x = -1;
+       this.y = -1; // can be fractional
+       this.zoom = 32; // pixels wide the shards are to be
+       this.updateEdges();
+}
+// prototypes, some less... notable? methods are
+// in ViewFrameUtils.js 
+ViewFrame.prototype.reloadChunkList = function () {
+       if (this.chunkScript) {
+               this.chunkScript.remove();
+               delete this.chunkScript;
+       }
+
+       this.chunkScript = document.createElement('script');
+       this.chunkScript.type = 'text/javascript';
+       this.chunkScript.src = 'Metadata.js';
+       document.getElementsByTagName('body')[0].append(this.chunkScript);
+
+       this.chunkScript.addEventListener('load', () => {
+               this.availableChunks = ViewFrame.chunks.chunkMetadata;
+               this.render();
+       });
+};
+
+ViewFrame.prototype.render = function () {
+       if (!this.availableChunks) return;
+       if (this.rendering) clearInterval(ViewFrame.intervalRef);
+       this.rendering = true;
+       this.updateEdges();
+       this.map.clearRect(0, 0, window.innerWidth, window.innerHeight);
+       // culling
+       this.loadedChunksByCoords
+               .forEach((chunk, coord) => { // check the bounds
+                       if (coord[0] < this.eastChunk &&
+                               coord[0] >= this.westChunk &&
+                               coord[1] <= this.northChunk &&
+                               coord[1] >= this.southChunk) {
+
+                               this.place(chunk, coord[0], coord[1]);
+                               return;
+                       }
+                       // its out of range!!!
+                       // get 'em boys!!!!!
+                       this.loadedChunksByCoords.delete(coord);
+                       this.loadedChunksByName.delete(coord.join('_'));
+                       chunk.remove();
+               });
+
+       // gathering what we need to load
+       const neededChunks = new Set();
+       for (var x = this.westChunk; x < this.eastChunk; x++) {
+               for (var y = this.southChunk; y < this.northChunk; y++) {
+                       const chunKey = [x, y]; // chunk + key = chunKey :)
+                       const name = chunKey.join('_');
+                       // continue if its not available, or it is loaded
+                       if (!this.availableChunks.has(name) ||
+                               this.loadedChunksByName.has(name)) continue;
+                       neededChunks.add(chunKey);
                }
-               ViewFrame.prototype.reloadChunkList = function() {
-                       console.log("Reloading chunks!"), this.chunkScript && (this.chunkScript.remove(), delete this.chunkScript), this.chunkScript = document.createElement("script"), this.chunkScript.type = "text/javascript", this.chunkScript.src = "Metadata.js",
-                               document.getElementsByTagName("body")[0].append(this.chunkScript), this.chunkScript.onload = (() => {
-                                       this.availableChunks = ViewFrame.chunks.chunkMetadata, null !== this.x && null !== this.y || (this.x = ViewFrame.chunks.startCoords[0], this.y = ViewFrame.chunks.startCoords[1]), this.renderOnReload && this.render()
-                               }), this.dirty = !0
-               }, ViewFrame.prototype.render = function() {
-                       if (!this.availableChunks) return;
-                       if (this.rendering) return;
-                       this.rendering = !0, this.dirty && this.updateEdges(), this.loadedChunksByCoords.forEach((t, e) => {
-                               if (e[0] < this.eastChunk && e[0] >= this.westChunk && e[1] <= this.northChunk && e[1] >= this.southChunk) {
-                                       let [s, i] = this.chunkToScreen(e[0], e[1]);
-                                       t.style.left = s + "px", t.style.top = i + "px";
-                                       const n = this.zoom / 32;
-                                       1 != n && (t.style.transform = `scale(${n})`)
-                               } else this.loadedChunksByCoords.delete(e), this.loadedChunksByName.delete(e.join("_")), t.remove()
+       }
+       // iterating over everything we need to load
+       const it = neededChunks.values();
+       ViewFrame.intervalRef = setInterval(() => {
+               let round = it.next();
+               if (!round.done) {
+                       // load
+                       const img = new Image(32, 32);
+                       const name = round.value.join('_');
+
+                       img.src = 'Chunks/' + name + '.png';
+
+                       decode(img, loadedImage => {
+                               this.place(img, round.value[0], round.value[1]);
                        });
-                       const t = new Set;
-                       for (var e = this.westChunk; e < this.eastChunk; e++)
-                               for (var s = this.southChunk; s < this.northChunk; s++) {
-                                       const i = [e, s],
-                                               n = i.join("_");
-                                       this.availableChunks.has(n) && !this.loadedChunksByName.has(n) && t.add(i)
-                               }
-                       const i = t.values();
-                       let n = setInterval(() => {
-                               let t = i.next();
-                               if (t.done) clearInterval(n), this.rendering = !1;
-                               else {
-                                       const e = new Image(32, 32),
-                                               s = t.value.join("_");
-                                       e.src = s + ".png", e.alt = s, decode(e, e => {
-                                               let [s, i] = this.chunkToScreen(t.value[0], t.value[1]);
-                                               e.style.left = s + "px", e.style.top = i + "px";
-                                               const n = this.zoom / 32;
-                                               1 != n && (chunk.style.transform = `scale(${n})`), this.map.append(e)
-                                       }), this.loadedChunksByName.set(s, e), this.loadedChunksByCoords.set(t.value, e)
-                               }
-                       }, 4)
-               }, ViewFrame.prototype.updateInfobox = function(t) {
-                       const e = this.availableChunks.get(t);
-                       this.infoboxSlots.forEach((t, s) => {
-                               t.innerText = e[s]
-                       })
-               }, ViewFrame.initInfobox = function(t, e) {
-                       ["prettyCoord:Loc.", "chunkAge:Age", "temp:Temp.", "YMax:Y Max", "fert:Fert.", "forestDens:Forest", "rain:Rain", "shrubDens:Shrub", "airBlocks:Air", "nonAirBlocks:Non-Air"].map(t => t.split(":")).forEach(s => {
-                               const i = s[0],
-                                       n = s[1],
-                                       h = document.createElement("tr"),
-                                       o = document.createElement("th");
-                               o.innerText = n;
-                               const r = document.createElement("td");
-                               r.innerText = "0", e.set(i, r), h.append(o, r), t.append(h)
-                       })
-               }, ViewFrame.prototype.screenToChunk = function(t, e) {
-                       return [(t - this.width / 2) / this.zoom, (e - this.height / 2) / this.zoom]
-               }, ViewFrame.prototype.chunkToScreen = function(t, e) {
-                       return [(t - this.west) * this.zoom, (e - this.south) * this.zoom]
-               }, ViewFrame.prototype.updateEdges = function() {
-                       if (!this.dirty) return;
-                       const t = Math.ceil(this.width / this.zoom),
-                               e = Math.ceil(this.height / this.zoom);
-                       this.east = this.x + t / 2, this.eastChunk = Math.ceil(this.east), this.west = this.x - t / 2, this.westChunk = Math.floor(this.west), this.north = this.y + e / 2, this.northChunk = Math.ceil(this.north), this.south = this.y - e / 2, this.southChunk =
-                               Math.floor(this.south), this.dirty = !1
-               }, ViewFrame.prototype.moveCenter = function(t, e) {
-                       let [s, i] = this.screenToChunk(t, e);
-                       this.x += s, this.y += i, this.dirty = !0
-               }, ViewFrame.prototype.clear = function() {
-                       this.loadedChunksByName.clear(), this.loadedChunksByCoords.clear(), this.chunkScript && this.chunkScript.remove(), delete this.chunkScript, delete ViewFrame.chunks, this.map.innerHTML = ""
-               }, Object.defineProperties(ViewFrame.prototype, {
-                       width: {
-                               get() {
-                                       return this.map.clientWidth
-                               }
-                       },
-                       height: {
-                               get() {
-                                       return this.map.clientHeight
-                               }
-                       },
-                       zoom: {
-                               get() {
-                                       return this._zoom
-                               },
-                               set(t) {
-                                       this._zoom = t, this.dirty = !0
-                               }
-                       }
+                       this.loadedChunksByName.set(name, img);
+                       this.loadedChunksByCoords.set(round.value, img);
+               } else {
+                       clearInterval(ViewFrame.intervalRef);
+                       this.rendering = false;
+               }
+       }, 4);
+};
+
+ViewFrame.prototype.place = function (img, x, y) {
+       x -= this.x;
+       y -= this.y;
+       x *= this.zoom;
+       y *= this.zoom;
+       x += this.width / 2;
+       y += this.height / 2;
+
+       this.map.drawImage(img, Math.floor(x), Math.floor(y), this.zoom, this.zoom);
+};
+
+ViewFrame.prototype.updateInfobox = function (chunkName) {
+       const chunkMeta = this.availableChunks.get(chunkName);
+       this.infoboxSlots.forEach((l, k) => {
+               l.innerText = chunkMeta ? chunkMeta[k] : '0';
+       });
+};</script></script>
+       <script type="text/javascript">ViewFrame.initInfobox = function (ibox, iboxSlots) {
+       // TODO: make faster
+       ViewFrame.chunks
+               .chunkMetadataNames.forEach((item, i) => {
+                       const slot = document.createElement('tr');
+                       const head = document.createElement('th');
+                       head.innerText = item;
+                       const row = document.createElement('td');
+                       row.innerText = '0';
+                       iboxSlots[i] = row;
+                       slot.append(head, row);
+                       ibox.append(slot);
                });
-               const vf = new ViewFrame;
-               vf.reloadChunkList(),
-                       function() {
-                               var t;
-                               window.addEventListener("resize", () => {
-                                       clearTimeout(t), vf.clear(), t = setTimeout(() => {
-                                               vf.updateEdges(), vf.render()
-                                       }, 500)
-                               })
-                       }(), vf.map.addEventListener("mousedown", t => {
-                               vf.moveCenter(t.x, t.y), setTimeout(() => {
-                                       vf.render()
-                               }, 250)
-                       }),
-                       function() {
-                               var t;
-                               vf.map.addEventListener("mousemove", e => {
-                                       e.target instanceof HTMLImageElement && t !== e.target && (t = e.target, vf.updateInfobox(e.target.alt))
-                               })
-                       }();
-               (function() {
-                       setInterval(() => {
-                               vf.reloadChunkList();
-                       }, 6000);
-               }());
-       </script>
+};
+
+ViewFrame.prototype.updateEdges = function () {
+       if (this.width != window.innerWidth || this.height != window.innerHeight) {
+               this.width = window.innerWidth;
+               this.map.canvas.width = this.width;
+               this.height = window.innerHeight;
+               this.map.canvas.height = this.height;
+               this.map.imageSmoothingEnabled = false;
+       }
+       const chunksWide = Math.ceil(this.width / this.zoom);
+       const chunksHigh = Math.ceil(this.height / this.zoom);
+
+       this.east = this.x + chunksWide / 2; // this is fractional and is used to keep track of the edges of the window
+       this.eastChunk = Math.ceil(this.east); // this is not and is used to track the chunks that need to load
+       this.west = this.x - chunksWide / 2;
+       this.westChunk = Math.floor(this.west);
+       this.north = this.y + chunksHigh / 2;
+       this.northChunk = Math.ceil(this.north);
+       this.south = this.y - chunksHigh / 2;
+       this.southChunk = Math.floor(this.south);
+};
+
+/**
+* dx and dy are the distances in chunks
+*/
+ViewFrame.prototype.moveCenter = function (dx, dy) {
+       // to pan when we click on the map!
+       this.x += (dx - this.width / 2) / this.zoom;
+       this.y += (dy - this.height / 2) / this.zoom;
+};
+
+/**
+* x and y are positions in chunks
+*/
+ViewFrame.prototype.setCenter = function (x, y) {
+       this.x = x;
+       this.y = y;
+};
+
+/**
+* x and y are positions in BLOCKS!!!!
+*/
+ViewFrame.prototype.setBlockwiseCenter = function (x, y) {
+       this.x = x / this.zoom;
+       this.y = y / this.zoom;
+};
+
+ViewFrame.prototype.clear = function () {
+       this.loadedChunksByName.clear();
+       this.loadedChunksByCoords.clear();
+       if (this.chunkScript) this.chunkScript.remove();
+       delete this.chunkScript;
+       delete ViewFrame.chunks;
+       this.map.clearRect(0, 0, window.innerWidth, window.innerHeight);
+};
+
+function decode(img, cb) {
+       img.decode()
+               .then(() => {
+                       cb(img);
+               })
+               .catch(() => {}); // so images arent added on error
+}</script></script>
+       <div class="infobox">
+               <h1>Chunk Info</h1>
+               <table class="infoboxTable">
+               </table>
+       </div>
+       <script type="text/javascript">const vf = new ViewFrame();
+vf.reloadChunkList();
+
+// the event handlers are in iifes so they dont make unneeded globals.
+// resize, delay re-render to reduce lag.
+(function () {
+       var id;
+       window.addEventListener('resize', () => {
+               clearTimeout(id);
+               id = setTimeout(() => {
+                       vf.render();
+               }, 500);
+       });
+}());
+
+// panning
+(function () {
+       var id;
+       vf.map.canvas.addEventListener('mousedown', event => {
+               clearTimeout(id);
+               vf.moveCenter(event.pageX, event.pageY);
+               id = setTimeout(() => {
+                       vf.render();
+               }, 250);
+       });
+}());
+
+// #### CONTROLS ####
+// hovering
+(function () {
+       var lastX = 0;
+       var lastY = 0;
+       vf.map.canvas.addEventListener('mousemove', event => {
+               // only count if the mouse moved more than a chunk
+               let x = Math.floor(vf.x +
+                       (event.clientX - vf.width / 2) / vf.zoom);
+               let y = Math.floor(vf.y +
+                       (event.clientY - vf.height / 2) / vf.zoom);
+               if (x == lastX && y == lastY) return;
+               lastX = x;
+               lastY = y;
+               vf.updateInfobox(x + '_' + y);
+       });
+}());
+
+// scroll/zoom
+(function () {
+       var id;
+       vf.map.canvas.addEventListener('wheel', event => {
+               clearTimeout(id);
+               id = setTimeout(() => {
+                       vf.render();
+               }, 250);
+               // this makes it so zooming out is faster
+               let dir = -Math.sign(event.deltaY);
+               if (vf.zoom < 16) // arbitrary value
+                       vf.zoom += dir;
+               else
+                       vf.zoom += dir * 4;
+               if (vf.zoom <= 0)
+                       vf.zoom += 1; // make sure it doesnt go to negative values
+       });
+}());
+
+// reload the chunk list every six seconds
+var devBlockReload = false; // disable via command line
+(function () {
+       setInterval(() => {
+               if (devBlockReload) return;
+               vf.reloadChunkList();
+       }, 6000);
+}());</script></script>
+
 </body>
 
 </html>
\ No newline at end of file