JavaScript でデバイスのカメラ使って撮影画像を取得

デバイスのカメラ使って撮影した画像取得までやってみる
サンプルは以下のページ

https://sueasen.github.io/javascript-exercise/work/camera/

# JavaScript
- 写真撮影した画像を描画するため `canvas` タグを準備
- デバイスのカメラを `navigator.mediaDevices.getUserMedia({ video: true, audio: false })` 取得
    - ブラウザ側でカメラ使用の許可求められるので許可する必要あり
    - 取得後に `stream` を `video.srcObject` に設定して `video.play()` でカメラの画像を `video` タグに表示 
- 写真撮影時に縦横比を見て計算する必要あり

```JavaScript
const video = document.querySelector('#video');
const canvas = document.createElement('canvas');

initVideoCamera();
initPhoto();
document.querySelector('#shoot').addEventListener('click', photoShoot);

/**
 * ビデオのカメラ設定(デバイスのカメラ映像をビデオに表示)
 */
function initVideoCamera() {
    navigator.mediaDevices.getUserMedia({ video: true, audio: false })
        .then((stream) => {
            video.srcObject = stream;
            video.play();
        })
        .catch(e => console.log(e));
}

/**
 * 写真の初期描画
 */
function initPhoto() {
    canvas.width = video.clientWidth;
    canvas.height = video.clientHeight;
    const context = canvas.getContext("2d");
    context.fillStyle = "#AAA";
    context.fillRect(0, 0, canvas.width, canvas.height);
    document.querySelector("#photo").src = canvas.toDataURL("image/png");
}

/**
 * 写真の撮影描画
 */
function photoShoot() {
    let drawSize = calcDrawSize();
    canvas.width = drawSize.width;
    canvas.height = drawSize.height;
    const context = canvas.getContext("2d");
    context.drawImage(video, 0, 0, canvas.width, canvas.height);
    document.querySelector("#photo").src = canvas.toDataURL("image/png");
}

/**
 * 描画サイズの計算
 * 縦横比が撮影(video)が大きい時は撮影の縦基準、それ以外は撮影の横基準で計算
 */
function calcDrawSize() {
    let videoRatio = video.videoHeight / video.videoWidth;
    let viewRatio = video.clientHeight / video.clientWidth;
    return videoRatio > viewRatio ?
        { height: video.clientHeight, width: video.clientHeight / videoRatio }
        : { height: video.clientWidth * videoRatio, width: video.clientWidth }
}
```

# HTML
カメラを表示する `video` タグと撮影画像を表示する `img` タグの準備だけ

```HTML
<!doctype html>
<html>

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="./style.css">
</head>

<body>
    <h3>カメラ画像取得</h3>
    <div class="flex-row">
        <div class="camera">
            <video id="video"></video>
            <div id="shoot">撮影</div>
        </div>
        <img id="photo">
    </div>
</body>

<script src="script.js"></script>

</html>
```

# CSS
こちらは位置調整してるだけ．．．

```CSS
@charset "utf-8";

body {
  text-align: center;
}

.flex-row {
  display: flex;
  justify-content: center;
}

#video {
  border: 1px solid black;
  width: 320px;
  height: 240px;
}

#photo {
  border: 1px solid black;
  width: 320px;
  height: 240px;
}

#movie {
  border: 1px solid black;
  width: 320px;
  height: 240px;
}

#shoot,
#recode-start,
#recode-stop {
  width: 100px;
  margin: 5px auto;
  border: solid 1px skyblue;
  border-radius: 30px;
  background-color: skyblue;
}

#shoot:hover,
#recode-start:hover,
#recode-stop:hover {
  opacity: 0.7;
}

.hidd {
  display: none;
}

#recode-stop {
  animation: recodding 2s infinite;
}

p.ret-element {
  margin-top: 0;
}

@keyframes recodding {
  0% {
    opacity: 1;
    /* border: solid 1px skyblue;
    background-color: skyblue; */
  }

  50% {
    opacity: 0.3;
  }

  100% {
    opacity: 1;
  }
}

@media (width <=1000px) {
  .flex-row {
    display: block;
  }
}
```