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

Side by Side Diff: tools/skpdiff/diff_viewer.js

Issue 1502173003: When was SkPDiff last used? (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years 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 | « tools/skpdiff/SkPMetricUtil_generated.h ('k') | tools/skpdiff/generate_pmetric_tables.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 var MAX_SWAP_IMG_SIZE = 400;
2 var MAGNIFIER_WIDTH = 200;
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;
8
9 angular.module('diff_viewer', []).
10 directive('imgCompare', function() {
11 // Custom directive for comparing (3-way) images
12 return {
13 restrict: 'E', // The directive can be used as an element name
14 replace: true, // The directive replaces itself with the template
15 template: '<canvas/>',
16 scope: true,
17 link: function(scope, elm, attrs, ctrl) {
18 var image = new Image();
19 var canvas = elm[0];
20 var ctx = canvas.getContext('2d');
21
22 var magnifyContent = false;
23 var maskCanvas = false;
24
25 // When the type attribute changes, load the image and then render
26 attrs.$observe('type', function(value) {
27 switch(value) {
28 case "alphaMask":
29 image.src = scope.record.differencePath;
30 maskCanvas = true;
31 break;
32 case "baseline":
33 image.src = scope.record.baselinePath;
34 magnifyContent = true;
35 break;
36 case "test":
37 image.src = scope.record.testPath;
38 magnifyContent = true;
39 break;
40 default:
41 console.log("Unknown type attribute on <img-compare>: " + va lue);
42 return;
43 }
44
45 image.onload = function() {
46 // compute the scaled image width/height for image and canvas
47 var divisor = 1;
48 // Make it so the maximum size of an image is MAX_SWAP_IMG_SIZ E,
49 // and the images are scaled down in halves.
50 while ((image.width / divisor) > MAX_SWAP_IMG_SIZE) {
51 divisor *= 2;
52 }
53
54 scope.setImgScaleFactor(1 / divisor);
55
56 // Set canvas to correct size
57 canvas.width = image.width * scope.imgScaleFactor;
58 canvas.height = image.height * scope.imgScaleFactor;
59
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();
70 }
71 });
72
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
84 // the default zoom level.
85 scope.$watch('magnifyCenter', function(magCenter) {
86 if (!magnifyContent) {
87 return;
88 }
89
90 scope.renderImage();
91
92 if (!magCenter) {
93 return;
94 }
95
96 var magX = magCenter.x - MAGNIFIER_HALF_WIDTH;
97 var magY = magCenter.y - MAGNIFIER_HALF_HEIGHT;
98
99 var magMaxX = canvas.width - MAGNIFIER_WIDTH;
100 var magMaxY = canvas.height - MAGNIFIER_HEIGHT;
101
102 var magRect = { x: Math.max(0, Math.min(magX, magMaxX)),
103 y: Math.max(0, Math.min(magY, magMaxY)),
104 width: MAGNIFIER_WIDTH,
105 height: MAGNIFIER_HEIGHT
106 };
107
108 var imgRect = { x: (magCenter.x / scope.imgScaleFactor) - MAGNIFIE R_HALF_WIDTH,
109 y: (magCenter.y / scope.imgScaleFactor) - MAGNIFI ER_HALF_HEIGHT,
110 width: MAGNIFIER_WIDTH,
111 height: MAGNIFIER_HEIGHT
112 };
113
114 // draw the magnified image
115 ctx.clearRect(magRect.x, magRect.y, magRect.width, magRect.height) ;
116 ctx.drawImage(image, imgRect.x, imgRect.y, imgRect.width, imgRect. height,
117 magRect.x, magRect.y, magRect.width, magRect.height) ;
118
119 // draw the outline rect
120 ctx.beginPath();
121 ctx.rect(magRect.x, magRect.y, magRect.width, magRect.height);
122 ctx.lineWidth = 2;
123 ctx.strokeStyle = 'red';
124 ctx.stroke();
125
126 });
127
128 // render the image to the canvas. This is often done every frame prio r
129 // to any special effects (i.e. magnification).
130 scope.renderImage = function() {
131 ctx.clearRect(0, 0, canvas.width, canvas.height);
132 ctx.drawImage(image, 0, 0, canvas.width, canvas.height);
133 };
134
135 // compute a rect (x,y,width,height) that represents the bounding box for
136 // the magnification effect
137 scope.computeMagnifierOutline = function(event) {
138 var scaledWidth = MAGNIFIER_WIDTH * scope.imgScaleFactor;
139 var scaledHeight = MAGNIFIER_HEIGHT * scope.imgScaleFactor;
140 return {
141 x: event.offsetX - (scaledWidth * 0.5),
142 y: event.offsetY - (scaledHeight * 0.5),
143 width: scaledWidth,
144 height: scaledHeight
145 };
146 };
147
148 // event handler for mouse events that triggers the magnification
149 // effect across the 3 images being compared.
150 scope.MagnifyDraw = function(event, startMagnify) {
151 if (startMagnify) {
152 scope.setMagnifierState(true);
153 } else if (!scope.magnifierOn) {
154 return;
155 }
156
157 scope.renderImage();
158
159 // render the magnifier outline rect
160 var rect = scope.computeMagnifierOutline(event);
161 ctx.save();
162 ctx.beginPath();
163 ctx.rect(rect.x, rect.y, rect.width, rect.height);
164 ctx.lineWidth = 2;
165 ctx.strokeStyle = 'red';
166 ctx.stroke();
167 ctx.restore();
168
169 // update scope on baseline / test that will cause them to render
170 scope.setMagnifyCenter({x: event.offsetX, y: event.offsetY});
171 };
172
173 // event handler that triggers the end of the magnification effect and
174 // resets all the canvases to their original state.
175 scope.MagnifyEnd = function(event) {
176 scope.renderImage();
177 // update scope on baseline / test that will cause them to render
178 scope.setMagnifierState(false);
179 scope.setMagnifyCenter(undefined);
180 };
181 }
182 };
183 });
184
185 function ImageController($scope, $http, $location, $timeout, $parse) {
186 $scope.imgScaleFactor = 1.0;
187 $scope.magnifierOn = false;
188 $scope.magnifyCenter = undefined;
189 $scope.updatedMaskSize = undefined;
190 $scope.maskSizeUpdated = false;
191
192 $scope.setImgScaleFactor = function(scaleFactor) {
193 $scope.imgScaleFactor = scaleFactor;
194 }
195
196 $scope.setMagnifierState = function(magnifierOn) {
197 $scope.magnifierOn = magnifierOn;
198 }
199
200 $scope.setMagnifyCenter = function(magnifyCenter) {
201 $scope.magnifyCenter = magnifyCenter;
202 }
203
204 $scope.updateMaskCanvasSize = function(updatedSize) {
205 $scope.updatedMaskSize = updatedSize;
206 }
207
208 $scope.maskCanvasSizeUpdated = function(flag) {
209 $scope.maskSizeUpdated = flag;
210 }
211 }
212
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 | « tools/skpdiff/SkPMetricUtil_generated.h ('k') | tools/skpdiff/generate_pmetric_tables.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698