X-Git-Url: https://git-public.kairo.at/?p=lantea.git;a=blobdiff_plain;f=js%2Fmap.js;h=5c93ae5741dbf71885253461fbe3e7b6e2a4cd32;hp=d269a9574aec018f21894c08aeb674341852a3e5;hb=cef88e12438c01ca96198c62b32e7d3e99617625;hpb=8389557a642218382b7294fde519389b72551388 diff --git a/js/map.js b/js/map.js index d269a95..5c93ae5 100644 --- a/js/map.js +++ b/js/map.js @@ -61,7 +61,7 @@ var gLoadingTile; var gMapPrefsLoaded = false; var gDragging = false; -var gDragTouchID; +var gDragTouchID, gPinchStartWidth; var gGeoWatchID; var gTrack = []; @@ -89,74 +89,105 @@ function initMap() { } } - var loopCnt = 0; - var getPersistentPrefs = function() { - if (mainDB) { - gWaitCounter++; - gPrefs.get("position", function(aValue) { - if (aValue) { - gPos = aValue; - gWaitCounter--; - } - }); - gWaitCounter++; - gPrefs.get("center_map", function(aValue) { - if (aValue === undefined) - document.getElementById("centerCheckbox").checked = true; - else - document.getElementById("centerCheckbox").checked = aValue; - setCentering(document.getElementById("centerCheckbox")); - gWaitCounter--; - }); - gWaitCounter++; - gPrefs.get("tracking_enabled", function(aValue) { - if (aValue === undefined) - document.getElementById("trackCheckbox").checked = true; - else - document.getElementById("trackCheckbox").checked = aValue; - gWaitCounter--; - }); - gWaitCounter++; - gTrackStore.getList(function(aTPoints) { - if (gDebug) - console.log(aTPoints.length + " points loaded."); - if (aTPoints.length) { - gTrack = aTPoints; + console.log("map vars set, loading prefs..."); + loadPrefs(); +} + +function loadPrefs(aEvent) { + if (aEvent && aEvent.type == "prefs-step") { + console.log("wait: " + gWaitCounter); + if (gWaitCounter == 0) { + gAction.removeEventListener(aEvent.type, loadPrefs, false); + gMapPrefsLoaded = true; + console.log("prefs loaded."); + + gTrackCanvas.addEventListener("mouseup", mapEvHandler, false); + gTrackCanvas.addEventListener("mousemove", mapEvHandler, false); + gTrackCanvas.addEventListener("mousedown", mapEvHandler, false); + gTrackCanvas.addEventListener("mouseout", mapEvHandler, false); + + gTrackCanvas.addEventListener("touchstart", mapEvHandler, false); + gTrackCanvas.addEventListener("touchmove", mapEvHandler, false); + gTrackCanvas.addEventListener("touchend", mapEvHandler, false); + gTrackCanvas.addEventListener("touchcancel", mapEvHandler, false); + gTrackCanvas.addEventListener("touchleave", mapEvHandler, false); + + gTrackCanvas.addEventListener("wheel", mapEvHandler, false); + + document.getElementById("body").addEventListener("keydown", mapEvHandler, false); + + document.getElementById("copyright").innerHTML = + gMapStyles[gActiveMap].copyright; + + gLoadingTile = new Image(); + gLoadingTile.src = "style/loading.png"; + gLoadingTile.onload = function() { + var throwEv = new CustomEvent("mapinit-done"); + gAction.dispatchEvent(throwEv); + }; + } + } + else { + if (aEvent) + gAction.removeEventListener(aEvent.type, loadPrefs, false); + gAction.addEventListener("prefs-step", loadPrefs, false); + gWaitCounter++; + gPrefs.get("position", function(aValue) { + if (aValue) { + gPos = aValue; + } + gWaitCounter--; + var throwEv = new CustomEvent("prefs-step"); + gAction.dispatchEvent(throwEv); + }); + gWaitCounter++; + gPrefs.get("center_map", function(aValue) { + if (aValue === undefined) + document.getElementById("centerCheckbox").checked = true; + else + document.getElementById("centerCheckbox").checked = aValue; + setCentering(document.getElementById("centerCheckbox")); + gWaitCounter--; + var throwEv = new CustomEvent("prefs-step"); + gAction.dispatchEvent(throwEv); + }); + gWaitCounter++; + gPrefs.get("tracking_enabled", function(aValue) { + if (aValue === undefined) + document.getElementById("trackCheckbox").checked = true; + else + document.getElementById("trackCheckbox").checked = aValue; + gWaitCounter--; + var throwEv = new CustomEvent("prefs-step"); + gAction.dispatchEvent(throwEv); + }); + gWaitCounter++; + var trackLoadStarted = false; + var 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--; - }); - } - else - setTimeout(getPersistentPrefs, 100); - loopCnt++; - if (loopCnt > 50) { - console.log("Loading prefs failed."); - } - }; - getPersistentPrefs(); - - gTrackCanvas.addEventListener("mouseup", mapEvHandler, false); - gTrackCanvas.addEventListener("mousemove", mapEvHandler, false); - gTrackCanvas.addEventListener("mousedown", mapEvHandler, false); - gTrackCanvas.addEventListener("mouseout", mapEvHandler, false); - - gTrackCanvas.addEventListener("touchstart", mapEvHandler, false); - gTrackCanvas.addEventListener("touchmove", mapEvHandler, false); - gTrackCanvas.addEventListener("touchend", mapEvHandler, false); - gTrackCanvas.addEventListener("touchcancel", mapEvHandler, false); - gTrackCanvas.addEventListener("touchleave", mapEvHandler, false); - - gTrackCanvas.addEventListener("wheel", mapEvHandler, false); - - document.getElementById("body").addEventListener("keydown", mapEvHandler, false); - - document.getElementById("copyright").innerHTML = - gMapStyles[gActiveMap].copyright; - - gLoadingTile = new Image(); - gLoadingTile.src = "style/loading.png"; - gWaitCounter++; - gLoadingTile.onload = function() { gWaitCounter--; }; + var throwEv = new CustomEvent("prefs-step"); + gAction.dispatchEvent(throwEv); + } + }); + } } function resizeAndDraw() { @@ -339,6 +370,10 @@ function drawMap(aPixels, aOverdraw) { } } } + drawTrack(); +} + +function drawTrack() { gLastDrawnPoint = null; gCurPosMapCache = undefined; gTrackContext.clearRect(0, 0, gTrackCanvas.width, gTrackCanvas.height); @@ -451,6 +486,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); } @@ -466,6 +509,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) { @@ -494,6 +578,7 @@ var mapEvHandler = { break; case "mouseup": case "touchend": + gPinchStartWidth = null; gDragging = false; showUI(); break; @@ -740,7 +825,7 @@ function endTracking() { function clearTrack() { gTrack = []; gTrackStore.clear(); - drawMap({left: 0, right: 0, top: 0, bottom: 0}); + drawTrack(); } var gTileService = {