开发者

jQuery resizable problem on rotated elements

I am truing to do a jQuery UI resize on a div that is rotated with 77deg. The result is totally uncontrollable.

To 开发者_Python百科replicate this please:

  • Go to http://jqueryui.com/demos/resizable/
  • Click on inspect with the Chrome/Mozila console the gray resizable element should be id="resizable".
  • Apply -webkit-transform: rotate(77deg) or -moz-transform: rotate(77deg)
  • Now try to resize that element

Is there a way to fix this? Thank you


Change the following functions in JQuery-ui resizable plugin

_mouseStart: function(event) {

var curleft, curtop, cursor,
o = this.options,
iniPos = this.element.position(),
el = this.element;

this.resizing = true;

// bugfix for http://dev.jquery.com/ticket/1749
if ( (/absolute/).test( el.css("position") ) ) {
    el.css({ position: "absolute", top: el.css("top"), left: el.css("left") });
} else if (el.is(".ui-draggable")) {
    el.css({ position: "absolute", top: iniPos.top, left: iniPos.left });
}

this._renderProxy();

curleft = num(this.helper.css("left"));
curtop = num(this.helper.css("top"));

if (o.containment) {
    curleft += $(o.containment).scrollLeft() || 0;
    curtop += $(o.containment).scrollTop() || 0;
}

//Store needed variables
this.offset = this.helper.offset();
this.position = { left: curleft, top: curtop };
this.size = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
this.originalSize = this._helper ? { width: el.outerWidth(), height: el.outerHeight() } : { width: el.width(), height: el.height() };
this.originalPosition = { left: curleft, top: curtop };
this.sizeDiff = { width: el.outerWidth() - el.width(), height: el.outerHeight() - el.height() };
this.originalMousePosition = { left: event.pageX, top: event.pageY };
var angle=0;
var matrix = $(el).css("-webkit-transform") ||
$(el).css("-moz-transform")    ||
$(el).css("-ms-transform")     ||
$(el).css("-o-transform")      ||
$(el).css("transform");
if(matrix !== 'none') {
    var values = matrix.split('(')[1].split(')')[0].split(',');
    var a = values[0];
    var b = values[1];
    var angle = Math.round(Math.atan2(b, a) * (180/Math.PI));
} 
else { 
    var angle = 0; 
}
if(angle < 0) 
    angle +=360;
this.angle = angle;
thi.rad = this.angle*Math.PI/180;
//Aspect Ratio
this.aspectRatio = (typeof o.aspectRatio === "number") ? o.aspectRatio : ((this.originalSize.width / this.originalSize.height) || 1);

cursor = $(el).find(".ui-resizable-" + this.axis).css("cursor");

$("body").css("cursor", cursor === "auto" ? this.axis + "-resize" : cursor);
var cornerItem = 0;
if(this.axis == 'ne')
    cornerItem = 3;
else if(this.axis == 'nw')
    cornerItem = 2;
else if(this.axis == 'sw')
    cornerItem = 1;
else if(this.axis == 'se')
    cornerItem = 0;
this.cornerItem = cornerItem;
var t1 = this.position.top;
var l1 = this.position.left;
var w1 = this.size.width;
var h1 = this.size.height;
var midX = l1 + w1/2;
var midY = t1 + h1/2;
var cornersX = [l1-midX, l1+w1-midX , l1+w1-midX, l1-midX];
var cornersY = [t1-midY, midY-(t1+h1), midY-t1, t1+h1-midY];
var newX = 1e10;
var newY = 1e10;
for (var i=0; i<4; i++) {
    if(i == this.cornerItem){
        this.prevX = cornersX[i]*Math.cos(this.rad) - cornersY[i]*Math.sin(this.rad) + midX;
        this.prevY = cornersX[i]*Math.sin(this.rad) + cornersY[i]*Math.cos(this.rad) + midY;
    }
}
el.addClass("ui-resizable-resizing");
this._propagate("start", event);
return true;
},

_mouseDrag: function(event) {
    //Increase performance, avoid regex
    var data,
    el = this.helper, props = {},
    smp = this.originalMousePosition,
    a = this.axis,
    prevTop = this.position.top,
    prevLeft = this.position.left,
    prevWidth = this.size.width,
    prevHeight = this.size.height;
    dx1 = (event.pageX-smp.left)||0,
    dy1 = (event.pageY-smp.top)||0;
    dx = ((dx1)*Math.cos(this.rad) + (dy1)*Math.sin(this.rad));
    dy =((dx1)*Math.sin(this.rad) - (dy1)*Math.cos(this.rad));
    el = this.element;
    var t1 = this.position.top;
    var l1 = this.position.left;
    var w1 = this.size.width;
    var h1 = this.size.height;
    var midX = l1 + w1/2;
    var midY = t1 + h1/2;
    var cornersX = [l1-midX, l1+w1-midX , l1+w1-midX, l1-midX];
    var cornersY = [t1-midY, midY-(t1+h1), midY-t1, t1+h1-midY];
    var newX = 1e10 , newY = 1e10 , curX =0, curY=0;
    for (var i=0; i<4; i++) {   
        if(i == this.cornerItem){
            newX = cornersX[i]*Math.cos(this.rad) - cornersY[i]*Math.sin(this.rad) + midX;
            newY = cornersX[i]*Math.sin(this.rad) + cornersY[i]*Math.cos(this.rad) + midY;
            curX = newX - this.prevX;
            curY = newY - this.prevY;
        }
    }
    trigger = this._change[a];
    if (!trigger) {
        return false;
    }

    // Calculate the attrs that will be change
    data = trigger.apply(this, [event, dx, dy]);

    // Put this in the mouseDrag handler since the user can start pressing shift while resizing
    this._updateVirtualBoundaries(event.shiftKey);
    if (this._aspectRatio || event.shiftKey) {
        data = this._updateRatio(data, event);
    }

    data = this._respectSize(data, event);

    this._updateCache(data);

    // plugins callbacks need to be called first
    this._propagate("resize", event);

    this.position.left = this.position.left - curX;
    this.position.top  = this.position.top - curY;
    if (this.position.top !== prevTop) {
        props.top = this.position.top + "px";
    }
    if (this.position.left !== prevLeft) {
        props.left = this.position.left + "px";
    }
    if (this.size.width !== prevWidth) {
        props.width = this.size.width + "px";
    }
    if (this.size.height !== prevHeight) {
        props.height = this.size.height + "px";
    }
    el.css(props);

    if (!this._helper && this._proportionallyResizeElements.length) {
        this._proportionallyResize();
    }

    // Call the user callback if the element was resized
    if ( ! $.isEmptyObject(props) ) {
        this._trigger("resize", event, this.ui());
    }


    return false;
},

_mouseStop: function(event) {

    this.resizing = false;
    var pr, ista, soffseth, soffsetw, s, left, top,
        o = this.options, that = this;

    if(this._helper) {

        pr = this._proportionallyResizeElements;
        ista = pr.length && (/textarea/i).test(pr[0].nodeName);
        soffseth = ista && $.ui.hasScroll(pr[0], "left") /* TODO - jump height */ ? 0 : that.sizeDiff.height;
        soffsetw = ista ? 0 : that.sizeDiff.width;

        s = { width: (that.helper.width()  - soffsetw), height: (that.helper.height() - soffseth) };
        left = (parseInt(that.element.css("left"), 10) + (that.position.left - that.originalPosition.left)) || null;
        top = (parseInt(that.element.css("top"), 10) + (that.position.top - that.originalPosition.top)) || null;

        if (!o.animate) {
            this.element.css($.extend(s, { top: top, left: left }));
        }

        that.helper.height(that.size.height);
        that.helper.width(that.size.width);

        if (this._helper && !o.animate) {
            this._proportionallyResize();
        }

    }

    $("body").css("cursor", "auto");
    this.element.removeClass("ui-resizable-resizing");

    this._propagate("stop", event);

    if (this._helper) {
        this.helper.remove();
    }
    return false;

},
_change: {
    e: function(event, dx, dy) {
        var cs = this.originalSize, sp = this.originalPosition,elwidth, elheight,lleft=0, ttop =0;
        if(this.axis == 'se'){
            elwidth = this.originalSize.width + dx;
            elheight = this.originalSize.height - dy;
            return { height: elheight , width: elwidth };
        }
        else{
            elwidth = this.originalSize.width + dx;
            elheight = this.originalSize.height + dy;
            return { height: elheight , width: elwidth };
        }
    },
    w: function(event, dx, dy) {
        var cs = this.originalSize, sp = this.originalPosition,elwidth, elheight,lleft=0, ttop =0;
        if(this.axis == 'nw'){
            elwidth = cs.width - dx;
            elheight = this.originalSize.height + dy;
            return { height: elheight , width: elwidth };

        }
        else{
            elwidth = cs.width - dx;
            elheight = this.originalSize.height - dy;
            return { height: elheight , width: elwidth };
        }
    },
    n: function(event, dx, dy) {
        var cs = this.originalSize, sp = this.originalPosition,elwidth, elheight,lleft=0, ttop =0;
        if(this.axis == 'nw'){
            elwidth = this.originalSize.width - dx;
            elheight = cs.height + dy;
            return { height: elheight , width: elwidth };
        }
        else{
            elwidth = this.originalSize.width + dx;
            elheight = cs.height + dy;
            return { height: elheight , width: elwidth };
        }               
    },
    s: function(event, dx, dy) {
        var cs = this.originalSize, sp = this.originalPosition,elwidth, elheight,lleft=0, ttop =0;
        if(this.axis == 'se'){
            elwidth = this.originalSize.width + dx;
            elheight = this.originalSize.height - dy;
            return { height: elheight , width: elwidth };
        }
        else {
            elwidth = this.originalSize.width - dx;
            elheight = this.originalSize.height - dy;
            return { height: elheight , width: elwidth };
        }
    },
    se: function(event, dx, dy) {
        return $.extend(this._change.s.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
    },
    sw: function(event, dx, dy) {
        return $.extend(this._change.s.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
    },
    ne: function(event, dx, dy) {
        return $.extend(this._change.n.apply(this, arguments), this._change.e.apply(this, [event, dx, dy]));
    },
    nw: function(event, dx, dy) {
        return $.extend(this._change.n.apply(this, arguments), this._change.w.apply(this, [event, dx, dy]));
    }
},


The mouse movements for the handles have not been rotated with the element.

If you select the right handle (which will be near the bottom if you use rotate(77deg), moving it left will shrink the width of the element, (which will appear similar to the height due to the rotation.)

To adjust the element size relative to its center, you will most probably have to update the code that resizes the element by vectoring the mouse movements to adjust the width/height.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜