JQuery.position() странность при использовании атрибута поворота CSS3
Я получаю абсолютно позиционированное положение позиций с помощью метода 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/
Ответы
Ответ 1
// 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);
});
Live demo: http://jsfiddle.net/2gVL4/4/
Итак, что здесь происходит:
-
Код CSS, который вращает изображение, хранится внутри специального класса CSS. Я делаю это, потому что хочу прочитать исходное положение изображения (перед вращением). Когда я прочитаю эту исходную позицию, я применяю класс .rot
, а затем снова прочитаю позицию для вычисления разности (дельта), которая хранится внутри данных элемента().
-
Теперь я могу прочитать позицию с помощью настраиваемого метода adjustedPosition
(который определен выше). Этот метод будет читать позицию элемента, а затем вычесть значения дельта, хранящиеся внутри данных() элемента.
-
Чтобы записать позицию, просто используйте метод css(pos)
, как обычно.
Ответ 2
Была аналогичная проблема. Существует простое решение (не элегантное, но работающее):
- установить текущий угол в 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;
}