马黑黑 发表于 2024-6-27 12:20

CSS关键帧动画之圆周运动演示

<style>
#mydiv {
        margin: 30px auto;
        width: 400px;
        height: 400px;
        border: 2px dotted lightblue;
        position: relative;
}
#mydiv::after {
        position: absolute;
        content: '';
        inset: 0;
        border: 1px dashed plum;
        border-radius: 50%;
}
.ball {
        position: absolute;
        box-sizing: border-box;
        left: calc(50% - 20px);
        top: calc(50% - 20px);
        width: 40px;
        height: 40px;
        background: linear-gradient(lightgreen, purple);
        border-radius: 50%;
}
.ball:nth-of-type(1) {
        background: silver;
}
.ball:nth-of-type(2) {
        transition: .4s;
        transform: rotate(var(--deg)) translateY(var(--distance));
        --deg: 0deg;
        --distance: 200px;
}
.wrap { margin: 30px auto; width: 400px; }
.msg { font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; }
@keyframes move { to { transform: rotate(calc(var(--deg) + 360deg)) translateY(var(--distance)); } }
</style>

<p>元素的 transform 属性,若 rotate 与 translate 配合使用,rotate(deg) 在前、translate(distance) 随后,则会令元素以自己为中心、以 distance 为半径,在旋转 deg 个角度的同时做圆周运动。以下,彩球初始位置在银色圆球处,现在它在虚线方框的正下方,因为它旋转了0度、沿Y轴平移了200px,即 transform: rotate(0deg) translateY(200px)。可以改变彩球的旋转角度和平移半径,也可以让小球执行关键帧动画,以便查看和感受 transform 属性旋转与平移配套使用的效果:</p>
<div id="mydiv">
        <div class="ball"></div>
        <div id="ball" class="ball"></div>
</div>
<div class="wrap">
        <p><output id="msg1" class="msg">transform: rotate(0) translateY(0);</output></p>
        <p>
                <label for="rDeg">旋转角度:</label>
                <input id="rDeg" type="range" max="360" min="-360" value="0" />
                <output id="sDeg">0deg</output>
        </p>
        <p>
                <label for="rDistance">移动半径:</label>
                <input id="rDistance" type="range" max="200" min="0" value="200" />
                <output id="sDistance">200px</output>
        </p>
        <p>
                <label for="rAuto">运行关键帧动画</label>
                <input id="rAuto" type="checkbox" />
        </p>
        <pre id="msg2" class="msg"></pre>
</div>

<script>
rDeg.oninput = rDistance.oninput = () => {
        sDeg.value = rDeg.value + 'deg';
        sDistance.value = rDistance.value + 'px';
        ball.style.setProperty('--deg', rDeg.value + 'deg');
        ball.style.setProperty('--distance', rDistance.value + 'px');
        msg1.value = `transform: rotate(${sDeg.value}) translateY(${sDistance.value});`;
};

rAuto.onclick = () => {
        if(!rAuto.checked) return;
        rDeg.disabled = rDistance.disabled = true;
        ball.style.animation = 'move 6s forwards';
        msg2.textContent = `
@keframes move {
    from { transform: rotate(${sDeg.value}) translateY(${sDistance.value}); }
    to { transform: rotate(${parseInt(sDeg.value) + 360}deg) translateY(${sDistance.value}); }
}`;
};

ball.onanimationend = () => {
        rDeg.disabled = rDistance.disabled = false;
        rAuto.checked = false;
        ball.style.animation = '';
};
</script>

马黑黑 发表于 2024-6-27 12:42

一楼的演示,都是基于 rotate + translateY 进行,其实呢,平移可以是X轴方向的,感兴趣的朋友可以试一下,我将在下层楼提供一楼的完整代码。

马黑黑 发表于 2024-6-27 12:42

一楼演示完整代码:
<style>
#mydiv {
        margin: 30px auto;
        width: 400px;
        height: 400px;
        border: 2px dotted lightblue;
        position: relative;
}
#mydiv::after {
        position: absolute;
        content: '';
        inset: 0;
        border: 1px dashed plum;
        border-radius: 50%;
}
.ball {
        position: absolute;
        box-sizing: border-box;
        left: calc(50% - 20px);
        top: calc(50% - 20px);
        width: 40px;
        height: 40px;
        background: linear-gradient(lightgreen, purple);
        border-radius: 50%;
}
.ball:nth-of-type(1) {
        background: silver;
}
.ball:nth-of-type(2) {
        transition: .4s;
        transform: rotate(var(--deg)) translateY(var(--distance));
        --deg: 0deg;
        --distance: 200px;
}
.wrap { margin: 30px auto; width: 400px; }
.msg { font: normal 16px/20px Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace; }
@keyframes move { to { transform: rotate(calc(var(--deg) + 360deg)) translateY(var(--distance)); } }
</style>

<p>元素的 transform 属性,若 rotate 与 translate 配合使用,rotate(deg) 在前、translate(distance) 随后,则会令元素以自己为中心、以 distance 为半径,在旋转 deg 个角度的同时做圆周运动。以下,彩球初始位置在银色圆球处,现在它在虚线方框的正下方,因为它旋转了0度、沿Y轴平移了200px,即 transform: rotate(0deg) translateY(200px)。可以改变彩球的旋转角度和平移半径,也可以让小球执行关键帧动画,以便查看和感受 transform 属性旋转与平移配套使用的效果:</p>
<div id="mydiv">
        <div class="ball"></div>
        <div id="ball" class="ball"></div>
</div>
<div class="wrap">
        <p><output id="msg1" class="msg">transform: rotate(0) translateY(0);</output></p>
        <p>
                <label for="rDeg">旋转角度:</label>
                <input id="rDeg" type="range" max="360" min="-360" value="0" />
                <output id="sDeg">0deg</output>
        </p>
        <p>
                <label for="rDistance">移动半径:</label>
                <input id="rDistance" type="range" max="200" min="0" value="200" />
                <output id="sDistance">200px</output>
        </p>
        <p>
                <label for="rAuto">运行关键帧动画</label>
                <input id="rAuto" type="checkbox" />
        </p>
        <pre id="msg2" class="msg"></pre>
</div>

<script>
rDeg.oninput = rDistance.oninput = () => {
        sDeg.value = rDeg.value + 'deg';
        sDistance.value = rDistance.value + 'px';
        ball.style.setProperty('--deg', rDeg.value + 'deg');
        ball.style.setProperty('--distance', rDistance.value + 'px');
        msg1.value = `transform: rotate(${sDeg.value}) translateY(${sDistance.value});`;
};

rAuto.onclick = () => {
        if(!rAuto.checked) return;
        rDeg.disabled = rDistance.disabled = true;
        ball.style.animation = 'move 6s forwards';
        msg2.textContent = `
@keframes move {
    from { transform: rotate(${sDeg.value}) translateY(${sDistance.value}); }
    to { transform: rotate(${parseInt(sDeg.value) + 360}deg) translateY(${sDistance.value}); }
}`;
};

ball.onanimationend = () => {
        rDeg.disabled = rDistance.disabled = false;
        rAuto.checked = false;
        ball.style.animation = '';
};
</script>

南无月 发表于 2024-6-27 12:50

艾玛,这里又写了个动画片{:4_199:}

南无月 发表于 2024-6-27 12:52

这个旋转角度可以看度数和位置,这应该是通用的吧,
平时都是盲猜。。。{:4_170:}
这回比较直观了

南无月 发表于 2024-6-27 12:53

@keframes move {
    from { transform: rotate(-139deg) translateY(145px); }
    to { transform: rotate(221deg) translateY(145px); }
}

这串代码怎么看着这么和蔼可亲呢{:4_170:}

马黑黑 发表于 2024-6-27 12:55

南无月 发表于 2024-6-27 12:53
@keframes move {
    from { transform: rotate(-139deg) translateY(145px); }
    to { transform: ro ...

这是帖子中经常的关键帧动画代码,具体描述动画的变化,然后又元素的 animation 去调用。

马黑黑 发表于 2024-6-27 12:56

南无月 发表于 2024-6-27 12:52
这个旋转角度可以看度数和位置,这应该是通用的吧,
平时都是盲猜。。。
这回比较直观了

盲猜也是本事哦

马黑黑 发表于 2024-6-27 12:56

南无月 发表于 2024-6-27 12:50
艾玛,这里又写了个动画片

{:4_173:}

红影 发表于 2024-6-27 16:03

这个可以在任意圈内半径上看小球的转动呢,真好{:4_187:}

红影 发表于 2024-6-27 16:07

发现个有趣的现象,彩球的background: linear-gradient(lightgreen, purple);在转动时,浅绿色永远朝向圆心呢{:4_204:}

南无月 发表于 2024-6-27 17:50

马黑黑 发表于 2024-6-27 12:56


我点 运行关键帧动画 ,它自动跑路。。
半径设小点就绕小圆周跑。。
这个好看还能跟它玩

南无月 发表于 2024-6-27 17:53

马黑黑 发表于 2024-6-27 12:56
盲猜也是本事哦

没本事的才盲猜,试一个30不行就90,再不就-90,
就是凭试的这些乱七八糟的数据总结不出个规律来。。
好在小白时间不值钱,慢慢耗还是可以滴。。{:4_173:}

南无月 发表于 2024-6-27 17:54

马黑黑 发表于 2024-6-27 12:55
这是帖子中经常的关键帧动画代码,具体描述动画的变化,然后又元素的 animation 去调用。

就是因为它能完成一些奥运会的高难度动作,所以看着跟看世界冠军似的十分顺眼{:4_170:}

马黑黑 发表于 2024-6-27 18:04

南无月 发表于 2024-6-27 17:54
就是因为它能完成一些奥运会的高难度动作,所以看着跟看世界冠军似的十分顺眼

貌似如此

马黑黑 发表于 2024-6-27 18:04

南无月 发表于 2024-6-27 17:53
没本事的才盲猜,试一个30不行就90,再不就-90,
就是凭试的这些乱七八糟的数据总结不出个规律来。。
...

{:4_203:}

马黑黑 发表于 2024-6-27 18:04

南无月 发表于 2024-6-27 17:50
我点 运行关键帧动画 ,它自动跑路。。
半径设小点就绕小圆周跑。。
这个好看还能跟它玩

{:4_189:}

马黑黑 发表于 2024-6-27 18:15

红影 发表于 2024-6-27 16:07
发现个有趣的现象,彩球的background: linear-gradient(lightgreen, purple);在转动时,浅绿色永远朝向圆心 ...

这个,原理你应该明白的:

小彩球运动分两个内容,一是旋转一周,rotate(360deg),二是平移一定距离,translate(200px)。当旋转属性在前、平移属性跟后,元素不是原点旋转,而是绕原点(本例原点与外框的中心重合)、拉动半径距离旋转。

对比一下月球绕地球的旋转原理。

南无月 发表于 2024-6-27 21:12

马黑黑 发表于 2024-6-27 18:04
貌似如此

{:4_173:}老师设计的都是高精尖的动作,流畅还好看

南无月 发表于 2024-6-27 21:12

马黑黑 发表于 2024-6-27 18:04


表情帝{:4_170:}上朝 了
页: [1] 2 3 4
查看完整版本: CSS关键帧动画之圆周运动演示