Browse Source
Add Snap widget to take quick photos
Add Snap widget to take quick photos
Link it ti PublishBrief (Chat soon)pull/853/head
8 changed files with 260 additions and 4 deletions
-
1app/views/news.tpl
-
7app/widgets/PublishBrief/_publishbrief_embed_default.tpl
-
1app/widgets/PublishBrief/locales.ini
-
12app/widgets/Snap/Snap.php
-
78app/widgets/Snap/snap.css
-
129app/widgets/Snap/snap.js
-
24app/widgets/Snap/snap.tpl
-
4app/widgets/Upload/upload.js
@ -0,0 +1,12 @@ |
|||||
|
<?php |
||||
|
|
||||
|
use Movim\Widget\Base; |
||||
|
|
||||
|
class Snap extends Base |
||||
|
{ |
||||
|
public function load() |
||||
|
{ |
||||
|
$this->addjs('snap.js'); |
||||
|
$this->addcss('snap.css'); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,78 @@ |
|||||
|
#snap { |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
background-color: #111; |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
z-index: 2; |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
#snap canvas { |
||||
|
border: 1rem #333 solid; |
||||
|
box-sizing: border-box; |
||||
|
} |
||||
|
|
||||
|
#snap canvas, |
||||
|
#snap video { |
||||
|
width: 100%; |
||||
|
height: 100%; |
||||
|
object-fit: contain; |
||||
|
} |
||||
|
|
||||
|
#snap select#snapsource { |
||||
|
display: none; |
||||
|
} |
||||
|
|
||||
|
#snap canvas { |
||||
|
position: absolute; |
||||
|
top: 0; |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
#snap button#snapshoot, |
||||
|
#snap button#snapupload { |
||||
|
right: calc(50% - 3.5rem); |
||||
|
position: absolute; |
||||
|
bottom: 2rem; |
||||
|
} |
||||
|
|
||||
|
#snap button#snapswitch { |
||||
|
left: 2rem; |
||||
|
} |
||||
|
|
||||
|
/* Controls */ |
||||
|
#snap ul.controls.list { |
||||
|
position: absolute; |
||||
|
width: 100%; |
||||
|
top: 0; |
||||
|
} |
||||
|
|
||||
|
#snap ul.controls.list > li { |
||||
|
padding: 3rem; |
||||
|
} |
||||
|
|
||||
|
#snap ul.controls.list > li span { |
||||
|
padding: 2rem; |
||||
|
} |
||||
|
|
||||
|
#snap ul.controls.list > li span.primary { |
||||
|
left: 0; |
||||
|
} |
||||
|
|
||||
|
/* States */ |
||||
|
#snap.shoot, |
||||
|
#snap.upload { |
||||
|
display: block; |
||||
|
} |
||||
|
|
||||
|
#snap.shoot ul.controls.list > li#snapback, |
||||
|
#snap.shoot #snapupload, |
||||
|
#snap.shoot #snapclose, |
||||
|
#snap.shoot canvas, |
||||
|
#snap.upload ul.controls.list > li#snapclose, |
||||
|
#snap.upload #snapshoot, |
||||
|
#snap.upload #snapback, |
||||
|
#snap.upload #snapswitch { |
||||
|
display: none; |
||||
|
} |
||||
@ -0,0 +1,129 @@ |
|||||
|
var Snap = { |
||||
|
snap: undefined, |
||||
|
video: undefined, |
||||
|
videoSelect: undefined, |
||||
|
canvas: undefined, |
||||
|
|
||||
|
gotStream: function() { |
||||
|
const constraints = { |
||||
|
video: { |
||||
|
deviceId: Snap.videoSelect.value, |
||||
|
width: {ideal: 1280}, |
||||
|
height: {ideal: 720} |
||||
|
} |
||||
|
}; |
||||
|
|
||||
|
if(navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { |
||||
|
navigator.mediaDevices.getUserMedia(constraints) |
||||
|
.then(stream => { |
||||
|
Snap.video.srcObject = stream; |
||||
|
}); |
||||
|
} |
||||
|
}, |
||||
|
gotDevices: function(deviceInfos) { |
||||
|
Snap.videoSelect.innerText = ''; |
||||
|
|
||||
|
const ids = []; |
||||
|
|
||||
|
for (let i = 0; i !== deviceInfos.length; ++i) { |
||||
|
const deviceInfo = deviceInfos[i]; |
||||
|
|
||||
|
if (deviceInfo.kind === 'videoinput' && !ids.includes(deviceInfo.deviceId)) { |
||||
|
const option = document.createElement('option'); |
||||
|
option.value = deviceInfo.deviceId; |
||||
|
option.text = deviceInfo.label; |
||||
|
Snap.videoSelect.add(option); |
||||
|
ids.push(deviceInfo.deviceId); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Snap.videoSelect.addEventListener('change', e => Snap.gotStream() ); |
||||
|
Snap.gotStream(); |
||||
|
|
||||
|
snap.classList = 'shoot'; |
||||
|
}, |
||||
|
shoot: function() { |
||||
|
Snap.canvas.width = Snap.video.videoWidth; |
||||
|
Snap.canvas.height = Snap.video.videoHeight; |
||||
|
var context = Snap.canvas.getContext('2d'); |
||||
|
context.drawImage(Snap.video, 0, 0, Snap.video.videoWidth, Snap.video.videoHeight); |
||||
|
Snap.video.pause(); |
||||
|
|
||||
|
Upload.name = 'snapshot.jpg'; |
||||
|
|
||||
|
Snap.canvas.toBlob( |
||||
|
function (blob) { |
||||
|
Upload.prepare(blob); |
||||
|
}, |
||||
|
'image/jpeg', |
||||
|
0.85 |
||||
|
); |
||||
|
|
||||
|
Snap.snap.classList = 'upload'; |
||||
|
}, |
||||
|
clear: function() { |
||||
|
Snap.video.play(); |
||||
|
var context = Snap.canvas.getContext('2d'); |
||||
|
context.clearRect(0, 0, Snap.canvas.width, Snap.canvas.height); |
||||
|
}, |
||||
|
close: function() { |
||||
|
let stream = Snap.video.srcObject; |
||||
|
|
||||
|
if (stream) { |
||||
|
stream.getTracks().forEach(function(track) { |
||||
|
track.stop(); |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
Snap.video.srcObject = null; |
||||
|
}, |
||||
|
init : function() { |
||||
|
|
||||
|
Snap.snap = document.querySelector('#snap'); |
||||
|
Snap.video = document.querySelector('#snap video'); |
||||
|
Snap.videoSelect = document.querySelector('#snap select#snapsource'); |
||||
|
Snap.canvas = document.querySelector('#snap canvas'); |
||||
|
|
||||
|
Snap.close(); // Just in case
|
||||
|
|
||||
|
navigator.mediaDevices.enumerateDevices().then(devices => Snap.gotDevices(devices)); |
||||
|
|
||||
|
document.querySelector("#snap #snapshoot").addEventListener('click', function() { |
||||
|
Snap.shoot(); |
||||
|
}); |
||||
|
|
||||
|
document.querySelector("#snap #snapupload").addEventListener('click', function() { |
||||
|
Upload.init(); |
||||
|
}); |
||||
|
|
||||
|
document.querySelector("#snap #snapback").addEventListener('click', function() { |
||||
|
Snap.snap.classList = ''; |
||||
|
Snap.close(); |
||||
|
}); |
||||
|
|
||||
|
document.querySelector("#snap #snapclose").addEventListener('click', function() { |
||||
|
Snap.snap.classList = 'shoot'; |
||||
|
Snap.video.play(); |
||||
|
}); |
||||
|
|
||||
|
document.querySelector("#snap #snapswitch").addEventListener('click', function() { |
||||
|
Snap.videoSelect.selectedIndex++; |
||||
|
|
||||
|
// No empty selection
|
||||
|
if (Snap.videoSelect.selectedIndex == -1) { |
||||
|
Snap.videoSelect.selectedIndex++; |
||||
|
} |
||||
|
|
||||
|
Snap.close(); |
||||
|
Snap.gotStream(); |
||||
|
}); |
||||
|
|
||||
|
Upload.attach(function(file) { |
||||
|
document.querySelector('input[name=embed]').value = file.uri; |
||||
|
PublishBrief.checkEmbed(); |
||||
|
|
||||
|
Snap.snap.classList = ''; |
||||
|
Snap.close(); |
||||
|
}); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,24 @@ |
|||||
|
<div id="snap"> |
||||
|
<video autoplay></video> |
||||
|
<canvas id="snapcanvas"></canvas> |
||||
|
<select id="snapsource"></select> |
||||
|
<button id="snapshoot" class="button action color green"> |
||||
|
<i class="material-icons">camera</i> |
||||
|
</button> |
||||
|
<button id="snapupload" class="button action color blue"> |
||||
|
<i class="material-icons">publish</i> |
||||
|
</button> |
||||
|
<button id="snapswitch" class="button action color"> |
||||
|
<i class="material-icons">switch_camera</i> |
||||
|
</button> |
||||
|
<ul class="list controls"> |
||||
|
<li> |
||||
|
<span id="snapback" class="primary icon color transparent active"> |
||||
|
<i class="material-icons">arrow_back</i> |
||||
|
</span> |
||||
|
<span id="snapclose" class="control icon color transparent active"> |
||||
|
<i class="material-icons">close</i> |
||||
|
</span> |
||||
|
</li> |
||||
|
</ul> |
||||
|
</div> |
||||
Write
Preview
Loading…
Cancel
Save
Reference in new issue