修改宽度或高度时动态更新 CSS3 旋转元素的变换原点

发布于 2024-11-30 00:45:32 字数 2589 浏览 1 评论 0原文

更改宽度/高度CSS 旋转 div 触发顶部/左侧重新定位 我需要一些帮助来解决 CSS 旋转和动态宽度/高度。

我理解 transform-origin 和我认为我需要在更新元素的宽度或高度的同时动态更新它。我只对技术解决方案感兴趣,而不是任何跨浏览器的聪明才智,因此 演示< /strong> 仅使用 -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);
}

并更新 通过滑块修改宽度/高度时,将角度滑块的设置为60

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

会产生正确的结果,因为元素会在<代码>x, y 尺寸,无需移动位置。但是,现在不再围绕所需的(中心点)原点旋转元素。

我尝试了一些变体(mousedown、mousemove、change),我认为会在修改宽度/高度之前设置原点,但

仍在移动位置。

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

我假设 jQuery 同时应用 CSS 更改,而我认为源需要在宽度/高度更改之前更新。

基本上,我希望形状始终围绕中心点旋转,并且如果形状已经旋转,则在修改宽度/高度时不要移动。

Following on from Changing width/height to a CSS rotated div triggers top/left reposition I need some help to solve a CSS rotation and dynamic width/height.

I understand transform-origin and think I need to dynamically update it at the same time the width or height of the element is updated. I'm only interested in the technical solution, rather than any cross-browser cleverness and hence the demo only uses the -webkit prefix.

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)'});
});

In the second demo, adding the CSS

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

and updating the value of the angle slider to 60

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

produces the correct result when modifying the width/height via the sliders, in that the element grows and shrinks in the x, y dimensions without moving position. However, rotating the element now no longer around the desired (centre point) origin.

I have tried some variations (mousedown, mousemove, change) on this which I thought would set the origin before the width/height is modified but the <div> is still shifting position.

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

I assume jQuery is applying the CSS changes at the same time, whereas I think that the origin needs updating before the width/height change.

Basically I want the shape to always rotate about the center point and to not move when modifying the width/height if the shape is already rotated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

银河中√捞星星 2024-12-07 00:45:32

FIDDLE 演示!!!

我首先要告诉你为什么会发生这种情况。正如您所看到的,当您的 div 不旋转时没有问题。那么为什么会出现这种奇怪的行为呢?

答案:因为你要求它...当你改变高度或宽度时,div 的 50% 或中点正在改变。因此,浏览器将您的 div 以未旋转 DIV 的新 50% 的方式放置,然后旋转它。

解决方案是将旋转的 div 包装在另一个具有固定宽度和高度以及 overflow:visible 的 div 中(假设为“#wrapper”)。

然后将 #rotated 放置在 #wrapper 内部,并在宽度或高度发生变化时,计算变化并以始终位于 #wrapper 中心的方式平移 #rotated div(例如,对于宽度,平移为 - (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)"});
});

FIDDLE DEMO!!!

I'm first ganna tell you WHY this is happening. As you can see when your div isn't rotated there is no problem. So why is this strange behaviour happening when it is?

Answer: Because you're asking it to... As you change the height or width, the div's 50%, or middle point is changing. and thus, the browser places your div in a way where the new 50% of the unrotated DIV would be, and then rotates it.

The solution is to wrap the rotated div in another div (lets say "#wrapper") with a fixed width and height and overflow:visible.

Then you place the #rotated inside the #wrapper and on width or height change, calculate the change and translate the #rotated div in a way where it is always in the center of #wrapper ( for example, for width,the translation is -(wrapWidth-newWidth)/2 ).

Then you rotate the wrapper and voila.

here's the code based on your setup:

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)"});
});
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文