让柱子摇起来可以不需要设定基点
本帖最后由 马黑黑 于 2022-4-7 08:11 编辑 <br /><br /><style>.pillar {
margin: 10px auto;
width: 20px;
height: 200px;
background: olive;
animation: sway 2s linear infinite alternate;
}
@keyframes sway {
from { transform: translateY(100px) rotate(45deg) translateY(-100px); }
to { transform: translateY(100px) rotate(-45deg) translateY(-100px); }
}
@keyframes sway1 {
from { transform: translateY(-100px) rotate(45deg) translateY(100px); }
to { transform: translateY(-100px) rotate(-45deg) translateY(100px); }
}
</style>
<div class="pillar"></div>
<p>上面的摇摆效果,常规的实现方式当然是用 transform的rotate来做,且必须设定transform-origin,否则底部无法固定——默认状况下,元素的rotate运动以自己的中心为基点。</p><p><br></p><p>transform-origin有时候很抽象,主要原因有两个方面:其一,我们需要给一个运动半径,其二,我们需要知道它rotate前的定位。</p><p><br></p><p>既然transform-origin很多时候难以理解和确定,我们或许可以绕开它(而不是回避它)。上面例子就是这样实现的,没有使用transform-origin来确定运动基点。代码如下:</p>
<pre style="font-size: 12px;"><style>
<span style="color: red;">.pillar </span>{
<span style="color: blue;">margin</span>: 20px auto 0;
<span style="color: blue;">width</span>: 20px;
<span style="color: blue;">height</span>: 200px;
<span style="color: blue;">background</span>: olive;
<span style="color: blue;">animation</span>: sway 2s linear infinite alternate;
}
<span style="color: red;">@keyframes sway </span>{
from { <span style="color: blue;">transform</span>: translateY(100px) rotate(45deg) translateY(-100px); }
to { <span style="color: blue;">transform</span>: translateY(100px) rotate(-45deg) translateY(-100px); }
}
</style>
<<span style="color:darkred">div</span> <span style="color: red">class</span><span style="color: blue">=</span><span style="color: magenta">"pillar"</span>><<span style="color: darkred">/div</span>>
<br></pre>
<p>我们把重点放在 sway 动画的设计。这里,我用了 translateY + rotate 来描述 from 和 to 这两种运动形态,先看 from :</p><p><br></p>
<p>在 from 语句里,我先让元素垂直方向平移 100px ,这100px是柱子高度的一半,其实它充当的是运动半径,接着旋转45度,再接着垂直方向平移 -100px!translateY一上一下的运动路径正好相互抵消,但它们的存在影响着rotate的效果,并非多余。</p>
<p><br></p><p>在 to 语句,translateY前后还是沿用了 from 语句里的方式,相互抵消,中间 rotate 的值改为 -45deg。</p><p><br></p><p>就是说,实际上我们要做的是让柱子要做的运动以底端为基点左右摆动,从45deg摆到-45deg。运动期间,原始状态时,即在摆动之始,translateY以相反的值两次参与其中,把 rotate 的动作包夹起来,这个运动过程实际上是物体在摇摆的时候我把它上提100个像素,再把它来回原位,这样,45度角的摇摆就不是以物体的中心为基点,而是以底部为基点。同样道理,rotate(-45deg)时,就是 to 语句的运动描述,也可以这么理解。</p>
<p><br></p>
<p>可能有朋友会问,为什么是translateY而不是translateX?这不难理解。在空间场景,rotate本身产生的变化有X坐标方向的趋向,只有相反方向的Y位移才可以改变旋转的基点。</p>
<p><br></p>
<p>那么,如果需要元素以上端为基点,又如何处理?这好办,改变 <span id="kM0.7138878478039028">@keyframes 动画中 </span>translateY 的前后的正负值便可,试看效果:</p>
<div class="pillar" style="animation: sway1 2s linear infinite alternate;"></div>
<p>至此,我们可以不需要设定 transform-origin 运动基点就可随心所欲地设计动画。但记住,我们还是需要基点,只不过我们所使用的新方式更为直观,对基点的修改也更为便捷。另外,非常方便的是,我们所使用的基点确定新方式,对元素的定位没有特别的要求,我们只需知道元素的某些尺寸。</p> 本帖最后由 马黑黑 于 2022-4-7 12:34 编辑
一楼实例代码整合:
<style>
.pillar {
margin: 20px auto 0;
width: 20px;
height: 200px;
background: #ffcc66;
animation: sway 2s linear infinite alternate;
}
@keyframes sway {
from { transform: translateY(100px) rotate(45deg) translateY(-100px); }
to { transform: translateY(100px) rotate(-45deg) translateY(-100px); }
}
@keyframes sway1 {
from { transform: translateY(-100px) rotate(45deg) translateY(100px); }
to { transform: translateY(-100px) rotate(-45deg) translateY(100px); }
}
</style>
<div class="pillar"></div>
<div class="pillar" style="animation: sway1 2s linear infinite alternate;"></div>
也就是说,原本是绕元素中心的旋转,对这个例子,通过取长度一半,“translateY以相反的值两次参与其中,把 rotate 的动作包夹起来”就能定位想要的基点。这法子真不错,可以绕开transform-origin的确定了{:4_199:} “transform-origin很多时候难以理解和确定”
认同,尤其对不规则图形来说,确定基点需要用到像素尺才行,很麻烦。黑黑的这个方法非常聪明,根本不需要管图形的形状,也能实现绕想要的点转动。{:4_199:} “可能有朋友会问,为什么是translateY而不是translateX?这不难理解。在空间场景,rotate本身产生的变化有X坐标方向的趋向,只有相反方向的Y位移才可以改变旋转的基点。”
对这句有异议,你这个是竖向的例子,若是横向的,就应该是translateX了吧? 马黑黑 发表于 2022-4-7 08:15
一楼实例代码整合:
对这个有点疑问,为什么两个动画都是sway,会不会冲突?html里出现了sway1,这个哪来的? 来学习 黑版早晨好!
学习、欣赏、赞扬。 梦油 发表于 2022-4-7 10:26
黑版早晨好!
学习、欣赏、赞扬。
上茶,上好茶,上特好的茶
{:4_190:} 红影 发表于 2022-4-7 09:55
对这个有点疑问,为什么两个动画都是sway,会不会冲突?html里出现了sway1,这个哪来的?
你没细看,第二个是 sway1{:5_117:} 红影 发表于 2022-4-7 09:42
也就是说,原本是绕元素中心的旋转,对这个例子,通过取长度一半,“translateY以相反的值两次参与其中,把 ...
transform-origin是正儿八经的语法,但它的确很抽象,所以如此变通可能更直观 红影 发表于 2022-4-7 09:44
“transform-origin很多时候难以理解和确定”
认同,尤其对不规则图形来说,确定基点需要用到像素尺才行, ...
至少,通过本帖的柱子摇摆可以看出,方法是可行的 红影 发表于 2022-4-7 09:46
“可能有朋友会问,为什么是translateY而不是translateX?这不难理解。在空间场景,rotate本身产生的变化有 ...
嗯,你说得对,应当根据物体所在的空间环境来决定。 马黑黑 发表于 2022-4-7 12:33
上茶,上好茶,上特好的茶
谢谢黑版。 梦油 发表于 2022-4-7 14:11
谢谢黑版。
{:5_108:} 马黑黑 发表于 2022-4-7 12:34
你没细看,第二个是 sway1
哦 哦,那是我弄错了,不好意思{:4_173:} 马黑黑 发表于 2022-4-7 12:43
transform-origin是正儿八经的语法,但它的确很抽象,所以如此变通可能更直观
还行,也不算太抽象。 马黑黑 发表于 2022-4-7 12:45
至少,通过本帖的柱子摇摆可以看出,方法是可行的
是的,非常可行呢,黑黑厉害,什么都能想出来{:4_199:} 马黑黑 发表于 2022-4-7 12:47
嗯,你说得对,应当根据物体所在的空间环境来决定。
嗯嗯,知道了{:4_187:} 红影 发表于 2022-4-7 20:55
是的,非常可行呢,黑黑厉害,什么都能想出来
思考总会有结果的吧,再说,有很多先行者