camera-info
ClarkeIS Build / Build-Docker-Image (push) Successful in 20s

This commit is contained in:
admin committed 2025-04-13 08:27:15 -04:00
1 parent b262f5a859
commit 34020fe8a8
9 files changed
+336 -73

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

+57
View File
@@ -0,0 +1,57 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="64mm"
height="64mm"
viewBox="0 0 64.000002 64"
version="1.1"
id="svg1"
inkscape:version="1.4 (e7c3feb100, 2024-10-09)"
sodipodi:docname="icon.svg"
inkscape:export-filename="icon.png"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<sodipodi:namedview
id="namedview1"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:document-units="mm"
inkscape:zoom="0.71268238"
inkscape:cx="291.85512"
inkscape:cy="94.011024"
inkscape:window-width="1920"
inkscape:window-height="1011"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="1"
inkscape:current-layer="layer1"
inkscape:export-bgcolor="#ffffffff" />
<defs
id="defs1" />
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(-32.216804,-67.856489)">
<path
id="path1"
style="fill:#00ffff;stroke:#000000;stroke-width:0.164;stroke-linecap:round"
d="M 64.216803,71.650989 A 14.47875,14.47875 0 0 0 49.7381,86.130208 14.47875,14.47875 0 0 0 52.866591,95.067131 L 64.216803,127.48737 75.567014,95.067131 A 14.47875,14.47875 0 0 0 78.695505,86.130208 14.47875,14.47875 0 0 0 64.216803,71.650989 Z" />
<circle
style="fill:#ff0000;stroke:#000000;stroke-width:0.164;stroke-linecap:round"
id="path2"
cx="64.216805"
cy="85.879189"
r="5.1190114" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

+35
View File
@@ -0,0 +1,35 @@
<!DOCTYPE html>
<html>
<head>
<title>camera info</title>
<link rel="stylesheet" href="main.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="manifest" href="manifest.json" />
</head>
<body>
<video id="magic_video" class="offscreen">video stream unavailable</video>
<div id="home" style="display: none;">
<button onclick="setdetails()" style="display: none;" id="endcamera">Next</button>
<canvas id="precanvas" class="offscreen"></canvas>
<div id="camview">
<div id="video-container">
<video id="preview">video stream unavailable</video>
</div>
<button onclick="takepicture()">Take Picture!</button>
</div>
</div>
<div id="details" style="display: none;">
<span>Longitude: <input type="number" id="long"/></span>
<span>Latitude: <input type="number" id="lat"/></span>
<button onclick="populateLocation()" id="here">Current Location</button>
<span>Title: <input type="text" id="title" placeholder="123 A Place"/></span>
<span>Notes: <input type="text" id="notes" placeholder="Location Notes" /></span>
<button onclick="render()">Finish</button>
</div>
<div id="finalresult" style="display: none;">
<canvas id="final" width="720" height="480"></canvas>
<button onclick="download()">Download!</button>
</div>
<script src="main.js"></script>
</body>
</html>
+83
View File
@@ -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;
}
+143
View File
@@ -0,0 +1,143 @@
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();
video.classList.add("unbounded");
document.getElementById("endcamera").style.display = "";
ctx.canvas.classList.remove("offscreen");
document.getElementById("camview").classList.add("took")
// si c'est portrait, nous doivons le tourner à landscape (parce que le canvas ont besoin d'un photo landscape pour marcher bien)
if (box.height > box.width) {
canvas.width = box.height;
canvas.height = box.width;
ctx.translate(box.width/2, box.height/2);
ctx.rotate(Math.PI / 2);
ctx.drawImage(video, -box.width/2, -box.height/2, box.width, box.height);
ctx.rotate(-Math.PI / 2);
ctx.translate(-box.width/2, -box.height/2);
}
else {
canvas.width = box.width;
canvas.height = box.height;
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.crossOrigin = "anonymous";
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();
}
+17
View File
@@ -0,0 +1,17 @@
{
"name": "camera info",
"start_url": ".",
"icons": [
{
"src": "icon.png",
"type": "image/png",
"sizes": "512x512"
},
{
"src": "icon.png",
"type": "image/png",
"sizes": "192x192"
}
],
"display": "standalone"
}
-18
View File
@@ -1,18 +0,0 @@
let old_scroll_top = document.documentElement.scrollTop;
function onscroll() {
if (document.documentElement.scrollTop > old_scroll_top + 100) {
document.getElementById("header").classList.add("hide");
old_scroll_top = document.documentElement.scrollTop;
}
if (document.documentElement.scrollTop < old_scroll_top) {
old_scroll_top = document.documentElement.scrollTop;
document.getElementById("header").classList.remove("hide");
}
}
window.addEventListener("wheel", onscroll);
window.addEventListener("scroll", onscroll);
+1 -29
View File
@@ -4,31 +4,6 @@
<<<<<<< HEAD
<!DOCTYPE html>
<html>
<head>
<title>Home | Clarke Information Systems</title>
<meta charset="utf-8" />
<link rel="stylesheet" href="http://localhost:8080/main.css" />
</head>
<body>
<div id="header">
header stuff!
</div>
<div id="main">
hi!
lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>lor<br>
</div>
<div id="footer">
footer stuff!
</div>
<script src="http://localhost:8080/header-hider.js"></script>
</body>
</html>
=======
<!DOCTYPE html>
<html>
@@ -51,13 +26,10 @@
</div>
</div>
<div class="center-text">
IN MERRY ENGLAND in the time of old, when good King Henry the Second ruled the land, there lived within the green glades of Sherwood Forest, suffering neither care nor want, but passing the time in merry games of archery or bouts of cudgel play, living upon the King's deer, and, by the laws of our gracious lord and sovereign King Harry, thine ears should be shaven close to thy head?" "Catch him!" cried a third. "Nay," said a fourth, "let him e'en go because of his tender years." Never a word said Robin Hood, but he looked at the foresters with a grim face; then, turning on his heel, strode away from them down the forest glade. But his heart was bitterly angry, for his blood was hot and youthful and prone to boil. Now, well would it have been for him who had first spoken had he left Robin Hood alone; but his anger was hot, both because the youth had gotten the better of him and because of the deep draughts of ale that he had slain a man. "Alas!" cried he, "thou hast found me an archer that will make thy wife to wring! I would that thou hadst ne'er said one word to me, or that I had never passed thy way, or e'en that my right forefinger had been stricken off ere that this had happened! In haste I smote, but grieve I sore at leisure!" And then, even in his trouble, he remembered the old saw that "What is done is done; and the egg cracked cannot be cured." And so he came to dwell in the greenwood that was to be his home for many a year to come, never again to see the sport. Then one came forward who had been chosen to play the priest because he had poached upon the King's venison, washed down with draughts of ale that he had been quaffing. So, of a sudden, without any warning, he sprang to his feet, and seized upon his bow and fitted it to a shaft. "Ay," cried he, "and I'll hurry thee anon." And he sent the arrow whistling after Robin. It was well for Robin Hood that that same forester's head was spinning with ale, or else he would never have taken another step. As it was, the arrow whistled within three inches of his head. Then he turned around and quickly drew his own bow, and sent an arrow back in return. "Ye said I was no archer," cried he aloud, "but say so now again!" The shaft flew straight; the archer fell forward with a cry, and lay on his face upon the ground, his arrows rattling about him from out of his quiver, the gray goose feather to his ear; the next moment the bowstring rang and the arrow sped down the glade as a sparrowhawk skims in a northern wind. High leaped the noblest hart of all the herd, only to fall dead, reddening the green path with his heart's blood. "Ha!" cried Robin, "how likest thou that shot, good fellow? I wot the wager were mine, an it were three hundred pounds." Then all the foresters were filled with rage, and he who had spoken first. "And here are twenty marks. I wager that thou causest no beast to die, with or without the aid of Our Lady." Then Robin took his good yew bow in his hand, and placing the tip at his instep, he strung it right deftly; then he nocked a broad clothyard arrow and, raising the bow, drew the gray goose feather to his ear; the next moment the bowstring rang and the arrow sped down the glade as a sparrowhawk skims in a northern wind. High leaped the noblest hart of all the herd, only to fall dead, reddening the green path with his heart's blood. "Ha!" cried Robin, "how likest thou that shot, good fellow? I wot the wager were mine, an it were three hundred pounds." Then all the foresters were filled with rage, and he who had spoken first. "And here are twenty marks. I wager that thou causest no beast to die, with or without the aid of Our Lady." Then Robin took his good stout yew bow and a score of yeomen leaped upon the stranger, but though they sprang quickly they found him ready and felt him strike right and left with his stout men about him. Here they found the rest of the band, some of whom had come in with a brace of fat does. Then they all built great fires and after a time roasted the does and broached a barrel of humming ale. Then when the feast was done Will Stutely spoke up. "It is now time, I ween, to christen our bonny babe, is it not so, merry boys?" And "Aye! Aye!" cried all, laughing till the woods echoed with their mirth. "Then seven sponsors shall we have," quoth Will Stutely, and hunting among all the band, sitting or lying upon the greensward, watched to see him shoot—he drew the arrow to his cheek and loosed the shaft right deftly, sending it so straight down the path that it clove the mark in the very center. "Aha!" cried he, "mend thou that if thou canst"; while even the yeomen clapped their hands at so fair a shot. "That is a keen shot indeed," quoth Robin. "Mend it I cannot, but mar it I may, perhaps." Then taking up his own good stout bow and nocking an arrow with care, he shot with his very greatest skill. Straight flew the arrow, and so true that it lit fairly upon the stranger's shaft and split it into splinters. Then allLine truncated
Website under construction. Check back later!
</div>
<script src="http://localhost:8080/main.js"></script>
</body>
</html>
>>>>>>> b97c574 (ehhh)
-26
View File
@@ -1,28 +1,3 @@
<<<<<<< HEAD
body {
margin: 0px;
padding: 0px;
display: flex;
flex-direction: column;
}
#header {
position: sticky;
top: 0px;
padding: 10px;
background-color: white;
box-shadow: 0px 0px 5px 5px black;
transition: transform 0.5s;
}
#footer {
margin-top: auto;
}
#header.hide {
transform: translateY(-100%);
}
=======
@@ -90,4 +65,3 @@ body {
#header.slide-away {
transform: translateY(calc(-100% - 5px));
}
>>>>>>> b97c574 (ehhh)