使用CSS3 rotate属性时jQuery .position()奇怪

时间:2011-02-22 13:42:59

标签: javascript jquery css css3 css-position

我通过jQuery .position()方法获得绝对定位的旋转元素位置,然后使用jQuery .css(pos)设置与位置相关的属性(顶部,左侧),其中pos是返回的数据按.position()。我认为它会将元素留在它的位置,但元素的位置正在发生变化。

如何使用设置旋转元素位置,以便按预期放置?也许有一个系数取决于改变位置的角度?

我正在使用Google Chrome v.9,Windows XP进行测试。

HTML

<div id="container">
  <div id="element"> 
    <img src="http://t0.gstatic.com/images?q=tbn:ANd9GcS0Fawya9MVMez80ZusMVtk_4-ScKCIy6J_fg84oZ37GzKaJXU74Ma0vENc"/>
  </div>
</div> 

CSS

#container {
    position: relative;   
    border: 1px solid #999;
    padding: 5px;
    height: 300px;
    width:300px;
}    
#element {
    position: absolute;
    top:50px;
    left: 60px;
    width: auto;
    border: 1px solid #999;
    padding: 5px;
    -webkit-transform: rotate(45deg);
    -moz-transform: rotate(45deg);
}

JS

$(document).ready(function(){
    var $el = $('#element'),
    // getting position    
        pos = $el.position();
    alert(pos.left + '/' + pos.top);
    // alerts 37/11

    // setting css position attributes equal to pos
    $el.css(pos);
    // re-getting position
    pos = $el.position();
    alert(pos.left + '/' + pos.top);
    // alerts 14/-28
});    

查看http://jsfiddle.net/Antaranian/2gVL4/

2 个答案:

答案 0 :(得分:7)

// Needed to read the "real" position
$.fn.adjustedPosition = function() {
    var p = $(this).position();
    return {
        left: p.left - this.data('dx'),
        top: p.top - this.data('dy')
    }
};

$(function() { 

    var img = $('img'),
        pos;

    // Calculate the delta
    img.each(function() {
        var po = $(this).position(), // original position
            pr = $(this).addClass('rot').position(); // rotated position

        $(this).data({
            dx: pr.left - po.left, // delta X
            dy: pr.top - po.top // delta Y
        });
    });

    // Read the position
    pos = img.adjustedPosition();    
    alert(pos.left + '/' + pos.top);     

    // Write the position
    img.css(pos);

    // Read the position again
    pos = img.adjustedPosition();    
    alert(pos.left + '/' + pos.top);

});

现场演示: http://jsfiddle.net/2gVL4/4/

那么这里发生了什么:

  1. 旋转图像的CSS代码存储在一个特殊的CSS类中。我这样做是因为我想读取图像的原始位置(旋转前)。一旦我读到原始位置,我就应用.rot类,然后再次读取位置以计算差值(delta),它存储在元素的数据()中。

  2. 现在,我可以通过自定义方法adjustedPosition(上面定义)来读取位置。此方法将读取元素的位置,然后减去存储在元素的data()内的delta值。

  3. 要编写位置,只需正常使用css(pos)方法即可。

答案 1 :(得分:1)

有类似的问题。有一个简单的解决方案(不优雅,但工作):

  • 将当前角度设置为0
  • 读取X / Y位置
  • 将角度恢复为其值

    var temp = $(this).position();
    temp.angle = getRotationDegrees( $(this) );            // remember current angle
    rotateObject($(this), 0);                              // set angle to 0
    temp.left = Math.round($(this).position().left);       // proper value
    temp.top = Math.round($(this).position().top);         // proper value
    
    // revert back the angle
    rotateObject($(this), temp.angle); 
    

使用过的功能:

    function rotateObject(obj, angle) {
        obj.css({ '-webkit-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ '-moz-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ '-ms-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ 'msTransform': 'rotate(' + angle + 'deg)'});
        obj.css({ '-o-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ '-sand-transform': 'rotate(' + angle + 'deg)'});
        obj.css({ 'transform': 'rotate(' + angle + 'deg)'});
    }

    function getRotationDegrees(obj) {
        var matrix = obj.css("-webkit-transform") ||
        obj.css("-moz-transform")    ||
        obj.css("-ms-transform")     ||
        obj.css("-o-transform")      ||
        obj.css("transform");
        if(matrix !== 'none') {
            var tr;
            if (tr = matrix.match('matrix\\((.*)\\)')) {
                tr = tr[1].split(',');
                if(typeof tr[0] != 'undefined' && typeof tr[1] != 'undefined') {
                    var angle = Math.round(Math.atan2(tr[1], tr[0]) * (180/Math.PI));
                }else{
                    var angle = 0; 
                }
            }else if(tr = matrix.match('rotate\\((.*)deg\\)')){
                var angle = parseInt(tr[1]); 
            }
        } else { var angle = 0; }
        return (angle < 0) ? angle + 360 : angle;
    }