add icons, loading image and make mouse zooming keep the zoomed point at the same...
authorRobert Kaiser <kairo@kairo.at>
Sun, 18 Dec 2011 20:08:29 +0000 (21:08 +0100)
committerRobert Kaiser <kairo@kairo.at>
Sun, 18 Dec 2011 20:08:29 +0000 (21:08 +0100)
index.html
js/map.js
manifest.appcache
manifest.webapp
style/lantea.css
style/lanteaIcon128.png [new file with mode: 0644]
style/lanteaIcon16.png [new file with mode: 0644]
style/lanteaIcon32.png [new file with mode: 0644]
style/lanteaIcon64.png [new file with mode: 0644]
style/loading.png [new file with mode: 0644]

index 65ec071c2f8438a6da34c5a6d021351d4884a840..8c889fc97226fa641d59cb4956b42be899451ec3 100644 (file)
@@ -43,6 +43,7 @@
   <script src="js/map.js"></script>
   <script src="js/ui.js"></script>
   <link rel="stylesheet" href="style/lantea.css">
   <script src="js/map.js"></script>
   <script src="js/ui.js"></script>
   <link rel="stylesheet" href="style/lantea.css">
+  <link rel="shortcut icon" href="style/lanteaIcon16.png" type="image/png">
 </head>
 <body>
 <h1>Lantea Map</h1>
 </head>
 <body>
 <h1>Lantea Map</h1>
@@ -50,6 +51,7 @@
 <div id="overlayArea">
 <input type="button" id="zoomInButton" value="+"
        onclick="zoomIn();">
 <div id="overlayArea">
 <input type="button" id="zoomInButton" value="+"
        onclick="zoomIn();">
+<span id="zoomLevel">Z</span>
 <input type="button" id="zoomOutButton" value="-"
        onclick="zoomOut();"><br/>
 <input type="button" id="settingsButton" value="Settings"
 <input type="button" id="zoomOutButton" value="-"
        onclick="zoomOut();"><br/>
 <input type="button" id="settingsButton" value="Settings"
@@ -66,6 +68,7 @@ Map style:
   Please use a browser that supports &lt;canvas&gt; elements.
 </canvas>
 
   Please use a browser that supports &lt;canvas&gt; elements.
 </canvas>
 
+<p id="debug"></p>
 <p id="copyright"></p>
 
 </body>
 <p id="copyright"></p>
 
 </body>
index 869ce2c13c2227a6a680afa2fd80f70fbdf0f43e..b1ae1a5f86ce8dc6032c5c3d19a340e12287349a 100644 (file)
--- a/js/map.js
+++ b/js/map.js
@@ -59,13 +59,15 @@ var gActiveMap = "osm_mapnik";
 
 var gPos = {x: 35630000.0, // Current position in the map in pixels at the maximum zoom level (18)
             y: 23670000.0, // The range is 0-67108864 (2^gMaxZoom * gTileSize)
 
 var gPos = {x: 35630000.0, // Current position in the map in pixels at the maximum zoom level (18)
             y: 23670000.0, // The range is 0-67108864 (2^gMaxZoom * gTileSize)
-            z: 5.0}; // This can be fractional if we are between zoom levels.
+            z: 5}; // This could be fractional if supported being between zoom levels.
 
 var gLastMouseX = 0;
 var gLastMouseY = 0;
 
 var gLastMouseX = 0;
 var gLastMouseY = 0;
+var gZoomFactor;
 
 
-// Used as an assiciative array. They keys have to be strings, ours will be "xindex,yindex,zindex" e.g. "13,245,12".
+// Used as an associative array. They keys have to be strings, ours will be "xindex,yindex,zindex" e.g. "13,245,12".
 var gTiles = {};
 var gTiles = {};
+var gLoadingTile;
 
 var gDragging = false;
 var gZoomTouchID;
 
 var gDragging = false;
 var gZoomTouchID;
@@ -92,6 +94,9 @@ function initMap() {
 
   document.getElementById("copyright").innerHTML =
       gMapStyles[gActiveMap].copyright;
 
   document.getElementById("copyright").innerHTML =
       gMapStyles[gActiveMap].copyright;
+
+  gLoadingTile = new Image();
+  gLoadingTile.src = "style/loading.png";
 }
 
 function resizeAndDraw() {
 }
 
 function resizeAndDraw() {
@@ -136,8 +141,9 @@ function mod(a, b) {
 }
 
 function normaliseIndices(x, y, z) {
 }
 
 function normaliseIndices(x, y, z) {
-  return {x: mod(x, Math.pow(2, z)),
-          y: mod(y, Math.pow(2, z)),
+  var zoomFactor = Math.pow(2, z);
+  return {x: mod(x, zoomFactor),
+          y: mod(y, zoomFactor),
           z: z};
 }
 
           z: z};
 }
 
@@ -155,13 +161,14 @@ function isOutsideWindow(t) {
   var y = pos[1];
   var z = pos[2];
 
   var y = pos[1];
   var z = pos[2];
 
-  var wid = gCanvas.width * Math.pow(2, gMaxZoom - z);
-  var ht = gCanvas.height * Math.pow(2, gMaxZoom - z);
+  var zoomFactor = Math.pow(2, gMaxZoom - z);
+  var wid = gCanvas.width * zoomFactor;
+  var ht = gCanvas.height * zoomFactor;
 
 
-  x *= Math.pow(2, gMaxZoom - z);
-  y *= Math.pow(2, gMaxZoom - z);
+  x *= zoomFactor;
+  y *= zoomFactor;
 
 
-  var sz = gTileSize * Math.pow(2, gMaxZoom - z);
+  var sz = gTileSize * zoomFactor;
   if (x > gPos.x + wid / 2 || y > gPos.y + ht / 2 ||
       x + sz < gPos.x - wid / 2 || y - sz < gPos.y - ht / 2)
     return true;
   if (x > gPos.x + wid / 2 || y > gPos.y + ht / 2 ||
       x + sz < gPos.x - wid / 2 || y - sz < gPos.y - ht / 2)
     return true;
@@ -183,10 +190,11 @@ function drawMap() {
   //   if (isOutsideWindow(t))
   //     delete gTiles[t];
   // }
   //   if (isOutsideWindow(t))
   //     delete gTiles[t];
   // }
-  var z = Math.round(gPos.z);
-  var wid = gCanvas.width * Math.pow(2, gMaxZoom - z); // Width in level 18 pixels.
-  var ht = gCanvas.height * Math.pow(2, gMaxZoom - z); // Height in level 18 pixels.
-  var size = gTileSize * Math.pow(2, gMaxZoom - z); // Tile size in level 18 pixels.
+  document.getElementById("zoomLevel").textContent = gPos.z;
+  gZoomFactor = Math.pow(2, gMaxZoom - gPos.z);
+  var wid = gCanvas.width * gZoomFactor; // Width in level 18 pixels.
+  var ht = gCanvas.height * gZoomFactor; // Height in level 18 pixels.
+  var size = gTileSize * gZoomFactor; // Tile size in level 18 pixels.
 
   var xMin = gPos.x - wid / 2; // Corners of the window in level 18 pixels.
   var yMin = gPos.y - ht / 2;
 
   var xMin = gPos.x - wid / 2; // Corners of the window in level 18 pixels.
   var yMin = gPos.y - ht / 2;
@@ -196,9 +204,9 @@ function drawMap() {
   // Go through all the tiles we want. If any of them aren't loaded or being loaded, do so.
   for (var x = Math.floor(xMin / size); x < Math.ceil(xMax / size); x++) {
     for (var y = Math.floor(yMin / size); y < Math.ceil(yMax / size); y++) {
   // Go through all the tiles we want. If any of them aren't loaded or being loaded, do so.
   for (var x = Math.floor(xMin / size); x < Math.ceil(xMax / size); x++) {
     for (var y = Math.floor(yMin / size); y < Math.ceil(yMax / size); y++) {
-      var xoff = (x * size - xMin) / Math.pow(2, gMaxZoom - z);
-      var yoff = (y * size - yMin) / Math.pow(2, gMaxZoom - z);
-      var tileKey = encodeIndex(x, y, z);
+      var xoff = (x * size - xMin) / gZoomFactor;
+      var yoff = (y * size - yMin) / gZoomFactor;
+      var tileKey = encodeIndex(x, y, gPos.z);
       if (gTiles[tileKey] && gTiles[tileKey].complete) {
         // Round here is **CRUICIAL** otherwise the images are filtered and the performance sucks (more than expected).
         gContext.drawImage(gTiles[tileKey], Math.round(xoff), Math.round(yoff));
       if (gTiles[tileKey] && gTiles[tileKey].complete) {
         // Round here is **CRUICIAL** otherwise the images are filtered and the performance sucks (more than expected).
         gContext.drawImage(gTiles[tileKey], Math.round(xoff), Math.round(yoff));
@@ -213,8 +221,7 @@ function drawMap() {
             drawMap();
           }
         }
             drawMap();
           }
         }
-        gContext.fillStyle = "#ffffff";
-        gContext.fillRect(Math.round(xoff), Math.round(yoff), gTileSize, gTileSize);
+        gContext.drawImage(gLoadingTile, Math.round(xoff), Math.round(yoff));
       }
     }
   }
       }
     }
   }
@@ -224,7 +231,7 @@ var mapEvHandler = {
   handleEvent: function(aEvent) {
     var touchEvent = aEvent.type.indexOf('touch') != -1;
 
   handleEvent: function(aEvent) {
     var touchEvent = aEvent.type.indexOf('touch') != -1;
 
-    // Bail out on unwanted map moves, but not mousewheel events.
+    // Bail out on unwanted map moves, but not zoom-changing events.
     if (aEvent.type != "DOMMouseScroll" && aEvent.type != "mousewheel") {
       // Bail out if this is neither a touch nor left-click.
       if (!touchEvent && aEvent.button != 0)
     if (aEvent.type != "DOMMouseScroll" && aEvent.type != "mousewheel") {
       // Bail out if this is neither a touch nor left-click.
       if (!touchEvent && aEvent.button != 0)
@@ -249,6 +256,7 @@ var mapEvHandler = {
         }
         var x = coordObj.clientX - gCanvas.offsetLeft;
         var y = coordObj.clientY - gCanvas.offsetTop;
         }
         var x = coordObj.clientX - gCanvas.offsetLeft;
         var y = coordObj.clientY - gCanvas.offsetTop;
+
         if (touchEvent || aEvent.button === 0) {
           gDragging = true;
         }
         if (touchEvent || aEvent.button === 0) {
           gDragging = true;
         }
@@ -262,8 +270,8 @@ var mapEvHandler = {
         if (gDragging === true) {
           var dX = x - gLastMouseX;
           var dY = y - gLastMouseY;
         if (gDragging === true) {
           var dX = x - gLastMouseX;
           var dY = y - gLastMouseY;
-          gPos.x -= dX * Math.pow(2, gMaxZoom - gPos.z);
-          gPos.y -= dY * Math.pow(2, gMaxZoom - gPos.z);
+          gPos.x -= dX * gZoomFactor;
+          gPos.y -= dY * gZoomFactor;
           drawMap();
         }
         gLastMouseX = x;
           drawMap();
         }
         gLastMouseX = x;
@@ -290,6 +298,17 @@ var mapEvHandler = {
           delta = -aEvent.detail / 3;
         }
 
           delta = -aEvent.detail / 3;
         }
 
+        // Calculate new center of the map - same point stays under the mouse.
+        // This means that the pixel distance between the old center and point
+        // must equal the pixel distance of the new center and that point.
+        var x = coordObj.clientX - gCanvas.offsetLeft;
+        var y = coordObj.clientY - gCanvas.offsetTop;
+        // Zoom factor after this action.
+        var newZoomFactor = Math.pow(2, gMaxZoom - gPos.z + (delta > 0 ? -1 : 1));
+        gPos.x -= (x - gCanvas.width / 2) * (newZoomFactor - gZoomFactor);
+        gPos.y -= (y - gCanvas.height / 2) * (newZoomFactor - gZoomFactor);
+        document.getElementById("debug").textContent = newZoomFactor + " - " + gZoomFactor;
+
         if (delta > 0)
           zoomIn();
         else if (delta < 0)
         if (delta > 0)
           zoomIn();
         else if (delta < 0)
index 6719f9707e30f0e68666994bdc218f3f205c86c3..a9b23fc62e4cc45abf5da411cb80e7901a72cbe3 100644 (file)
@@ -6,6 +6,11 @@ manifest.webapp
 js/map.js
 js/ui.js
 style/lantea.css
 js/map.js
 js/ui.js
 style/lantea.css
+style/loading.png
+style/lanteaIcon16.png
+style/lanteaIcon32.png
+style/lanteaIcon64.png
+style/lanteaIcon128.png
 
 NETWORK:
 
 
 NETWORK:
 
index d3cc356c7670ae514aea8fdb23c414198d837d37..b51cf3e0357e44583ccbca681cf575333e2036ab 100644 (file)
@@ -1,11 +1,17 @@
 {
 {
-  "name": "Lantea",
-  "description": "geologger",
+  "name": "Lantea Map",
+  "description": "Mapping and tracking application",
   "launch_path": "/index.html",
   "developer": {
     "name": "Robert Kaiser",
     "url": "http://www.kairo.at/"
   },
   "launch_path": "/index.html",
   "developer": {
     "name": "Robert Kaiser",
     "url": "http://www.kairo.at/"
   },
+  "icons": {
+    "16": "/style/lanteaIcon16.png",
+    "32": "/style/lanteaIcon32.png",
+    "64": "/style/lanteaIcon64.png",
+    "128": "/style/lanteaIcon128.png"
+  },
   "installs_allowed_from": [
     "https://apps-preview.mozilla.org",
     "https://apps.mozilla.org"
   "installs_allowed_from": [
     "https://apps-preview.mozilla.org",
     "https://apps.mozilla.org"
index d39eed6b75d9dc3bf3d706b808dad3eef423ea6f..8338a293714839bfcd04e230479c64429cf17456 100644 (file)
@@ -52,6 +52,13 @@ h1 {
   z-index: 5;
 }
 
   z-index: 5;
 }
 
+#zoomLevel {
+  background-color: rgba(255, 255, 255, .8);
+  border-radius: 3px;
+  padding: 0 3px;
+}
+
+
 #settings {
   display: none;
   background-color: rgba(255, 255, 255, .8);
 #settings {
   display: none;
   background-color: rgba(255, 255, 255, .8);
@@ -73,6 +80,13 @@ h1 {
   z-index: 1;
 }
 
   z-index: 1;
 }
 
+#debug {
+  position: absolute;
+  bottom: .5em;
+  left: .5em;
+  margin: 0;
+}
+
 #copyright {
   position: absolute;
   bottom: .5em;
 #copyright {
   position: absolute;
   bottom: .5em;
diff --git a/style/lanteaIcon128.png b/style/lanteaIcon128.png
new file mode 100644 (file)
index 0000000..e7ac5fa
Binary files /dev/null and b/style/lanteaIcon128.png differ
diff --git a/style/lanteaIcon16.png b/style/lanteaIcon16.png
new file mode 100644 (file)
index 0000000..2027513
Binary files /dev/null and b/style/lanteaIcon16.png differ
diff --git a/style/lanteaIcon32.png b/style/lanteaIcon32.png
new file mode 100644 (file)
index 0000000..55d92c8
Binary files /dev/null and b/style/lanteaIcon32.png differ
diff --git a/style/lanteaIcon64.png b/style/lanteaIcon64.png
new file mode 100644 (file)
index 0000000..438e463
Binary files /dev/null and b/style/lanteaIcon64.png differ
diff --git a/style/loading.png b/style/loading.png
new file mode 100644 (file)
index 0000000..e147275
Binary files /dev/null and b/style/loading.png differ