<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script src="https://cdn.tailwindcss.com"></script>
<title>Camera Figma Exact</title>
</head>
<body class="flex justify-center bg-gray-100 py-10">
<div class="w-96 h-[852px] relative bg-gradient-to-l from-cyan-200 to-indigo-500 overflow-hidden">
<!-- 投稿する -->
<div id="submitPost"
class="w-96 h-16 left-[12px] top-[691px] absolute bg-white border-[3px] border-black cursor-pointer">
</div>
<div class="w-96 h-5 left-[19px] top-[714px] absolute text-center text-black text-xl pointer-events-none">
投稿する
</div>
<!-- 場所 -->
<div class="w-64 h-16 left-[128px] top-[587px] absolute bg-white border-[3px] border-black"></div>
<div class="w-32 h-12 left-[4px] top-[592px] absolute text-black text-2xl font-bold">
場所
</div>
<input id="locationInput"
class="w-60 h-16 left-[135px] top-[587px] absolute bg-transparent text-black text-2xl font-bold outline-none"
placeholder="直接入力もできます"
/>
<select id="locationSelect"
class="w-60 h-16 left-[135px] top-[587px] absolute bg-transparent text-transparent outline-none">
<option>周辺の場所を取得中...</option>
</select>
<!-- 撮影日時 -->
<div class="w-64 h-16 left-[128px] top-[508px] absolute bg-white border-[3px] border-black"></div>
<input id="dateInput"
type="date"
class="w-60 h-16 left-[133px] top-[508px] absolute bg-transparent text-black text-2xl font-bold outline-none"
/>
<div class="w-32 h-12 left-[4px] top-[513px] absolute text-black text-2xl font-bold">
撮影日時
</div>
<!-- カメラ -->
<div class="w-80 h-60 left-[35.26px] top-[216px] absolute bg-white border-[3px] border-black overflow-hidden">
<video id="video" class="w-full h-full object-cover hidden" autoplay playsinline muted></video>
</div>
<div id="startCamera"
class="w-80 h-20 left-[41.51px] top-[306.52px] absolute text-center text-black text-2xl font-bold cursor-pointer select-none">
カメラを起動
</div>
<!-- ミッション -->
<div class="w-96 h-28 left-[12px] top-[51px] absolute bg-sky-950 rounded-[20px] border-[5px] border-stone-400"></div>
<div class="w-80 h-24 left-[25px] top-[64px] absolute text-center text-amber-400 text-3xl">
酒田の大獅子を<br>撮影せよ!
</div>
</div>
<script>
/* 日付 */
dateInput.value = new Date().toISOString().split("T")[0];
/* ===== カメラ(PC・スマホ確実対応) ===== */
startCamera.onclick = async () => {
if (!navigator.mediaDevices || !navigator.mediaDevices.getUserMedia) {
alert("このブラウザはカメラに対応していません");
return;
}
if (location.protocol !== "https:" && location.hostname !== "localhost") {
alert("カメラはHTTPS環境でのみ使用できます");
return;
}
try {
const stream = await navigator.mediaDevices.getUserMedia({
video: {
facingMode: { ideal: "environment" },
width: { ideal: 1280 },
height: { ideal: 720 }
}
});
video.srcObject = stream;
video.classList.remove("hidden");
startCamera.classList.add("hidden");
} catch (e) {
alert("カメラの使用が許可されていないか、利用できません");
}
};
/* ===== 周辺検索(失敗時フォールバック付き) ===== */
async function loadNearbyPlaces() {
if (!navigator.geolocation) {
locationSelect.innerHTML = `<option>位置情報非対応</option>`;
return;
}
navigator.geolocation.getCurrentPosition(async pos => {
const { latitude, longitude } = pos.coords;
try {
const query = `
[out:json][timeout:10];
(
node(around:1000,${latitude},${longitude})["name"];
);
out tags 20;
`;
const res = await fetch("https://overpass-api.de/api/interpreter", {
method: "POST",
body: query
});
if (!res.ok) throw new Error();
const data = await res.json();
locationSelect.innerHTML = `<option value="">場所を選択</option>`;
let count = 0;
data.elements.forEach(e => {
if (e.tags?.name && count < 20) {
const opt = document.createElement("option");
opt.value = e.tags.name;
opt.textContent = e.tags.name;
locationSelect.appendChild(opt);
count++;
}
});
if (count === 0) throw new Error();
} catch {
locationSelect.innerHTML = `<option value="">検索失敗(手入力してください)</option>`;
}
}, () => {
locationSelect.innerHTML = `<option value="">位置情報が拒否されました</option>`;
});
}
loadNearbyPlaces();
/* 選択 → 入力欄へ */
locationSelect.onchange = () => {
if (locationSelect.value) {
locationInput.value = locationSelect.value;
}
};
/* 投稿 */
submitPost.onclick = () => {
if (!locationInput.value) {
alert("場所を入力または選択してください");
return;
}
alert(`投稿\n場所:${locationInput.value}\n日時:${dateInput.value}`);
};
</script>
</body>
</html>