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
-
12app/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