Странность jQuery .position () при использовании атрибута поворота CSS3 - PullRequest
15 голосов
/ 22 февраля 2011

Я получаю абсолютно позиционированное положение повернутых элементов с помощью метода 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 ]

7 голосов
/ 22 февраля 2011
// 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, а затем снова считываю позицию, чтобы вычислить разницу (дельта), которая хранится в данных элемента ().

  2. Теперь я могу прочитать позицию с помощью пользовательского метода adjustedPosition (который определен выше).Этот метод считывает положение элемента, а затем вычитает значения дельты, хранящиеся внутри data () элемента.

  3. Чтобы записать позицию, просто используйте метод css(pos), например:обычно.

1 голос
/ 15 июля 2016

Была похожая проблема.Существует простое решение (не элегантное, но работающее):

  • установить текущий угол на 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;
    }
...