diff options
| author | Pliable Pixels <pliablepixels@gmail.com> | 2017-01-06 15:02:36 -0500 |
|---|---|---|
| committer | Pliable Pixels <pliablepixels@gmail.com> | 2017-01-06 15:02:36 -0500 |
| commit | 7d019a5b495bd512202c353f320c242695ddd671 (patch) | |
| tree | 07a3bf001e317b5fa7b106548ed8b3bc39c58f3d | |
| parent | e91f7c28aa780027c6e399820615871011e3311f (diff) | |
zone editing UI framework sort of done - no backend code, so hiding for now #423
| -rw-r--r-- | www/css/style.css | 1 | ||||
| -rw-r--r-- | www/js/MonitorModalCtrl.js | 210 | ||||
| -rw-r--r-- | www/js/app.js | 15 | ||||
| -rw-r--r-- | www/templates/monitors-modal.html | 62 |
4 files changed, 254 insertions, 34 deletions
diff --git a/www/css/style.css b/www/css/style.css index c25dfd59..3383e3fd 100644 --- a/www/css/style.css +++ b/www/css/style.css @@ -1224,6 +1224,7 @@ videogular div.event-time { .zonelayer .zonepoint { stroke:#2ecc71; fill:#2ecc71; +fill-opacity: 0.8; } .zonelayer .Active { diff --git a/www/js/MonitorModalCtrl.js b/www/js/MonitorModalCtrl.js index af1cd5d4..0a18e1c6 100644 --- a/www/js/MonitorModalCtrl.js +++ b/www/js/MonitorModalCtrl.js @@ -17,6 +17,12 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ $scope.zoneArray = []; var originalZones = []; $scope.isZoneEdit = false; + var _moveStart = false; + var targetID = ""; + $scope.imageZoomable = true; + + + $scope.csize = ($rootScope.platformOS == 'desktop') ? 10:20; window.addEventListener("resize", function(){imageLoaded();}, false); @@ -401,20 +407,74 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ $scope.saveZones = function() { + var str=""; + for (var i=0; i < originalZones.length; i++) + { + str = str + "o:"+originalZones[i].coords+"<br/>n:"+$scope.zoneArray[i].coords+"--------------------------------------------------<br/>"; + + } $rootScope.zmPopup = SecuredPopups.show('confirm', { title: 'Sure', - template: 'Shall we save?', + template: str, okText: $translate.instant('kButtonOk'), cancelText: $translate.instant('kButtonCancel'), }); }; + $scope.changeCircleSize = function() + { + $scope.csize = Math.max (($scope.csize + 5) % 31, 10); + + }; + $scope.toggleZoneEdit = function() { $scope.isZoneEdit = !$scope.isZoneEdit; + + + $scope.connKey = (Math.floor((Math.random() * 999999) + 1)).toString(); + + + if ($scope.isZoneEdit) + { + $ionicScrollDelegate.$getByHandle("imgscroll").zoomTo(1, true); + $scope.imageZoomable = false; + //document.getElementById("imgscroll").zooming="false"; + + for (var i=0; i < $scope.circlePoints.length; i++) + { + var t = document.getElementById("circle-"+i); + if (t) + { + t.removeEventListener("touchstart",moveStart); + t.removeEventListener("mousedown",moveStart); + //t.removeEventListener("mousemove",moveContinue); + //t.removeEventListener("mouseup",moveStop); + + + t.addEventListener("touchstart",moveStart); + t.addEventListener("mousedown",moveStart); + //t.addEventListener("mousemove",moveContinue); + //t.addEventListener("mouseup",moveStop); + + + console.log ("Found circle-"+i); + } + else + { + console.log ("did not find circle-"+i); + } + + } + } + else // get out of edit + { + + $scope.imageZoomable = true; + } }; @@ -430,23 +490,26 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ imageLoaded(); }; + $scope.checkZoom = function() + { + //var z = $ionicScrollDelegate.$getByHandle("imgscroll").getScrollPosition().zoom; + //imageLoaded(); + + }; + $scope.circleTouch = function (evt) { console.log ("TOUCH"); }; - $scope.circleOnDrag = function (evt, ndx) + //$scope.circleOnDrag = function (evt, ndx) + function recomputePolygons (ax, ay, ndx,z) { - //console.log ("DRAG"); - - //evt.preventDefault(); - //evt.stopPropagation(); - var ax = evt.gesture.center.pageX; - var ay = evt.gesture.center.pageY; - + // we get screen X/Y - need to translate // to SVG points + console.log ("recompute with",ax,"&",ay); var svg=document.getElementById('zsvg'); var pt = svg.createSVGPoint(); pt.x = ax; @@ -465,6 +528,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ { newPoints = newPoints + " " +$scope.circlePoints[i].x+","+$scope.circlePoints[i].y; } + console.log ("recomputed polygon:", newPoints); } // console.log ("OLD ZONE FOR:"+zi+" is "+$scope.zoneArray[zi].coords ); //console.log ("NEW ZONE FOR:"+zi+" is "+newPoints); @@ -472,7 +536,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ //console.log ("INDEX="+ndx+" DRAG="+svgP.x+":"+svgP.y); - }; + } // credit: http://stackoverflow.com/questions/41411891/most-elegant-way-to-parse-scale-and-re-string-a-string-of-number-co-ordinates?noredirect=1#41411927 // This function scales coords of zones based on current image size @@ -485,6 +549,85 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ }).join(' '); } + function moveContinue(event) + { + if (!_moveStart) {return;} + + console.log ("CONTINUE: target id="+targetID); + + + /*if(event.preventDefault) event.preventDefault(); + if (event.gesture) event.gesture.preventDefault() ; + if (event.gesture) event.gesture.stopPropagation();*/ + + var x,y; + + var z = $ionicScrollDelegate.$getByHandle("imgscroll").getScrollPosition().zoom; + console.log ("zoom is:"+z); + + //console.log(event, this, "t"); + if (event.touches) + { + //console.log ("TOUCH"); + x = event.targetTouches[0].pageX; + y = event.targetTouches[0].pageY; + + } + else + { + //console.log ("MOUSE"); + x = event.clientX ; + y = event.clientY ; + + + } + + + console.log ("X="+x+" Y="+y + " sl="+document.body.scrollLeft+ " sy="+document.body.scrollTop); + $timeout (function() {recomputePolygons (x,y,targetID,1);}); + + + } + + function moveStop (event) + { + _moveStart = false; + console.log ("STOP"); + } + + function moveStart(event) + { + + _moveStart=true; + targetID = event.target.id.substring(7); + console.log ("START: target id="+targetID); + + if(event.preventDefault) event.preventDefault(); + if (event.gesture) event.gesture.preventDefault() ; + if (event.gesture) event.gesture.stopPropagation(); + + var z = $ionicScrollDelegate.$getByHandle("imgscroll").getScrollPosition().zoom; + console.log ("zoom is:"+z); + + var x,y; + // perhaps event.targetTouches[0]? + if (event.touches) + { + //console.log(event.changedTouches[0], this, "t"); + x = event.touches[0].pageX; + y = event.touches[0].pageY; + + } + else + { + //console.log(event, this, "t"); + x = event.clientX ; + y = event.clientY ; + + } + console.log ("X="+x+" Y="+y + " sl="+document.body.scrollLeft+ " sy="+document.body.scrollTop); + + } // called when the live monitor image loads @@ -494,11 +637,14 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ var img =document.getElementById("singlemonitor"); + //$scope.cw = img.naturalWidth; + //$scope.ch = img.naturalHeight; + $scope.cw = img.naturalWidth; $scope.ch = img.naturalHeight; - - console.log (img.clientWidth+ "x"+img.clientHeight ); + //console.log ("REPORTED DIM:" + $scope.cw+ "x"+$scope.ch ); + //console.log ("ORIGINAL DIM:" + img.naturalWidth+ "x"+img.naturalHeight); //https://server/zm/api/zones/forMonitor/7.json // $scope.zoneArray = []; @@ -515,10 +661,14 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ { var sx = $scope.cw/ow; var sy = $scope.ch/oh; - $scope.zoneArray.push({ - coords:scaleCoords(originalZones[i].coords,sx,sy), + //$scope.zoneArray.push({ + // coords:scaleCoords(originalZones[i].coords,sx,sy), + // type:originalZones[i].type}); + $scope.zoneArray.push({ + coords:originalZones[i].coords, type:originalZones[i].type}); + } // now create a points array for circle handles @@ -531,13 +681,17 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ { var o=itm.split(','); $scope.circlePoints.push({x:o[0],y:o[1], zoneIndex:i}); - console.log ("CIRCLE X="+o[0]+"Y="+o[1]); + + // console.log ("CIRCLE X="+o[0]+"Y="+o[1]); }); } + + + } //------------------------------------------------------------- @@ -1083,7 +1237,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ $scope.imageFit = !$scope.imageFit; if ($scope.imageFit) - $scope.aspectFit=""; + $scope.aspectFit="xMidYMid meet"; else $scope.aspectFit = "xMidYMid slice"; @@ -1264,6 +1418,19 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ //------------------------------------------------------------- $scope.zoomImage = function(val) { + + if ($scope.isZoneEdit) + { + $ionicLoading.show( + { + //template: $translate.instant('kError'), + template: 'zoom disabled in zone edit mode', + noBackdrop: true, + duration: 2000 + }); + + return; + } var zl = parseInt($ionicScrollDelegate.$getByHandle("imgscroll").getScrollPosition().zoom); if (zl == 1 && val == -1) { @@ -1501,6 +1668,7 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ { originalZones.push ({ coords:succ.data.zones[i].Zone.Coords, + area: succ.data.zones[i].Zone.Area, type:succ.data.zones[i].Zone.Type}); } @@ -1518,6 +1686,16 @@ angular.module('zmApp.controllers').controller('MonitorModalCtrl', ['$scope', '$ $scope.monStatus = ""; document.addEventListener("pause", onPause, false); document.addEventListener("resume", onResume, false); + + document.addEventListener("mouseup", moveStop, false); + document.addEventListener("touchend", moveStop, false); + + document.addEventListener("mousemove", moveContinue, false); + document.addEventListener("touchmove", moveContinue, false); + + + + $scope.showZones = false; getZones(); diff --git a/www/js/app.js b/www/js/app.js index 7b95eddc..dd8a16cc 100644 --- a/www/js/app.js +++ b/www/js/app.js @@ -869,7 +869,7 @@ angular.module('zmApp', [ var d = $q.defer(); - + console.log (">>>>>>>>>>> DO LOGIN"); NVRDataModel.processFastLogin() // coming here means login not needed, old login is valid @@ -883,6 +883,7 @@ angular.module('zmApp', [ // coming here means login is needed function(error) { + console.log (">>>>>>>>>>>> FAST FAILED - THIS IS OK"); var statename = $ionicHistory.currentStateName(); @@ -905,6 +906,8 @@ angular.module('zmApp', [ $rootScope.zmCookie = ''; // first try to login, if it works, good // else try to do reachability + + console.log (">>>>>>>>>>>> CALLING DO LOGIN"); proceedWithLogin() .then(function(success) { @@ -917,6 +920,7 @@ angular.module('zmApp', [ function(error) // login to main failed, so try others { + console.log (">>>>>>>>>>>> Failed first login, trying reachability"); NVRDataModel.getReachableConfig(true) .then(function(data) { @@ -966,6 +970,8 @@ angular.module('zmApp', [ }); } + console.log (">>>>>>>>>>>>>> ISRECAPTCHA"); + NVRDataModel.isReCaptcha() .then(function(result) { @@ -995,10 +1001,14 @@ angular.module('zmApp', [ }); var loginData = NVRDataModel.getLogin(); + console.log (">>>>>>>>>>>>>> PARALLEL POST WITH RECAPTCHA TO "+loginData.url); + + //NVRDataModel.debug ("*** AUTH LOGIN URL IS " + loginData.url); $http( { method: 'POST', + timeout:5000, //withCredentials: true, url: loginData.url + '/index.php', headers: @@ -1026,6 +1036,7 @@ angular.module('zmApp', [ }) .success(function(data, status, headers) { + console.log (">>>>>>>>>>>>>> PARALLEL POST SUCCESS"); $ionicLoading.hide(); // Coming here does not mean success @@ -1084,6 +1095,8 @@ angular.module('zmApp', [ }) .error(function(error, status) { + + console.log (">>>>>>>>>>>>>> PARALLEL POST ERROR"); $ionicLoading.hide(); //console.log("**** ZM Login FAILED"); diff --git a/www/templates/monitors-modal.html b/www/templates/monitors-modal.html index 6da3cbff..a6e93ec6 100644 --- a/www/templates/monitors-modal.html +++ b/www/templates/monitors-modal.html @@ -1,30 +1,38 @@ <div ng-controller="MonitorModalCtrl" ng-cloak> <ion-modal-view cache-view="false" style="background-color:#444444"> - <ion-content ng-cloak on-double-tap="closeModal();"> + <ion-content ng-cloak on-double-tap="closeModal();" scroll="false"> - <div id="imagecontainer"> - <ion-scroll delegate-handle="imgscroll" has-bouncing=false min-zoom=1 zooming="true" direction="xy" style="width: 100%;" overflow-scroll="false"> + <div id="imagecontainer" > + <ion-scroll ng-if="!isZoneEdit" on-scroll="checkZoom()" delegate-handle="imgscroll" has-bouncing=false min-zoom=1 zooming="true" direction="xy" style="width: 100%;" overflow-scroll="false"> <!-- android needs this 100vh - otherwise max- does not work --> <!-- --> <div id="monitorimage" style="height: 100vh;" class="main"> <div ng-if="$root.authSession!='undefined'"> <div ng-if="!animationInProgress && !isBackground() && connKey"> <!--<span style="color:white">{{currentStreamMode}}</span>--> + <img id="singlemonitor" style="width:100vw; height:100vh;" image-spinner-loader="lines" image-spinner-src="{{monitor.Monitor.streamingURL}}/nph-zms?mode={{currentStreamMode}}&monitor={{monitorId}}&scale={{quality}}{{$root.authSession}}&rand={{$root.modalRand}}&connkey={{connKey}}" ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}" on-swipe-left="onSwipe(monitorId,1)" on-swipe-right="onSwipe(monitorId,-1)" on-double-tap="closeModal();" imageonload="imageLoaded()" /> + </div> + <div ng-if="animationInProgress || isBackground()"> + <img style="width:100vw; height:100vh" ng-src="img/pausevideo.png" class="object-fit_contain" /> + </div> + </div> + <div ng-if="$root.authSession=='undefined'"> + <img id="singlemonitor" ng-src="img/pausevideo.png" style="width:100vw; height:100vh; display:block;" class="object-fit_contain" width="{{((devWidth)/(7-monitorSize[$index]))}}px;" /> + </div> + </div> + </ion-scroll> - <!-- zone overlays if enabled --> - <div ng-show="showZones"> - <svg id="zsvg" width="100vw" height="100vh" class="zonelayer" ng-attr-view_box="0 0 {{cw}} {{ch}}" ng-attr-preserve_aspect_ratio="{{aspectFit}}" on-swipe-left="onSwipe(monitorId,1)" on-swipe-right="onSwipe(monitorId,-1)" on-double-tap="closeModal();"> - - <polygon ng-repeat="item in zoneArray track by $index" ng-class="{'object-fit_cover {{item.type}}':imageFit==false, 'object-fit_contain {{item.type}}':imageFit==true}" ng-attr-points="{{item.coords}}" /> </polygon> - - - <circle ng-show="isZoneEdit" ng-repeat="item in circlePoints track by $index" on-drag="circleOnDrag($event, $index)" class="zonepoint" ng-class="{'object-fit_cover {{item.type}}':imageFit==false, 'object-fit_contain {{item.type}}':imageFit==true}" ng-attr-cx="{{item.x}}" ng-attr-cy="{{item.y}}" r="7"/> - - - </svg> - </div> + <!-- egads, ion-scroll is a bind-on-start directive, so I have to repeat this thanks to zooming = false. Must be a better way --> + <ion-scroll ng-if="isZoneEdit" delegate-handle="imgscroll" has-bouncing=false min-zoom=1 zooming="false" direction="xy" style="width: 100%;" overflow-scroll="false"> + <!-- android needs this 100vh - otherwise max- does not work --> + <!-- --> + <div id="monitorimage" style="height: 100vh;" class="main"> + <div ng-if="$root.authSession!='undefined'"> + <div ng-if="!animationInProgress && !isBackground() && connKey"> + <!--<span style="color:white">{{currentStreamMode}}</span>--> + <img id="singlemonitor" style="width:100vw; height:100vh;" image-spinner-loader="lines" image-spinner-src="{{monitor.Monitor.streamingURL}}/nph-zms?mode={{currentStreamMode}}&monitor={{monitorId}}&scale={{quality}}{{$root.authSession}}&rand={{$root.modalRand}}&connkey={{connKey}}" ng-class="{'object-fit_cover':imageFit==false, 'object-fit_contain':imageFit==true}" on-swipe-left="onSwipe(monitorId,1)" on-swipe-right="onSwipe(monitorId,-1)" on-double-tap="closeModal();" imageonload="imageLoaded()" /> </div> <div ng-if="animationInProgress || isBackground()"> <img style="width:100vw; height:100vh" ng-src="img/pausevideo.png" class="object-fit_contain" /> @@ -35,6 +43,22 @@ </div> </div> </ion-scroll> + + <!-- zone overlays if enabled --> + <div ng-show="showZones"> + <svg id="zsvg" width="100vw" height="100vh" class="zonelayer" ng-attr-view_box="0 0 {{cw}} {{ch}}" ng-attr-preserve_aspect_ratio="{{aspectFit}}" on-swipe-left="onSwipe(monitorId,1)" on-swipe-right="onSwipe(monitorId,-1)" on-double-tap="closeModal();"> + + <polygon ng-repeat="item in zoneArray track by $index" ng-class="{'object-fit_cover {{item.type}}':imageFit==false, 'object-fit_contain {{item.type}}':imageFit==true}" ng-attr-points="{{item.coords}}" /> </polygon> + + + <circle id="circle-{{$index}}" ng-show="isZoneEdit" ng-repeat="item in circlePoints track by $index" class="zonepoint" ng-class="{'object-fit_cover {{item.type}}':imageFit==false, 'object-fit_contain {{item.type}}':imageFit==true}" ng-attr-cx="{{item.x}}" ng-attr-cy="{{item.y}}" ng-attr-r="{{csize}}"/> + + + </svg> + </div> + + + </div> </ion-content> <div ng-show="isControllable=='1' && showPTZ"> @@ -98,14 +122,18 @@ </li> <!-- zone editing is TBD --> - <li ng-if="showZones && $root.platformOS=='desktop' && 0"> + <li ng-if="showZones && 0"> <a href="" ng-click="toggleZoneEdit()"> <i class="icon ion-edit"></i></a> </li> - <li ng-if="showZones && isZoneEdit "> + <li ng-if="showZones && isZoneEdit"> <a href="" ng-click="saveZones()"> <i class="icon ion-android-done-all"></i></a> </li> + <li ng-if="showZones && isZoneEdit"> + <a href="" ng-click="changeCircleSize()"> <i class="icon ion-navigate"></i></a> + </li> + <li> <a href="" ng-click="toggleCycle()"> <i class="icon ion-android-bicycle"></i>-{{cycleText}}</a> </li> |
