【问题标题】:Animate each point of a polygon individually分别为多边形的每个点设置动画
【发布时间】:2019-05-10 19:24:58
【问题描述】:

我有一个网站菜单,它由多个多边形组成,用户可以单击它们。此外,多边形共享一些节点。到目前为止一切顺利(参见下面的代码)。

现在,我想以一种方式为这些多边形设置动画,使它们在一个缓慢而无限的循环中动态地改变它们的形状。为此,我需要单独为每个节点设置动画。我想过让节点沿着一条路径(例如一个小圆圈)移动,每个节点都以自己的速度移动。

有没有办法只使用 SVG/CSS 来做到这一点?还是我需要用js或snap寻找解决方案?由于菜单是网页的核心功能部分,因此我希望它尽可能简单和原味。

这是我从this thread 复制的两个多边形的工作示例。

polygon {
  stroke-width: 1;
  stroke: red;
  fill: transparent;
}
polygon:hover {
  fill: red;
}
<svg viewBox="0 0 999 799">
  <polygon points="445,161 345,174 500,10" />

  <polygon points="445,161 345,174 500,270" />
</svg>

下面的 sn-p 显示了迄今为止我能想到的移动单个节点的唯一方法。不幸的是,它需要所有其他点的坐标。由于节点在各种多边形之间共享,因此此解决方案不适用于我。

<polygon points="" fill="red">
 <animate attributeName="points" dur="1s" fill="freeze"
          from="0,0, 0,100, 100,100"
          to="0,0, 0,100, 100,50"/>
</polygon>

非常感谢您的帮助!

【问题讨论】:

  • 也许用路径创建整个事物,这样就不会重复,然后使用 SMIL 为路径的命令设置动画。
  • 谢谢@RobertLongson。我担心,如果我使用路径,这些区域将无法点击。或者你知道如何做到这一点?
  • 你必须自己弄清楚点击意味着什么,是的。
  • 为每个多边形仔细构建 SMIL,使其与所有其他多边形的运动保持一致。

标签: animation svg polygon snap.svg


【解决方案1】:

我会为此使用 javascript,并且我会使用点数组。然后我会为这些点的位置设置动画。您使用这些点绘制多边形。请参阅我的代码中的函数function resetPoints()。我希望这是您的要求。

let points = [
  {x:445,y:161,a:.7},
  {x:345,y:147,a:2.1},
  {x:500,y:10,a:3.9},
  {x:500,y:270,a:5.2}
]

let r = 20;// the radius of rotation. In this case is a unique value. It may be a different value for every point
let speed = .01;//the speed of rotation. In this case is a unique value. It may be a different value for every point 


//get center rotation
points.forEach(p=>{
  p.c = {};
  let a = 2*Math.PI - p.a;//angle
  p.c.x = p.x + r*Math.cos(a);
  p.c.y = p.y + r*Math.sin(a);
});



//resetPoints();

function Frame(){
  requestAnimationFrame(Frame)
  points.forEach(p=>{
    p.a += speed;
    p.x = p.c.x + r*Math.cos(p.a);
    p.y = p.c.y + r*Math.sin(p.a);
  });
  
  resetPoints();
}

Frame();

// a function to draw the polygons in base of the points

function resetPoints(){
  let pts1 = `${points[0].x}, ${points[0].y} 
            ${points[1].x}, ${points[1].y} 
            ${points[2].x}, ${points[2].y}`
  let pts2 = `${points[0].x}, ${points[0].y} 
            ${points[1].x}, ${points[1].y} 
            ${points[3].x}, ${points[3].y}`

a.setAttributeNS(null,"points",pts1);
b.setAttributeNS(null,"points",pts2);
}
polygon {
  stroke-width: 1;
  stroke: red;
  fill: transparent;
}
polygon:hover {
  fill: red;
}
<svg viewBox="0 0 999 799">
  <polygon id="a" points="445,161 345,174 500,10" />

  <polygon id="b" points="445,161 345,174 500,270" />
</svg>

【讨论】:

  • 这正是我要找的,非常感谢!
  • 有一个小错字:在函数 Frame() 中,它应该是 sin(p.a) 而不是 cos(p.a)。我试图编辑,但它需要先审查才能显示。 (但是,我认为它看起来更好,当节点沿着轴而不是圆圈移动时;.))
猜你喜欢
  • 1970-01-01
  • 2017-08-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多