RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 1266489
Accepted
Sevastopol'
Sevastopol'
Asked:2022-04-06 01:11:03 +0000 UTC2022-04-06 01:11:03 +0000 UTC 2022-04-06 01:11:03 +0000 UTC

显示此效果的数学钟摆动画[重复]

  • 772
这个问题已经在这里得到了回答:
显示此效果的牛顿摇篮动画 5 个答案
1 年前关闭。

数学钟摆是一个振荡器,它是一个机械系统,由一个无重量的不可伸展线或光杆末端的质点组成,并位于一个均匀的重力场中。螺纹(杆)的另一端通常是固定的。(有关详细信息,请参阅维基百科参考)

数学钟摆

我对@Alexandr_TT提出的问题(牛顿的摇篮,演示此效果的动画)感兴趣,有必要创建一个演示此物理体验的动画,对此我有一个反问。

这是平衡位置处的数学钟摆的代码CSS:

/*Маятник*/

.newton_cradle {
  position: relative;
  margin: 0 auto;
  margin-top: 90px;
  width: 100px;
  height: 100px;
  border-radius: 100px;
  background: repeating-linear-gradient( 45deg, black, transparent 100px);
  background: radial-gradient(circle at 65% 15%, white 1px, lightgray 3%, gray 60%, lightgray 100%);
  box-shadow: 1px 5px 10px 3px rgb(0 0 0 / 10%);
}


/*Украшательства маятника*/

.newton_cradle::before {
  content: '';
  display: block;
  position: absolute;
  top: 20px;
  left: 20px;
  width: 40px;
  height: 40px;
  border-radius: 100%;
  background-color: white;
  filter: blur(10px);
}


/*Нить*/

.newton_cradle::after {
  content: '';
  display: block;
  position: absolute;
  top: -90px;
  left: 48px;
  height: 90px;
  width: 2px;
  background: gray;
}
<div class="newton_cradle"></div>

这是平衡位置处的数学钟摆的代码SMIL SVG:

<svg id="svg" viewBox="-100 45 220 45" height="280px" width="500px">

<g>
  <!--Маятник-->
  <circle r="20" cy="67" cx="31.75" fill="url(#gr)" stroke="none" stroke-width="4.99999" />
  <!--Нить-->
  <path transform="scale(0.26458333)" d="M 120 40 L 120 180 L 120 40 z" fill="none" stroke="dimgray" stroke-width="2px" />
</g>

<!--Украшательства маятника-->
<radialGradient id="gr" r="100%" fx="30%" fy="30%"><stop stop-color="white" offset="10%"></stop><stop stop-color="darkgray" offset="45%"></stop><stop stop-color="gray" offset="100%" stop-opacity="0"/></radialGradient>

</svg>

问题:
如上图所示,如何播放钟摆沿半径圆弧摆动的动画?与垂直方向的偏差角度无关紧要。在实现中要理解的最重要的事情是如何通过这样的动画使不可扩展的线程(杆)的一端(旋转中心)保持静止。有兴趣详细描述这种通过手段和技术创建动画和转换效果的CSS实现SMIL SVG。

css3
  • 3 3 个回答
  • 10 Views

3 个回答

  • Voted
  1. Sevastopol'
    2022-04-06T01:11:03Z2022-04-06T01:11:03Z

    我建议考虑使用CSS.

    您可以播放带有规则的钟摆摆动的动画,@keyframes并为该规则设置通用关键帧,包括其中所需的属性和值。from这样的动画一点也不复杂,使用and关键字就足够了to。

    transform我们可以使用属性和变换函数再现偏离垂直的角度rotate。有关此属性的更多信息

    该函数rotate允许我们将元素旋转给定角度。语法是:transform: rotate(угол); 例如,我们可以将倾斜角度设置为30deg正值(顺时针)和-30deg负值(逆时针)。有关此值的更多信息

    /*Анимация*/
    
    @keyframes animate {
      from {
        transform: rotate(-30deg);
      }
      to {
        transform: rotate(30deg);
      }
    }
    
    
    /*Маятник*/
    
    .newton_cradle {
      position: relative;
      margin: 0 auto;
      margin-top: 90px;
      width: 100px;
      height: 100px;
      border-radius: 100px;
      background: repeating-linear-gradient( 45deg, black, transparent 100px);
      background: radial-gradient(circle at 65% 15%, white 1px, lightgray 3%, gray 60%, lightgray 100%);
      box-shadow: 1px 5px 10px 3px rgb(0 0 0 / 10%);
      
      transform: rotate(-30deg);
      animation: animate 0.8s infinite alternate linear;
    }
    
    
    /*Украшательства маятника*/
    
    .newton_cradle::before {
      content: '';
      display: block;
      position: absolute;
      top: 20px;
      left: 20px;
      width: 40px;
      height: 40px;
      border-radius: 100%;
      background-color: white;
      filter: blur(10px);
    }
    
    
    /*Нить*/
    
    .newton_cradle::after {
      content: '';
      display: block;
      position: absolute;
      top: -90px;
      left: 48px;
      height: 90px;
      width: 2px;
      background: gray;
    }
    <div class="newton_cradle"></div>

    现在我们剩下最重要的问题:如何通过这样的动画使不可拉伸的线(杆)的一端(枢轴点)不动?

    让我们回到函数rotate。这是它的定义:它允许我们相对于属性指定的变换点将元素旋转给定的角度transform-origin。

    该属性transform-origin设置元素将被转换的相对点的坐标。语法如下:transform-origin: x y z;, 其中x, y,z分别是 X、Y 和 Z 坐标。 有关此属性的更多信息

    所以,让我们把这个属性付诸实践,为它设置我们需要的值:transform-origin: 50% -90px 0;,看看我们得到了什么结果:

    /*Анимация*/
    
    @keyframes animate {
      from {
        transform: rotate(-30deg);
      }
      to {
        transform: rotate(30deg);
      }
    }
    
    
    /*Маятник*/
    
    .newton_cradle {
      position: relative;
      margin: 0 auto;
      margin-top: 90px;
      width: 100px;
      height: 100px;
      border-radius: 100px;
      background: repeating-linear-gradient( 45deg, black, transparent 100px);
      background: radial-gradient(circle at 65% 15%, white 1px, lightgray 3%, gray 60%, lightgray 100%);
      box-shadow: 1px 5px 10px 3px rgb(0 0 0 / 10%);
      
      transform: rotate(-30deg);
      animation: animate 0.8s infinite alternate linear;
      
      transform-origin: 50% -90px 0;
    }
    
    
    /*Украшательства маятника*/
    
    .newton_cradle::before {
      content: '';
      display: block;
      position: absolute;
      top: 20px;
      left: 20px;
      width: 40px;
      height: 40px;
      border-radius: 100%;
      background-color: white;
      filter: blur(10px);
    }
    
    
    /*Нить*/
    
    .newton_cradle::after {
      content: '';
      display: block;
      position: absolute;
      top: -90px;
      left: 48px;
      height: 90px;
      width: 2px;
      background: gray;
    }
    <div class="newton_cradle"></div>

    • 5
  2. Best Answer
    Alexandr_TT
    2022-04-06T18:58:06Z2022-04-06T18:58:06Z

    静态,无动画

    <svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
             width="100%" height="100%" viewBox="0 0 400 400">  
    <defs>
       <radialGradient id="Rg" r="90%" fx="50%" fy="30%">
            <stop stop-color="#F3F3F3" offset="5%"></stop>
            <stop stop-color="#3E3D44" offset="45%"></stop>    
            <stop stop-color="black" offset="100%" stop-opacity="0.72"/>
        </radialGradient>
    </defs> 
               <!-- Траектория движения шарика -->
    <circle fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" cx="200" cy="10" r="200" />
                     <!-- Верхняя полка -->
    <polyline fill="none" stroke="#d3d3d3" stroke-width="20" points="0,0 400,0"/>    
                     <!-- Левая граница -->
     <polyline fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" points="200,10 58.58,151.42" />     
                     <!-- Правая граница -->
       <polyline fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" points="200,10 341.42, 151.42"/>
    
                <!-- Шарик на нитке -->
       <g id="G1" fill="url(#Rg)" > 
               <!-- Нитка -->
        <polyline fill="none" stroke="#4C4B53" stroke-width="3"  points="200,10 200,210"/>
            <circle  fill="url(#Rg)" stroke-width="3"  cx="200" cy="210" r="20" />
       </g>
                              <!-- Центр вращения -->
     <circle fill="gold" stroke="black" stroke-width="1"  cx="200" cy="10" r="4" />  
    </svg>   

    对摆动的钟摆进行动画处理的最佳方法是使用transform="rotate" MDN

    rotate( <a> [<x> <y>])a围绕指定点旋转度数。如果省略可选参数x和y,则旋转将围绕当前用户系统的原点

    因此,有必要找到并指定旋转中心的准确坐标。

    在此示例中,您不需要找到它们,因为它们是在设计期间预先选择的。这是一个带有坐标的黄色 x="200"圆圈y="10"

                              <!-- Центр вращения -->
     <circle fill="gold" stroke="black" stroke-width="1"  cx="200" cy="10" r="4" />  
    

    球的悬挂线将从旋转中心开始

    <polyline fill="none" stroke="#4C4B53" stroke-width="3"  points="200,10 200,210"/>
    

    为了使线程和球同步动画,您需要将它们组合成一个组并将动画命令应用于该组:

     <animateTransform xlink:href="#G1"
           attributeName="transform"
           type="rotate"
           begin="0.5s"
           dur="4s"
           values="
             45, 200, 10;
            -45, 200,10;
             45, 200, 10"
         repeatCount="indefinite"
                />
    

    该属性values指定球的最大偏转角

    一切准备就绪,可以实现动画了:

    <svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
             width="50%" height="50%" viewBox="0 0 400 400" >  
    <defs>
       <radialGradient id="Rg" r="90%" fx="50%" fy="30%">
            <stop stop-color="#F3F3F3" offset="5%"></stop>
            <stop stop-color="#3E3D44" offset="45%"></stop>    
            <stop stop-color="black" offset="100%" stop-opacity="0.72"/>
        </radialGradient>
    </defs> 
               <!-- Траектория движения шарика -->
    <circle fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" cx="200" cy="10" r="200" />
                     <!-- Верхняя полка -->
    <polyline fill="none" stroke="#d3d3d3" stroke-width="20" points="0,0 400,0"/>    
     
     <polyline fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" points="200,10 58.58,151.42">
        </polyline>   
       <polyline fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" points="200,10 341.42, 151.42"/>
    
                <!-- Шарик на нитке -->
    <g id="G1" fill="url(#Rg)" transform="translate(0,0) rotate(45, 200, 10)" >
        <polyline fill="none" stroke="black" stroke-width="3"  points="200,10 200,210"/>
    <circle  fill="url(#Rg)" stroke-width="3"  cx="200" cy="210" r="20" />
     </g>
       <animateTransform xlink:href="#G1"
           attributeName="transform"
           type="rotate"
           begin="0.5s"
           dur="2.5s"
           values="
             45, 200, 10;
            -45, 200,10;
             45, 200, 10"
             repeatCount="indefinite"
                />
                              <!-- Центр вращения -->
     <circle fill="gold" stroke="black" stroke-width="1"  cx="200" cy="10" r="4" />  
    </svg>

    正如@MBo评论

    是否可以改变角速度?在实摆中,速度在较低点较高,而在较高点则减小到零。以同样的速度,它看起来像从墙上飞下来

    对于解决方案,您可以使用向动画添加属性
    keySplines =" 0.63 0.015 0.13 0.97; 0.63 0.015 0.13 0.97"

    您可以使用生成器选择参数

    在此处输入图像描述

    从图中可以看出,动画的开头和结尾部分会走得很慢,中间会快很多。

    最终代码:

    添加到之前的动画示例:

    calcMode="spline"
     keySplines =" 0.63 0.015 0.13 0.97; 0.63 0.015 0.13 0.97"
    

    <svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
             width="75%" height="75%" viewBox="0 0 400 400" >  
    <defs>
       <radialGradient id="Rg" r="90%" fx="50%" fy="30%">
            <stop stop-color="#F3F3F3" offset="5%"></stop>
            <stop stop-color="#3E3D44" offset="45%"></stop>    
            <stop stop-color="black" offset="100%" stop-opacity="0.72"/>
        </radialGradient>
    </defs> 
               <!-- Траектория движения шарика -->
    <circle fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" cx="200" cy="10" r="200" />
                     <!-- Верхняя полка -->
    <polyline fill="none" stroke="#d3d3d3" stroke-width="20" points="0,0 400,0"/>    
     
     <polyline fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" points="200,10 58.58,151.42">
        </polyline>   
       <polyline fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" points="200,10 341.42, 151.42"/>
    
                <!-- Шарик на нитке -->
    <g id="G1" fill="url(#Rg)" transform="translate(0,0) rotate(45, 200, 10)"  >
        <polyline   fill="none" stroke="black" stroke-width="3"  points="200,10 200,210"/>
          <circle  fill="url(#Rg)" stroke-width="3"  cx="200" cy="210" r="20" />
    </g>
       <animateTransform xlink:href="#G1"
           attributeName="transform"
           type="rotate"
           begin="0.5s"
           dur="2.5s"
           values="
             45, 200, 10;
            -45, 200,10;
             45, 200, 10"
             calcMode="spline"
             keySplines =" 0.63 0.015 0.13 0.97; 0.63 0.015 0.13 0.97"
             repeatCount="indefinite"
                /> 
                              <!-- Центр вращения -->
     <circle fill="gold" stroke="black" stroke-width="1"  cx="200" cy="10" r="4" />  
    </svg>

    这个解决方案的普遍性表明,只改变摆的偏转角度就足够了,一切都会起作用。60度的偏转角度:

    <svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
             width="50%" height="50%" viewBox="0 0 400 400"  >  
    <defs>
       <radialGradient id="Rg" r="90%" fx="50%" fy="30%">
            <stop stop-color="#F3F3F3" offset="5%"></stop>
            <stop stop-color="#3E3D44" offset="45%"></stop>    
            <stop stop-color="black" offset="100%" stop-opacity="0.72"/>
        </radialGradient>
    </defs> 
               <!-- Траектория движения шарика -->
    <circle fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" cx="200" cy="10" r="200" />
                     <!-- Верхняя полка -->
    <polyline fill="none" stroke="#d3d3d3" stroke-width="20" points="0,0 400,0"/>    
     
     <polyline fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" points="200,10 58.58,151.42">
        </polyline>   
       <polyline fill="none" stroke="#d3d3d3" stroke-width="3" stroke-dasharray="15,7.5" points="200,10 341.42, 151.42"/>
    
                <!-- Шарик на нитке -->
    <g id="G1" fill="url(#Rg)" transform="translate(0,0) rotate(60, 200, 10)" >
        <polyline fill="none" stroke="black" stroke-width="3"  points="200,10 200,210"/>
          <circle  fill="url(#Rg)" stroke-width="3"  cx="200" cy="210" r="20" />
    </g>
       <animateTransform xlink:href="#G1"
           attributeName="transform"
           type="rotate"
           begin="0.5s"
           dur="2.5s"
           values="
           60, 200, 10;
            -60, 200,10;
             60, 200, 10"
             calcMode="spline"
             keySplines =" 0.63 0.015 0.13 0.97; 0.63 0.015 0.13 0.97"
             repeatCount="indefinite"
                />
                              <!-- Центр вращения -->
     <circle fill="gold" stroke="black" stroke-width="1"  cx="200" cy="10" r="4" />  
    </svg>

    CSS 选项

    我看不出在 CSS 中做 SVG 做得好的并且适用于图形的意义:天花板、旋转中心、运动路径、SVG 中留下的摆锤偏转边界

    所有可能已转移到的 SVG 样式<style>

    使用实现的摆锤摆动动画animation @keyframes

    .poly {
    fill:none;
    stroke:#d3d3d3;
    stroke-width:3;
    stroke-dasharray:15,7.5;
    } 
    .G1 {
    transform:translate(0,0) rotate(45deg); 
    transform-origin:200px 10px;
    animation: pan 4s ease infinite 0.5s;
    }
    
    @keyframes pan {
    0%{transform:rotate(45deg);}
    50%{transform:rotate(-45deg);}
    100%{transform:rotate(45deg);}
    
    }
    <svg  xmlns="http://www.w3.org/2000/svg"  xmlns:xlink="http://www.w3.org/1999/xlink"
             width="50%" height="50%" viewBox="0 0 400 400" >  
    <defs>
       <radialGradient id="Rg" r="90%" fx="50%" fy="30%">
            <stop stop-color="#F3F3F3" offset="5%"></stop>
            <stop stop-color="#3E3D44" offset="45%"></stop>    
            <stop stop-color="black" offset="100%" stop-opacity="0.72"/>
        </radialGradient>
    </defs> 
               <!-- Траектория движения шарика -->
    <circle class="poly" id="circ1"  cx="200" cy="10" r="200" />
                     <!-- Верхняя полка -->
    <polyline fill="none" stroke="#d3d3d3" stroke-width="20" points="0,0 400,0"/>    
     
     <polyline class="poly" fill="none"  points="200,10 58.58,151.42">
        </polyline>   
       <polyline class="poly" points="200,10 341.42, 151.42"/>
    
                <!-- Шарик на нитке -->
    <g class="G1" fill="url(#Rg)"  >
        <polyline   fill="none" stroke="black" stroke-width="3"  points="200,10 200,210"/>
          <circle  fill="url(#Rg)" stroke-width="3"  cx="200" cy="210" r="20" />
    </g>
      
                              <!-- Центр вращения -->
     <circle fill="gold" stroke="black" stroke-width="1"  cx="200" cy="10" r="4" />  
    </svg>   

    • 5
  3. Sevastopol'
    2022-04-06T08:06:58Z2022-04-06T08:06:58Z

    我建议考虑使用该技术的钟摆动画的变体SMIL SVG,并使用变换再现振荡type="translate"- 沿轴移动球x和y(更多关于变换的类型),以及单独重新绘制线程元素,为属性选择合适的值,这为绘制更多关于属性d的路径提供了定义。让我们看看我们从中得到了什么:

    <svg id="svg" viewBox="-110 45 220 45" height="280px" width="500px">
    
      <!--Анимация маятника-->
      <animateTransform xlink:href="#an1" attributeName="transform" type="translate" begin="0s" values="0,0; 36.25,-5; 0,0; -36.25,-5; 0,0" dur="2s" repeatCount="indefinite" fill="freeze" />
          
      <!--Анимация нити-->
      <animate xlink:href="#an2" attributeName="d" begin="0s" values="M 120 40 L 120 180 L 120 40 z; M 120 40 L 220 170 L 120 40 z; M 120 40 L 120 180 L 120 40 z; M 120 40 L 20 170 L 120 40 z; M 120 40 L 120 180 L 120 40 z" dur="2s" repeatCount="indefinite" fill="freeze" />
    
    <g>
      <!--Маятник-->
      <circle id="an1" r="20" cy="67" cx="31.75" fill="url(#gr)" stroke="none" stroke-width="4.99999" />
      <!--Нить-->
      <path id="an2" transform="scale(0.26458333)" d="M 120 40 L 120 180 L 120 40 z" fill="none" stroke="dimgray" stroke-width="2px" />
    </g>
    
    <!--Украшательства маятника-->
    <radialGradient id="gr" r="100%" fx="30%" fy="30%"><stop stop-color="white" offset="10%"></stop><stop stop-color="darkgray" offset="45%"></stop><stop stop-color="gray" offset="100%" stop-opacity="0"/></radialGradient>
    
    </svg>

    结论:不难看出,这种摆锤动画的播放方式看起来不太逼真。当然,如果你太努力了,那么很有可能获得更大的真实感,但这将是一个更耗时的过程。此外,当您只能使用一个动画时,必须使用两个动画,因此该选项更加复杂。显然,要重现钟摆的动画,更正确的方法是使用元素的旋转变换type="rotate"。

    • 2

相关问题

  • 如何用线条绘制立体图并进行动画处理?

  • 如何将心形图像添加到按钮?

  • 如何布置菜单

  • 如何将转换应用于按钮内的文本?

  • 如何在网格中制作滚动项目?

  • 图片与文本重叠的矩形

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    表格填充不起作用

    • 2 个回答
  • Marko Smith

    提示 50/50,有两个,其中一个是正确的

    • 1 个回答
  • Marko Smith

    在 PyQt5 中停止进程

    • 1 个回答
  • Marko Smith

    我的脚本不工作

    • 1 个回答
  • Marko Smith

    在文本文件中写入和读取列表

    • 2 个回答
  • Marko Smith

    如何像屏幕截图中那样并排排列这些块?

    • 1 个回答
  • Marko Smith

    确定文本文件中每一行的字符数

    • 2 个回答
  • Marko Smith

    将接口对象传递给 JAVA 构造函数

    • 1 个回答
  • Marko Smith

    正确更新数据库中的数据

    • 1 个回答
  • Marko Smith

    Python解析不是css

    • 1 个回答
  • Martin Hope
    Alexandr_TT 2020年新年大赛! 2020-12-20 18:20:21 +0000 UTC
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5