Cropper


jQuery.cropper是一款使用簡單且功能強大的圖片剪裁jQuery插件。該圖片剪裁插件支持圖片放大縮小,支持圖片旋轉,支持觸摸屏設備,支持canvas,並且支持跨瀏覽器使用。 

官網:https://github.com/fengyuanchen/cropper

使用方法 
使用該圖片剪裁插件首先要引入必要的js和css文件。

 

<script src="/path/to/jquery.js"></script><!-- jQuery is required -->
<link href="/path/to/cropper.css" rel="stylesheet">
<script src="/path/to/cropper.js"></script>      

 

HTML結構 
可以將圖片或canvas直接包裹到一個塊級元素中。

 

<!-- Wrap the image or canvas with a block element -->
<div class="container">
    <img src="picture.jpg">
</div>

 

調用插件 
可以使用$.fn.cropper方法來初始化該圖片剪裁插件。

var options = {
    aspectRatio: 4 / 3,//設置裁切框的寬高比。默認情況下,裁剪框是自由比例。
    preview: '.img-preview',
    crop: function (e) {
        $dataX.html(Math.round(e.x));
        $dataY.html(Math.round(e.y));
        $dataHeight.html(Math.round(e.height));
        $dataWidth.html(Math.round(e.width));
        $dataRotate.html(e.rotate);
        $dataScaleX.html(e.scaleX);
        $dataScaleY.html(e.scaleY);
        var _$dataWH = reductionTo(Math.round(e.width), Math.round(e.height));
        $dataWH.html(_$dataWH[0] + '/' + _$dataWH[1]);
    }
};
// 初始化函數
$image.cropper(options);
$image.cropper({
    built: function () {
    }
});

 

參數

  • 你可以通過$().cropper(options)方法來設置參數。如果你想改變全局默認參數,可以使用$.fn.cropper.setDefaults(options)方法。

  • aspectRatio:類型:Number,默認值NaN。設置剪裁容器的比例。

  • crop:類型:Function,默認值null。當改變剪裁容器或圖片時的事件函數。

  • preview:類型:String(jQuery選擇器),默認值''。添加額外的元素(容器)的預覽。注意:

  • 最大寬度是剪裁容器的初始化寬度

  • 最大高度是剪裁容器的初始化高度

  • 如果你設置了aspectRatio參數,確保預覽容器具有相同的比例

  • strict:類型:Boolean,默認值true。在strict模式中,canvas不能小於容器,剪裁容器不能再canvas之外。

  • responsive:類型:Boolean,默認值true。是否在窗口尺寸改變的時候重置cropper。

  • checkImageOrigin:類型:Boolean,默認值true。默認情況下,插件會檢測圖片的源,如果是跨域圖片,圖片元素會被添加crossOrigin class,並會為圖片的url添加一個時間戳來使getCroppedCanvas變為可用。添加時間戳會使圖片重新加載,以使跨域圖片能夠使用getCroppedCanvas。在圖片上添加crossOrigin class會阻止在圖片url上添加時間戳,及圖片的重新加載。

  • background:類型:Boolean,默認值true。是否在容器上顯示網格背景。

  • modal:類型:Boolean,默認值true。是否在剪裁框上顯示黑色的模態窗口。

  • guides:類型:Boolean,默認值true。是否在剪裁框上顯示虛線。

  • highlight:類型:Boolean,默認值true。是否在剪裁框上顯示白色的模態窗口。

  • autoCrop:類型:Boolean,默認值true。是否在初始化時允許自動剪裁圖片。

  • autoCropArea:類型:Number,默認值0.8(圖片的80%)。0-1之間的數值,定義自動剪裁區域的大小。

  • dragCrop:類型:Boolean,默認值true。是否允許移除當前的剪裁框,並通過拖動來新建一個剪裁框區域。

  • movable:類型:Boolean,默認值true。是否允許移動剪裁框。

  • resizable:類型:Boolean,默認值true。是否允許改變剪裁框的大小。

  • zoomable:類型:Boolean,默認值true。是否允許放大縮小圖片。

  • mouseWheelZoom:類型:Boolean,默認值true。是否允許通過鼠標滾輪來縮放圖片。

  • touchDragZoom:類型:Boolean,默認值true。是否允許通過觸摸移動來縮放圖片。

  • rotatable:類型:Boolean,默認值true。是否允許旋轉圖片。

  • minContainerWidth:類型:Number,默認值200。容器的最小寬度。

  • minContainerHeight:類型:Number,默認值100。容器的最小高度。

  • minCanvasWidth:類型:Number,默認值0。canvas 的最小寬度(image wrapper)。

  • minCanvasHeight:類型:Number,默認值0。canvas 的最小高度(image wrapper)。

  • build:類型:Function,默認值null。build.cropper事件的簡寫方式。

  • built:類型:Function,默認值null。built.cropper事件的簡寫方式。

  • dragstart:類型:Function,默認值null。dragstart.cropper事件的簡寫方式。

  • dragmove:類型:Function,默認值null。dragmove.cropper事件的簡寫方式。

  • dragend:類型:Function,默認值null。dragend.cropper事件的簡寫方式。

  • zoomin:類型:Function,默認值null。zoomin.cropper事件的簡寫方式。

  • zoomout:類型:Function,默認值null。zoomout.cropper事件的簡寫方式。

eg:

//index.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <link rel="stylesheet" href="css/cropper.css">
    <link rel="stylesheet" href="css/main.css">
</head>
<body>
<div class="wrapper">
    <!--用塊元素(容器)包裝圖像或畫布元素-->
    <div class="img-container">
        <img id="image" src="images/picture.jpg" alt="">
    </div>
    <div class="img-preview-container">
        <h1>預覽區域</h1>
        <div class="img-preview">
            <img src="" alt="">
        </div>
    </div>

    <div class="text-container">
        <div class="param-container">
            <div class="param">
                <div class="name">X:</div>
                <div class="value" id="dataX"></div>
                <div class="unit">px</div>
            </div>
            <div class="param">
                <div class="name">Y:</div>
                <div class="value" id="dataY"></div>
                <div class="unit">px</div>
            </div>
            <div class="param">
                <div class="name">Width:</div>
                <div class="value" id="dataWidth"></div>
                <div class="unit">px</div>
            </div>
            <div class="param">
                <div class="name">Height:</div>
                <div class="value" id="dataHeight"></div>
                <div class="unit">px</div>
            </div>
            <div class="param">
                <div class="name">Rotate:</div>
                <div class="value" id="dataRotate"></div>
                <div class="unit">deg</div>
            </div>
            <div class="param">
                <div class="name">ScaleX:</div>
                <div class="right-value" id="dataScaleX"></div>
            </div>
            <div class="param">
                <div class="name">ScaleY:</div>
                <div class="right-value" id="dataScaleY"></div>
            </div>
            <div class="param">
                <div class="name">W/H:</div>
                <div class="right-value" id="dataWH"></div>
            </div>
        </div>
    </div>
    <div class="btn-container" id="ratio_container">
        <div class="btn" data-ratio="16/9">16/9</div>
        <div class="btn" data-ratio="4/3">4/3</div>
        <div class="btn" data-ratio="1">1/1</div>
        <div class="btn" data-ratio="2/3">2/3</div>
        <div class="btn" data-ratio="">Free</div>
    </div>
    <div class="btn-container" id="move_container">
        <div class="btn" data-movex="0" data-movey="-10">上移</div>
        <div class="btn" data-movex="0" data-movey="10">下移</div>
        <div class="btn" data-movex="-10" data-movey="0">左移</div>
        <div class="btn" data-movex="10" data-movey="0">右移</div>
    </div>
    <div class="btn-container" id="zoom_container">
        <div class="btn" data-zoom="0.1">放大</div>
        <div class="btn" data-zoom="-0.1" data-movey="10">縮小</div>
    </div>
    <div class="btn-container" id="rotate_container">
        <div class="btn" data-rotate="45">順時針旋轉</div>
        <div class="btn" data-rotate="-45" data-movey="10">逆時針旋轉</div>
    </div>
    <div class="btn-container" id="scale_container">
        <div class="btn" data-scale="x">左右翻轉</div>
        <div class="btn" data-scale="y" data-movey="10">上下翻轉</div>
    </div>
    <div class="btn-container">
        <div class="btn" id="enable">可用</div>
        <div class="btn" id="disable">凍結</div>
        <div class="btn" id="reset1">重置1</div>
        <div class="btn" id="reset2">重置2</div>
        <div class="btn" id="clear">清空</div>
        <div class="btn" id="destroy">銷毀</div>
        <div class="btn">
            <input class="input-upload" id="upload" type="file">
            上傳圖片
        </div>
    </div>
    <div class="btn-container">
        <div class="btn" id="replace">修改圖片地址</div>
    </div>
    <div class="btn-container">
        <div class="btn" id="getCroppedCanvas">裁剪:get Cropped Canvas</div>
    </div>
    <div class="btn-container">
        <div class="btn" id="submit">提交</div>
    </div>
    <img src="" id="test" width="500px" height="500px" alt="">
<div class="fixed-canvas hiddle">
    <div class="fixed-bg"></div>
    <div class="canvas-container">
        <h1>裁剪區域</h1>
        <div class="canvas" id="canvas">
        </div>
        <div class="btn-container" id="modal_canvas_btn">
            <a class="btn" href="javascript:;" >取消</a>
            <a class="btn" id="download" href="javascript:;" download="images/picture.jpg">下載</a>
        </div>
    </div>
</div>
</div>
<script src="js/jquery-3.2.1.js"></script>
<script src="js/cropper.js"></script>
<script src="js/main.js"></script>

</body>
</html>

 

 

//main.css
*{margin: 0;padding: 0;outline: none}
*:active{-webkit-tap-highlight-color: rgba(0,0,0,0)}
a{text-decoration: none}
.disabled{pointer-events: none;opacity:.65}
h1{font-size: 18px;margin-bottom: 20px}
.hiddle{display: none!important;}
.wrapper{margin: 20px auto;min-width: 1200px}
.img-container{margin-left: 20px;display: inline-block;width: 600px;height: 342px;overflow: hidden;}
.img-preview-container{margin-left: 10px;display: inline-block;vertical-align: top}
.img-preview-container .img-preview{width: 300px;height: 171px;overflow: hidden;border: 1px #ccc solid}
.img-preview-container img{border: 1px #aaa solid}
.fixed-canvas{position: fixed;left: 50%;top:20px; width: 600px;margin-left: -300px;border:1px #aaa solid;border-radius: 6px;}
.fixed-canvas .fixed-bg{position: fixed;left: 0%;top:0%;right:0;bottom:0;background: rgba(0,0,0,.6);z-index:1}
.fixed-canvas .canvas-container{background: #fff;padding: 30px 20px;width: 100%;height: 100%;position: relative;z-index: 2;border-radius: 6px;box-sizing: border-box}
.fixed-canvas .canvas-container .canvas{width: 456px;border: 1px #ccc solid}
.fixed-canvas .canvas-container .canvas canvas{width: 100%}
/*限制圖像寬度以避免容器溢出*/
.img-container img{max-width: 100%} /*這個規則很重要,請不要忽略這個*/
.text-container{display: inline-block;padding-left: 20px}
.text-container .param-container{vertical-align: top}
.param-container .param{display: inline-block;margin: 10px;width: 202px;height:33px;border: 1px #aaa solid;border-radius: 6px;box-sizing: border-box;font-size: 0}
.param-container .param .name,.param-container .param .value,.param-container .param .unit,.param-container .param .right-value{display: inline-block;height:100%;box-sizing: border-box;text-align: center;color:#495057;vertical-align: top;font-size: 16px;line-height: 31px}
.param-container .param .name,.param-container .param .unit{background: #ccc}
.param-container .param .name{width: 80px}
.param-container .param .value{width: 80px}
.param-container .param .unit{width: 40px}
.param-container .param .right-value{width: 120px;}

.btn-container{margin: 20px;display: inline-block;height: 33px;background: #007bff;border-radius: 6px}
.btn-container .btn{position: relative;padding: 0 20px;display: inline-block;height: 100%;vertical-align: top;color: #fff;line-height: 33px;cursor: pointer;overflow: hidden}
.input-upload{position: absolute;top: 0;left: 0;bottom: 0;right: 0;display: inline-block;border: 1px red solid;opacity: 0;}

 

//main.js
$(function () {
    'use strict';
    var $image = $('#image');
    var $download = $('#download');
    var $dataX = $('#dataX');
    var $dataY = $('#dataY');
    var $dataHeight = $('#dataHeight');
    var $dataWidth = $('#dataWidth');
    var $dataRotate = $('#dataRotate');
    var $dataScaleX = $('#dataScaleX');
    var $dataScaleY = $('#dataScaleY');
    var $dataWH = $('#dataWH');
    var options = {
        aspectRatio: 4 / 3,//設置裁切框的寬高比。默認情況下,裁剪框是自由比例。
        preview: '.img-preview',
        crop: function (e) {
            $dataX.html(Math.round(e.x));
            $dataY.html(Math.round(e.y));
            $dataHeight.html(Math.round(e.height));
            $dataWidth.html(Math.round(e.width));
            $dataRotate.html(e.rotate);
            $dataScaleX.html(e.scaleX);
            $dataScaleY.html(e.scaleY);
            var _$dataWH = reductionTo(Math.round(e.width), Math.round(e.height));
            $dataWH.html(_$dataWH[0] + '/' + _$dataWH[1]);
        }
    };
    // 初始化函數
    $image.cropper(options);
    $image.cropper({
        built: function () {
        }
    });

    // 修改裁剪比例函數
    $('#ratio_container .btn').click(function (event) {
        event.stopPropagation();
        var dataRatio = $(this).attr('data-ratio');
        $image.cropper('destroy').cropper({'aspectRatio': dataRatio});
    });
    // 移動函數
    $('#move_container .btn').click(function (event) {
        event.stopPropagation();
        var dataMovex = parseInt($(this).attr('data-movex'));
        var dataMovey = parseInt($(this).attr('data-movey'));
        $image.cropper('move', dataMovex, dataMovey)
    });

    // 移動函數
    $('#move_container .btn').click(function (event) {
        event.stopPropagation();
        var dataMovex = parseInt($(this).attr('data-movex'));
        var dataMovey = parseInt($(this).attr('data-movey'));
        $image.cropper('move', dataMovex, dataMovey)
    });

    // Keyboard
    $(document.body).on('keydown', function (e) {
        if (!$image.data('cropper') || this.scrollTop > 300) {
            return;
        }
        switch (e.which) {
            case 37:
                e.preventDefault();
                $image.cropper('move', -1, 0);
                break;

            case 38:
                e.preventDefault();
                $image.cropper('move', 0, -1);
                break;

            case 39:
                e.preventDefault();
                $image.cropper('move', 1, 0);
                break;

            case 40:
                e.preventDefault();
                $image.cropper('move', 0, 1);
                break;
        }

    });
    // 放大縮小
    $('#zoom_container .btn').click(function (event) {
        event.stopPropagation();
        var dataZoom = $(this).attr('data-zoom');
        $image.cropper('zoom', dataZoom);
    });
    // 旋轉
    $('#rotate_container .btn').click(function (event) {
        event.stopPropagation();
        var dataRotate = $(this).attr('data-rotate');
        $image.cropper('rotate', dataRotate);
    });
    // 翻轉
    var scalexVal = 1;
    var scaleyVal = 1;
    $('#scale_container .btn').click(function (event) {
        event.stopPropagation();
        var dataScale = $(this).attr('data-scale');
        if (dataScale == 'x') {
            scalexVal = -scalexVal;
            $image.cropper('scaleX', scalexVal);
        } else if (dataScale == 'y') {
            scaleyVal = -scaleyVal;
            $image.cropper('scaleY', scaleyVal);
        }
    });
    // enable():使cropper可用。
    $('#enable').click(function (event) {
        event.stopPropagation();
        $image.cropper('enable');
    });
    // disable():凍結cropper。
    $('#disable').click(function (event) {
        event.stopPropagation();
        $image.cropper('disable');
    });
    // reset():重置剪裁區域的圖片到初始狀態。
    $('#reset1').click(function (event) {
        event.stopPropagation();
        $image.cropper('crop');
        $image.cropper('destroy').cropper({'preview': '.img-preview'});
    });
    $('#reset2').click(function (event) {
        event.stopPropagation();
        $image.cropper('reset');
        $image.cropper('destroy').cropper({'preview': '.img-preview'});
    });
    // clear():清空剪裁區域。
    $('#clear').click(function (event) {
        event.stopPropagation();
        $image.cropper('clear');
    });
    // destroy():銷毀剪裁函數。
    $('#destroy').click(function (event) {
        event.stopPropagation();
        $image.cropper('destroy');
    });
    //上傳圖片
    $('#upload').change(function (event) {
        var files = this.files;
        if (files && files.length) {
            var file = files[0];
            if (/\.(gif|jpg|jpeg|png|GIF|JPG|PNG)$/.test(file.name)) {
                var uploadedImageURL = window.URL.createObjectURL(file);
                $image.cropper('destroy').attr('src', uploadedImageURL).cropper(options);
                $download.attr('download', uploadedImageURL);
                $('#upload').val('');
            } else {
                alert('請選擇正確的圖片格式!');
            }
        }
    });
    //修改圖片地址
    var imgUrl = 'images/picture.jpg';
    $('#replace').click(function (event) {
        event.stopPropagation();
        imgUrl = (imgUrl == 'images/picture_new.jpg' ? 'images/picture.jpg' : 'images/picture_new.jpg');
        $image.cropper('replace', imgUrl);
        $download.attr('download', imgUrl);
    });
    // 輸出裁剪好的圖片
    $('#getCroppedCanvas').click(function (event) {
        event.stopPropagation();
        var imgurl = $image.cropper("getCroppedCanvas");
        $("#canvas").html(imgurl);
        $download.attr('href', imgurl.toDataURL());
        $('.fixed-canvas').removeClass('hiddle');
    });
    //點擊取消或者下載之后
    $('#modal_canvas_btn .btn').click(function (event) {
        $('.fixed-canvas').addClass('hiddle');
    });
    // 獲取數據
    $('#getData').click(function (event) {
        event.stopPropagation();
        var getData = $image.cropper("getData")
        console.log(getData);
    });
    //提交裁剪好的圖片到后台
    $('#submit').click(function (event) {
        var imgData = $image.cropper("getCroppedCanvas").toDataURL();
        // console.log(imgData);
        $.ajax({
            url: '',
            dataType: 'json',
            type: "POST",
            data: {"image": imgData},
            success: function () {
                console.log('Upload success');
            },
            error: function () {
                console.log('Upload error');
            }
        });

    });


});

function destory() {
    $image.cropper('destroy').cropper(options);
}

//m,n為正整數的分子和分母
function reductionTo(m, n) {
    var arr = [];
    if (!isInteger(m) || !isInteger(n)) {
        // console.log('m和n必須為整數');
        arr[0] = 0;
        arr[1] = 0;
        return arr;
    } else if (m <= 0 || n <= 0) {
        // console.log('m和n必須大於0');
        arr[0] = 0;
        arr[1] = 0;
        return arr;
    }
    var a = m;
    var b = n;
    (a >= b) ? (a = m, b = n) : (a = n, b = m);
    if (m != 1 && n != 1) {
        for (var i = b; i >= 2; i--) {
            if (m % i == 0 && n % i == 0) {
                m = m / i;
                n = n / i;
            }
        }
    }
    arr[0] = m;
    arr[1] = n;
    return arr;
}

//判斷一個數是否為整數
function isInteger(obj) {
    return obj % 1 === 0
}

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM