Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(154)

Side by Side Diff: gm/rebaseline_server/static/diff_viewer.js

Issue 149473005: Add magnifier to rebaseline server (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Remove unneeded mask size logic Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | gm/rebaseline_server/static/loader.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 var MAX_SWAP_IMG_SIZE = 400; 1 var MAX_SWAP_IMG_SIZE = 200;
2 var MAGNIFIER_WIDTH = 200; 2 var MAGNIFIER_WIDTH = 100;
3 var MAGNIFIER_HEIGHT = 200; 3 var MAGNIFIER_HEIGHT = 100;
4 var MAGNIFIER_HALF_WIDTH = MAGNIFIER_WIDTH * 0.5; 4 var MAGNIFIER_HALF_WIDTH = MAGNIFIER_WIDTH * 0.5;
5 var MAGNIFIER_HALF_HEIGHT = MAGNIFIER_HEIGHT * 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; 6 var MAGNIFIER_SCALE_FACTOR = 2.0;
8 7
9 angular.module('diff_viewer', []). 8 angular.module('diff_viewer', []).directive('imgCompare', function() {
10 directive('imgCompare', function() {
11 // Custom directive for comparing (3-way) images 9 // Custom directive for comparing (3-way) images
12 return { 10 return {
13 restrict: 'E', // The directive can be used as an element name 11 restrict: 'E', // The directive can be used as an element name
14 replace: true, // The directive replaces itself with the template 12 replace: true, // The directive replaces itself with the template
15 template: '<canvas/>', 13 template: '<canvas/>',
16 scope: true, 14 scope: true,
17 link: function(scope, elm, attrs, ctrl) { 15 link: function(scope, elm, attrs, ctrl) {
18 var image = new Image(); 16 var image = new Image();
19 var canvas = elm[0]; 17 var canvas = elm[0];
20 var ctx = canvas.getContext('2d'); 18 var ctx = canvas.getContext('2d');
21
22 var magnifyContent = false; 19 var magnifyContent = false;
23 var maskCanvas = false;
24 20
25 // When the type attribute changes, load the image and then render 21 // When the type attribute changes, load the image and then render
26 attrs.$observe('type', function(value) { 22 attrs.$observe('type', function(value) {
27 switch(value) { 23 switch(value) {
28 case "alphaMask": 24 case "differingPixelsInWhite":
29 image.src = scope.record.differencePath; 25 magnifyContent = true;
30 maskCanvas = true; 26 break;
27 case "differencePerPixel":
31 break; 28 break;
32 case "baseline": 29 case "baseline":
33 image.src = scope.record.baselinePath;
34 magnifyContent = true; 30 magnifyContent = true;
35 break; 31 break;
36 case "test": 32 case "test":
37 image.src = scope.record.testPath;
38 magnifyContent = true; 33 magnifyContent = true;
39 break; 34 break;
40 default: 35 default:
41 console.log("Unknown type attribute on <img-compare>: " + va lue); 36 console.log("Unknown type attribute on <img-compare>: " + va lue);
42 return; 37 return;
43 } 38 }
44 39
40 image.src = attrs.src;
45 image.onload = function() { 41 image.onload = function() {
46 // compute the scaled image width/height for image and canvas 42 // compute the scaled image width/height for image and canvas
47 var divisor = 1; 43 var divisor = 1;
48 // Make it so the maximum size of an image is MAX_SWAP_IMG_SIZ E, 44 // Make it so the maximum size of an image is MAX_SWAP_IMG_SIZ E,
49 // and the images are scaled down in halves. 45 // and the images are scaled down in halves.
50 while ((image.width / divisor) > MAX_SWAP_IMG_SIZE) { 46 while ((image.width / divisor) > MAX_SWAP_IMG_SIZE) {
51 divisor *= 2; 47 divisor *= 2;
52 } 48 }
53 49
54 scope.setImgScaleFactor(1 / divisor); 50 scope.setImgScaleFactor(1 / divisor);
55 51
56 // Set canvas to correct size 52 // Set canvas to correct size
57 canvas.width = image.width * scope.imgScaleFactor; 53 canvas.width = image.width * scope.imgScaleFactor;
58 canvas.height = image.height * scope.imgScaleFactor; 54 canvas.height = image.height * scope.imgScaleFactor;
59 55
60 // update the size for non-alphaMask canvas when loading basel ine image
61 if (!scope.maskSizeUpdated) {
62 if (!maskCanvas) {
63 scope.updateMaskCanvasSize({width: canvas.width, heigh t: canvas.height});
64 }
65 scope.maskCanvasSizeUpdated(true);
66 }
67
68 // render the image onto the canvas
69 scope.renderImage(); 56 scope.renderImage();
70 } 57 }
71 }); 58 });
72 59
73 // when updatedMaskSize changes, update mask canvas size.
74 scope.$watch('updatedMaskSize', function(updatedSize) {
75 if (!maskCanvas) {
76 return;
77 }
78
79 canvas.width = updatedSize.width;
80 canvas.height = updatedSize.height;
81 });
82
83 // When the magnify attribute changes, render the magnified rect at 60 // When the magnify attribute changes, render the magnified rect at
84 // the default zoom level. 61 // the default zoom level.
85 scope.$watch('magnifyCenter', function(magCenter) { 62 scope.$watch('magnifyCenter', function(magCenter) {
86 if (!magnifyContent) { 63 if (!magnifyContent) {
87 return; 64 return;
88 } 65 }
89 66
90 scope.renderImage(); 67 scope.renderImage();
91 68
92 if (!magCenter) { 69 if (!magCenter) {
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 var scaledHeight = MAGNIFIER_HEIGHT * scope.imgScaleFactor; 116 var scaledHeight = MAGNIFIER_HEIGHT * scope.imgScaleFactor;
140 return { 117 return {
141 x: event.offsetX - (scaledWidth * 0.5), 118 x: event.offsetX - (scaledWidth * 0.5),
142 y: event.offsetY - (scaledHeight * 0.5), 119 y: event.offsetY - (scaledHeight * 0.5),
143 width: scaledWidth, 120 width: scaledWidth,
144 height: scaledHeight 121 height: scaledHeight
145 }; 122 };
146 }; 123 };
147 124
148 // event handler for mouse events that triggers the magnification 125 // event handler for mouse events that triggers the magnification
149 // effect across the 3 images being compared. 126 // effect across the 4 images being compared.
150 scope.MagnifyDraw = function(event, startMagnify) { 127 scope.MagnifyDraw = function(event, startMagnify) {
151 if (startMagnify) { 128 if (startMagnify) {
152 scope.setMagnifierState(true); 129 scope.setMagnifierState(true);
153 } else if (!scope.magnifierOn) { 130 } else if (!scope.magnifierOn) {
154 return; 131 return;
155 } 132 }
156 133
157 scope.renderImage(); 134 scope.renderImage();
158 135
159 // render the magnifier outline rect 136 // render the magnifier outline rect
(...skipping 10 matching lines...) Expand all
170 scope.setMagnifyCenter({x: event.offsetX, y: event.offsetY}); 147 scope.setMagnifyCenter({x: event.offsetX, y: event.offsetY});
171 }; 148 };
172 149
173 // event handler that triggers the end of the magnification effect and 150 // event handler that triggers the end of the magnification effect and
174 // resets all the canvases to their original state. 151 // resets all the canvases to their original state.
175 scope.MagnifyEnd = function(event) { 152 scope.MagnifyEnd = function(event) {
176 scope.renderImage(); 153 scope.renderImage();
177 // update scope on baseline / test that will cause them to render 154 // update scope on baseline / test that will cause them to render
178 scope.setMagnifierState(false); 155 scope.setMagnifierState(false);
179 scope.setMagnifyCenter(undefined); 156 scope.setMagnifyCenter(undefined);
180 }; 157 };
181 } 158 }
182 }; 159 };
183 }); 160 });
184 161
185 function ImageController($scope, $http, $location, $timeout, $parse) { 162 function ImageController($scope, $http, $location, $timeout, $parse) {
186 $scope.imgScaleFactor = 1.0; 163 $scope.imgScaleFactor = 1.0;
187 $scope.magnifierOn = false; 164 $scope.magnifierOn = false;
188 $scope.magnifyCenter = undefined; 165 $scope.magnifyCenter = undefined;
189 $scope.updatedMaskSize = undefined;
190 $scope.maskSizeUpdated = false;
191 166
192 $scope.setImgScaleFactor = function(scaleFactor) { 167 $scope.setImgScaleFactor = function(scaleFactor) {
193 $scope.imgScaleFactor = scaleFactor; 168 $scope.imgScaleFactor = scaleFactor;
194 } 169 }
195 170
196 $scope.setMagnifierState = function(magnifierOn) { 171 $scope.setMagnifierState = function(magnifierOn) {
197 $scope.magnifierOn = magnifierOn; 172 $scope.magnifierOn = magnifierOn;
198 } 173 }
199 174
200 $scope.setMagnifyCenter = function(magnifyCenter) { 175 $scope.setMagnifyCenter = function(magnifyCenter) {
201 $scope.magnifyCenter = magnifyCenter; 176 $scope.magnifyCenter = magnifyCenter;
202 } 177 }
203
204 $scope.updateMaskCanvasSize = function(updatedSize) {
205 $scope.updatedMaskSize = updatedSize;
206 }
207
208 $scope.maskCanvasSizeUpdated = function(flag) {
209 $scope.maskSizeUpdated = flag;
210 }
211 } 178 }
212 179
213 function DiffListController($scope, $http, $location, $timeout, $parse) {
214 // Detect if we are running the web server version of the viewer. If so, we set a flag and
215 // enable some extra functionality of the website for rebaselining.
216 $scope.isDynamic = ($location.protocol() == "http" || $location.protocol() = = "https");
217
218 // Label each kind of differ for the sort buttons.
219 $scope.differs = [
220 {
221 "title": "Different Pixels"
222 },
223 {
224 "title": "Perceptual Difference"
225 }
226 ];
227
228 // Puts the records within AngularJS scope
229 $scope.records = SkPDiffRecords.records;
230
231 // Keep track of the index of the last record to change so that shift clicki ng knows what range
232 // of records to apply the action to.
233 $scope.lastSelectedIndex = undefined;
234
235 // Indicates which diff metric is used for sorting
236 $scope.sortIndex = 1;
237
238 // Called by the sort buttons to adjust the metric used for sorting
239 $scope.setSortIndex = function(idx) {
240 $scope.sortIndex = idx;
241
242 // Because the index of things has most likely changed, the ranges of sh ift clicking no
243 // longer make sense from the user's point of view. We reset it to avoid confusion.
244 $scope.lastSelectedIndex = undefined;
245 };
246
247 // A predicate for pulling out the number used for sorting
248 $scope.sortingDiffer = function(record) {
249 return record.diffs[$scope.sortIndex].result;
250 };
251
252 // Flash status indicator on the page, and then remove it so the style can p otentially be
253 // reapplied later.
254 $scope.flashStatus = function(success) {
255 var flashStyle = success ? "success-flash" : "failure-flash";
256 var flashDurationMillis = success ? 500 : 800;
257
258 // Store the style in the record. The row will pick up the style this wa y instead of through
259 // index because index can change with sort order.
260 $scope.statusClass = flashStyle;
261
262 // The animation cannot be repeated unless the class is removed the elem ent.
263 $timeout(function() {
264 $scope.statusClass = "";
265 }, flashDurationMillis);
266 };
267
268 $scope.selectedRebaseline = function(index, event) {
269 // Retrieve the records in the same order they are displayed.
270 var recordsInOrder = $parse("records | orderBy:sortingDiffer")($scope);
271
272 // If the user is shift clicking, apply the last tick/untick to all elem ents in between this
273 // record, and the last one they ticked/unticked.
274 if (event.shiftKey && $scope.lastSelectedIndex !== undefined) {
275 var currentAction = recordsInOrder[index].isRebaselined;
276 var smallerIndex = Math.min($scope.lastSelectedIndex, index);
277 var largerIndex = Math.max($scope.lastSelectedIndex, index);
278 for (var recordIndex = smallerIndex; recordIndex <= largerIndex; rec ordIndex++) {
279 recordsInOrder[recordIndex].isRebaselined = currentAction;
280 }
281 $scope.lastSelectedIndex = index;
282 }
283 else
284 {
285 $scope.lastSelectedIndex = index;
286 }
287
288 };
289
290 $scope.commitRebaselines = function() {
291 // Gather up all records that have the rebaseline set.
292 var rebaselines = [];
293 for (var recordIndex = 0; recordIndex < $scope.records.length; recordInd ex++) {
294 if ($scope.records[recordIndex].isRebaselined) {
295 rebaselines.push($scope.records[recordIndex].testPath);
296 }
297 }
298 $http.post("/commit_rebaselines", {
299 "rebaselines": rebaselines
300 }).success(function(data) {
301 $scope.flashStatus(data.success);
302 }).error(function() {
303 $scope.flashStatus(false);
304 });
305 };
306 }
OLDNEW
« no previous file with comments | « no previous file | gm/rebaseline_server/static/loader.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698