自動化されたアスペクト比計算機を作成：画像アップロードとプレビューで正確な寸法計算と変換を実現

私は、アスペクト比の計算と変換をシンプルで迅速に行うツールを目指して、**自動化されたアスペクト比計算機**を開発しました。このツールでは、画像をアップロードして新しい寸法をすぐにプレビューでき、ソーシャルメディアやデザインプロジェクトでの調整に最適です。

### なぜこのツールを作成したのか？

![After - Resized Image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/627966/d26e8c75-4177-4ecd-3afc-65899c0bcc12.png)

画像や動画の比率を調整する際に、正確なアスペクト比が必要になることが多いです。誤った比率だと、画像が伸びたり縮んだりしてしまうことがあるため、正確な寸法での変換を支援するためにこのツールを作成しました。

### 使い方ガイド

1. **現在の寸法を入力または選択**  
   画像や動画の幅と高さを入力します。プリセット比率から選択することもできます。

2. **新しいアスペクト比または寸法を選択**  
   必要なアスペクト比を入力ボックスに直接入力するか、あらかじめ設定された比率を選択します。

3. **計算された寸法をプレビュー**  
   新しい寸法が自動的に計算され、リアルタイムでプレビューできます。

4. **微調整**  
   必要に応じて細かな寸法を調整できます。比率は保持されます。

5. **適用またはダウンロード**  
   新しいサイズに満足したら、画像を保存するか、編集ソフトで調整を適用します。

### 特徴

- **迅速な計算**：理想の比率で即座に新しい寸法が表示されます。
- **プリセットオプション**：よく使われるアスペクト比も用意。
- **デバイス対応**：モバイルでもデスクトップでも使いやすく最適化。

Aspect Ratio Calculator Live: www.shinesfox.com/p/aspect-ratio-calculator.html

## 技術的概要

### 1. `debounce(func, delay)`

この関数は、指定された遅延時間内に繰り返し呼び出される関数の実行を制御します。デバウンスは、ユーザーの入力やウィンドウのリサイズなど、短時間に発生するイベントに対するパフォーマンスを向上させます。

```ruby:title.rb
function debounce(func, delay) {
    let timeout;
    return function(...args) {
        clearTimeout(timeout);
        timeout = setTimeout(() => func.apply(this, args), delay);
    };
}
```

### 2. `setPreset()`

この関数は、選択されたプリセットに基づいて、ピクセルの幅、高さ、アスペクト比を設定します。プリセットの選択肢に応じて、適切な値を入力フィールドに設定し、結果を更新します。

```ruby:title.rb
function setPreset() {
    const preset = document.querySelector('#preset-select').value;
    if (preset === '16:9') {
        widthInput.value = 1920;
        heightInput.value = 1080;
    } else if (preset === '4:3') {
        widthInput.value = 1600;
        heightInput.value = 1200;
    }
    updateResult(widthInput.value, heightInput.value);
}
```

### 3. `checkAndSetPreset()`

この関数は、ユーザーが入力したピクセルの幅と高さを基に、どのプリセットが選択されるべきかを確認します。プリセットに一致する場合は、対応する値を設定します。

```ruby:title.rb
function checkAndSetPreset() {
    const width = parseInt(widthInput.value);
    const height = parseInt(heightInput.value);
    if (width / height === 16 / 9) {
        presetSelect.value = '16:9';
    } else if (width / height === 4 / 3) {
        presetSelect.value = '4:3';
    }
}
```

### 4. `calculateHeight()`

この関数は、与えられたアスペクト比に基づいて、高さを計算します。ピクセルの幅が変更されたときにトリガーされ、高さを更新し、結果を反映させます。

```ruby:title.rb
function calculateHeight() {
    const width = parseInt(widthInput.value);
    const ratio = 16 / 9; // 例として16:9のアスペクト比
    heightInput.value = Math.round(width / ratio);
    updateResult(width, heightInput.value);
}
```

### 5. `calculateWidth()`

この関数は、与えられたアスペクト比に基づいて、幅を計算します。ピクセルの高さが変更されたときにトリガーされ、幅を更新し、結果を反映させます。

```ruby:title.rb
function calculateWidth() {
    const height = parseInt(heightInput.value);
    const ratio = 16 / 9; // 例として16:9のアスペクト比
    widthInput.value = Math.round(height * ratio);
    updateResult(widthInput.value, height);
}
```

### 6. `updateResult(width, height, ratioWidth, ratioHeight)`

この関数は、現在の寸法とアスペクト比を表示します。与えられた幅と高さを使って、簡略化されたアスペクト比も計算し、結果を画面に表示します。

```ruby:title.rb
function updateResult(width, height) {
    const aspectRatio = (width / height).toFixed(2);
    resultDisplay.textContent = `幅: ${width}, 高さ: ${height}, アスペクト比: ${aspectRatio}`;
}
```

### 7. `loadImage(event)`

この関数は、ユーザーが画像をアップロードしたときに呼び出されます。選択された画像の幅と高さを取得し、それに基づいてアスペクト比を計算し、結果を更新します。

```ruby:title.rb
function loadImage(event) {
    const file = event.target.files[0];
    const img = new Image();
    img.onload = function() {
        widthInput.value = img.width;
        heightInput.value = img.height;
        updateResult(img.width, img.height);
    };
    img.src = URL.createObjectURL(file);
}
```

### 8. `downloadImage()`

この関数は、現在表示されている画像をダウンロードするために使用されます。ユーザーが指定した幅と高さで、更新された画像をPNG形式で保存します。

```ruby:title.rb
function downloadImage() {
    const canvas = document.createElement('canvas');
    canvas.width = widthInput.value;
    canvas.height = heightInput.value;
    const ctx = canvas.getContext('2d');
    ctx.drawImage(currentImage, 0, 0, canvas.width, canvas.height);
    canvas.toBlob(function(blob) {
        const link = document.createElement('a');
        link.href = URL.createObjectURL(blob);
        link.download = 'image.png';
        link.click();
    });
}
```

### 使う場面

私がこのツールを最も活用する場面として、ソーシャルメディア用のリサイズや異なるデバイス対応のための画像調整があります。この計算機は、画像のクオリティを損なわず、異なるメディアフォーマットでの使用に最適化します。