1. ホーム
  2. Web制作
  3. html5

キャンバスの描画は、contain または cover モードで適応され、中央に配置されます。

2022-01-31 17:01:34

キャンバス描画のdrawImageは、異なる画像サイズとスケールを必要とするので、html+cssのレイアウトと同様に、異なるニーズに合わせてcontain and coverする必要があります。

含む

画像の長辺が完全に表示されるように、アスペクト比を維持したまま拡大縮小します。つまり、画像の全体が表示できるようにします。

コンテインモードで画像を固定ボックスの矩形内に配置する場合、画像の多少の拡大縮小が必要です。

その原理は

画像の長辺が完全に表示できるように幅と高さが不揃いな場合、画像の高辺が固定ボックスに対応する辺と等しくなるように元画像を拡大縮小し、他の辺を等比級数で求めます

画像の幅と高さが等しい場合、固定ボックスの幅と高さで拡大縮小画像の幅と高さが決まり、固定ボックスの幅が高さより大きい場合、拡大縮小画像は固定ボックスの高さより高くなり、もう片方は比例します。

        /**
         * @param {Number} sx fixes the x coordinate of the box, sy fixes the y left scale of the box
         * @param {Number} box_w the width of the fixed box, box_h the height of the fixed box
         * @param {Number} source_w the width of the original image, source_h the height of the original image
         * @return {Object} {drawImage's parameters, x coordinate, y coordinate, width and height of the scaled image}, corresponding to drawImage(imageResource, dx, dy, dWidth, dHeight)
         */
        function containImg(sx, sy , box_w, box_h, source_w, source_h){
            var dx = sx,
                dy = sy,
                dWidth = box_w,
                dHeight = box_h;
            if(source_w > source_h || (source_w == source_h && box_w < box_h)){
                dHeight = source_h*dWidth/source_w;
            dy = sy + (box_h-dHeight)/2;

            }else if(source_w < source_h || (source_w == source_h && box_w > box_h)){
                dWidth = source_w*dHeight/source_h;
                dx = sx + (box_w-dWidth)/2;
            }
            return{
                dx,
                dy,
                dWidth,
                dHeight
            }
        }


        var c=document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        ctx.fillStyle = '#e1f0ff';
        // fix the position and size of the box - the image needs to be placed inside this box
        ctx.fillRect(30, 30, 150, 200);

        var img = new Image();
        img.onload = function () {
            console.log(img.width,img.height);
            
            var imgRect = containImg(30,30,150,200,img.width,img.height);
            console.log('imgRect',imgRect);
            ctx.drawImage(img, imgRect.dx, imgRect.dy, imgRect.dWidth, imgRect.dHeight); 
            
        }
        img.src = ". /timg2.jpg";  
        //Note: In img preload mode, onload should be placed above the value assigned to src to avoid the situation where the onload event cannot be triggered if there is already a cache and the event in onload is not executed

カバー

画像をアスペクト比で拡大縮小しておくと、画像の短辺だけが完全に表示されることになります。つまり、通常、画像は水平方向または垂直方向にのみ完全であり、それ以外の方向では傍受が発生します。

原理を説明します。

画像の一部を固定ボックスの縮尺で取り込む

        /**
         * @param {Number} box_w width of the fixed box, box_h height of the fixed box
         * @param {Number} source_w the width of the original image, source_h the height of the original image
         * @return {Object} {the intercepted image information}, corresponding to drawImage(imageResource, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight) parameter
        */
        function coverImg(box_w, box_h, source_w, source_h){
            var sx = 0,
                sy = 0,
                sWidth = source_w,
                sHeight = source_h;
            if(source_w > source_h || (source_w == source_h && box_w < box_h)){
                sWidth = box_w*sHeight/box_h;
                sx = (source_w-sWidth)/2;
            }else if(source_w < source_h || (source_w == source_h && box_w > box_h)){
                sHeight = box_h*sWidth/box_w;
                sy = (source_h-sHeight)/2;
            }
            return{
                sx,
                sy,
                sWidth,
                sHeight
            }
        }


        var c=document.getElementById("myCanvas");
        var ctx = c.getContext("2d");
        ctx.fillStyle = '#e1f0ff';
        // fix the position and size of the box - the image needs to be placed inside this box
        ctx.fillRect(30, 30, 150, 200);

        var img = new Image();
        img.onload = function () {
            console.log(img.width,img.height);
            
            var imgRect = coverImg(150,200,img.width,img.height);
            console.log('imgRect',imgRect);
            ctx.drawImage(img, imgRect.sx, imgRect.sy, imgRect.sWidth, imgRect.sHeight, 30, 30, 150, 200); 
        }
        img.src = ". /timg2.jpg";  
        //Note: In img preload mode, onload should be placed above the value assigned to src to avoid the situation where the onload event cannot be triggered if there is already a cache, and thus the event in onload does not execute

この記事がお役に立てれば幸いです。そして、スクリプト・ハウスを応援していただければ幸いです。