* You can obtain one at http://mozilla.org/MPL/2.0/. */
var gMapCanvas, gMapContext, gTrackCanvas, gTrackContext, gGeolocation;
-var gDebug = false;
+var gDebug = true;
var gTileSize = 256;
var gMaxZoom = 18; // The minimum is 0.
var gMapPrefsLoaded = false;
var gDragging = false;
-var gDragTouchID;
+var gDragTouchID, gPinchStartWidth;
var gGeoWatchID;
var gTrack = [];
gPrefs.get("position", function(aValue) {
if (aValue) {
gPos = aValue;
- gWaitCounter--;
}
+ gWaitCounter--;
+ var throwEv = new CustomEvent("prefs-step");
+ gAction.dispatchEvent(throwEv);
});
gWaitCounter++;
gPrefs.get("center_map", function(aValue) {
gAction.dispatchEvent(throwEv);
});
gWaitCounter++;
- gTrackStore.getList(function(aTPoints) {
- if (gDebug)
- console.log(aTPoints.length + " points loaded.");
- if (aTPoints.length) {
- gTrack = aTPoints;
+ var trackLoadStarted = false, redrawBase = 100;
+ gTrackStore.getListStepped(function(aTPoint) {
+ if (aTPoint) {
+ // Add in front and return new length.
+ var tracklen = gTrack.unshift(aTPoint);
+ // Redraw track periodically, larger distance the longer it gets.
+ // Initial paint will do initial track drawing.
+ if (tracklen % redrawBase == 0) {
+ drawTrack();
+ redrawBase = tracklen;
+ }
+ }
+ else {
+ // Last point received.
+ drawTrack();
+ }
+ if (!trackLoadStarted) {
+ // We have the most recent point, if present, rest will load async.
+ trackLoadStarted = true;
+ gWaitCounter--;
+ var throwEv = new CustomEvent("prefs-step");
+ gAction.dispatchEvent(throwEv);
}
- gWaitCounter--;
- var throwEv = new CustomEvent("prefs-step");
- gAction.dispatchEvent(throwEv);
});
}
}
}
}
}
+ drawTrack();
+}
+
+function drawTrack() {
gLastDrawnPoint = null;
gCurPosMapCache = undefined;
gTrackContext.clearRect(0, 0, gTrackCanvas.width, gTrackCanvas.height);
case "mousedown":
case "touchstart":
if (touchEvent) {
+ if (aEvent.targetTouches.length == 2) {
+ gPinchStartWidth = Math.sqrt(
+ Math.pow(aEvent.targetTouches.item(1).clientX -
+ aEvent.targetTouches.item(0).clientX, 2) +
+ Math.pow(aEvent.targetTouches.item(1).clientY -
+ aEvent.targetTouches.item(0).clientY, 2)
+ );
+ }
gDragTouchID = aEvent.changedTouches.item(0).identifier;
coordObj = aEvent.changedTouches.identifiedTouch(gDragTouchID);
}
break;
case "mousemove":
case "touchmove":
+ if (touchEvent && aEvent.targetTouches.length == 2) {
+ curPinchStartWidth = Math.sqrt(
+ Math.pow(aEvent.targetTouches.item(1).clientX -
+ aEvent.targetTouches.item(0).clientX, 2) +
+ Math.pow(aEvent.targetTouches.item(1).clientY -
+ aEvent.targetTouches.item(0).clientY, 2)
+ );
+ if (!gPinchStartWidth)
+ gPinchStartWidth = curPinchStartWidth;
+
+ if (gPinchStartWidth / curPinchStartWidth > 1.7 ||
+ gPinchStartWidth / curPinchStartWidth < 0.6) {
+ var newZoomLevel = gPos.z + (gPinchStartWidth < curPinchStartWidth ? 1 : -1);
+ if ((newZoomLevel >= 0) && (newZoomLevel <= gMaxZoom)) {
+ // Calculate new center of the map - preserve middle of pinch.
+ // This means that pixel distance between old center and middle
+ // must equal pixel distance of new center and middle.
+ var x = (aEvent.targetTouches.item(1).clientX +
+ aEvent.targetTouches.item(0).clientX) / 2 -
+ gMapCanvas.offsetLeft;
+ var y = (aEvent.targetTouches.item(1).clientY +
+ aEvent.targetTouches.item(0).clientY) / 2 -
+ gMapCanvas.offsetTop;
+
+ // Zoom factor after this action.
+ var newZoomFactor = Math.pow(2, gMaxZoom - newZoomLevel);
+ gPos.x -= (x - gMapCanvas.width / 2) * (newZoomFactor - gZoomFactor);
+ gPos.y -= (y - gMapCanvas.height / 2) * (newZoomFactor - gZoomFactor);
+
+ if (gPinchStartWidth < curPinchStartWidth)
+ zoomIn();
+ else
+ zoomOut();
+
+ // Reset pinch start width and start another pinch gesture.
+ gPinchStartWidth = null;
+ }
+ }
+ // If we are in a pinch, do not drag.
+ break;
+ }
var x = coordObj.clientX - gMapCanvas.offsetLeft;
var y = coordObj.clientY - gMapCanvas.offsetTop;
if (gDragging === true) {
break;
case "mouseup":
case "touchend":
+ gPinchStartWidth = null;
gDragging = false;
showUI();
break;
function clearTrack() {
gTrack = [];
gTrackStore.clear();
- drawMap({left: 0, right: 0, top: 0, bottom: 0});
+ drawTrack();
}
var gTileService = {