From 6768c7e7ef195bef5006a5c4ae85ef7d9e155b0e Mon Sep 17 00:00:00 2001 From: Roland Gruber Date: Wed, 22 Jul 2020 08:23:49 +0200 Subject: [PATCH] webcam support --- lam/lib/html.inc | 63 +++++++++++++++++++++++++++++++ lam/lib/modules/inetOrgPerson.inc | 21 ++++++++++- lam/templates/lib/500_lam.js | 46 ++++++++++++++++++++++ 3 files changed, 128 insertions(+), 2 deletions(-) diff --git a/lam/lib/html.inc b/lam/lib/html.inc index 21fb7b7d..051d88f1 100644 --- a/lam/lib/html.inc +++ b/lam/lib/html.inc @@ -4973,5 +4973,68 @@ class htmlResponsiveTable extends htmlElement { } +/** + * Renders a canvas. + * + * @author Roland Gruber + */ +class htmlCanvas extends htmlElement { + + private $id; + + /** + * Constructor + * + * @param string $id html id + */ + public function __construct($id) { + $this->id = $id; + } + + /** + * @inheritDoc + */ + function generateHTML($module, $input, $values, $restricted, &$tabindex, $scope) { + $classesValue = ''; + if (!empty($this->cssClasses)) { + $classesValue = ' class="' . implode(' ', $this->cssClasses) . '"'; + } + echo ''; + echo ''; + return array(); + } +} + +/** + * Renders a video. + * + * @author Roland Gruber + */ +class htmlVideo extends htmlElement { + + private $id; + + /** + * Constructor + * + * @param string $id html id + */ + public function __construct($id) { + $this->id = $id; + } + + /** + * @inheritDoc + */ + function generateHTML($module, $input, $values, $restricted, &$tabindex, $scope) { + $classesValue = ''; + if (!empty($this->cssClasses)) { + $classesValue = ' class="' . implode(' ', $this->cssClasses) . '"'; + } + echo ''; + return array(); + } +} ?> diff --git a/lam/lib/modules/inetOrgPerson.inc b/lam/lib/modules/inetOrgPerson.inc index 47fbeef2..f6439fab 100644 --- a/lam/lib/modules/inetOrgPerson.inc +++ b/lam/lib/modules/inetOrgPerson.inc @@ -1704,9 +1704,26 @@ class inetOrgPerson extends baseModule implements passwordService { $container->add(new htmlSubTitle(_('Upload image')), 12); $label = _('Photo file'); $container->add(new htmlResponsiveInputFileUpload('photoFile', $label, 'photoUpload'), 12); + $container->addVerticalSpacer('0.5rem'); + $container->addLabel(new htmlOutputText(' ', false)); + $container->addField(new htmlAccountPageButton(get_class($this), 'photo', 'upload', _('Upload'))); $container->addVerticalSpacer('1rem'); - $container->addLabel(new htmlAccountPageButton(get_class($this), 'photo', 'upload', _('Upload'))); - $container->addField(new htmlAccountPageButton(get_class($this), 'attributes', 'back', _('Back'))); + $webcamContent = new htmlResponsiveRow(); + $webcamContent->add(new htmlSubTitle(_('Get from webcam')), 12); + $webcamContent->addLabel(new htmlOutputText(_('Image'))); + $webcamContent->addField(new htmlVideo('lam-webcam-video')); + $webcamContent->addLabel(new htmlOutputText(' ', false)); + $webcamButtonGroup = new htmlGroup(); + $captureButton = new htmlButton('lam-webcam-capture', _('Capture')); + $captureButton->setOnClick('window.lam.tools.startWebcamCapture(event);'); + $webcamButtonGroup->addElement($captureButton); + $webcamButtonGroup->addElement(new htmlAccountPageButton(get_class($this), 'photo', 'upload', _('Upload'))); + $webcamButtonGroup->addElement(new htmlCanvas('lam-webcam-canvas')); + $webcamContent->addField($webcamButtonGroup); + $webcamDiv = new htmlDiv('lam_webcam_div', $webcamContent, array('hidden')); + $container->add($webcamDiv, 12); + $container->addVerticalSpacer('1rem'); + $container->add(new htmlAccountPageButton(get_class($this), 'attributes', 'back', _('Back')), 12); } else { $container->add(new htmlSubTitle(_('Crop image')), 12); diff --git a/lam/templates/lib/500_lam.js b/lam/templates/lib/500_lam.js index d7839e40..4ec1ce52 100644 --- a/lam/templates/lib/500_lam.js +++ b/lam/templates/lib/500_lam.js @@ -934,6 +934,51 @@ window.lam.tools.setInitialFocus = function() { jQuery('.lam-initial-focus').focus(); }; +/** + * Initializes the webcam capture. + */ +window.lam.tools.initWebcamCapture = function() { + var contentDiv = jQuery('#lam_webcam_div'); + if (contentDiv.length === 0) { + return; + } + if (navigator.mediaDevices && navigator.mediaDevices.enumerateDevices) { + navigator.mediaDevices.enumerateDevices() + .then(function(mediaDevices) { + mediaDevices.forEach(mediaDevice => { + if (mediaDevice.kind === 'videoinput') { + contentDiv.show(); + } + }); + }); + } +}; + +/** + * Starts the webcam capture. + */ +window.lam.tools.startWebcamCapture = function(event) { + event.preventDefault(); + var canvas = document.getElementById('lam-webcam-canvas'); + var video = document.getElementById('lam-webcam-videofor'); + navigator.mediaDevices.getUserMedia({ + video: { + facingMode: 'user', + width: { min: 1024, ideal: 1280, max: 1920 }, + height: { min: 576, ideal: 720, max: 1080 } + }, + audio: false + }) + .then(function(stream) { + video.srcObject = stream; + video.play(); + }) + .catch(function(err) { + console.log("An error occurred: " + err); + }); + return false; +} + window.lam.tools.schema = window.lam.tools.schema || {}; /** @@ -1788,6 +1833,7 @@ jQuery(document).ready(function() { window.lam.tools.addSavedSelectListener(); window.lam.tools.activateTab(); window.lam.tools.setInitialFocus(); + window.lam.tools.initWebcamCapture(); window.lam.tools.schema.select(); window.lam.html.activateLightboxes(); window.lam.html.preventEnter();