| OLD | NEW |
| (Empty) |
| 1 // What portion of the image width will be taken up by the magnifier. | |
| 2 var MAGNIFIER_WIDTH_FACTOR = 0.66; | |
| 3 | |
| 4 angular.module('diff_viewer', []).directive('imgCompare', function() { | |
| 5 // Custom directive for comparing (3-way) images | |
| 6 return { | |
| 7 restrict: 'E', // The directive can be used as an element name | |
| 8 replace: true, // The directive replaces itself with the template | |
| 9 template: '<canvas/>', | |
| 10 scope: true, | |
| 11 link: function(scope, elm, attrs, ctrl) { | |
| 12 var image = new Image(); | |
| 13 var canvas = elm[0]; | |
| 14 var ctx = canvas.getContext('2d'); | |
| 15 var magnifyContent = false; | |
| 16 | |
| 17 // When the type attribute changes, set magnifyContent appropriately. | |
| 18 attrs.$observe('type', function(value) { | |
| 19 switch(attrs.type) { | |
| 20 case "differingPixelsInWhite": | |
| 21 magnifyContent = true; | |
| 22 break; | |
| 23 case "differencePerPixel": | |
| 24 break; | |
| 25 case "baseline": | |
| 26 magnifyContent = true; | |
| 27 break; | |
| 28 case "test": | |
| 29 magnifyContent = true; | |
| 30 break; | |
| 31 default: | |
| 32 console.log("Unknown type attribute on <img-compare>: " + va
lue); | |
| 33 return; | |
| 34 } | |
| 35 }); | |
| 36 | |
| 37 // Reset ImageController's scale and render the image; | |
| 38 // we need to do this whenever attrs.src or attrs.width changes. | |
| 39 scope.setScaleAndRender = function() { | |
| 40 // compute the scaled image width/height for image and canvas | |
| 41 scope.setImgScale(image.width, attrs.width); | |
| 42 | |
| 43 // Set canvas to correct size | |
| 44 canvas.width = image.width / scope.imgScaleDivisor; | |
| 45 canvas.height = image.height / scope.imgScaleDivisor; | |
| 46 | |
| 47 scope.renderImage(); | |
| 48 }; | |
| 49 attrs.$observe('src', function(value) { | |
| 50 image.src = attrs.src; | |
| 51 image.onload = scope.setScaleAndRender; | |
| 52 }); | |
| 53 attrs.$observe('width', scope.setScaleAndRender); | |
| 54 | |
| 55 // When the magnify attribute changes, render the magnified rect at | |
| 56 // the default zoom level. | |
| 57 scope.$watch('magnifyCenter', function(magCenter) { | |
| 58 if (!magnifyContent) { | |
| 59 return; | |
| 60 } | |
| 61 | |
| 62 scope.renderImage(); | |
| 63 | |
| 64 if (!magCenter) { | |
| 65 return; | |
| 66 } | |
| 67 | |
| 68 var magX = magCenter.x - scope.magnifierHalfWidth; | |
| 69 var magY = magCenter.y - scope.magnifierHalfHeight; | |
| 70 | |
| 71 var magMaxX = canvas.width - scope.magnifierWidth; | |
| 72 var magMaxY = canvas.height - scope.magnifierHeight; | |
| 73 | |
| 74 var magRect = { x: Math.max(0, Math.min(magX, magMaxX)), | |
| 75 y: Math.max(0, Math.min(magY, magMaxY)), | |
| 76 width: scope.magnifierWidth, | |
| 77 height: scope.magnifierHeight | |
| 78 }; | |
| 79 | |
| 80 var imgRect = { x: (magCenter.x * scope.imgScaleDivisor) - scope.m
agnifierHalfWidth, | |
| 81 y: (magCenter.y * scope.imgScaleDivisor) - scope.m
agnifierHalfHeight, | |
| 82 width: scope.magnifierWidth, | |
| 83 height: scope.magnifierHeight | |
| 84 }; | |
| 85 | |
| 86 // draw the magnified image | |
| 87 ctx.clearRect(magRect.x, magRect.y, magRect.width, magRect.height)
; | |
| 88 ctx.drawImage(image, imgRect.x, imgRect.y, imgRect.width, imgRect.
height, | |
| 89 magRect.x, magRect.y, magRect.width, magRect.height)
; | |
| 90 | |
| 91 // draw the outline rect | |
| 92 ctx.beginPath(); | |
| 93 ctx.rect(magRect.x, magRect.y, magRect.width, magRect.height); | |
| 94 ctx.lineWidth = 2; | |
| 95 ctx.strokeStyle = 'red'; | |
| 96 ctx.stroke(); | |
| 97 | |
| 98 }); | |
| 99 | |
| 100 // render the image to the canvas. This is often done every frame prio
r | |
| 101 // to any special effects (i.e. magnification). | |
| 102 scope.renderImage = function() { | |
| 103 ctx.clearRect(0, 0, canvas.width, canvas.height); | |
| 104 ctx.drawImage(image, 0, 0, canvas.width, canvas.height); | |
| 105 }; | |
| 106 | |
| 107 // compute a rect (x,y,width,height) that represents the bounding box
for | |
| 108 // the magnification effect | |
| 109 scope.computeMagnifierOutline = function(event) { | |
| 110 var scaledWidth = scope.magnifierWidth / scope.imgScaleDivisor; | |
| 111 var scaledHeight = scope.magnifierHeight / scope.imgScaleDivisor; | |
| 112 return { | |
| 113 x: event.offsetX - (scaledWidth * 0.5), | |
| 114 y: event.offsetY - (scaledHeight * 0.5), | |
| 115 width: scaledWidth, | |
| 116 height: scaledHeight | |
| 117 }; | |
| 118 }; | |
| 119 | |
| 120 // event handler for mouse events that triggers the magnification | |
| 121 // effect across the 4 images being compared. | |
| 122 scope.MagnifyDraw = function(event, startMagnify) { | |
| 123 if (startMagnify) { | |
| 124 scope.setMagnifierState(true); | |
| 125 } else if (!scope.magnifierOn) { | |
| 126 return; | |
| 127 } | |
| 128 | |
| 129 scope.renderImage(); | |
| 130 | |
| 131 // render the magnifier outline rect | |
| 132 var rect = scope.computeMagnifierOutline(event); | |
| 133 ctx.save(); | |
| 134 ctx.beginPath(); | |
| 135 ctx.rect(rect.x, rect.y, rect.width, rect.height); | |
| 136 ctx.lineWidth = 2; | |
| 137 ctx.strokeStyle = 'red'; | |
| 138 ctx.stroke(); | |
| 139 ctx.restore(); | |
| 140 | |
| 141 // update scope on baseline / test that will cause them to render | |
| 142 scope.setMagnifyCenter({x: event.offsetX, y: event.offsetY}); | |
| 143 }; | |
| 144 | |
| 145 // event handler that triggers the end of the magnification effect and | |
| 146 // resets all the canvases to their original state. | |
| 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 }; | |
| 155 }); | |
| 156 | |
| 157 function ImageController($scope, $http, $location, $timeout, $parse) { | |
| 158 $scope.imgScaleDivisor = 1.0; | |
| 159 $scope.magnifierOn = false; | |
| 160 $scope.magnifyCenter = undefined; | |
| 161 | |
| 162 $scope.setImgScale = function(srcImageWidth, displayWidth) { | |
| 163 $scope.imgScaleDivisor = srcImageWidth / displayWidth; | |
| 164 $scope.magnifierWidth = displayWidth * MAGNIFIER_WIDTH_FACTOR; | |
| 165 $scope.magnifierHeight = $scope.magnifierWidth; | |
| 166 $scope.magnifierHalfWidth = $scope.magnifierWidth / 2; | |
| 167 $scope.magnifierHalfHeight = $scope.magnifierHeight / 2; | |
| 168 } | |
| 169 | |
| 170 $scope.setMagnifierState = function(magnifierOn) { | |
| 171 $scope.magnifierOn = magnifierOn; | |
| 172 } | |
| 173 | |
| 174 $scope.setMagnifyCenter = function(magnifyCenter) { | |
| 175 $scope.magnifyCenter = magnifyCenter; | |
| 176 } | |
| 177 } | |
| OLD | NEW |