Динамически обновлять transform-origin повернутого элемента CSS3 при изменении ширины или высоты - PullRequest
12 голосов
/ 18 августа 2011

Исходя из Изменение ширины / высоты на повернутый CSS div вызывает перемещение вверх / влево Мне нужна помощь, чтобы решить поворот CSS и динамическую ширину / высоту.

Я понимаю transform-origin и думаю, что мне нужно динамически обновлять его, в то же время обновляется ширина или высота элемента.Меня интересует только техническое решение, а не кросс-браузерная хитрость, и поэтому демо использует только префикс -webkit.

HTML

<div id="wrap">
    <div id="rotated">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
    Width: <input id="width" type="range" min="20" max="400" step="1" value="200">
    Height: <input id="height" type="range" min="20" max="400" step="1" value="100">
    Angle: <input id="angle" type="range" min="0" max="360" step="1" value="0">
</div>

CSS

#rotated {
    background:lightblue;
    border:1px dotted #000;
    height:100px;
    width:200px;
    position:absolute;
    top:300px;
    left:100px;
    overflow:hidden;
}

#width, #height, #angle {
    display:block;
    margin-bottom:10px;
    width:200px;
}

JavaScript

$('#width').change(function() {
    $('#rotated').css({width:this.value + 'px'});
});

$('#height').change(function() {
    $('#rotated').css({height:this.value + 'px'});
});

$('#angle').change(function() {
    $('#rotated').css({'-webkit-transform': 'rotate(' + this.value + 'deg)'});
});

В вторая демонстрация , добавление CSS

#rotated {
    -webkit-transform-origin: 100px 50px;
    -webkit-transform: rotate(60deg);
}

и обновление value ползунка angle до 60

Angle: <input id="angle" type="range" min="0" max="360" step="1" value="60">

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

Я пробовал несколько вариантов (mousedown, mousemove, change), которые, как я думал, установили источник до того, как ширина / высота станетизменен, но <div> все еще смещает позицию.

$('#width, #height, #angle').change(function() {
    $('#rotated').css({'-webkit-transform-origin': $('#width').val()/2 + 'px' + $('#height').val()/2 + 'px'});
});

Я предполагаю, что jQuery применяет изменения CSS одновременно, тогда как я думаю, что источник нуждается в обновлении перед шириной/ изменение высоты.

По сути, я хочу, чтобы фигура всегда вращалась вокруг центральной точки и не двигалась при изменении ширины / высоты, если фигура уже повернута.

1 Ответ

14 голосов
/ 01 сентября 2011

FIDDLE DEMO !!!

Я первый хочу сказать вам, ПОЧЕМУ это происходит.Как вы можете видеть, когда ваш div не вращается, проблем нет.Так почему же происходит такое странное поведение?

Ответ: Потому что вы просите это ... Когда вы изменяете высоту или ширину, меняется div или 50% средней точки.и, таким образом, браузер размещает ваш div таким образом, чтобы были новые 50% неотвернутого DIV, а затем поворачивал его.

Решение состоит в том, чтобы обернуть повернутый div в другой div (скажем, "#обертка ") с фиксированной шириной и высотой и overflow:visible.

Затем вы помещаете #rotated внутри #wrapper и при изменении ширины или высоты, рассчитываете изменение и переводите #rotated div таким образом, чтобыон всегда находится в центре #wrapper (например, для ширины перевод - - (wrapWidth-newWidth) / 2).

Затем вы вращаете обертку и вуаля.

вот код, основанный на вашей настройке:

HTML:

<div id="wrap">
    Width: <input id="width" type="range" min="20" max="400" step="1" value="200">
    Height: <input id="height" type="range" min="20" max="400" step="1" value="100">
    Angle: <input id="angle" type="range" min="0" max="360" step="1" value="60">
</div>
<div id="rotateWrap">
    <div id="rotated">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.</div>
</div>

CSS :

#width, #height, #angle {
    position:relative;
    display:block;
    margin-bottom:10px;
    width:200px;
}

#rotateWrap{
    position:absolute;
    overflow:visible;
    height:100px;
    width:200px;
    top:200px;
    left:100px;
    outline:2px solid red;
    -webkit-transform-origin: 50% 50%;

}

#rotated {
    background:lightblue;
    position:relative;
    overflow:hidden;
    height:100px;
}

#wrap{
    position:absolute;
}

JAVASCRIPT

wPrev=$("#rotateWrap").width();
hPrev=$("#rotateWrap").height();

$('#width').mousedown(function(){
}).change(function() {
    $("#rotated").width(newW=$(this).val())
        .css({left: -(newW-wPrev)/2 + "px"});
});

$('#height').mousedown(function(){
}).change(function() {
    $("#rotated").height(newH=$(this).val())
        .css({top: -(newH-hPrev)/2 + "px"});
});


$('#angle').change(function() {
    $("#rotateWrap").css({"-webkit-transform":"rotate("+$(this).val()+"deg)"});
});
...