图片剪切器

34 篇文章 0 订阅
5 篇文章 0 订阅

效果图


图片剪切功能

  1. 剪切选择框
  2. 剪切区域实时预览
  3. 剪切图片

剪切选择框

  1. 创建一个选择框(如效果图中的白色虚线组成的框)
  2. 选择框具有拖拽移动、边界检测(不能超出所在容器)、改变大小(我实现的是可以通过八个点改变大小)、可以反向拖动(就是在你右边的点拖动时,当前X坐标小于你选择框的X时,进行反向计算)
  3. 选择框有最小宽高限制、最大宽高限制、固定宽高限制
  4. 所选区域坐标换算

代码

css:
        /**图片剪切*/
           .dx-croping
           {
               position:absolute;
               border:dashed 1px #cbc8c8;
               box-sizing:border-box;
               z-index:99;
           }    
           .dx-croping .croping-move
           {
               position:absolute;
               left:0;
               top:0;
               right:0;
               bottom:0;
               z-index:3;
               overflow:hidden;
           }
           .dx-croping.dx-croping-noresize>.croping-pot
           {
               display:none;
           }
           .dx-croping .croping-wrap
           {
               position:absolute;
               left:0;
               top:0;
               right:0;
               bottom:0;
               z-index:2;
               overflow:hidden;
           }
          .dx-croping  .croping-pot
           {
               position:absolute;
               height:8px;
               width:8px;
               z-index:4;
               border:dashed 1px #cbc8c8;
               background-color:transparent;
           }
           .dx-croping .croping-ltop-pot
           {
               top:0px;
               left:0px;
               cursor:se-resize;
               border-left:0;
               border-top:0;
           }
           .dx-croping .croping-lcenter-pot
           {
               top:50%;
               margin-top:-5px;
               left:0;
               cursor:w-resize;
               border-left:0;
           }
            .dx-croping .croping-lbottom-pot{
               bottom:0;
               left:0;
               border-left:0;
               border-bottom:0;
               cursor:sw-resize;
           }
             .dx-croping  .croping-rtop-pot
           {
               top:0px;
               right:0px;
                 cursor:sw-resize;
                border-right:0;
               border-top:0;
           }
           .dx-croping .croping-rcenter-pot
           {
               top:50%;
               margin-top:-5px;
               right:0px;
               cursor:w-resize;
               border-right:0;
               
           }
           .dx-croping .croping-rbottom-pot{
               bottom:0px;
               right:0px;
               border-right:0;
               border-bottom:0;
               cursor:se-resize;
           }

            .dx-croping .croping-top-pot
           {
               top:0;
               left:50%;
               margin-left:-5px;
               border-top:0;
               cursor:s-resize;
           }
            .dx-croping .croping-bottom-pot{
                bottom:0;
               left:50%;
               margin-left:-5px;
                border-bottom:0;
                cursor:s-resize;
           }
       
   .dx-cropimage-wrapper
   {
       position:relative;
       width:640px;
       height:428px;
   }
   .dx-cropimage-image
   {
       border:0;
   }
   .dx-cropimage-mask
   {
      position:absolute;
      background-color:rgba(0, 0, 0,0.5);
       left:0;
       top:0;
        right:0;
       bottom:0;
        z-index:3;
   }
         /**图片剪切end*/
  


html:

<img src="/assets/images/domokun.jpg" id="cropImage" />
<div id="previewid"></div>



JS:
  var MouseEvents = Dx.ui.Widget.extend((function () {
                var MOUSEEVENTS = {
                    'down': 'mousedown',
                    'move': 'mousemove',
                    'up': 'mouseup'
                };
                function getPointer(e) {
                    e = e || { x: 0, y: 0 };
                    return {
                        x: e.pageX,
                        y: e.pageY
                    };
                }
                return {
                    options: {
                        selector: null
                    },
                    events: ['onDown', 'onMove', 'onUp'],
                    initialize: function (element, options) {
                        this.callSuper('initialize', element, options);
                        Dx._.bindAll(this, 'onDown', 'onMove', 'onUp')
                        this.$doc = $(document);
                        this.delegateEvents(this.element, MOUSEEVENTS.down, this.options.selector, this.onDown);
                        this.startPointer = getPointer();
                        this.lastPointer = getPointer();
                        this.currentPointer = getPointer();
                        this.vx = 0;
                        this.vy = 0;
                    },
                    onDown: function (e) {
                        e.preventDefault();
                        this.startPointer = getPointer(e);
                        this._startMouse();  
                        this.vx = 0;
                        this.vy = 0;
                        this.trigger('onDown', e);
                    },
                    onMove: function (e) {
                        this.lastPointer = this.currentPointer;
                        this.currentPointer = getPointer(e);
                        this.vx = this.currentPointer.x - this.startPointer.x;
                        this.vy = this.currentPointer.y - this.startPointer.y;
                        this.trigger('onMove', e);
                    },
                    onUp: function (e) {
                        this.undelegateEvents(this.$doc);
                        this.trigger('onUp', e);
                    },
                    _startMouse: function () {
                        this.delegateEvents(this.$doc, MOUSEEVENTS.move, this.onMove);
                        this.delegateEvents(this.$doc, MOUSEEVENTS.up, this.onUp);
                    }
                };
            })());
            var CropZone = Dx.ui.Widget.extend(function () {
            
                var template = '<div class="dx-croping"><div class="croping-wrap"></div><div class="croping-move"></div><div class="croping-pot croping-ltop-pot"></div><div class="croping-pot croping-lcenter-pot"></div><div class="croping-pot croping-lbottom-pot"></div><div class="croping-pot croping-top-pot"></div><div class="croping-pot croping-bottom-pot"></div><div class="croping-pot croping-rtop-pot"></div><div class="croping-pot croping-rcenter-pot"></div><div class="croping-pot croping-rbottom-pot"></div></div>';
                function getBoundary(element,isBorder)
                {
                    var offset = element.offset(), 
                        outerWidth = element.outerWidth(),
                        outerHeight = element.outerHeight(), 
                        borderWidth = parseInt(element.css('borderWidth')), left = offset.left, top = offset.top, right = left + outerWidth, bottom = top + outerHeight;
                    if (!isBorder)
                    {
                        left += borderWidth;
                        top += borderWidth;
                        outerWidth -= borderWidth * 2;
                        outerHeight -= borderWidth * 2;
                        bottom = top + outerHeight;
                        right = left + outerWidth;
                    }
                    return {
                        left: left,
                        top: top,
                        right: right,
                        bottom:bottom,
                        width: outerWidth,
                        height: outerHeight
                    };
                }
                var cursors = {
                    'croping-move': 'move',
                    'croping-ltop-pot': "se-resize",
                    'croping-lcenter-pot': "w-resize",
                    'croping-lbottom-pot': "sw-resize",
                    'croping-top-pot': 's-resize',
                    'croping-bottom-pot': 's-resize',
                    'croping-rtop-pot': 'sw-resize',
                    'croping-rcenter-pot': "w-resize",
                    'croping-rbottom-pot': "se-resize"
                };

                return {
                    options: {
                        width: null,
                        height: null,
                        minWidth: 0,
                        minHeight: 0,
                        maxWidth: 0,
                        maxHeight:0,
                        aspectRatio: 0.4,
                        isResize:true
                    },
                    events: ['onCropEnd', 'onCropChange'],
                    initialize: function (element, options)
                    {
                        this.callSuper('initialize', element, options);
                        this.element.append(template);
                        this.$crop = this.element.children('.dx-croping');
                        this.$cropwrap = this.$crop.children('.croping-wrap');
                        this.init();
                        this.initEvents();

                    },
                    init:function()
                    {
                        if (this.options.width && this.options.height) {
                            this.element.css({
                                width: this.options.width,
                                height: this.options.height
                            });
                        }
                        this.$offsetParent = this.$crop.offsetParent();
                        this.boundary = getBoundary(this.element);
                        this.viewportOffset = getBoundary(this.$offsetParent);
                        this.cropBoxData = {};       
                        this.maxWidth =this.options.maxWidth>0? Math.min(this.options.maxWidth, this.boundary.width):this.boundary.width;
                        this.maxHeight = this.options.maxHeight > 0 ? Math.min(this.options.maxHeight, this.boundary.height) : this.boundary.height;
                        this.minWidth = Math.min(Math.max(this.options.minWidth, 0),this.maxWidth);
                        this.minHeight = Math.min(Math.max(this.options.minHeight,0),this.maxHeight);
                        var  width=Math.min(Math.max(this.boundary.width*this.options.aspectRatio,this.minWidth),this.maxWidth);
                        var  height=Math.min(Math.max(this.boundary.height*this.options.aspectRatio,this.minHeight),this.maxHeight);
                        this.setResize({
                            width:width,
                            height:height,
                            left:(this.boundary.width-width)/2,
                            top:(this.boundary.height-height)/2
                        });
                        if(!this.options.isResize)
                        {
                            this.$crop.addClass('dx-croping-noresize');
                        }
                    },
                    initEvents:function()
                    {
                        var that = this;
                        var _mouseEvents = new MouseEvents(this.$crop, {
                            onDown: function(e)
                            {
                        
                                var className = e.target.className.split(' '), eventName = className.shift();
                                this.eventName = eventName;
                                this.className = className.pop() || eventName;
                                this.cropBoundary = getBoundary(that.$crop, true);
                                that.setCursor(this.className);
                                this.trigger(eventName + '-down', e);
                            },
                            onMove:function(e)
                            {
                                this.trigger(this.eventName + '-move', e);
                            },
                            onUp:function(e)
                            {
                                that.removeCursor(this.className);
                                this.trigger(this.eventName + '-up', e);
                                that.trigger('onCropEnd')
                            }
                        });


                        _mouseEvents.on('croping-move-move', function (e) {
                            this.left = this.cropBoundary.left + this.vx;
                            this.top = this.cropBoundary.top + this.vy;
                            that.setPosition(that.aabb(this.left, this.top, this.cropBoundary.width, this.cropBoundary.height));
                        });
                        _mouseEvents.on('croping-pot-down', function (e) {
                            this.oldLeft=0;
                            this.oldTop=0;
                        });
                        _mouseEvents.on('croping-pot-move', function (e) {
                            var
                                    boundary = that.boundary,
                                    vx = this.vx,
                                     vy = this.vy,
                                     left = this.cropBoundary.left,
                                     top = this.cropBoundary.top,
                                      width = this.cropBoundary.width,
                                      height = this.cropBoundary.height,
                                      right = this.cropBoundary.right,
                                      bottom = this.cropBoundary.bottom,
                                      vH=height+vy,vW=width+vx;


                            switch (this.className)
                            {
                                case "croping-rtop-pot":
                                    vH = height - vy;
                                    if (vH > 0) {
                                        height = Math.min(vH, bottom - boundary.top);
                                        top = Math.max(top + vy, boundary.top);
                                    } else {
                                        top = bottom;
                                        height = Math.min(Math.abs(vH), boundary.bottom - top);

                                    }
                                    if (vW > 0) {
                                        width = Math.min(vW, boundary.right - left);
                                    } else {
                                        width = Math.min(Math.abs(vW), left - boundary.left);
                                        left = Math.max(left + vW, boundary.left);
                                    }
                                    break;
                                case "croping-rcenter-pot":
                                    if (vW > 0) {
                                        width = Math.min(vW, boundary.right - left);
                                    } else {
                                        width = Math.min(Math.abs(vW), left - boundary.left);
                                        left = Math.max(left + vW, boundary.left);
                                    }
                                    break;
                                case "croping-rbottom-pot":
                                    if (vH > 0)
                                    {
                                        height = Math.min(vH, boundary.bottom - top);
                                    } else {
                                        height = Math.min(Math.abs(vH),top-boundary.top);
                                        top = Math.max(top + vH, boundary.top);
                                    }
                                    if (vW > 0) {
                                        width = Math.min(vW, boundary.right - left);
                                    } else {
                                        width = Math.min(Math.abs(vW), left - boundary.left);
                                        left = Math.max(left + vW, boundary.left);
                                    }
                                    break;
                                case "croping-ltop-pot":
                                    vH = height - vy;
                                    vW = width - vx;
                                    if (vH > 0) {
                                        height = Math.min(vH, bottom - boundary.top);
                                        top = Math.max(top + vy, boundary.top);
                                    } else {
                                        top = bottom;
                                        height = Math.min(Math.abs(vH), boundary.bottom - top);

                                    }
                                    if (vW > 0) {
                                        width = Math.min(vW, right - boundary.left);
                                        left = Math.max(left + vx, boundary.left);
                                    } else {
                                        width = Math.min(Math.abs(vW), boundary.right - right);
                                        left = right;
                                    }
                                    break;
                                case "croping-lcenter-pot":
                                    vW = width - vx;
                                    if (vW > 0) {
                                        width = Math.min(vW, right - boundary.left);
                                        left = Math.max(left + vx, boundary.left);
                                    } else {
                                        width = Math.min(Math.abs(vW), boundary.right - right);
                                        left = right;
                                    }
                                    break;
                                case "croping-lbottom-pot":
                                    vW = width - vx;
                                    if (vH > 0) {
                                        height = Math.min(vH, boundary.bottom - top);
                                    } else {
                                        height = Math.min(Math.abs(vH), top - boundary.top);
                                        top = Math.max(top + vH, boundary.top);
                                    }
                                    if (vW > 0) {
                                        width = Math.min(vW, right - boundary.left);
                                        left = Math.max(left + vx, boundary.left);
                                    } else {
                                        width = Math.min(Math.abs(vW), boundary.right-right);
                                        left = right;
                                    }
                                    break;
                                case "croping-top-pot":
                                    vH = height - vy;
                                    if (vH > 0) {
                                        height = Math.min(vH, bottom - boundary.top);
                                        top = Math.max(top + vy, boundary.top);
                                    } else {
                                        top = bottom;
                                        height = Math.min(Math.abs(vH), boundary.bottom - top);

                                    }
                                    break;
                                case "croping-bottom-pot":
                                    if (vH > 0) {
                                        height = Math.min(vH, boundary.bottom - top);
                                    } else {
                                        height = Math.min(Math.abs(vH), top - boundary.top);
                                        top = Math.max(top + vH, boundary.top);
                                    }
                                    break;
                            }
                            if (that.minWidth > 0 && width < that.minWidth)
                            {
                                width = that.minWidth;
                                left = this.oldLeft;
                            }
                            if (that.minHeight > 0 && height < that.minHeight) {
                                height = that.minHeight;
                                top = this.oldTop;
                            }
                            if (that.maxWidth > 0 && width > that.maxWidth) {
                                width = that.maxWidth;
                               left = this.oldLeft;
                            }
                            if (that.maxHeight > 0 && height > that.maxHeight) {
                                height = that.maxHeight;
                               top = this.oldTop;
                            }
                            that.setResize({
                                    left: left,
                                    top: top,
                                    width: width,
                                    height:height
                             });                           
                            this.oldLeft = left;
                            this.oldTop = top;
                        });


             
                    },
                    aabb:function(left,top,width,height)
                    {
                        return {
                            left: Math.min(Math.max(this.boundary.left, left), this.boundary.right - width),
                            top:Math.min(Math.max(this.boundary.top, top), this.boundary.bottom - height)
                        };
                    },
                    setResize: function (obj) {
                        var width = obj.width, height = obj.height, left = obj.left - this.viewportOffset.left, top = obj.top - this.viewportOffset.top;
                        this.$crop.css({
                            width: width,
                            height: height,
                            left: left,
                            top: top
                        });
                        this.cropBoxData.left = left;
                        this.cropBoxData.top = top;
                        this.cropBoxData.width = width;
                        this.cropBoxData.height = height;
                        this.trigger('onCropChange');
                    },
                    setPosition: function (position)
                    {
                        var left = position.left - this.viewportOffset.left, top = position.top - this.viewportOffset.top;
                        this.$crop.css({
                            left: left,
                            top: top
                        });
                        this.cropBoxData.left = left;
                        this.cropBoxData.top = top;
                        this.trigger('onCropChange');
                    },
                    getCropData:function()
                    {
                        return $.extend({}, this.cropBoxData);
                    },
                    setCursor:function(className)
                    {
                        this.element.css('cursor', cursors[className]);
                    },
                    removeCursor: function () {
                        this.element.css('cursor','');
                    }

                };
            }());
            var CropImage = Dx.ui.extendWidget('CropImage3', function (parent) {

                var template = '  <div id="cropImage" class="dx-cropimage-wrapper"><div class="dx-cropimage-image"></div><div class="dx-cropimage-mask"></div></div>';
                return parent.extend({
                    options: {
                        width: null,
                        height: null,
                        preview:null
                    },
                    events: ['onCropEnd', 'onCropChange'],
                    initialize:function(element,options)
                    {
                        this.callSuper('initialize', element, options);
                        this.wrapper = $(template).insertAfter(this.element);
                        this.wrapper.find('.dx-cropimage-image').append(this.element);
                        this.width=this.options.width||this.element[0].width;
                        this.height = this.options.height || this.element[0].height;
                        this.element[0].width=this.width;
                        this.element[0].height = this.height;
                        this.$cloneImage = this.element.clone();
                        this.$cloneImage.removeAttr('id');
                        var that = this;
                        var _CropZone = this._cropZone = new CropZone(this.wrapper, $.extend({}, this.options, {
                            width: this.width,
                            height: this.height
                        }));
                        _CropZone.$cropwrap.append(this.$cloneImage);
                        _CropZone.on('onCropChange', function () {
                            that.renderCropImage();
                        });
                        if (this.options.preview) {
                            this.$preview = $(this.options.preview);
                            this.$previewWrap = $('<div>').css('overflow','hidden').appendTo(this.$preview);
                            this.$previewImage = this.$cloneImage.clone().appendTo(this.$previewWrap);
                        }
                        this.renderCropImage();
                    },
                    renderCropImage:function()
                    {
                        var cropZone = this._cropZone, cropData = cropZone.getCropData();
                        var styles={
                            marginLeft: -cropData.left + "px",
                            marginTop: -cropData.top + "px"
                        };
                        this.$cloneImage.css(styles);
                        if (this.options.preview)
                        {
                            this.$previewWrap.css({
                                width: cropData.width,
                                height:cropData.height
                            });
                            this.$previewImage.css(styles)
                        }
                    },
                    toDataURL:function()
                    {
                        var canvas = document.createElement('canvas'), cropZone = this._cropZone, cropData = cropZone.getCropData();
                        var ctx = canvas.getContext('2d');
                        canvas.width = cropData.width;
                        canvas.height = cropData.height;
                        ctx.drawImage(this.element[0], cropData.left, cropData.top, cropData.width, cropData.height, 0, 0, cropData.width, cropData.height);
                        return canvas.toDataURL();
                    }
                });
            });
            var _CropImage = window._CropImage = new Dx.ui.CropImage('#cropImage', {
                preview: "#previewid",
                minWidth: 100,
                minHeight: 100,
                isResize: true,
                onCropEnd:function()
                {
                    img[0].src = _CropImage.toDataURL();
                }

            });


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值