以下がHTML、CSS、JavaScriptのコードになります。カメラの機能を使用するためには、HTTPS経由でアクセスする必要があります。また、このアプリはFirebaseを使用しています。
```html
<!DOCTYPE html>
<html>
<head>
<title>棚卸しカウントアプリ</title>
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://www.gstatic.com/firebasejs/8.2.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.2/firebase-analytics.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.2/firebase-auth.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.2/firebase-storage.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.2.2/firebase-firestore.js"></script>
</head>
<body>
<div id="camera-container">
<video id="camera" autoplay></video>
<button id="capture-btn" disabled>写真を撮る</button>
</div>
<div id="result-container">
<ul id="count-list">
</ul>
</div>
<script>
// Firebaseの初期化
const firebaseConfig = {
// Firebaseのキーをここに入力してください
};
firebase.initializeApp(firebaseConfig);
firebase.analytics();
const firestore = firebase.firestore();
const storageRef = firebase.storage().ref();
// カメラの初期化
const camera = document.getElementById("camera");
const captureBtn = document.getElementById("capture-btn");
const constraints = {
video: true,
audio: false,
};
navigator.mediaDevices.getUserMedia(constraints)
.then(function(mediaStream) {
camera.srcObject = mediaStream;
camera.onloadedmetadata = function(e) {
camera.play();
captureBtn.disabled = false;
};
})
.catch(function(err) {
console.log(err.name + ": " + err.message);
});
// 写真を撮る
captureBtn.addEventListener("click", function() {
const context = document.createElement("canvas").getContext("2d");
context.canvas.width = camera.videoWidth;
context.canvas.height = camera.videoHeight;
context.drawImage(camera, 0, 0, camera.videoWidth, camera.videoHeight);
const dataUrl = context.canvas.toDataURL("image/jpeg");
uploadImage(dataUrl);
});
// 画像をFirebaseにアップロードする
function uploadImage(dataUrl) {
const timestamp = Date.now().toString();
const ref = storageRef.child(timestamp + ".jpg");
const uploadTask = ref.putString(dataUrl, "data_url");
uploadTask.on("state_changed", function(snapshot) {
const progress = Math.floor((snapshot.bytesTransferred / snapshot.totalBytes) * 100);
console.log("Upload is " + progress + "% done");
}, function(error) {
alert("画像のアップロードに失敗しました。");
}, function() {
// アップロードが完了したので、画像のURLを取得する
uploadTask.snapshot.ref.getDownloadURL().then(function(downloadURL) {
// Firestoreにドキュメントを追加する
firestore.collection("items").add({
photoUrl: downloadURL,
count: 1,
timestamp: timestamp,
}).then(function(docRef) {
console.log("Document written with ID: ", docRef.id);
showCounts();
}).catch(function(error) {
alert("Firestoreにドキュメントを追加できませんでした。");
});
});
});
}
// リストを表示する
function showCounts() {
const countList = document.getElementById("count-list");
countList.innerHTML = "";
firestore.collection("items").orderBy("timestamp", "desc").get().then(function(querySnapshot) {
querySnapshot.forEach(function(doc) {
const li = document.createElement("li");
li.innerHTML = `${doc.get("count")}個 / <img src="${doc.get("photoUrl")}" />`;
countList.appendChild(li);
});
}).catch(function(error) {
alert("Firestoreからデータを取得できませんでした。");
});
}
// 初期表示
showCounts();
</script>
</body>
</html>
```
CSSは以下のようになります。
```css
#camera-container {
display: flex;
flex-direction: column;
align-items: center;
margin-top: 30px;
}
#capture-btn {
padding: 10px 20px;
border: none;
border-radius: 3px;
background-color: #4CAF50;
color: white;
font-size: 18px;
cursor: pointer;
margin-top: 20px;
}
#result-container {
margin-top: 50px;
width: 100%;
display: flex;
justify-content: center;
}
#count-list {
list-style: none;
padding: 0;
margin: 0;
}
#count-list li {
margin-bottom: 10px;
font-size: 18px;
display: flex;
align-items: center;
}
#count-list li img {
max-width: 200px;
margin-left: 10px;
}
```
このアプリでは、Firebaseを使用して写真をアップロードして、Firestoreにカウントとタイムスタンプを保存します。保存したデータを元にリストを表示することができます。