hytzgroup / blog

write & read & though
0 stars 0 forks source link

resizable原理 #7

Open hytzgroup opened 5 years ago

hytzgroup commented 5 years ago

resizable原理

(function($){
    function resize(e){
        var resizeData = e.data;
        var opts = $.data(e.data.target,'resizable').options;
        if(resizeData.dir.indexOf('e') != -1){
            // 在目标元素的e,假设要拖大元素
            // left不变,width变大 e.pageX-resizeData.startY
            var width = resizeData.startWidth + e.pageX - resizeData.startX;
            width = Math.min(
                Math.max(width,opts.minWidth),
                opts.maxWidth
            );
            resizeData.width = width;
        }
        if(resizeData.dir.indexOf('s') != -1){
            var height = resizeData.startHeight + e.pageY -resizeData.startY;
            height = Math.min(
                Math.max(height, opts.minHeight),
                opts.maxHeight
            );
            resizeData.height = height;
        }
        if(resizeData.dir.indexOf('w') != -1){
            // 在拖拽元素的w,假设要减小元素
            // width减小 e.pageX - resizeData.startX
            // left 增大 left + outerWidth(右边线)- 当前的width
            var width = resizeData.startWidth - (e.pageX - opresizeDatats.startX);
            width = Math.min(
                Math.max(width,opts.minWidth),
                opts.maxWidth
            );
            resizeData.width = width;
            resizeData.left = resizeData.startLeft + resizeData.startWidth - resizeData.width;
        }
        if(resizeData.indexOf('n') != -1){
            var height = resizeData.startHeight - (e.pageY - resizeData.startY);
            height = Math.min(
                Math.max(height,opts.minHeight),
                opts.maxHeight
            );
            resizeData.height = height;
            resizeData.top = resizeData.startTop + resizeData.startHeight - resizeData.height;
        }
    }

    function applyResize(e){
        var resizeData = e.data;
        if($.boxModel == true){
            $(e.data.target).css({
                width:resizeData.width - resizeData.deltaWidth,
                height:resizeData.height - resizeData.deltaHeight,
                left:resizeData.left,
                top:resizeData.top
            })
        }else{
            $(e.data.target).css({
                width:resizeData.width,
                height:resizeData.height,
                left:resizeData.left,
                top:resizeData.top
            })
        }
    }

    function onMouseDown(e){
        $.fn.resizable.isResizing = true;
        $.data(e.data.target, 'resizable').options.onStartResize.call(e.data.target, e);
        return false;
    }

    function onMouseMove(e){
        resize(e);
        var opts = $(e.data.target,'resizable').options;
        if(opts.onResize.call(e.data,target, e) != false){
            applyResize(e);
        }
        return false;
    }

    function onMouseUp(e){
        $.fn.resizable.isResizing = false;
        resize(e, true);
        applyResize(e);
        var opts = $.data(e.data.target, 'resizable').options;
        opts.onStopResize.call(e.data.target, e);
        $(document).unbind('.resizable');
        $('body').css('cursor','');
        return false;
    }

    function getDirection(e){
        var opts = $.data(e.data.target,'resizable').options;
        var $target = $(e.data.target);
        var dir = '';
        var offset = $target.offset();
        var outerWidth = $target.outerWidth();
        var outerHeight = $target.outerHeight();
        var edge = opts.edge;
        // 方向是在盒子的内部有5像素的偏移
        if(e.pageY > offset.top && e.pageY < offset.top + edge){
            dir += 'n';
        }else {
            if(e.pageY < offset.top + outerHeight && e.pageY > offset.top +outerHeight - edge){
                dir += 's';
            }
        }

        if(e.pageX > offset.left && e.pageX < e.pageX < offset.left + edge){
            dir += 'w';
        }else{
            if(e.pageX < offset.left + outerWidth && e.pageX > offset.left + outerWidth - edge){
                dir += 'e';
            }
        }
        var dirsArray = opts.handles.split(',');
        dirsArray = $.map(dirsArray, function(h){
            return $.trim(h).toLowerCase();
        });
        if($.inArray('all',dirsArray) >= 0 || $.inArray(dir, dirsArray) >= 0){
            return dir;
        }
        for(var i = 0; i < dir.length; i++){
            var index = $.inArray(dir.substr(i,1), dirsArray);
            if(index >= 0){
                return dirsArray[index];
            }
        }
        return '';
    }

    $.fn.resizable = function(options,params){
        if(typeof options == 'string'){
            return $.fn.resizable.methods[options](this,params);
        }
        return this.each(function(){
            var opts = null;
            var state = $.data(this, 'resizable');
            if(state){
                $(this).unbind('.resizable');
                opts = $.extend(state.options, options || {});
            }else{
                opts = $.extend({},$.fn.resizable.defaults, options || {});
                $.data(this, 'resizable', {options: opts});
            }
            if(opts.disabled == true){
                return;
            }
            $(this)
                .bind('mousemove.resizable', {target:this}, function(e){
                    if($.fn.resizable.isResizing){
                        return;
                    }
                    var dir = getDirection(e);
                    $(e.data.target).css('cursor',dir ? dir+'-resize':'')
                })
                .bind('mouseleave.resizable',{target:this},function(e){
                    $(e.data.target).css('cursor','');
                })
                .bind('mousedown.resizable',{target:this}, function(e){
                    var dir = getDirection(e);
                    if(dir == ''){
                        return;
                    }
                    var resizeData = {
                        target: e.data.target,
                        dir: dir,
                        startLeft: getValue('left'),
                        startTop: getValue('top'),
                        left: getValue('left'),
                        top: getValue('top'),
                        startX: e.pageX,
                        startY: e.pageY,
                        startWidth: $(e.data.target).outerWidth(),
                        startHeight: $(e.data.target).outerHeight(),
                        width:$(e.data.target).outerWidth(),
                        height:$(e.data.target).outerHeight(),
                        deltaWidth:$(e.data.target).outerWidth() - $(e.data.target).width(),
                        deltaHeight:$(e.data.target).outerHeight() - $(e.data.target).height()
                    };
                    $(document).bind('mousedown.resizable',resizeData, onMouseDown);
                    $(document).bind('mousemove.resizable',resizeData, onMouseMove);
                    $(document).bind('mouseup.resizeable',resizeData, onMouseUp);
                    $('body').css('cursor', dir+'-resize');

                    function getValue(css){
                        var val = parseInt($(e.data.target).css(css));
                        if(isNaN(val)){
                            return 0;
                        }else{
                            return val;
                        }
                    }
                })
        })
    };
    $.fn.resizable.methods = {
        options:function(){},
        enable:function(){},
        disable:function(){}
    };
    $.fn.resizable.defaults = {
        disabled: false,
        handles: 'n, e, s, w, ne, se, sw, nw, all',
        minWidth: 10,
        minHeight: 10,
        maxWidth: 10000,
        maxHeight: 10000,
        edge: 5,
        onStartResize:function(){},
        onResize:function(){},
        onStopResize:function(){}
    };
    $.fn.resizable.isResizing = false;
})(jQuery)