blob: e7156b359f4596d5e2cc7773e4f145ee263a4bd0 [file] [log] [blame]
zachr@google.com6f8e2c52013-08-07 15:43:04 +00001var MAX_SWAP_IMG_SIZE = 400;
2
zachr@google.com1bc995e2013-07-12 13:39:53 +00003angular.module('diff_viewer', []).
4config(['$routeProvider', function($routeProvider) {
5 // Show the list of differences by default
6 $routeProvider.
7 otherwise({ templateUrl: '/diff_list.html', controller: DiffListController});
8}]).
9directive('swapImg', function() {
10 // Custom directive for showing an image that gets swapped my mouseover.
11 return {
12 restrict: 'E', // The directive can be used as an element name
13 replace: true, // The directive replaces itself with the template
14 template: '<canvas ng-mouseenter="swap()" ng-mouseleave="swap()"></canvas>',
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
25 scope.render = function() {
26 var image;
27 if (scope.side == "left") {
28 image = leftImage;
29 } else {
30 image = rightImage;
31 }
32
zachr@google.com6f8e2c52013-08-07 15:43:04 +000033 // Make it so the maximum size of an image is MAX_SWAP_IMG_SIZE, and the images are
34 // scaled down in halves.
zachr@google.com1bc995e2013-07-12 13:39:53 +000035 var divisor = 1;
zachr@google.com6f8e2c52013-08-07 15:43:04 +000036 while ((image.width / divisor) > MAX_SWAP_IMG_SIZE) {
zachr@google.com1bc995e2013-07-12 13:39:53 +000037 divisor *= 2;
38 }
39
40 // Set canvas to correct size and draw the image into it
41 elm[0].width = image.width / divisor;
42 elm[0].height = image.height / divisor;
43 ctx.drawImage(image, 0, 0, elm[0].width, elm[0].height);
44 };
45
46 // When the leftSrc attribute changes, load the image and then rerender
47 attrs.$observe('leftSrc', function(value) {
48 leftImage.src = value;
49 leftImage.onload = function() {
50 if (scope.side == "left") {
51 scope.render();
52 }
53 };
54 });
55
56 // When the rightSrc attribute changes, load the image and then rerender
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
66 // Swap which side to draw onto the canvas and then rerender
67 scope.swap = function() {
68 if (scope.side == "left") {
69 scope.side = "right";
70 } else {
71 scope.side = "left";
72 }
73 scope.render();
74 };
75 }
76 };
77});
78
zachr@google.com6f8e2c52013-08-07 15:43:04 +000079function DiffListController($scope, $http, $timeout) {
zachr@google.com1bc995e2013-07-12 13:39:53 +000080 // Label each kind of differ for the sort buttons.
zachr@google.com9432c0c2013-07-09 21:08:28 +000081 $scope.differs = [
82 {
83 "title": "Different Pixels"
84 },
85 {
86 "title": "Perceptual Difference"
87 }
88 ];
zachr@google.com1bc995e2013-07-12 13:39:53 +000089
90 // Puts the records within AngularJS scope
zachr@google.com9432c0c2013-07-09 21:08:28 +000091 $scope.records = SkPDiffRecords.records;
zachr@google.com1bc995e2013-07-12 13:39:53 +000092
93 // Indicates which diff metric is used for sorting
94 $scope.sortIndex = 1;
95
96 // Called by the sort buttons to adjust the metric used for sorting
97 $scope.setSortIndex = function(idx) {
98 $scope.sortIndex = idx;
99 };
100
101 // A predicate for pulling out the number used for sorting
102 $scope.sortingDiffer = function(record) {
103 return record.diffs[$scope.sortIndex].result;
104 };
zachr@google.com6f8e2c52013-08-07 15:43:04 +0000105
106 // Flash status indicators on the rows, and then remove them so the style can potentially be
107 // reapplied later.
108 $scope.flashRowStatus = function(success, record) {
109 var flashStyle = success ? "success-flash" : "failure-flash";
110 var flashDurationMillis = success ? 500 : 800;
111
112 // Store the style in the record. The row will pick up the style this way instead of through
113 // index because index can change with sort order.
114 record.cssClasses = flashStyle;
115
116 // The animation cannot be repeated unless the class is removed the element.
117 $timeout(function() {
118 record.cssClasses = "";
119 }, flashDurationMillis);
120 }
121
122 $scope.setHashOf = function(imagePath, record) {
123 $http.post("/set_hash", {
124 "path": imagePath
125 }).success(function(data) {
126 $scope.flashRowStatus(data.success, record);
127 }).error(function() {
128 $scope.flashRowStatus(false, record);
129 });
130
131 };
zachr@google.com1bc995e2013-07-12 13:39:53 +0000132}