文字を変形させてでも画面いっぱいに収める方法

WebはHTML「ドキュメント」というくらいのもので基本はドキュメントのマークアップ言語です。TeXとかWordの延長です。したがってコンテンツの量が多くなるとスクロールするのが当たり前となっています。

一方でユーザインターフェースの多くはスクロールを良しとしていません。ポスター・フォトカード・映画・看板、いずれもスクロールという操作を必要とはしません。

ということで、「文字を描画するがスクロールさせない範囲で画面いっぱいに描画して、上下左右もフルに使うデジタル時計」というサンプルです。

### ソース

```tokei.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>全画面デジタル時計</title>
<style>
html, body {
  margin: 0;
  padding: 0;
  width: 100vw;
  height: 100vh;
  background: #000;
  overflow: hidden;
}
#clock-container {
  width: 100vw;
  height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
}
#clock {
  color: #ff0000;
  font-family: 'Consolas', 'Roboto', 'Courier New', monospace;
  font-weight: 900;
  text-shadow: 0 0 15px rgba(255,0,0,0.5);
  white-space: nowrap;
  line-height: 1;
  font-size: 100px;
  display: inline-block;
  will-change: transform;
  user-select: none;
}
.colon {
  transition: opacity 0.15s;
  display: inline-block;
}
.colon.hide {
  opacity: 0;
}
</style>
</head>
<body>
<div id="clock-container">
  <span id="clock"><span class="hour">00</span><span class="colon">:</span><span class="minute">00</span></span>
</div>
<script>
function fitClock() {
  const container = document.getElementById('clock-container');
  const clock = document.getElementById('clock');
  clock.style.transform = 'scale(1,1)';
  clock.style.fontSize = '100px';
  const clockRect = clock.getBoundingClientRect();
  const containerRect = container.getBoundingClientRect();
  const scaleX = containerRect.width / clockRect.width;
  const scaleY = containerRect.height / clockRect.height;
  clock.style.transform = `scale(${scaleX}, ${scaleY})`;
}

function updateTimeAndColon() {
  const now = new Date();
  const h = String(now.getHours()).padStart(2, '0');
  const m = String(now.getMinutes()).padStart(2, '0');
  document.querySelector('#clock .hour').textContent = h;
  document.querySelector('#clock .minute').textContent = m;

  // コロンの点滅（偶数秒で表示、奇数秒で非表示）
  const colon = document.querySelector('#clock .colon');
  if (now.getSeconds() % 2 === 0) {
    colon.classList.remove('hide');
  } else {
    colon.classList.add('hide');
  }
  fitClock();
}

window.addEventListener('resize', fitClock);
setInterval(updateTimeAndColon, 1000);
updateTimeAndColon();
</script>
</body>
</html>
```

### 実行結果

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/53489/981ac126-0ad9-4de4-b1d7-07e6bffb20fb.png)


ポイントはここです。

```javascript
function fitClock() {
  const container = document.getElementById('clock-container');
  const clock = document.getElementById('clock');
  clock.style.transform = 'scale(1,1)';
  clock.style.fontSize = '100px';
  const clockRect = clock.getBoundingClientRect();
  const containerRect = container.getBoundingClientRect();
  const scaleX = containerRect.width / clockRect.width;
  const scaleY = containerRect.height / clockRect.height;
  clock.style.transform = `scale(${scaleX}, ${scaleY})`;
}
```
まず文字をspanで書くだけ書いて、そのspan要素をgetBoundingClientRectでサイズをみます。外枠のDIVとの比率をみて、transformメソッドで変形させます。transformメソッドは縦横を両方指定できるのでそこで縦横比を変えることができます。

### 用途

いろんな機種が入り混じった中古タブレットを使ってデジタルサイネージを作りたい！