动画SVG多边形

时间:2016-02-21 00:17:03

标签: javascript jquery css svg

我写了一个绘制多边形的代码:

  var svg = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
  svg.setAttribute('width', '100%');
  svg.setAttribute('height', window.innerHeight);
  document.querySelector('#bg').appendChild(svg);

for(var x = 0; x < polygons.length; x++){
  var polygon = document.createElementNS(svg.namespaceURI, 'polygon');
  polygon.setAttribute('points', polygons[0 + x]);
  polygon.setAttribute('fill', polygons[0 + x][1]);
  svg.appendChild(polygon);
}

我的多边形点代码: http://codepen.io/anon/pen/WrqrbB

我想动画这个类似于这个动画的多边形: http://codepen.io/zessx/pen/ZGBMXZ

如何为多边形制作动画?

1 个答案:

答案 0 :(得分:0)

你可以

  • 调用动画函数来根据需要操作坐标值,
  • 将它们转换为字符串,例如使用.join()
  • 将结果字符串作为其points属性值发送回多边形,重新绘制形状(就像您最初创建形状时一样),
  • 拥有动画功能,完成后,使用requestAnimationFrame以合理的内置延时再次自行调用。

以下代码段提供了可以做什么的基本概念。

(请注意,我已经在我的示例中重新定义了数组polygons,因此它与您所拥有的不同,但为了简单起见,这是在本示例中完成的。)

var svg = document.getElementsByTagName("svg")[0];
var polygons = [], numSteps = 100, stepNum = 0;
var coords = [
  [40, 20, 80, 20, 80, 60, 40, 60],
  [140, 20, 180, 20, 160, 50]
];

for (var x = 0; x < coords.length; x++) {  
  polygons[x] = document.createElementNS(svg.namespaceURI, 'polygon');
  polygons[x].setAttribute('points', coords[x].join());
  svg.appendChild(polygons[x]);
}

function anim() {
  for (var x = 0; x < coords.length; x++) {
    coords[x] = coords[x].map(function(coord) {
      return coord + 4 * (Math.random() - 0.5);
    });
    polygons[x].setAttribute('points', coords[x].join());
    stepNum += 1;
  }
  if (stepNum < numSteps) requestAnimationFrame(anim);
}

anim();
<svg></svg>

更新以上代码段通常显示如何为多边形设置动画。但是,在您的情况下,还有一个问题。在您的codepen演示中,很明显您已经分别对每个多边形的点坐标进行了硬编码。因此,如果你想移动一个点,那么对于每个接触该点的多边形,你将不得不更新至少2个(如果不是更多的地方)的坐标。

更好的方法是创建一个单独的所有点数组,然后根据该数组定义每个多边形。 (这类似于有时在3D图形中完成的事情,例如WebGL。)以下代码片段演示了这种方法。

var svg = document.getElementsByTagName("svg")[0];
var polyElems = [], numSteps = 100, stepNum = 0;
var pts = [[120,20], [160,20], [200,20], [240,20], [100,50], [140,50], [180,50], [220,50], [260,50], [120,80], [160,80], [200,80], [240,80]];
var polyPts = [[0,1,5], [1,2,6], [2,3,7], [0,4,5], [1,5,6], [2,6,7], [3,7,8], [4,5,9], [5,6,10], [6,7,11], [7,8,12], [5,9,10], [6,10,11], [7,11,12]];

for (var x = 0; x < polyPts.length; x++) {
  polyElems[x] = document.createElementNS(svg.namespaceURI, 'polygon');
  polyElems[x].setAttribute('fill', '#'+Math.floor(Math.random()*16777215).toString(16));
    // random hex color routine from http://www.paulirish.com/2009/random-hex-color-code-snippets/
  drawPolygon(x);
}

function anim() {
  pts = pts.map(function(pt) {
    return pt.map(function(coord) {
      return coord + 3 * (Math.random() - 0.5); // move each point
    });
  });
  for (var x = 0; x < polyPts.length; x++) {drawPolygon(x);}
  stepNum += 1;
  if (stepNum < numSteps) requestAnimationFrame(anim); // redo anim'n until all anim'n steps done
}

anim(); // start the animation

function drawPolygon(x) {
  var ptNums = polyPts[x];
  var currCoords = [pts[ptNums[0]], pts[ptNums[1]], pts[ptNums[2]]].join();
    // creates a string of coordinates; note that [[1,2],[3,4],[5,6]].join() yields "1,2,3,4,5,6"
  polyElems[x].setAttribute('points', currCoords);
  svg.appendChild(polyElems[x]);
}
<svg></svg>