Newbie_小白
没有都对的别人,也没有全错的自己,至少要有自己的坚持,无关他人、无关外物!

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
}

 

 

posted on 2017-12-22 11:22  Newbie_小白  阅读(4574)  评论(0编辑  收藏  举报