马黑黑 发表于 2022-4-7 22:32

太阳、地球与月球

本帖最后由 马黑黑 于 2022-4-7 22:34 编辑 <br /><br /><style>

#outer {
        margin: auto;
        width: 760px;
        height: 700px;
        background: #333;
        position: relative;
}

#outer div { position: absolute; border-radius: 50%; padding:0; }

#sun {
        --x: 50px;
        width: 80px;
        height: 80px;
        left: calc(50% - 40px);
        top: calc(50% - 40px);
        background: gold;
        box-shadow: 0 0 10px white;
        animation: orbit 40s linear infinite
}

#earth {
        --x: 200px;
        width: 40px;
        height: 40px;
        left: calc(50% - 20px);
        top: calc(50% - 20px);
        background: aqua;
        animation: orbit 36.5s linear infinite;
}

#moon {
        --x: 60px;
        width: 20px;
        height: 20px;
        left: calc(50% - 10px);
        top: calc(50% - 10px);
        background: white;
        animation: orbit 2.7s linear infinite;
}

@keyframes orbit {
        from { transform: rotate(0deg) translateY(var(--x)) rotate(0deg); }
        to { transform: rotate(360deg) translateY(var(--x)) rotate(-360deg); }
}

</style>

<div id="outer">
        <div id="sun">
                <div id="earth">
                        <div id="moon"></div>
                </div>
        </div>
</div>

马黑黑 发表于 2022-4-7 22:40

论坛对元素的padding有默认值,需要清除。

先看HTML结构:
<div id="outer">
        <div id="sun">
                <div id="earth">
                        <div id="moon"></div>
                </div>
        </div>
</div>外层是日地月的运动场所,是总父层,其下子层是日。日的子元素是地,地的子元素是月。

这个结构符合自然规律,为运动的设计提供便利。

马黑黑 发表于 2022-4-7 23:08

本帖最后由 马黑黑 于 2022-4-8 08:10 编辑

未有运动之前,日地月三者的位置如下图所示:



图片随意截取。我要说的是,太阳、地球、月球都居中,而且是绝对居中。怎么做到的?以太阳为例,它隶属于黑色“舞台”,是黑色背景div的子元素,position为绝对定位,left和top通过 calc 函数依据自身的宽高进行计算:

      width: 80px;
      height: 80px;
      left: calc(50% - 40px);
      top: calc(50% - 40px);


50%的left和top不能令其绝对居中,这是元素左上角基于父元素的xy坐标位置,要减去高宽的一半,太阳才会在舞台正中央。地球、月球使用同样的方法精准定位。之所以要精准定位,是为了配合动画的设计:动画设定运动对象以父元素的圆点为核心,以一定半径做圆周运动。

定位之后,还是以太阳为例,就可以以他所在的父元素的中心位置为运动圆点,按设定的半径围绕这个点旋转。地球绕太阳转,则始终以太阳的圆心为环绕核心;月球绕地球转同理,环绕的是地心。

我设计的动画只有一个,非常精妙:

@keyframes orbit {
      from { transform: rotate(0deg) translateY(var(--x)) rotate(0deg); }
      to { transform: rotate(360deg) translateY(var(--x)) rotate(-360deg); }
}


它不需要设置运动基点,通过transform的rotate和translateY来描述动画形态,from(从) 0deg、0deg 到(to) 360deg、-360deg的旋转变化,期间还有from(从) translateY(var(--x)) to(到) translateY(var(--x)) 的位移变化,是rotate和translateY/X的合作营造了对象运动的基点,无需额外设置transform-origin。这个动画将由太阳、地球和月球调用,它们的运动半径不一样,所以设定了一个CSS变量 var(--x),赋值在各个元素的CSS代码里。

这个动画设计不是很好理解,尤其是rotate旋转。旋转的动作,最开始都不做,所以是前后都是0deg,变化周期的最后旋转形态,前后是正负360deg,故此,整周是旋转了360deg,然后又抵消回来。结果是,如果太阳、地球、月亮上面有文字,文字都是站着的。但它的这一从0到360度的旋转,与translate相配合,就能令对象做环绕圆周运动。

说明一下,from和to的最后一个rotate主要是为了平衡运动对象的姿势,本例可以删掉。

马黑黑 发表于 2022-4-7 23:09

全部代码:<style>

#outer {
        margin: auto;
        width: 760px;
        height: 700px;
        background: #333;
        position: relative;
}

#outer div { position: absolute; border-radius: 50%; }

#sun {
        --x: 50px;
        width: 80px;
        height: 80px;
        left: calc(50% - 40px);
        top: calc(50% - 40px);
        background: gold;
        box-shadow: 0 0 10px white;
        animation: orbit 40s linear infinite
}

#earth {
        --x: 200px;
        width: 40px;
        height: 40px;
        left: calc(50% - 20px);
        top: calc(50% - 20px);
        background: aqua;
        animation: orbit 36.5s linear infinite;
}

#moon {
        --x: 60px;
        width: 20px;
        height: 20px;
        left: calc(50% - 10px);
        top: calc(50% - 10px);
        background: white;
        animation: orbit 2.7s linear infinite;
}

@keyframes orbit {
        from { transform: rotate(0deg) translateY(var(--x)) rotate(0deg); }
        to { transform: rotate(360deg) translateY(var(--x)) rotate(-360deg); }
}

</style>

<div id="outer">
        <div id="sun">
                <div id="earth">
                        <div id="moon"></div>
                </div>
        </div>
</div>

马黑黑 发表于 2022-4-7 23:11

在论坛,下面这句要加入 padding: 0; 以取消论坛默认的padding值

#outer div { position: absolute; border-radius: 50%; }

梦油 发表于 2022-4-8 11:09

嘿嘿朋友早晨好!学习、欣赏了。

转转 发表于 2022-4-8 11:27

一个字,棒;两个字,棒棒,三个字,棒棒棒

马黑黑 发表于 2022-4-8 12:17

转转 发表于 2022-4-8 11:27
一个字,棒;两个字,棒棒,三个字,棒棒棒

四个字:棒棒糖糖{:4_170:}

樵歌 发表于 2022-4-8 13:29

马术越来越有创意越精彩了{:4_199:}

红影 发表于 2022-4-8 13:31

马黑黑 发表于 2022-4-7 23:08
未有运动之前,日地月三者的位置如下图所示:




一个动画把三个运动一锅端了,这个厉害{:4_199:}

红影 发表于 2022-4-8 13:34

“结果是,如果太阳、地球、月亮上面有文字,文字都是站着的。”
不但把运动轨迹一个动画就解决了,而且连转动也同步,这个没法想象,太厉害了。{:4_187:}
要是一个个打开来写,不但麻烦,而且极容易弄得不同步。

红影 发表于 2022-4-8 13:36

对这个帖子感觉太惊奇了{:4_199:}
刚做完三个水滴的,一个个去弄水滴和涟漪,把我头都弄晕了。而这个的简洁高效实在是出乎意料{:5_116:}

马黑黑 发表于 2022-4-8 18:17

红影 发表于 2022-4-8 13:31
一个动画把三个运动一锅端了,这个厉害

动动脑子就成

马黑黑 发表于 2022-4-8 18:18

樵歌 发表于 2022-4-8 13:29
马术越来越有创意越精彩了

一般一般,班里倒数第三

马黑黑 发表于 2022-4-8 18:18

红影 发表于 2022-4-8 13:36
对这个帖子感觉太惊奇了
刚做完三个水滴的,一个个去弄水滴和涟漪,把我头都弄晕了。而这个的简 ...

磨炼的多了,就能写出出高效运行的代码

马黑黑 发表于 2022-4-8 18:19

红影 发表于 2022-4-8 13:34
“结果是,如果太阳、地球、月亮上面有文字,文字都是站着的。”
不但把运动轨迹一个动画就解决了,而且连 ...

那样会很繁琐

红影 发表于 2022-4-8 23:14

马黑黑 发表于 2022-4-8 18:17
动动脑子就成

动脑也需要对代码熟悉才动得出来呢{:4_173:}

红影 发表于 2022-4-8 23:14

马黑黑 发表于 2022-4-8 18:18
磨炼的多了,就能写出出高效运行的代码

嗯嗯,向着这个目标前进{:4_187:}

马黑黑 发表于 2022-4-8 23:16

红影 发表于 2022-4-8 23:14
嗯嗯,向着这个目标前进

自信是成功的最好助手

马黑黑 发表于 2022-4-8 23:16

红影 发表于 2022-4-8 23:14
动脑也需要对代码熟悉才动得出来呢

动了就能熟悉
页: [1] 2 3 4 5 6
查看完整版本: 太阳、地球与月球