元素A围绕元素B旋转时的偏移量设置问题

元素A围绕元素B旋转时的偏移量设置问题

希望小方块绕着大方块的中心做地月环绕

http://img1.sycdn.imooc.com//climg/6112914809149ec410840470.jpg

现在这段代码是可以实现效果,但是其中transform-origin的值和translate偏移量是反复调出来的,完全没摸到规律。

比如我设置了translate(400px, 0),小方块应该向右移动400,但实际上这距离没有400,transform-origin旋转的圆心往左偏移多少,最后调试出来的-135px也不知道为什么是这么多。


假设我希望小方块的中心距离大方块中心100px,改变rotate的值能看到小方块围绕大方块地月环绕运动,transform-origin和translate应该设为多少?是怎么算出来的?


HTML:

<body>
<div class="flag">
<div class="square big"></div>
<div class="square small"></div>
</div>
</body>

CSS:

<style>
* {
margin: 0;
padding: 0;
}

.flag {
width: 500px;
height: 300px;
background-color: #ddd;
position: relative;
}

.flag .square {
width: 50px;
height: 50px;
position: absolute;
top: 100px;
left: 100px;
}

.flag .big {
background-color: darkred;
}

.flag .small {
background-color: deeppink;
transform: scale(0.4) translate(400px, 0) rotate(45deg);
transform-origin: -135px 25px;
}
</style>


正在回答

登陆购买课程后可参与讨论,去登陆

3回答

同学你好,截图中的代码表示匹配属于父元素box4的特定类型的第3个子元素p标签,由于“我是3号”所在p标签,属于box盒子下的第三个子元素p标签,所以会被选中。

http://img1.sycdn.imooc.com//climg/61138ed40918db4f12640586.jpg

而粘贴的代码中,.flag .sub-star:nth-of-type(1) 确实表示的应该是选中flag下的第一个类名为sub-star的子元素,但是由于设置的类名,并不能排除选择的是div还是p等其他类型的标签,所以解析时,第一个div元素会影响选择的顺序。

可以调整下代码测试理解下,如下:

将第一个div标签改成p标签

http://img1.sycdn.imooc.com//climg/611391bd0905f02b21500914.jpg

此时解析,就会排除第一个子元素p标签,正确选择到第一个类名为sub-star的元素,如下:

http://img1.sycdn.imooc.com//climg/61139228092731a335800920.jpg

同学可以将这个现象作为特殊情况,特殊记忆一下,实际开发中,更推荐给元素设置不同的类名来设置不同的样式即可。

祝学习愉快~

好帮手慕慕子 2021-08-11 14:28:02

同学你好,对于你的问题解答如下:

1、因为缩放后,元素改变大小,导致视觉上位置发生改变移除了屏幕。

2、同学这个560px是设置的left属性值,并不是偏移量translate的值。同学不用多余纠结,计算可能会存在误差,重点是要通过控制台慢慢调试值来实现效果。

3、:nth-of-type(n) 选择器匹配属于父元素的特定类型的第n个子元素, 因为flag下第一个元素是main-star,第一个sub-start元素是作为flag下的第二个子元素的,所以要选择第一个sub-start元素,应该将序号设置为2

4、同学这种实现效果的思路也是可以的,但是代码有些复杂,可以参考如下思路简化书写,示例:

单个五角星实现思路如下:

http://img1.sycdn.imooc.com//climg/60fb71e4091785f906770552.jpg

效果:
http://img1.sycdn.imooc.com//climg/60fb71f1095f60a402190151.jpg

然后通过伪元素,再添加一个三角形:

http://img1.sycdn.imooc.com//climg/60fb72540904a33205690332.jpg

效果:
http://img1.sycdn.imooc.com//climg/60fb725f096c2f8502720144.jpg

然后通过旋转、偏移值等方式让它们重叠在一起:

http://img1.sycdn.imooc.com//climg/60fb72b109deea3805800448.jpg

效果:

http://img1.sycdn.imooc.com//climg/60fb72bc09b09d1002370157.jpg

添加伪元素,再添加一个三角形:

http://img1.sycdn.imooc.com//climg/60fb72e709fc7b7105650332.jpg

效果:
http://img1.sycdn.imooc.com//climg/60fb72f309e1752502710161.jpg

旋转并调整偏移值:

http://img1.sycdn.imooc.com//climg/60fb7320090d606605660426.jpg

这样一个五角星就布局完成了:

http://img1.sycdn.imooc.com//climg/60fb732c091448a702090170.jpg

可以结合如下示例代码测试理解

<!DOCTYPE HTML>
<html>
<head>
<meta charset="utf-8">
<title></title>
<style type="text/css">
/* 设置红色背景盒子样式 */
.box1 {
width: 300px;
height: 200px;
background-color: red;
}
.star {
width: 0;
height: 0;
border-top: 40px solid yellow;
border-left: 65px solid transparent;
border-right: 65px solid transparent;
margin-top: 100px;
position: absolute;
}
/* 统一设置伪元素相同的样式 */
.star::before,
.star::after {
content: "";
display: block;
width: 0;
height: 0;
border-top: 40px solid yellow;
border-left: 65px solid transparent;
border-right: 65px solid transparent;
position: absolute;
top: -40px;
left: -65px;
}
/* 单独设置伪元素的旋转角度 */
.star::before {
transform: rotate(-75deg);
}
.star::after {
transform: rotate(-146deg);
}
/* 单独设置每颗五角星的缩放,位移,以及旋转角度 */
.star1 {
transform: scale(0.5) translate(-40px, -130px);
}
.star2 {
transform: scale(0.2) translate(120px, -520px) rotate(30deg);
}
.star3 {
transform: scale(0.2) translate(190px, -380px) rotate(30deg);
}
.star4 {
transform: scale(0.2) translate(200px, -240px) rotate(30deg);
}
.star5 {
transform: scale(0.2) translate(120px, -120px) rotate(30deg);
}
</style>
</head>
<body>
<!-- 此处写代码 -->
<div class="box1">
<div class="star star1"></div>
<div class="star star2"></div>
<div class="star star3"></div>
<div class="star star4"></div>
<div class="star star5"></div>
</div>
</body>
</html>

具体的旋转角度和移动等距离,同学不用太纠结,可以通过控制台慢慢调整,实现效果美观即可。

祝学习愉快~

  • 提问者 大天使凉冰 #1

    关于nth-child()和nth-of-type()


    视频里不是说nth-child是“选择第3个子元素,且第3个子元素是p时才被选择”,这个例子中第3个元素是h3不是p,所以没被选择

    nth-of-type是“选择第3个为p的元素”


    那我使用.sub-star:nth-of-type(1),不是应该可以选中第1个.sub-star吗,虽然.sub-star前面还有别的元素



    2021-08-11 15:58:19
  • 提问者 大天使凉冰 #2

    前面截图没放成功



    2021-08-11 16:03:50
  • 提问者 大天使凉冰 #3

    如果我用.sub-star:nth-child(1),因为前面有其他元素,选择是不对的

    但是我用.sub-star:nth-of-type(1),应该是对的啊


    http://img1.sycdn.imooc.com//climg/611384f509ca643915620712.jpg

    http://img1.sycdn.imooc.com//climg/6113854609c84cf215720712.jpg

    2021-08-11 16:07:39
好帮手慕慕子 2021-08-11 11:34:31

同学你好,对于你的问题解答如下:

1、因为small元素设置了缩放,导致small元素设置x轴偏移400px,而实际并没有偏移这个值。可以去掉缩放查看下效果,设置x轴偏移400px,实际偏移的值就是400px,示例

http://img1.sycdn.imooc.com//climg/611330f909860eaa38360824.jpg

2、transform-origin主要是改变一个元素变形的原点,不会影响元素的偏移量translate的。

3、“假设我希望小方块的中心距离大方块中心100px,改变rotate的值能看到小方块围绕大方块地月环绕运动”这个效果具体参考如下步骤:

(1)由于将小方块整体缩放了0.4, 那么小方块显示的宽高为20px。

(2)大小方块的中心距离为100px, 那么考虑到缩放的影响,所以需要将偏移量设置为250px = 100px / 0.4,示例:

http://img1.sycdn.imooc.com//climg/61133854096cd0f234720610.jpg

(3)由于设置缩放,元素属于变形了,所以(1)(2)步骤的基础上,设置transfor-origin属性值后,会改变元素变形了原点,导致元素缩放位置发生变化,所以无法准确的来计算具体的transform-origin的属性值,推荐同学在控制台,通过慢慢调试这几个属性值来实现效果。


祝学习愉快~

  • 提问者 大天使凉冰 #1

    五星红旗那个作业,还有2个问题

    问题1.

    为了避免小五角星缩放后再绕大五角星旋转会让几个偏移的值不好设,我把基础五角星的设成小五角星的大小,然后大五角星放大2.5倍,放大之后,大五角星移动出屏幕外了,必须设非常大的left的值才能挪回来

    http://img1.sycdn.imooc.com//climg/61135ce709a96be604190361.jpg

    1.1. 我之前并未给.star设置过top或left值,为什么它会再加了缩放之后偏移出屏幕了呢?

    1.2. 按照前面老师你说的缩放倍数和偏移距离的公式 设置的偏移量 = 期望的偏移量 / 缩放倍数,假设我希望大五角星有向下向右的偏移80px左右,但缩放倍数现在是2.5,设置的偏移量应该很小才是,为什么反而要设560px这么大呢?


    问题2. 

    4个小五角星命名为.sub-star,我分别用.sub-star:nth-of-type()的为小五角星添加旋转

    http://img1.sycdn.imooc.com//climg/61135f44097980c004720352.jpg


    但是第一个sub-star对应的样式是.sub-star:nth-of-type(2)

    nth-of-type(1)不是从子元素序列中找出第1个类名为.sub-star的元素吗,用的又不是nth-child(1),为什么还是对应到.sub-star:nth-of-type(2)上去了呢?


    http://img1.sycdn.imooc.com//climg/61135f1109dc146504460390.jpg


    代码:

    <!DOCTYPE html>
    <html lang="en">

    <head>
        <meta charset="UTF-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>五星紅旗</title>
        <style>
            * {
                margin: 0;
                padding: 0;
            }
            
            .flag {
                width: 600px;
                height: 400px;
                background-color: red;
                position: relative;
            }
            /* 五角星 */
            
            .star {
                position: relative;
            }
            /* 五角星的五个角 */
            
            .star .angle {
                width: 0;
                height: 0;
                border: 4px solid transparent;
                border-bottom: 12px solid yellow;
                transform-origin: 4px 16px;
                position: absolute;
                top: 0;
                left: 0;
            }
            
            .star .angle:nth-child(2) {
                transform: rotate(72deg);
            }
            
            .star .angle:nth-child(3) {
                transform: rotate(144deg);
            }
            
            .star .angle:nth-child(4) {
                transform: rotate(216deg);
            }
            
            .star .angle:nth-child(5) {
                transform: rotate(288deg);
            }
            /* 大五角星 */
            
            .flag .main-star {
                top: 80px;
                left: 560px;
                transform: scale(2.5);
            }
            /* 小五角星 */
            
            .flag .sub-star {
                position: absolute;
                top: 104px;
                left: 116px;
                transform: translate(80px, 0);
                transform-origin: -75px 0;
            }
            
            .flag .sub-star:nth-of-type(1) {
                transform: translate(80px, 0) rotate(-36deg);
            }
            
            .flag .sub-star:nth-of-type(2) {
                transform: translate(80px, 0) rotate(-12deg);
            }
            
            .flag .sub-star:nth-of-type(3) {
                transform: translate(80px, 0) rotate(12deg);
            }
            
            .flag .sub-star:nth-of-type(4) {
                transform: translate(80px, 0) rotate(36deg);
            }
        </style>
    </head>

    <body>
        <div class="flag">
            <div class="star main-star">
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
            </div>
            <div class="star sub-star">
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
            </div>
            <div class="star sub-star">
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
            </div>
            <div class="star sub-star">
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
            </div>
            <div class="star sub-star">
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
                <div class="angle"></div>
            </div>
        </div>
    </body>

    </html>


    2021-08-11 13:32:43
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
请稍等 ...
意见反馈 帮助中心 APP下载
官方微信

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师