123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301 |
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="UTF-8">
- <meta name="apple-mobile-web-app-capable" content="yes" />
- <meta name="viewport" content="user-scalable=no, width=device-width, initial-scale=1, maximum-scale=1"/>
- <meta name="theme-color" content="#4b75ff">
- <link rel="stylesheet" href="../script/semantic/semantic.min.css">
- <script src="../script/jquery.min.js"></script>
- <script src="../script/semantic/semantic.min.js"></script>
- <script src="../script/ao_module.js"></script>
- <link rel="manifest" crossorigin="use-credentials" href="manifest.json">
- <title>Camera</title>
- <style>
- body{
- background-color: #000000;
- }
- .previewer{
- width: 100%;
- max-height: 100%;
- }
- #controls{
- position: fixed;
- left: 0px;
- bottom: 0px;
- width: 100%;
- padding: 12px;
- padding-bottom: 20px;
-
- }
- #verticalUI .shutterContainer{
- display: flex;
- justify-content: space-evenly;
- }
- #verticalUI .shutter.image{
- width: 5em;
- }
- #sidewayUI .shutterContainer{
- position: fixed;
- right: 0px;
- height: 100%;
- top:0px;
- width: 5em;
- }
-
- #sidewayUI .shutter.image{
- position: absolute;
- right: 20px;
- width: 5em;
- top: 50%;
- -ms-transform: translateY(-50%);
- transform: translateY(-50%);
- }
- #shutterCover{
- position: fixed;
- top:0px;
- left: 0px;
- width: 100%;
- height: 100%;
- background-color: black;
- display:none;
- }
- #albumn{
- position: fixed;
- bottom: 20px;
- right: 12px;
- width: 6em;
- }
- .ablumnpreview{
- width: 5em;
- }
- .latestPreview{
- width: 5em !important;
- height: 5em !important;
- }
- .zoombarcontainer{
- width: 100%;
- padding-bottom: 8px;
- padding-left: 20px;
- padding-right: 20px;
- }
- .sideway.zoombarcontainer{
- display: flex;
- justify-content: space-evenly;
- }
- #zoombar{
- width: 100%;
- }
- #zoombar.sideway{
- width: 50% !important;
- }
- </style>
- </head>
- <body>
- <video id="camera" class="previewer" autoplay></video>
- <div id="shutterCover"></div>
- <canvas id="canvas" style="display:none;"></canvas>
- <div id="albumn">
- <div class="ablumnpreview">
- <img class="ui fluid image latestPreview" src="img/module_icon.png">
- </div>
- </div>
- <div id="controls">
- <div class="zoombarcontainer">
- <input id="zoombar" type="range" min="1" max="100" value="50">
- </div>
- <div id="verticalUI">
- <div class="shutterContainer">
- <div onclick="takePicture();" ontouchdown="takePicture();">
- <img class="ui shutter image" src="img/shutter.png">
- </div>
- </div>
- </div>
- <div id="sidewayUI">
- <div class="shutterContainer">
- <div onclick="takePicture();" ontouchdown="takePicture();">
- <img class="ui shutter image" src="img/shutter.png">
- </div>
- </div>
- </div>
- </div>
- <script>
- let isMobile = false;
- let saveFolder = "user:/Photo/DCIM";
- if( /Android|webOS|iPhone|iPad|Mac|Macintosh|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
- isMobile = true;
- }
- $(document).ready(function(){
- ao_module_agirun("Camera/backend/readydir.js", {savetarget: saveFolder}, function(){
- //Folder structure ready
- initcamera();
- });
- loadAblumnPreview();
- });
- $(window).on("resize", function(){
- handleWindowResize();
- });
- handleWindowResize();
- function handleWindowResize(){
- var width = window.innerWidth;
- var height = window.innerHeight;
- if (width > height){
- //Using the phone sideway
- $("#verticalUI").hide();
- $("#sidewayUI").show();
- $(".zoombarcontainer").addClass("sideway");
- $("#zoombar").addClass("sideway");
- }else{
- //Use the phone vertically
- $("#verticalUI").show();
- $("#sidewayUI").hide();
- $(".zoombarcontainer").removeClass("sideway");
- $("#zoombar").removeClass("sideway");
- }
- }
- function loadAblumnPreview(){
- ao_module_agirun("Camera/backend/loadLatestPhoto.js", {savetarget: saveFolder}, function(data){
- if (data.error !== undefined){
- console.log(data.error);
- }else{
- $(".latestPreview").attr("src", `../media/?file=${data}`);
- console.log(data);
- }
-
- });
- }
-
- function takePicture(){
- $("#shutterCover").show(0);
- setTimeout(function(){
- $("#shutterCover").hide();
- }, 500);
- var canvas = document.getElementById('canvas');
- var video = document.getElementById('camera');
- canvas.width = video.videoWidth;
- canvas.height = video.videoHeight;
- canvas.getContext('2d').drawImage(video, 0, 0, video.videoWidth, video.videoHeight);
- canvas.toBlob(function(blob){
- //const img = new Image();
- //img.src = URL.createObjectURL(blob);
- //window.open(img.src);
- //Generate a filename for this photo
- var d = new Date();
- var filename = "DSC_" + d.getFullYear() + d.getMonth() + d.getDate() + "_" + d.getHours() + d.getMinutes() + d.getSeconds() + ".jpg";
- //Upload it to server
- uploadImageToServer(filename, blob, function(){
- //Update the image preview
- loadAblumnPreview();
- });
- }, "image/jpeg");
- }
- //Upload the file to server
- function uploadFile(file, uploadPath, callback=undefined){
- let url = '../../system/file_system/upload'
- let formData = new FormData()
- let xhr = new XMLHttpRequest()
- formData.append('file', file);
- formData.append('path', uploadPath);
- xhr.open('POST', url, true)
- xhr.upload.addEventListener("progress", function(e) {
- var progress = (e.loaded * 100.0 / e.total) || 100;
- console.log(progress);
- });
- xhr.addEventListener('readystatechange', function(e) {
- if (xhr.readyState == 4 && xhr.status == 200) {
- //Uplaod process ok
- var resp = JSON.parse(e.target.response);
- if (callback != undefined){
- callback(resp);
- }
- }else{
- //Upload failed
- if (callback != undefined){
- callback({
- error: "File upload failed"
- });
- }
- }
- });
- xhr.send(formData);
- }
- function uploadImageToServer(filename, blob, callback){
- var imageFile = ao_module_utils.blobToFile(blob, filename, blob.type);
- uploadFile(imageFile, "user:/Photo/DCIM", callback);
- }
- function initcamera(){
- //Define the camera constraints
- const constraints = {
- video: {
- width: { ideal: 2048 },
- height: { ideal: 1080 },
- zoom: true,
- facingMode: 'environment'
- },
- audio: false
- };
- const video = document.querySelector("video");
- navigator.mediaDevices.getUserMedia(constraints).then((stream) => {
- const [track] = stream.getVideoTracks();
- try{
- const capabilities = track.getCapabilities();
- const settings = track.getSettings();
- console.log(track, settings);
- video.srcObject = stream;
- //Check if zoom exists. If yes, allow zoom
- if (!('zoom' in settings)) {
- $("#zoombar").hide();
- }else{
- var input = $("#zoombar")[0];
-
- input.min = capabilities.zoom.min;
- input.max = capabilities.zoom.max;
- input.step = capabilities.zoom.step;
- input.value = settings.zoom;
- input.oninput = function(event) {
- track.applyConstraints({
- advanced: [ {zoom: event.target.value} ]
- });
- }
- }
- }catch(ex){
- //This video input support nothing
- $("#zoombar").hide();
- video.srcObject = stream;
- }
-
- });
- }
-
- </script>
- </body>
- </html>
|