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

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

Issue 29103005: update skpdiff visualization (image magnification with alpha mask) (Closed) Base URL: https://skia.googlecode.com/svn/trunk
Patch Set: Created 7 years, 2 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 | Annotate | Revision Log
OLDNEW
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698