Browse Source

Update 'take a profile picture' implementation to allow preview of taken picture.

pull/40/head
Evan Theurer 11 years ago
parent
commit
eab6c09d3e
  1. 18
      src/styles/components/_settings.scss
  2. 122
      static/js/directives/settings.js
  3. 18
      static/partials/settings.html

18
src/styles/components/_settings.scss

@ -71,6 +71,24 @@
right: 10px; right: 10px;
top: 10px; top: 10px;
} }
.showTakePicture {
position: relative;
.btn {
margin: 5px 0px;
}
}
.btn-takePicture {
position: absolute;
top: 110px;
right: 90px;
}
.countdownToTakePicture {
font-size: 45px;
color: $componentbg;
position: absolute;
top: 55px;
left: 95px;
}
.form-horizontal { .form-horizontal {
.controls { .controls {
@include breakpt($breakpoint-settings-medium, max-width, only screen) { @include breakpt($breakpoint-settings-medium, max-width, only screen) {

122
static/js/directives/settings.js

@ -22,11 +22,12 @@ define(['underscore', 'text!partials/settings.html'], function(_, template) {
return ["$compile", "mediaStream", function($compile, mediaStream) { return ["$compile", "mediaStream", function($compile, mediaStream) {
var controller = ['$scope', 'desktopNotify', 'mediaSources', 'safeApply', 'availableLanguages', 'translation', function($scope, desktopNotify, mediaSources, safeApply, availableLanguages, translation) { var controller = ['$scope', 'desktopNotify', 'mediaSources', 'safeApply', 'availableLanguages', 'translation', '$timeout',function($scope, desktopNotify, mediaSources, safeApply, availableLanguages, translation, $timeout) {
$scope.layout.settings = false; $scope.layout.settings = false;
$scope.showAdvancedSettings = true; $scope.showAdvancedSettings = true;
$scope.showTakePicture = false; $scope.showTakePicture = false;
$scope.previewPicture = false;
$scope.showTakePictureReady = true; $scope.showTakePictureReady = true;
$scope.rememberSettings = true; $scope.rememberSettings = true;
$scope.desktopNotify = desktopNotify; $scope.desktopNotify = desktopNotify;
@ -72,59 +73,92 @@ define(['underscore', 'text!partials/settings.html'], function(_, template) {
safeApply($scope); safeApply($scope);
}); });
}; };
$scope.takePicture = function(element, stop) { $scope.takePicture = function(element, take, retake, stop) {
var delayToTakePicture = 3000;
var takePictureCountFrom = 3;
var takePictureCountDown = function() {
$scope.countdown = {};
$scope.countdown.num = 3;
$timeout(function() {
$scope.countdown.num = 2;
}, delayToTakePicture/takePictureCountFrom*1);
$timeout(function() {
$scope.countdown.num = 1;
}, delayToTakePicture/takePictureCountFrom*2);
$timeout(function() {
$scope.countdown.num = null;
}, delayToTakePicture/takePictureCountFrom*3);
};
if (stop) { if (stop) {
$scope.showTakePicture = false; $scope.showTakePicture = false;
$scope.previewPicture = false;
if (localStream) { if (localStream) {
localStream.stop(); localStream.stop();
localStream = null; localStream = null;
} }
} else { return;
var video = $(element).parent().find("video").get(0); }
if (!$scope.showTakePicture) {
$scope.showTakePictureReady = false; var video = $(element).parent().parent().find("video").get(0);
var videoConstraints = true; var makePicture = function() {
if ($scope.user.settings.cameraId) { takePictureCountDown();
videoConstraints = { $timeout(function() {
optional: [{sourceId: $scope.user.settings.cameraId}] $scope.previewPicture = true;
} video.pause();
} }, delayToTakePicture);
getUserMedia({video: videoConstraints}, function(stream) { };
if ($scope.showTakePictureReady) {
stream.stop() if (!$scope.showTakePicture) {
return; $scope.showTakePictureReady = false;
} var videoConstraints = true;
$scope.showTakePicture = true; if ($scope.user.settings.cameraId) {
localStream = stream; videoConstraints = {
$scope.showTakePictureReady = true; optional: [{sourceId: $scope.user.settings.cameraId}]
attachMediaStream(video, stream); };
safeApply($scope); }
}, function(error) { getUserMedia({video: videoConstraints}, function(stream) {
console.error('Failed to get access to local media. Error code was ' + error.code); if ($scope.showTakePictureReady) {
$scope.showTakePictureReady = true; stream.stop();
safeApply($scope); return;
});
return;
} else {
var canvas = $(element).parent().find("canvas").get(0);
var videoWidth = video.videoWidth;
var videoHeight = video.videoHeight;
var aspectRatio = videoWidth/videoHeight;
if (!aspectRatio) {
// NOTE(longsleep): In Firefox the video size becomes available at sound point later - crap!
console.warn("Unable to compute aspectRatio", aspectRatio);
aspectRatio = 1.3333333333333333;
} }
var x = (46*aspectRatio-46)/-2 $scope.showTakePicture = true;
canvas.getContext("2d").drawImage(video, x, 0, 46*aspectRatio, 46); localStream = stream;
$scope.user.buddyPicture = canvas.toDataURL("image/jpeg"); $scope.showTakePictureReady = true;
console.info("Image size", $scope.user.buddyPicture.length); attachMediaStream(video, stream);
localStream.stop(); safeApply($scope);
localStream = null; }, function(error) {
console.error('Failed to get access to local media. Error code was ' + error.code);
$scope.showTakePictureReady = true; $scope.showTakePictureReady = true;
$scope.showTakePicture = false;
safeApply($scope); safeApply($scope);
});
return;
} else if (take) {
makePicture();
} else if (retake) {
video.play();
$scope.previewPicture = false;
makePicture();
} else {
var canvas = $(element).parent().parent().find("canvas").get(0);
var videoWidth = video.videoWidth;
var videoHeight = video.videoHeight;
var aspectRatio = videoWidth/videoHeight;
if (!aspectRatio) {
// NOTE(longsleep): In Firefox the video size becomes available at sound point later - crap!
console.warn("Unable to compute aspectRatio", aspectRatio);
aspectRatio = 1.3333333333333333;
} }
var x = (46*aspectRatio-46)/-2;
canvas.getContext("2d").drawImage(video, x, 0, 46*aspectRatio, 46);
$scope.user.buddyPicture = canvas.toDataURL("image/jpeg");
console.info("Image size", $scope.user.buddyPicture.length);
localStream.stop();
localStream = null;
$scope.showTakePictureReady = true;
$scope.showTakePicture = false;
$scope.previewPicture = false;
safeApply($scope);
} }
}; };

18
static/partials/settings.html

@ -11,11 +11,25 @@
<div style="margin-bottom:5px"> <div style="margin-bottom:5px">
<img ng-show="user.buddyPicture" ng-src="{{user.buddyPicture}}" alt="" /> <img ng-show="user.buddyPicture" ng-src="{{user.buddyPicture}}" alt="" />
</div> </div>
<div class="collapse" collapse="!showTakePicture"> <div class="collapse showTakePicture" collapse="!showTakePicture">
<div class="countdownToTakePicture" ng-show="countdown.num">
<span ng-bind="countdown.num"></span>
</div>
<video autoplay="autoplay" width="200"></video> <video autoplay="autoplay" width="200"></video>
<canvas style="display:none" width="46" height="46"></canvas> <canvas style="display:none" width="46" height="46"></canvas>
<a class="btn btn-xs btn-success btn-takePicture" ng-show="!previewPicture" ng-click="takePicture($event.target, true)"> {{_('Take')}}</a>
<a class="btn btn-xs btn-success btn-takePicture" ng-show="previewPicture" ng-click="takePicture($event.target, false, true)"> {{_('Retake')}}</a>
<div>
<a class="btn btn-small btn-default" ng-click="takePicture($event.target, false, false, true)"> {{_('Cancel')}}</a>
<a class="btn btn-small btn-primary" ng-disabled="!previewPicture" ng-click="takePicture($event.target)"> {{_('Set as Profile Picture')}}</a>
</div>
</div>
<div>
<a class="btn btn-small btn-success" ng-show="!showTakePicture" ng-disabled="!showTakePictureReady" ng-click="takePicture($event.target)"> {{_('Take picture')}}</a>
<span ng-show="!showTakePictureReady">
<i class="fa fa-spinner fa-spin"></i> {{_('Waiting for camera')}}
</span>
</div> </div>
<a class="btn btn-small btn-success" ng-disabled="!showTakePictureReady" ng-click="takePicture($event.target)"> {{_('Take picture')}}</a> <span ng-show="!showTakePictureReady"><i class="fa fa-spinner fa-spin"></i> {{_('Waiting for camera')}}</span><a class="btn btn-small btn-default" ng-show="showTakePicture" ng-click="takePicture($event.target, true)"> {{_('Cancel')}}</a>
</label> </label>
</div> </div>
</div> </div>

Loading…
Cancel
Save