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

Side by Side Diff: chrome/browser/resources/settings/people_page/camera.js

Issue 2617663002: WIP: run clang-format-js on lots of things (Closed)
Patch Set: merge Created 3 years, 11 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
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview 6 * @fileoverview
7 * 'settings-camera' is the Polymer control used to take a picture from the 7 * 'settings-camera' is the Polymer control used to take a picture from the
8 * user webcam to use as a ChromeOS profile picture. 8 * user webcam to use as a ChromeOS profile picture.
9 */ 9 */
10 (function() { 10 (function() {
11 11
12 /**
13 * Dimensions for camera capture.
14 * @const
15 */
16 var CAPTURE_SIZE = {
17 height: 480,
18 width: 480
19 };
20
21 Polymer({
22 is: 'settings-camera',
23
24 properties: {
25 /**
26 * True if the user has selected the camera as the user image source.
27 * @type {boolean}
28 */
29 cameraActive: {
30 type: Boolean,
31 observer: 'cameraActiveChanged_',
32 value: false,
33 },
34
35 /**
36 * True when the camera is actually streaming video. May be false even when
37 * the camera is present and shown, but still initializing.
38 * @private {boolean}
39 */
40 cameraOnline_: {
41 type: Boolean,
42 value: false,
43 },
44
45 /**
46 * True if the photo is currently marked flipped.
47 * @private {boolean}
48 */
49 isFlipped_: {
50 type: Boolean,
51 value: false,
52 },
53 },
54
55 /** @override */
56 attached: function() {
57 this.$.cameraVideo.addEventListener('canplay', function() {
58 this.cameraOnline_ = true;
59 }.bind(this));
60 },
61
62 /** 12 /**
63 * Performs photo capture from the live camera stream. 'phototaken' event 13 * Dimensions for camera capture.
64 * will be fired as soon as captured photo is available, with 'dataURL' 14 * @const
65 * property containing the photo encoded as a data URL.
66 * @private
67 */ 15 */
68 takePhoto: function() { 16 var CAPTURE_SIZE = {height: 480, width: 480};
69 if (!this.cameraOnline_) 17
70 return; 18 Polymer({
71 var canvas = 19 is: 'settings-camera',
72 /** @type {HTMLCanvasElement} */ (document.createElement('canvas')); 20
73 canvas.width = CAPTURE_SIZE.width; 21 properties: {
74 canvas.height = CAPTURE_SIZE.height; 22 /**
75 this.captureFrame_( 23 * True if the user has selected the camera as the user image source.
76 this.$.cameraVideo, 24 * @type {boolean}
77 /** @type {!CanvasRenderingContext2D} */ (canvas.getContext('2d'))); 25 */
78 26 cameraActive: {
79 var photoDataUrl = this.isFlipped_ ? this.flipFrame_(canvas) : 27 type: Boolean,
80 canvas.toDataURL('image/png'); 28 observer: 'cameraActiveChanged_',
81 this.fire('phototaken', {photoDataUrl: photoDataUrl}); 29 value: false,
82 30 },
83 announceAccessibleMessage( 31
84 loadTimeData.getString('photoCaptureAccessibleText')); 32 /**
85 }, 33 * True when the camera is actually streaming video. May be false even
86 34 * when
87 /** 35 * the camera is present and shown, but still initializing.
88 * Observer for the cameraActive property. 36 * @private {boolean}
89 * @private 37 */
90 */ 38 cameraOnline_: {
91 cameraActiveChanged_: function() { 39 type: Boolean,
92 if (this.cameraActive) 40 value: false,
93 this.startCamera_(); 41 },
94 else 42
43 /**
44 * True if the photo is currently marked flipped.
45 * @private {boolean}
46 */
47 isFlipped_: {
48 type: Boolean,
49 value: false,
50 },
51 },
52
53 /** @override */
54 attached: function() {
55 this.$.cameraVideo.addEventListener('canplay', function() {
56 this.cameraOnline_ = true;
57 }.bind(this));
58 },
59
60 /**
61 * Performs photo capture from the live camera stream. 'phototaken' event
62 * will be fired as soon as captured photo is available, with 'dataURL'
63 * property containing the photo encoded as a data URL.
64 * @private
65 */
66 takePhoto: function() {
67 if (!this.cameraOnline_)
68 return;
69 var canvas =
70 /** @type {HTMLCanvasElement} */ (document.createElement('canvas'));
71 canvas.width = CAPTURE_SIZE.width;
72 canvas.height = CAPTURE_SIZE.height;
73 this.captureFrame_(
74 this.$.cameraVideo,
75 /** @type {!CanvasRenderingContext2D} */ (canvas.getContext('2d')));
76
77 var photoDataUrl = this.isFlipped_ ? this.flipFrame_(canvas) :
78 canvas.toDataURL('image/png');
79 this.fire('phototaken', {photoDataUrl: photoDataUrl});
80
81 announceAccessibleMessage(
82 loadTimeData.getString('photoCaptureAccessibleText'));
83 },
84
85 /**
86 * Observer for the cameraActive property.
87 * @private
88 */
89 cameraActiveChanged_: function() {
90 if (this.cameraActive)
91 this.startCamera_();
92 else
93 this.stopCamera_();
94 },
95
96 /**
97 * Tries to start the camera stream capture.
98 * @private
99 */
100 startCamera_: function() {
95 this.stopCamera_(); 101 this.stopCamera_();
96 }, 102 this.cameraStartInProgress_ = true;
97 103
98 /** 104 var successCallback = function(stream) {
99 * Tries to start the camera stream capture. 105 if (this.cameraStartInProgress_) {
100 * @private 106 this.$.cameraVideo.src = URL.createObjectURL(stream);
101 */ 107 this.cameraStream_ = stream;
102 startCamera_: function() { 108 } else {
103 this.stopCamera_(); 109 this.stopVideoTracks_(stream);
104 this.cameraStartInProgress_ = true; 110 }
105 111 this.cameraStartInProgress_ = false;
106 var successCallback = function(stream) { 112 }.bind(this);
107 if (this.cameraStartInProgress_) { 113
108 this.$.cameraVideo.src = URL.createObjectURL(stream); 114 var errorCallback = function() {
109 this.cameraStream_ = stream; 115 this.cameraOnline_ = false;
116 this.cameraStartInProgress_ = false;
117 }.bind(this);
118
119 navigator.webkitGetUserMedia(
120 {video: true}, successCallback, errorCallback);
121 },
122
123 /**
124 * Stops camera capture, if it's currently cameraActive.
125 * @private
126 */
127 stopCamera_: function() {
128 this.cameraOnline_ = false;
129 this.$.cameraVideo.src = '';
130 if (this.cameraStream_)
131 this.stopVideoTracks_(this.cameraStream_);
132 // Cancel any pending getUserMedia() checks.
133 this.cameraStartInProgress_ = false;
134 },
135
136 /**
137 * Stops all video tracks associated with a MediaStream object.
138 * @param {!MediaStream} stream
139 * @private
140 */
141 stopVideoTracks_: function(stream) {
142 var tracks = stream.getVideoTracks();
143 for (var t of tracks)
144 t.stop();
145 },
146
147 /**
148 * Flip the live camera stream.
149 * @private
150 */
151 onTapFlipPhoto_: function() {
152 this.isFlipped_ = !this.isFlipped_;
153 this.$.userImageStreamCrop.classList.toggle('flip-x', this.isFlipped_);
154
155 var flipMessageId = this.isFlipped_ ? 'photoFlippedAccessibleText' :
156 'photoFlippedBackAccessibleText';
157 announceAccessibleMessage(loadTimeData.getString(flipMessageId));
158 },
159
160 /**
161 * Captures a single still frame from a <video> element, placing it at the
162 * current drawing origin of a canvas context.
163 * @param {!HTMLVideoElement} video Video element to capture from.
164 * @param {!CanvasRenderingContext2D} ctx Canvas context to draw onto.
165 * @private
166 */
167 captureFrame_: function(video, ctx) {
168 var width = video.videoWidth;
169 var height = video.videoHeight;
170 if (width < CAPTURE_SIZE.width || height < CAPTURE_SIZE.height) {
171 console.error(
172 'Video capture size too small: ' + width + 'x' + height + '!');
173 }
174 var src = {};
175 if (width / CAPTURE_SIZE.width > height / CAPTURE_SIZE.height) {
176 // Full height, crop left/right.
177 src.height = height;
178 src.width = height * CAPTURE_SIZE.width / CAPTURE_SIZE.height;
110 } else { 179 } else {
111 this.stopVideoTracks_(stream); 180 // Full width, crop top/bottom.
181 src.width = width;
182 src.height = width * CAPTURE_SIZE.height / CAPTURE_SIZE.width;
112 } 183 }
113 this.cameraStartInProgress_ = false; 184 src.x = (width - src.width) / 2;
114 }.bind(this); 185 src.y = (height - src.height) / 2;
115 186 ctx.drawImage(
116 var errorCallback = function() { 187 video, src.x, src.y, src.width, src.height, 0, 0, CAPTURE_SIZE.width,
117 this.cameraOnline_ = false; 188 CAPTURE_SIZE.height);
118 this.cameraStartInProgress_ = false; 189 },
119 }.bind(this); 190
120 191 /**
121 navigator.webkitGetUserMedia({video: true}, successCallback, errorCallback);
122 },
123
124 /**
125 * Stops camera capture, if it's currently cameraActive.
126 * @private
127 */
128 stopCamera_: function() {
129 this.cameraOnline_ = false;
130 this.$.cameraVideo.src = '';
131 if (this.cameraStream_)
132 this.stopVideoTracks_(this.cameraStream_);
133 // Cancel any pending getUserMedia() checks.
134 this.cameraStartInProgress_ = false;
135 },
136
137 /**
138 * Stops all video tracks associated with a MediaStream object.
139 * @param {!MediaStream} stream
140 * @private
141 */
142 stopVideoTracks_: function(stream) {
143 var tracks = stream.getVideoTracks();
144 for (var t of tracks)
145 t.stop();
146 },
147
148 /**
149 * Flip the live camera stream.
150 * @private
151 */
152 onTapFlipPhoto_: function() {
153 this.isFlipped_ = !this.isFlipped_;
154 this.$.userImageStreamCrop.classList.toggle('flip-x', this.isFlipped_);
155
156 var flipMessageId = this.isFlipped_ ?
157 'photoFlippedAccessibleText' : 'photoFlippedBackAccessibleText';
158 announceAccessibleMessage(loadTimeData.getString(flipMessageId));
159 },
160
161 /**
162 * Captures a single still frame from a <video> element, placing it at the
163 * current drawing origin of a canvas context.
164 * @param {!HTMLVideoElement} video Video element to capture from.
165 * @param {!CanvasRenderingContext2D} ctx Canvas context to draw onto.
166 * @private
167 */
168 captureFrame_: function(video, ctx) {
169 var width = video.videoWidth;
170 var height = video.videoHeight;
171 if (width < CAPTURE_SIZE.width || height < CAPTURE_SIZE.height) {
172 console.error('Video capture size too small: ' +
173 width + 'x' + height + '!');
174 }
175 var src = {};
176 if (width / CAPTURE_SIZE.width > height / CAPTURE_SIZE.height) {
177 // Full height, crop left/right.
178 src.height = height;
179 src.width = height * CAPTURE_SIZE.width / CAPTURE_SIZE.height;
180 } else {
181 // Full width, crop top/bottom.
182 src.width = width;
183 src.height = width * CAPTURE_SIZE.height / CAPTURE_SIZE.width;
184 }
185 src.x = (width - src.width) / 2;
186 src.y = (height - src.height) / 2;
187 ctx.drawImage(video, src.x, src.y, src.width, src.height,
188 0, 0, CAPTURE_SIZE.width, CAPTURE_SIZE.height);
189 },
190
191 /**
192 * Flips frame horizontally. 192 * Flips frame horizontally.
193 * @param {!(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement)} source 193 * @param {!(HTMLImageElement|HTMLCanvasElement|HTMLVideoElement)} source
194 * Frame to flip. 194 * Frame to flip.
195 * @return {string} Flipped frame as data URL. 195 * @return {string} Flipped frame as data URL.
196 */ 196 */
197 flipFrame_: function(source) { 197 flipFrame_: function(source) {
198 var canvas = document.createElement('canvas'); 198 var canvas = document.createElement('canvas');
199 canvas.width = CAPTURE_SIZE.width; 199 canvas.width = CAPTURE_SIZE.width;
200 canvas.height = CAPTURE_SIZE.height; 200 canvas.height = CAPTURE_SIZE.height;
201 var ctx = canvas.getContext('2d'); 201 var ctx = canvas.getContext('2d');
202 ctx.translate(CAPTURE_SIZE.width, 0); 202 ctx.translate(CAPTURE_SIZE.width, 0);
203 ctx.scale(-1.0, 1.0); 203 ctx.scale(-1.0, 1.0);
204 ctx.drawImage(source, 0, 0); 204 ctx.drawImage(source, 0, 0);
205 return canvas.toDataURL('image/png'); 205 return canvas.toDataURL('image/png');
206 }, 206 },
207 }); 207 });
208 208
209 })(); 209 })();
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698