0

https://jsfiddle.net/1gf6xzyz/3/ はフィドルへのリンクです。JS コードの重要なポイントを、何を試しているかを示します。

22行目:クロッパーを画像オブジェクトにアタッチする場所です。クロッパーは、わかりやすい名前を持つ画像とオプションへの参照を取るクラスです。重要なものは次のとおりです。

  • ratioDim - トリミング ウィンドウの縦横比。
  • maxCaptureWidth - トリミングできる画像の最大幅。

    cropper = new Cropper.Img('imgSelector', {
                        minWidth : 120,
                        minHeight : 90,
                        ratioDim : {
                            x : 120,
                            y : 90
                        },
                        displayOnInit : true,
                        imageDataCallback : imageDataCallback,
                        maxCaptureWidth : 400,
                    })
    

トリミング ライブラリは 47 行目から始まります。必要に応じて既存のライブラリを調整しました。

行 357 - これは、画像が読み込まれた後にクロッパーが画像にアタッチされる場所です。発生する変換は、358 から 386 にリストされています。

    onLoad : function() {
            /*
             * Build the container and all related elements, will result in
             * the following
             * 
             * <div class="imgCrop_wrap"> <img ... this.img ... /> <div
             * class="imgCrop_dragArea"> <!-- the inner spans are only
             * required for IE to stop it making the divs 1px high/wide -->
             * <div class="imgCrop_overlay imageCrop_north"><span></span></div>
             * <div class="imgCrop_overlay imageCrop_east"><span></span></div>
             * <div class="imgCrop_overlay imageCrop_south"><span></span></div>
             * <div class="imgCrop_overlay imageCrop_west"><span></span></div>
             * <div class="imgCrop_selArea"> <!-- marquees --> <!-- the
             * inner spans are only required for IE to stop it making the
             * divs 1px high/wide --> <div class="imgCrop_marqueeHoriz
             * imgCrop_marqueeNorth"><span></span></div> <div
             * class="imgCrop_marqueeVert imgCrop_marqueeEast"><span></span></div>
             * <div class="imgCrop_marqueeHoriz imgCrop_marqueeSouth"><span></span></div>
             * <div class="imgCrop_marqueeVert imgCrop_marqueeWest"><span></span></div>
             * <!-- handles --> <div class="imgCrop_handle imgCrop_handleN"></div>
             * <div class="imgCrop_handle imgCrop_handleNE"></div> <div
             * class="imgCrop_handle imgCrop_handleE"></div> <div
             * class="imgCrop_handle imgCrop_handleSE"></div> <div
             * class="imgCrop_handle imgCrop_handleS"></div> <div
             * class="imgCrop_handle imgCrop_handleSW"></div> <div
             * class="imgCrop_handle imgCrop_handleW"></div> <div
             * class="imgCrop_handle imgCrop_handleNW"></div> <div
             * class="imgCrop_clickArea"></div> </div> <div
             * class="imgCrop_clickArea"></div> </div> </div>
             */
    .......
    }

574 行目 - この関数の最初の部分は、指定された「maxCaptureWidth」に従って画像の最大寸法を設定しようとします。関数の残りの部分は、画像に対するトリミング領域の左上と右下の座標を計算します。

    var ratioOfContainer = this.img.naturalHeight
                    / this.img.naturalWidth;
    var baseWidth = (this.img.naturalWidth > this.options.maxCaptureWidth) ? this.options.maxCaptureWidth
                    : this.img.naturalWidth;
    var corelatedHeight = baseWidth * ratioOfContainer;

    this.img.width = baseWidth;
    this.img.height = corelatedHeight;

    this.imgW = baseWidth;

    this.imgH = corelatedHeight;

656 行目から 658 行目 - これらは、イメージをキャンバスにキャプチャするための主要な関数です。selArea は、キャンバスに描画される領域です。

    this.selArea.show();
    this.drawArea();
    this.endCrop();

758 行目 - クロッパーの幅を取得するユーティリティ。

    calcW : function() {
        return (this.areaCoords.x2 - this.areaCoords.x1);
    }

768 行目 - クロッパーの高さを取得するユーティリティ。

    calcH : function() {
        return (this.areaCoords.y2 - this.areaCoords.y1);
    }

1170 行目 - 描画領域は、クロッパーがサイズ変更または移動された場合に呼び出されることが保証されている関数です。現在のクロッパーの位置に従って、イメージ オーバーレイにスタイルを適用します。

1230 行目 - キャンバスへの描画機能はここから始まります。この部分は、IE と Chrome の両方で正常に動作します。Firefox では、クロッパーの左上が画像の左上と一致する場合にのみ機能します。また、クロッパーを上下または左右に動かすと、キャプチャーされた画像が歪みます。コンテキストの drawimage 関数に渡されるパラメーターを徹底的にチェックしましたが、問題はありません。

    var ratioDimHeight = this.img.naturalHeight / this.img.height;
    var ratioDimWidth = this.img.naturalWidth / this.img.width;

    var canvas = document.createElement("canvas");
    canvas.width = areaWidth;
    canvas.height = areaHeight;
    var context = canvas.getContext("2d");              

    context
            .drawImage(
                    this.img,
                    this.areaCoords.x1 * ratioDimWidth,
                    this.areaCoords.y1 * ratioDimHeight,
                    this.img.width * ratioDimWidth,
                    this.img.height * ratioDimHeight,
                    0, 0, this.img.width,
                    this.img.height);
    this.imageData = canvas.toDataURL('image/png');

行 1252 - トリミングされた画像を dataurl として抽出し、フォーム送信時に ajax を使用してサーバー側に送信し、画像バイトを s3 にアップロードします。

Firefox で動作しない理由がわかりません。助けていただければ幸いです。ご検討いただきありがとうございます。

4

1 に答える 1

0

私にとって有効な変更は次のとおりです。

           this.img.width = this.img.width - this.areaCoords.x1;
           this.img.height = this.img.height - this.areaCoords.y1;
           context
                    .drawImage(
                            this.img,
                            this.areaCoords.x1 * ratioDimWidth,
                            this.areaCoords.y1 * ratioDimHeight,
                            this.img.width * ratioDimWidth,
                            this.img.height * ratioDimHeight,
                            0, 0, this.img.width * ratioDimWidth,
                            this.img.height * ratioDimHeight);
           this.imageData = canvas.toDataURL('image/png');

           this.img.width = this.img.width + this.areaCoords.x1;
           this.img.height = this.img.height + this.areaCoords.y1;

クロップウィンドウの寸法に従って画像の寸法を縮小する必要があります。どういうわけか、Firefox はキャンバス キャプチャを他のブラウザとは異なる画像サイズと関連付けます。巧妙な方法で解決したと言えたらいいのですが:) drawimage関数をいじって、その動作を観察し、この「ハック」にたどり着きました。多分それは誰かにとって役に立ちます。

きちんとしたトリミング ライブラリの DEfusion に再び感謝します。

于 2015-08-05T12:32:36.477 に答える