diff --git a/frog-realestate-pwa/icon.png b/frog-realestate-pwa/icon.png
new file mode 100644
index 0000000..7c07dbc
Binary files /dev/null and b/frog-realestate-pwa/icon.png differ
diff --git a/frog-realestate-pwa/icon.svg b/frog-realestate-pwa/icon.svg
new file mode 100644
index 0000000..679b193
--- /dev/null
+++ b/frog-realestate-pwa/icon.svg
@@ -0,0 +1,57 @@
+
+
+
+
diff --git a/frog-realestate-pwa/index.html b/frog-realestate-pwa/index.html
new file mode 100644
index 0000000..3cd25cf
--- /dev/null
+++ b/frog-realestate-pwa/index.html
@@ -0,0 +1,35 @@
+
+
+
+ Real Estate Picture Taker Thingy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Longitude:
+ Latitude:
+
+ Title:
+ Notes:
+
+
+
+
+
+
+
+
+
diff --git a/frog-realestate-pwa/main.css b/frog-realestate-pwa/main.css
new file mode 100644
index 0000000..622c1f6
--- /dev/null
+++ b/frog-realestate-pwa/main.css
@@ -0,0 +1,83 @@
+body {
+ margin: 0px;
+ padding: 0px;
+}
+
+body > div {
+ position: absolute;
+ top: 0px;
+ left: 0px;
+ width: 100vw;
+ height: 100vh;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+body > div > * {
+ margin: 20px;
+}
+
+#camview {
+ max-width: 100vw;
+ box-shadow: 0px 0px 50px 0px black;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ padding: 30px;
+ box-sizing: border-box;
+}
+
+
+#camview.took {
+ position: fixed;
+ right: 0px;
+ bottom: 0px;
+ width: 150px;
+ z-index: 100;
+ display: inline-flex;
+ background-color: white;
+ padding: 10px;
+}
+
+#camview.took > button {
+ font-size: 1em;
+}
+
+#video-container {
+ max-width: 100%;
+}
+
+#camview > button {
+ font-size: 2em;
+}
+
+#precanvas {
+ height: 100%;
+ max-height: 4in;
+ flex-shrink: 0;
+}
+
+#preview {
+ width: 100%;
+ display: inline-block;
+}
+
+.offscreen {
+ position: absolute;
+ top: -10000px;
+ left: -10000px;
+}
+
+video.unbounded {
+ position: absolute;
+ height: 100vw !important;
+ width: auto;
+}
+
+#final {
+ max-width: 100vw;
+ border: 1px solid black;
+}
\ No newline at end of file
diff --git a/frog-realestate-pwa/main.js b/frog-realestate-pwa/main.js
new file mode 100644
index 0000000..f7acd6b
--- /dev/null
+++ b/frog-realestate-pwa/main.js
@@ -0,0 +1,132 @@
+function frame(e) {
+ for (let el of document.querySelectorAll("body > div")) {
+ if (el.style.display != "none") {
+ el.style.display = "none";
+ window.app[el.id].exit();
+ }
+ }
+ document.getElementById(e).style.display = "";
+ window.app[e].enter();
+}
+
+let canvas = document.getElementById("precanvas");
+let ctx = canvas.getContext("2d");
+let video = document.getElementById("magic_video");
+
+function takepicture() {
+ let box = video.getBoundingClientRect();
+ canvas.width = box.width;
+ canvas.height = box.height;
+ video.classList.add("unbounded");
+ document.getElementById("endcamera").style.display = "";
+ ctx.canvas.classList.remove("offscreen");
+ document.getElementById("camview").classList.add("took")
+ requestAnimationFrame(() => {
+ ctx.drawImage(video, 0, 0, box.width, box.height);
+ video.classList.remove("unbounded");
+ })
+}
+
+function setdetails() {
+ frame("details");
+}
+
+
+if ("geolocation" in navigator) {
+ document.getElementById("here").style.display = "";
+}
+
+function populateLocation() {
+ navigator.geolocation.getCurrentPosition(pos => {
+ document.getElementById("long").value = pos.coords.longitude;
+ document.getElementById("lat").value = pos.coords.latitude;
+ });
+}
+
+function render() {
+ frame("finalresult");
+}
+
+window.app = {
+ "home": {
+ enter() {
+ let preview = document.getElementById("preview");
+ navigator.mediaDevices.getUserMedia({ video: {
+ facingMode: { ideal: "environment" }
+ }, audio : false }).then((stream) => {
+ video.srcObject = stream;
+ video.play();
+ preview.srcObject = stream;
+ preview.play();
+ window.app.stream = stream;
+ });
+ },
+ exit() {
+ window.app.stream.getTracks().forEach(track => {
+ track.stop();
+ });
+ }
+ },
+ "details": {
+ enter() {
+ },
+ exit() {
+
+ }
+ },
+ "finalresult": {
+ enter() {
+ let canvas = document.getElementById("final");
+ let ctx = canvas.getContext("2d");
+ ctx.font = "bold 48px sans-serif";
+ ctx.filLStyle = "black";
+ ctx.fillText(document.getElementById("title").value, 0, 48);
+ ctx.font = "bold 24px sans-serif";
+ ctx.fillText(new Date().toLocaleString(), 0, 76);
+ let lat = document.getElementById("lat").value;
+ let long = document.getElementById("long").value;
+ /*reverse_geocode(lat, long).then(res => {
+ ctx.fillText(res, 0, 104);
+ });*/
+ ctx.fillText("https://maps.google.com/maps?q=" + lat + "," + long, 0, 128);
+ ctx.fillText("Notes: " + document.getElementById("notes").value, 0, 154);
+ let image = document.getElementById("precanvas");
+ ctx.drawImage(image, 0, 160, 720 * 1/2, image.height / image.width * 720 * 1/2);
+ maps_static(lat, long, img => {
+ ctx.drawImage(img, 365, 160);
+ });
+ },
+ exit() {
+
+ }
+ }
+}
+
+frame("home");
+
+
+async function reverse_geocode(lat, long) {
+ let res = await fetch("https://maps.googleapis.com/maps/api/geocode/json?zoom=6&latlng=" + lat + "," + long + "&key=AIzaSyD_zbdxwN7_aOMNH69eAL9bSS814Ix-UM8");
+ let json = await res.json();
+ return json.results[0].formatted_address;
+}
+
+
+function maps_static(lat, long, cbk) {
+ let img = document.createElement("img");
+ document.body.appendChild(img);
+ img.classList.add("offscreen");
+ img.src = "https://maps.googleapis.com/maps/api/staticmap?size=355x300&key=AIzaSyD_zbdxwN7_aOMNH69eAL9bSS814Ix-UM8&markers=label:S%7C" + lat + "," + long;
+ img.onload = () => {
+ cbk(img);
+ };
+}
+
+
+function download() {
+ let canvas = document.getElementById("final");
+ let anchor = document.createElement("a");
+ anchor.href = canvas.toDataURL();
+ anchor.download = "file.png";
+ anchor.click();
+}
\ No newline at end of file
diff --git a/frog-realestate-pwa/manifest.json b/frog-realestate-pwa/manifest.json
new file mode 100644
index 0000000..b372ec9
--- /dev/null
+++ b/frog-realestate-pwa/manifest.json
@@ -0,0 +1,12 @@
+{
+ "name": "Real Estate Pictures Tool",
+ "start_url": ".",
+ "icons": [
+ {
+ "src": "icon.png",
+ "type": "image/png",
+ "sizes": "64x64"
+ }
+ ],
+ "display": "standalone"
+}