Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 var MAX_SWAP_IMG_SIZE = 400; | |
|
epoger
2014/02/03 21:17:13
Do we need copyright notice up here?
| |
| 2 var MAGNIFIER_WIDTH = 200; | |
| 3 var MAGNIFIER_HEIGHT = 200; | |
|
epoger
2014/02/03 21:17:13
So, if we are hosting this file within Google Stor
| |
| 4 var MAGNIFIER_HALF_WIDTH = MAGNIFIER_WIDTH * 0.5; | |
| 5 var MAGNIFIER_HALF_HEIGHT = MAGNIFIER_HEIGHT * 0.5; | |
| 6 var MAGNIFIER_SCALE_FACTOR = 2.0; | |
| 7 | |
| 8 angular.module('diff_viewer', []).directive('imgCompare', function() { | |
| 9 // Custom directive for comparing (3-way) images | |
|
epoger
2014/02/03 21:17:13
Maybe it's just me, but this all seems like magic
| |
| 10 return { | |
| 11 restrict: 'E', // The directive can be used as an element name | |
| 12 replace: true, // The directive replaces itself with the template | |
| 13 template: '<canvas/>', | |
| 14 scope: true, | |
| 15 link: function(scope, elm, attrs, ctrl) { | |
| 16 var image = new Image(); | |
| 17 var canvas = elm[0]; | |
| 18 var ctx = canvas.getContext('2d'); | |
| 19 | |
| 20 var magnifyContent = false; | |
| 21 var maskCanvas = false; | |
| 22 | |
| 23 // When the type attribute changes, load the image and then render | |
| 24 attrs.$observe('type', function(value) { | |
| 25 switch(value) { | |
| 26 case "differingPixelsInWhite": | |
| 27 image.src = attrs.src; | |
| 28 // maskCanvas = true; | |
|
epoger
2014/02/03 21:17:13
why is this commented out?
| |
| 29 magnifyContent = true; | |
| 30 break; | |
| 31 case "differencePerPixel": | |
| 32 image.src = attrs.src; | |
| 33 maskCanvas = true; | |
| 34 break; | |
| 35 case "baseline": | |
| 36 image.src = attrs.src; | |
| 37 magnifyContent = true; | |
| 38 break; | |
| 39 case "test": | |
| 40 image.src = attrs.src; | |
| 41 magnifyContent = true; | |
| 42 break; | |
| 43 default: | |
| 44 console.log("Unknown type attribute on <img-compare>: " + va lue); | |
| 45 return; | |
| 46 } | |
| 47 | |
| 48 image.onload = function() { | |
| 49 // compute the scaled image width/height for image and canvas | |
| 50 var divisor = 1; | |
| 51 // Make it so the maximum size of an image is MAX_SWAP_IMG_SIZ E, | |
| 52 // and the images are scaled down in halves. | |
| 53 while ((image.width / divisor) > MAX_SWAP_IMG_SIZE) { | |
| 54 divisor *= 2; | |
| 55 } | |
| 56 | |
| 57 scope.setImgScaleFactor(1 / divisor); | |
|
epoger
2014/02/03 21:17:13
I don't know how JavaScript handles floating point
| |
| 58 | |
| 59 // Set canvas to correct size | |
| 60 canvas.width = image.width * scope.imgScaleFactor; | |
| 61 canvas.height = image.height * scope.imgScaleFactor; | |
| 62 | |
| 63 // update the size for non-alphaMask canvas when loading basel ine image | |
| 64 if (!scope.maskSizeUpdated) { | |
| 65 if (!maskCanvas) { | |
| 66 scope.updateMaskCanvasSize({width: canvas.width, heigh t: canvas.height}); | |
| 67 } | |
| 68 scope.maskCanvasSizeUpdated(true); | |
| 69 } | |
| 70 | |
| 71 // render the image onto the canvas | |
| 72 scope.renderImage(); | |
| 73 } | |
| 74 }); | |
| 75 | |
| 76 // when updatedMaskSize changes, update mask canvas size. | |
|
epoger
2014/02/03 21:17:13
Somewhere there needs to be an explanation of what
| |
| 77 scope.$watch('updatedMaskSize', function(updatedSize) { | |
| 78 if (!maskCanvas) { | |
| 79 return; | |
| 80 } | |
| 81 | |
| 82 // rmistry: Commented out because was throwing js errors. | |
|
epoger
2014/02/03 21:17:13
So, does this function do anything now?
| |
| 83 // canvas.width = updatedSize.width; | |
| 84 // canvas.height = updatedSize.height; | |
| 85 }); | |
| 86 | |
| 87 // When the magnify attribute changes, render the magnified rect at | |
| 88 // the default zoom level. | |
| 89 scope.$watch('magnifyCenter', function(magCenter) { | |
| 90 if (!magnifyContent) { | |
| 91 return; | |
| 92 } | |
| 93 | |
| 94 scope.renderImage(); | |
| 95 | |
| 96 if (!magCenter) { | |
| 97 return; | |
| 98 } | |
| 99 | |
| 100 var magX = magCenter.x - MAGNIFIER_HALF_WIDTH; | |
| 101 var magY = magCenter.y - MAGNIFIER_HALF_HEIGHT; | |
| 102 | |
| 103 var magMaxX = canvas.width - MAGNIFIER_WIDTH; | |
| 104 var magMaxY = canvas.height - MAGNIFIER_HEIGHT; | |
| 105 | |
| 106 var magRect = { x: Math.max(0, Math.min(magX, magMaxX)), | |
| 107 y: Math.max(0, Math.min(magY, magMaxY)), | |
| 108 width: MAGNIFIER_WIDTH, | |
| 109 height: MAGNIFIER_HEIGHT | |
| 110 }; | |
| 111 | |
| 112 var imgRect = { x: (magCenter.x / scope.imgScaleFactor) - MAGNIFIE R_HALF_WIDTH, | |
| 113 y: (magCenter.y / scope.imgScaleFactor) - MAGNIFI ER_HALF_HEIGHT, | |
| 114 width: MAGNIFIER_WIDTH, | |
| 115 height: MAGNIFIER_HEIGHT | |
| 116 }; | |
| 117 | |
| 118 // draw the magnified image | |
| 119 ctx.clearRect(magRect.x, magRect.y, magRect.width, magRect.height) ; | |
| 120 ctx.drawImage(image, imgRect.x, imgRect.y, imgRect.width, imgRect. height, | |
| 121 magRect.x, magRect.y, magRect.width, magRect.height) ; | |
| 122 | |
| 123 // draw the outline rect | |
| 124 ctx.beginPath(); | |
| 125 ctx.rect(magRect.x, magRect.y, magRect.width, magRect.height); | |
| 126 ctx.lineWidth = 2; | |
| 127 ctx.strokeStyle = 'red'; | |
| 128 ctx.stroke(); | |
| 129 | |
| 130 }); | |
| 131 | |
| 132 // render the image to the canvas. This is often done every frame prio r | |
| 133 // to any special effects (i.e. magnification). | |
| 134 scope.renderImage = function() { | |
| 135 ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| 136 ctx.drawImage(image, 0, 0, canvas.width, canvas.height); | |
| 137 }; | |
| 138 | |
| 139 // compute a rect (x,y,width,height) that represents the bounding box for | |
| 140 // the magnification effect | |
| 141 scope.computeMagnifierOutline = function(event) { | |
| 142 var scaledWidth = MAGNIFIER_WIDTH * scope.imgScaleFactor; | |
| 143 var scaledHeight = MAGNIFIER_HEIGHT * scope.imgScaleFactor; | |
| 144 return { | |
| 145 x: event.offsetX - (scaledWidth * 0.5), | |
| 146 y: event.offsetY - (scaledHeight * 0.5), | |
| 147 width: scaledWidth, | |
| 148 height: scaledHeight | |
| 149 }; | |
| 150 }; | |
| 151 | |
| 152 // event handler for mouse events that triggers the magnification | |
| 153 // effect across the 4 images being compared. | |
| 154 scope.MagnifyDraw = function(event, startMagnify) { | |
| 155 if (startMagnify) { | |
|
epoger
2014/02/03 21:17:13
seems like indent levels shift freely between 2 an
| |
| 156 scope.setMagnifierState(true); | |
| 157 } else if (!scope.magnifierOn) { | |
| 158 return; | |
| 159 } | |
| 160 | |
| 161 scope.renderImage(); | |
| 162 | |
| 163 // render the magnifier outline rect | |
| 164 var rect = scope.computeMagnifierOutline(event); | |
| 165 ctx.save(); | |
| 166 ctx.beginPath(); | |
| 167 ctx.rect(rect.x, rect.y, rect.width, rect.height); | |
| 168 ctx.lineWidth = 2; | |
| 169 ctx.strokeStyle = 'red'; | |
| 170 ctx.stroke(); | |
| 171 ctx.restore(); | |
| 172 | |
| 173 // update scope on baseline / test that will cause them to render | |
| 174 scope.setMagnifyCenter({x: event.offsetX, y: event.offsetY}); | |
| 175 }; | |
| 176 | |
| 177 // event handler that triggers the end of the magnification effect and | |
| 178 // resets all the canvases to their original state. | |
| 179 scope.MagnifyEnd = function(event) { | |
| 180 scope.renderImage(); | |
| 181 // update scope on baseline / test that will cause them to render | |
| 182 scope.setMagnifierState(false); | |
| 183 scope.setMagnifyCenter(undefined); | |
| 184 }; | |
| 185 } | |
| 186 }; | |
| 187 }); | |
| 188 | |
| 189 function ImageController($scope, $http, $location, $timeout, $parse) { | |
| 190 $scope.imgScaleFactor = 1.0; | |
| 191 $scope.magnifierOn = false; | |
| 192 $scope.magnifyCenter = undefined; | |
| 193 $scope.updatedMaskSize = undefined; | |
| 194 $scope.maskSizeUpdated = false; | |
| 195 | |
| 196 $scope.setImgScaleFactor = function(scaleFactor) { | |
| 197 $scope.imgScaleFactor = scaleFactor; | |
| 198 } | |
| 199 | |
| 200 $scope.setMagnifierState = function(magnifierOn) { | |
| 201 $scope.magnifierOn = magnifierOn; | |
| 202 } | |
| 203 | |
| 204 $scope.setMagnifyCenter = function(magnifyCenter) { | |
| 205 $scope.magnifyCenter = magnifyCenter; | |
| 206 } | |
| 207 | |
| 208 $scope.updateMaskCanvasSize = function(updatedSize) { | |
|
epoger
2014/02/03 21:17:13
Is there some reason we don't use consistent namin
| |
| 209 $scope.updatedMaskSize = updatedSize; | |
| 210 } | |
| 211 | |
| 212 $scope.maskCanvasSizeUpdated = function(flag) { | |
|
epoger
2014/02/03 21:17:13
What is this function for? How does it relate to
| |
| 213 $scope.maskSizeUpdated = flag; | |
| 214 } | |
| 215 } | |
| OLD | NEW |