zoukankan      html  css  js  c++  java
  • 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
    }

     

  • 相关阅读:
    iOS集成ijkplayer视频直播框架,遇到的bug和坑...
    push notification获取device token
    ios xcode Code signing failed 解决方案
    ios 返回指定导航控制器
    ios git 终端提交
    mysql问题集合
    mysql 备份和恢复
    cacti 异常问题
    硬盘各项检测
    LVS DR模式(直接路由模式)
  • 原文地址:https://www.cnblogs.com/theWayToAce/p/8085139.html
Copyright © 2011-2022 走看看