HTML5 キャンバスを動的な親/フレックス ボックス コンテナーに合わせる方法 質問する

HTML5 キャンバスを動的な親/フレックス ボックス コンテナーに合わせる方法 質問する

動的にサイズ変更できるフレックスボックス コンテナー内にキャンバスを作成する方法はありますか?

できれば CSS のみのソリューションが望ましいですが、再描画には JavaScript が必要だと思いますか?

1 つの解決策としては、サイズ変更イベントをリッスンし、キャンバスをフレックス ボックスの親のサイズに合わせて拡大縮小してから強制的に再描画することだと思いますが、できるだけ多くの CSS を使用するか、よりクリーンでコードの少ないソリューションを使用したいと思います。

現在のアプローチは CSS ベースで、キャンバスは親のフレックス ボックス要素に応じてサイズが変更されます。以下のスクリーンショットでは、グラフィックがぼやけて再配置され、キャンバスからオーバーフローしています。

引き伸ばされた画像/キャンバスに溢れるグラフィック

CS: ...

html,body{
            margin:0;
            width:100%;
            height:100%;
        }
        body{
            display:flex;
            flex-direction:column;
        }
header{
            width:100%;
            height:40px;
            background-color:red;
        }
        main{
            display:flex;
            flex: 1 1 auto;
            border: 1px solid blue;
            width:80vw;
        }
        canvas{
            flex: 1 1 auto;
            background-color:black;
        }

HTML:

<header>
</header>
<main>
    <canvas id="stage"></canvas>
</main>

ジャバスクリプト:

$( document ).ready(function() {
    var ctx = $("#stage")[0].getContext("2d");
    ctx.strokeStyle="#FFFFFF";
    ctx.beginPath();
    ctx.arc(100,100,50,0,2*Math.PI);
    ctx.stroke();
});

問題を示す JS フィドル:https://jsfiddle.net/h2v1w0a1/

ベストアンサー1

キャンバスを画像として考えてください。元のサイズとは異なるサイズに拡大すると、ある時点でぼやけて表示されます。ブラウザが選択した補間アルゴリズムによっては、早い段階でぼやけることもあります。キャンバスの場合、ブラウザはバイキュービックよりもバイリニアを選択する傾向があるため、実際の画像よりもぼやけるリスクが高くなります。

キャンバス内のものをできるだけ鮮明にレンダリングしたい場合、これを実現する唯一の方法は、JavaScript を使用して親のサイズに合わせ、CSS を避けることです (後者は、印刷などの場合や、「Retina 解像度」が必要な場合に適しています)。

親コンテナのサイズをピクセル単位で取得するには、次を使用しますgetComputedStyle()(以下の更新を参照)。

var parent = canvas.parentNode,
    styles = getComputedStyle(parent),
    w = parseInt(styles.getPropertyValue("width"), 10),
    h = parseInt(styles.getPropertyValue("height"), 10);

canvas.width = w;
canvas.height = h;

フィドル

(注: Chrome では現時点では計算されたフレックスに関していくつかの問題があるようです)

アップデート

もっと簡単な方法は次のとおりです:

var rect = canvas.parentNode.getBoundingClientRect();
canvas.width = rect.width;
canvas.height = rect.height;

フィドル

おすすめ記事