diff options
author | Orangerot <purple@orangerot.dev> | 2024-12-10 06:28:50 +0100 |
---|---|---|
committer | Orangerot <purple@orangerot.dev> | 2024-12-10 06:28:50 +0100 |
commit | f08b0b4d51f1ba0f003cd9bffd6b481a92ae52de (patch) | |
tree | f0e69ae356b3f6cf2d0ba346d0d19ffef4e1a76a | |
parent | 76872c7bdec8ba2c681ebb752899f43cdd74941a (diff) |
feat: use webcam to take picture
-rw-r--r-- | index.html | 16 | ||||
-rw-r--r-- | main.js | 43 | ||||
-rw-r--r-- | style.css | 17 |
3 files changed, 65 insertions, 11 deletions
@@ -11,21 +11,22 @@ <link rel="stylesheet" href="style.css"> <title>Imagine - Image Editor</title> </head> - <body style="padding-top: 100dvh; " class=""> + <body style="padding-top: 100dvh; " class="import-active"> <div class="navbar columns is-mobile is-fixed-top"> <div class="column"> <div class="hero is-fullheight" style="min-height: 100dvh;"> <div class="hero-body"> <div class="container"> <canvas id="myCanvas" class="is-visible-editor" width="300" height="300"></canvas> - <div class="columns is-mobile is-hidden-editor"> + <video id="video" class="is-visible-camera" width="300" height="300"></video> + <div class="columns is-mobile is-visible-import"> <div class="column"> <button id="take-picture" class="button is-large is-responsive is-fullwidth py-6" style="display: flex; flex-direction: column; align-items: center;" > - <i class="fa-solid fa-6x fa-camera mb-4"></i> - Take a Picture + <i class="fa-solid fa-6x fa-video mb-4"></i> + Use Camera </button> </div> <div class="column"> @@ -46,10 +47,15 @@ bottom: 30px"> <i class="fa-solid fa-sliders mr-2"></i> Settings </a> - <button id="back" class="button is-visible-editor" style="position: absolute; left: 30px; + <button id="back" class="button is-hidden-import" style="position: absolute; left: 30px; top: 30px"> <i class="fa-solid fa-arrow-left mr-2"></i> Back </button> + <div style="position: absolute; bottom: 30px; left: 30px; right: 30px"> + <button id="cheese" class="button is-large is-fullwidth is-visible-camera" > + <i class="fa-solid fa-camera mr-2"></i> Take a Picture + </button> + </div> </div> </div> </div> @@ -1,4 +1,5 @@ let canvas; +let video; let ctx; let settings = { brightness: {}, @@ -12,10 +13,12 @@ const img = new Image(); document.addEventListener("DOMContentLoaded", function() { canvas = document.getElementById("myCanvas"); ctx = canvas.getContext("2d"); - document.getElementById("back").addEventListener("click", () => document.body.classList.remove("editor-enabled")); + video = document.getElementById("video"); + document.getElementById("back").addEventListener("click", () => document.body.className = "import-active"); // bind listeners - document.getElementById("take-picture").addEventListener("click", take_picture); + document.getElementById("take-picture").addEventListener("click", use_camera); + document.getElementById("cheese").addEventListener("click", take_picture); document.getElementById("upload-image").addEventListener("change", upload_image) document.getElementById("save").addEventListener("click", save_image) @@ -23,6 +26,20 @@ document.addEventListener("DOMContentLoaded", function() { window.addEventListener("resize", () => draw(true)) + video.addEventListener("canplay", function() { + const width = 320; + let height = video.videoHeight / (video.videoWidth / width); + + // Firefox currently has a bug where the height can't be read from + // the video, so we will make assumptions if this happens. + + if (isNaN(height)) { + height = width / (4 / 3); + } + video.width = width; + video.height = height; + }); + for (let setting in settings) { // make an array out of an iterable const elements = [...document.getElementsByClassName(setting)]; @@ -48,13 +65,31 @@ function reset_all(setting) { draw(true); } +function use_camera() { + navigator.mediaDevices + .getUserMedia({ video: true, audio: false }) + .then((stream) => { + video.srcObject = stream; + video.play(); + document.body.className = "camera-active"; + }) + .catch((err) => { + console.error(`An error occurred: ${err}`); + }); +} + function take_picture() { - document.body.classList.add("editor-enabled"); + canvas.width = video.width; + canvas.height = video.height; + ctx.drawImage(video, 0, 0, canvas.width, canvas.height); + img.src = canvas.toDataURL("image/png"); + img.onload = () => draw(true); + document.body.className = "editor-active"; } function upload_image() { - document.body.classList.add("editor-enabled"); + document.body.className = "editor-active"; console.log(this.files[0]); @@ -8,10 +8,23 @@ canvas { max-height: 100%; } -body:not(.editor-enabled) .is-visible-editor { +video { + width: 100%; + height: 100%; +} + +body:not(.import-active) .is-visible-import { + display: none !important; +} + +body:not(.camera-active) .is-visible-camera { + display: none !important; +} + +body:not(.editor-active) .is-visible-editor { display: none !important; } -body.editor-enabled .is-hidden-editor { +body.import-active .is-hidden-import { display: none !important; } |