Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 var MAX_SWAP_IMG_SIZE = 400; | 1 var MAX_SWAP_IMG_SIZE = 400; |
| 2 var MAGNIFIER_WIDTH = 200; | |
|
epoger
2013/10/21 15:02:53
Is the web UI available somewhere for me to view e
| |
| 3 var MAGNIFIER_HEIGHT = 200; | |
| 4 var MAGNIFIER_HALF_WIDTH = MAGNIFIER_WIDTH * 0.5; | |
| 5 var MAGNIFIER_HALF_HEIGHT = MAGNIFIER_HEIGHT * 0.5; | |
| 6 // TODO add support for a magnified scale factor | |
| 7 var MAGNIFIER_SCALE_FACTOR = 2.0; | |
| 2 | 8 |
| 3 angular.module('diff_viewer', []). | 9 angular.module('diff_viewer', []). |
| 4 config(['$routeProvider', function($routeProvider) { | 10 directive('imgCompare', function() { |
| 5 // Show the list of differences by default | 11 // Custom directive for showing an image that gets swapped my mouseover. |
|
epoger
2013/10/21 15:02:53
my -> by?
djsollen
2013/11/06 16:02:30
Done.
| |
| 6 $routeProvider. | 12 return { |
| 7 otherwise({ templateUrl: '/diff_list.html', controller: DiffListController}) ; | 13 restrict: 'E', // The directive can be used as an element name |
| 8 }]). | 14 replace: true, // The directive replaces itself with the template |
| 9 directive('swapImg', function() { | 15 template: '<canvas/>', |
| 10 // Custom directive for showing an image that gets swapped my mouseover. | 16 scope: true, |
| 11 return { | 17 link: function(scope, elm, attrs, ctrl) { |
| 12 restrict: 'E', // The directive can be used as an element name | 18 var image = new Image(); |
| 13 replace: true, // The directive replaces itself with the template | 19 var canvas = elm[0]; |
| 14 template: '<canvas ng-mouseenter="swap()" ng-mouseleave="swap()"></canva s>', | 20 var ctx = canvas.getContext('2d'); |
| 15 scope: { // The attributes below are bound to the scope | |
| 16 leftSrc: '@', | |
| 17 rightSrc: '@', | |
| 18 side: '@' | |
| 19 }, | |
| 20 link: function(scope, elm, attrs, ctrl) { | |
| 21 var leftImage = new Image(); | |
| 22 var rightImage = new Image(); | |
| 23 var ctx = elm[0].getContext('2d'); | |
| 24 | 21 |
| 25 scope.render = function() { | 22 var magnifiyContent = false; |
|
epoger
2013/10/21 15:02:53
magnifiy -> magnify
djsollen
2013/11/06 16:02:30
Done.
| |
| 26 var image; | |
| 27 if (scope.side == "left") { | |
| 28 image = leftImage; | |
| 29 } else { | |
| 30 image = rightImage; | |
| 31 } | |
| 32 | 23 |
| 33 // Make it so the maximum size of an image is MAX_SWAP_IMG_SIZE, and the images are | 24 // When the type attribute changes, load the image and then render |
| 34 // scaled down in halves. | 25 attrs.$observe('type', function(value) { |
| 35 var divisor = 1; | 26 switch(value) { |
| 36 while ((image.width / divisor) > MAX_SWAP_IMG_SIZE) { | 27 case "alphaMask": |
| 37 divisor *= 2; | 28 image.src = scope.record.differencePath; |
| 38 } | 29 break; |
| 30 case "baseline": | |
| 31 image.src = scope.record.baselinePath; | |
| 32 magnifiyContent = true; | |
| 33 break; | |
| 34 case "test": | |
| 35 image.src = scope.record.testPath; | |
|
epoger
2013/10/21 15:02:53
inconsistent indentation in here
| |
| 36 magnifiyContent = true; | |
| 37 break; | |
| 38 default: | |
| 39 console.log("Unknown type attribute on <img-compare>: " + va lue); | |
| 40 return; | |
| 41 } | |
| 39 | 42 |
| 40 // Set canvas to correct size and draw the image into it | 43 image.onload = function() { |
| 41 elm[0].width = image.width / divisor; | 44 // compute the scaled image width/height for image and canvas |
| 42 elm[0].height = image.height / divisor; | 45 var divisor = 1; |
| 43 ctx.drawImage(image, 0, 0, elm[0].width, elm[0].height); | 46 // Make it so the maximum size of an image is MAX_SWAP_IMG_SIZ E, |
| 47 // and the images are scaled down in halves. | |
| 48 while ((image.width / divisor) > MAX_SWAP_IMG_SIZE) { | |
|
epoger
2013/10/21 15:02:53
The iterative implementation is _ok_, but couldn't
| |
| 49 divisor *= 2; | |
| 50 } | |
| 51 | |
| 52 scope.setImgScaleFactor(1 / divisor); | |
| 53 | |
| 54 // Set canvas to correct size | |
| 55 canvas.width = image.width * scope.imgScaleFactor; | |
| 56 canvas.height = image.height * scope.imgScaleFactor; | |
| 57 | |
| 58 // render the image onto the canvas | |
| 59 scope.renderImage(); | |
| 60 } | |
| 61 }); | |
| 62 | |
| 63 // When the magnify attribute changes, render the magnified rect at | |
| 64 // the default zoom level. | |
| 65 scope.$watch('magnifyCenter', function(magCenter) { | |
| 66 if (!magnifiyContent) { | |
| 67 return; | |
| 68 } | |
| 69 | |
| 70 scope.renderImage(); | |
| 71 | |
| 72 if (!magCenter) { | |
| 73 return; | |
| 74 } | |
| 75 | |
| 76 var magX = magCenter.x - MAGNIFIER_HALF_WIDTH; | |
| 77 var magY = magCenter.y - MAGNIFIER_HALF_HEIGHT; | |
| 78 | |
| 79 var magMaxX = canvas.width - MAGNIFIER_WIDTH; | |
| 80 var magMaxY = canvas.height - MAGNIFIER_HEIGHT; | |
| 81 | |
| 82 var magRect = { x: Math.max(0, Math.min(magX, magMaxX)), | |
| 83 y: Math.max(0, Math.min(magY, magMaxY)), | |
| 84 width: MAGNIFIER_WIDTH, | |
| 85 height: MAGNIFIER_HEIGHT | |
| 86 }; | |
| 87 | |
| 88 var imgRect = { x: (magCenter.x / scope.imgScaleFactor) - MAGNIFIE R_HALF_WIDTH, | |
| 89 y: (magCenter.y / scope.imgScaleFactor) - MAGNIFI ER_HALF_HEIGHT, | |
| 90 width: MAGNIFIER_WIDTH, | |
| 91 height: MAGNIFIER_HEIGHT | |
| 92 }; | |
| 93 | |
| 94 // draw the magnified image | |
| 95 ctx.clearRect(magRect.x, magRect.y, magRect.width, magRect.height) ; | |
| 96 ctx.drawImage(image, imgRect.x, imgRect.y, imgRect.width, imgRect. height, | |
| 97 magRect.x, magRect.y, magRect.width, magRect.height) ; | |
| 98 | |
| 99 // draw the outline rect | |
| 100 ctx.beginPath(); | |
| 101 ctx.rect(magRect.x, magRect.y, magRect.width, magRect.height); | |
| 102 ctx.lineWidth = 2; | |
| 103 ctx.strokeStyle = 'red'; | |
| 104 ctx.stroke(); | |
| 105 | |
| 106 }); | |
| 107 | |
| 108 scope.renderImage = function() { | |
| 109 ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| 110 ctx.drawImage(image, 0, 0, canvas.width, canvas.height); | |
| 111 }; | |
| 112 | |
| 113 scope.computeMagnifierOutline = function(event) { | |
| 114 var scaledWidth = MAGNIFIER_WIDTH * scope.imgScaleFactor; | |
| 115 var scaledHeight = MAGNIFIER_HEIGHT * scope.imgScaleFactor; | |
| 116 return { | |
| 117 x: event.offsetX - (scaledWidth * 0.5), | |
| 118 y: event.offsetY - (scaledHeight * 0.5), | |
| 119 width: scaledWidth, | |
| 120 height: scaledHeight | |
| 44 }; | 121 }; |
| 122 }; | |
| 45 | 123 |
| 46 // When the leftSrc attribute changes, load the image and then reren der | 124 scope.MagnifyDraw = function(event, startMagnify) { |
|
epoger
2013/10/21 15:02:53
please document the function parameters and behavi
| |
| 47 attrs.$observe('leftSrc', function(value) { | 125 if (startMagnify) { |
| 48 leftImage.src = value; | 126 scope.setMagnifierState(true); |
|
epoger
2013/10/21 15:02:53
inconsistent indentation again
| |
| 49 leftImage.onload = function() { | 127 } else if (!scope.magnifierOn) { |
| 50 if (scope.side == "left") { | 128 return; |
| 51 scope.render(); | 129 } |
| 52 } | |
| 53 }; | |
| 54 }); | |
| 55 | 130 |
| 56 // When the rightSrc attribute changes, load the image and then rere nder | 131 scope.renderImage(); |
| 57 attrs.$observe('rightSrc', function(value) { | |
| 58 rightImage.src = value; | |
| 59 rightImage.onload = function() { | |
| 60 if (scope.side == "right") { | |
| 61 scope.render(); | |
| 62 } | |
| 63 }; | |
| 64 }); | |
| 65 | 132 |
| 66 // Swap which side to draw onto the canvas and then rerender | 133 // render the magnifier outline rect |
| 67 scope.swap = function() { | 134 var rect = scope.computeMagnifierOutline(event); |
| 68 if (scope.side == "left") { | 135 ctx.save(); |
| 69 scope.side = "right"; | 136 ctx.beginPath(); |
| 70 } else { | 137 ctx.rect(rect.x, rect.y, rect.width, rect.height); |
| 71 scope.side = "left"; | 138 ctx.lineWidth = 2; |
| 72 } | 139 ctx.strokeStyle = 'red'; |
| 73 scope.render(); | 140 ctx.stroke(); |
| 74 }; | 141 ctx.restore(); |
| 75 } | 142 |
| 76 }; | 143 // update scope on baseline / test that will cause them to render |
| 144 scope.setMagnifyCenter({x: event.offsetX, y: event.offsetY}); | |
| 145 }; | |
| 146 | |
| 147 scope.MagnifyEnd = function(event) { | |
| 148 scope.renderImage(); | |
| 149 // update scope on baseline / test that will cause them to render | |
| 150 scope.setMagnifierState(false); | |
| 151 scope.setMagnifyCenter(undefined); | |
| 152 }; | |
| 153 } | |
| 154 }; | |
| 77 }); | 155 }); |
| 78 | 156 |
| 157 function ImageController($scope, $http, $location, $timeout, $parse) { | |
| 158 $scope.imgScaleFactor = 1.0; | |
|
epoger
2013/10/21 15:02:53
given that the image is always REDUCED, not expand
| |
| 159 $scope.magnifierOn = false; | |
| 160 $scope.magnifyCenter = undefined; | |
| 161 | |
| 162 $scope.setImgScaleFactor = function(scaleFactor) { | |
| 163 $scope.imgScaleFactor = scaleFactor; | |
| 164 } | |
| 165 | |
| 166 $scope.setMagnifierState = function(magnifierOn) { | |
| 167 $scope.magnifierOn = magnifierOn; | |
| 168 } | |
| 169 | |
| 170 $scope.setMagnifyCenter = function(magnifyCenter) { | |
| 171 $scope.magnifyCenter = magnifyCenter; | |
| 172 } | |
| 173 } | |
| 174 | |
| 79 function DiffListController($scope, $http, $location, $timeout, $parse) { | 175 function DiffListController($scope, $http, $location, $timeout, $parse) { |
| 80 // Detect if we are running the web server version of the viewer. If so, we set a flag and | 176 // Detect if we are running the web server version of the viewer. If so, we set a flag and |
| 81 // enable some extra functionality of the website for rebaselining. | 177 // enable some extra functionality of the website for rebaselining. |
| 82 $scope.isDynamic = ($location.protocol() == "http" || $location.protocol() = = "https"); | 178 $scope.isDynamic = ($location.protocol() == "http" || $location.protocol() = = "https"); |
| 83 | 179 |
| 84 // Label each kind of differ for the sort buttons. | 180 // Label each kind of differ for the sort buttons. |
| 85 $scope.differs = [ | 181 $scope.differs = [ |
| 86 { | 182 { |
| 87 "title": "Different Pixels" | 183 "title": "Different Pixels" |
| 88 }, | 184 }, |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 163 } | 259 } |
| 164 $http.post("/commit_rebaselines", { | 260 $http.post("/commit_rebaselines", { |
| 165 "rebaselines": rebaselines | 261 "rebaselines": rebaselines |
| 166 }).success(function(data) { | 262 }).success(function(data) { |
| 167 $scope.flashStatus(data.success); | 263 $scope.flashStatus(data.success); |
| 168 }).error(function() { | 264 }).error(function() { |
| 169 $scope.flashStatus(false); | 265 $scope.flashStatus(false); |
| 170 }); | 266 }); |
| 171 }; | 267 }; |
| 172 } | 268 } |
| OLD | NEW |