X-Git-Url: https://git-public.kairo.at/?p=lantea.git;a=blobdiff_plain;f=js%2Fmap.js;h=e0f0a39708ae98a301b02bddb4281c0af884455c;hp=62a14d489db4059c6c047f10ca5f2a890ec43a56;hb=7e9524be0118bd5890d84b83ced68e8ab3decf5f;hpb=b911a7d66567a9912b1f131f27234a5354646fa5 diff --git a/js/map.js b/js/map.js index 62a14d4..e0f0a39 100644 --- a/js/map.js +++ b/js/map.js @@ -3,7 +3,7 @@ * 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. @@ -61,7 +61,7 @@ var gLoadingTile; var gMapPrefsLoaded = false; var gDragging = false; -var gDragTouchID; +var gDragTouchID, gPinchStartWidth; var gGeoWatchID; var gTrack = []; @@ -135,10 +135,10 @@ function loadPrefs(aEvent) { gPrefs.get("position", function(aValue) { if (aValue) { gPos = aValue; - gWaitCounter--; - var throwEv = new CustomEvent("prefs-step"); - gAction.dispatchEvent(throwEv); } + gWaitCounter--; + var throwEv = new CustomEvent("prefs-step"); + gAction.dispatchEvent(throwEv); }); gWaitCounter++; gPrefs.get("center_map", function(aValue) { @@ -162,15 +162,29 @@ function loadPrefs(aEvent) { 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); }); } } @@ -355,6 +369,10 @@ function drawMap(aPixels, aOverdraw) { } } } + drawTrack(); +} + +function drawTrack() { gLastDrawnPoint = null; gCurPosMapCache = undefined; gTrackContext.clearRect(0, 0, gTrackCanvas.width, gTrackCanvas.height); @@ -467,6 +485,14 @@ var mapEvHandler = { 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); } @@ -482,6 +508,47 @@ var mapEvHandler = { 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) { @@ -510,6 +577,7 @@ var mapEvHandler = { break; case "mouseup": case "touchend": + gPinchStartWidth = null; gDragging = false; showUI(); break; @@ -756,7 +824,7 @@ function endTracking() { function clearTrack() { gTrack = []; gTrackStore.clear(); - drawMap({left: 0, right: 0, top: 0, bottom: 0}); + drawTrack(); } var gTileService = {