我制作了一个绘制和动画多边形的脚本:
http://codepen.io/anon/pen/GZRxRV
实际上我添加了一些多边形(我想添加超过50个)。
但我想像这样动画我的身材(缓慢的宽度和高度变换):
http://codepen.io/anon/pen/mVYWJQ
如何为我的三角形图实现类似的动画?
var svg = document.getElementsByTagName("svg")[0];
var polyElems = [], numSteps = -660, stepNum = 0;
/*var pts = [[451.1,386.7], [93.5,194], [343.4,-7.1]];*/
var pts = [[-5.1,-7.1], [343.4,-7.1], [386.7,194],
[451.1,93.5], [386.7,194], [343.4,-7.1],
[-5.1,-7.1], [262.3,183.5], [386.7,194],
];
// var palette = [['#ff0000'], ['#000']];
var palette = ['#49c9d5','#02abc8','#02abc8','#430017'];
var polyPts = [[0,1,2],[3,2,1],[0,7,2]];
for (var x = 0; x < polyPts.length; x++) {
polyElems[x] = document.createElementNS(svg.namespaceURI, 'polygon');
polyElems[x].setAttribute('fill', [palette[x]]);
// 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 + 1 * (Math.random() - 0.5); // move each point
});
});
for (var x = 0; x < polyPts.length; x++) {drawPolygon(x);}
stepNum += 5;
/*if (stepNum < numSteps) */requestAnimationFrame(anim); // redo anim'n until all anim'n steps don
}
window.setInterval(anim(), 1);
//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]);
}
答案 0 :(得分:0)
你想要为你的Delaunay风格的三角形设置一个“摆动”动画。
<强>问题强>
任何一个三角形都可能与其他几个三角形共享一个顶点。
假设TriangleA&amp; TriangleB共享一个共同的顶点。
你不能只是“摆动”triangleA的顶点,因为这会导致TriangleA和TriangleB在该公共顶点处分离。
<强>解决方案强>
对于每个共同的顶点,您必须用相同的顶点指示每个多边形,以将它们的公共顶点移动到完全相同的新“摆动”点。
这是一种方法(警告:伪代码跟随!):
创建多边形(如果需要,再添加50个):
创建一个包含每个多边形顶点(polygon == triangle)的数组。所以每个多边形的点[0],点[1]和point [2]进入一个顶点数组。
var vertices=[];
vertices.push({ poly:poly1, x:poly1.point[0].x, y:poly1.point[0].y, index:0 });
vertices.push({ poly:poly1, x:poly1.point[1].x, y:poly1.point[1].y, index:1 });
vertices.push({ poly:poly1, x:poly1.point[2].x, y:poly1.point[2].y, index:2 });
... and same for each poly#
要“摆动”,迭代顶点数组并通过摆动因子更改每个公共顶点。例如,您可能会发现3个三角形共享[x==5 / y==10]
的公共顶点。要摆动,您可以告诉3个三角形中的每一个将该公共顶点更改为[x==7 / y==9]
。为了使动画看起来更平滑,您可以在一段时间内将动画从[5,10]动画到[7,9]。
示例代码和演示:
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;
var points=[[-5.1,-7.1], [343.4,-7.1], [386.7,194],
[451.1,93.5], [386.7,194], [343.4,-7.1],
[-5.1,-7.1], [262.3,183.5], [386.7,194]
];
var vertices=[];
var vpoints=[];
var tris=[];
var colors=['skyblue','salmon','lightgreen'];
var wobbles=[{x:0,y:0},{x:0,y:0},{x:0,y:0}];
for(var i=0;i<points.length;i++){
// make pt easier to match
pt={
x:Math.round(points[i][0]),
y:Math.round(points[i][1])
}
var vindex=-1;
for(var k=0;k<vertices.length;k++){
var vp=vertices[k].point;
if(vp.x==pt.x && vp.y==pt.y){ vindex=k; break; }
}
if(vindex<0){
vertices.push({ point:pt });
vindex=vertices.length-1;
}
vpoints.push(vindex);
}
for(var i=0;i<points.length;i+=3){
var id=parseInt(i/3);
var tri={
id:id,
color:colors[id],
points:[vpoints[i+0],vpoints[i+1],vpoints[i+2]],
draw:function(){
var pt0=vertices[this.points[0]].point;
var pt1=vertices[this.points[1]].point;
var pt2=vertices[this.points[2]].point;
var w0=vertices[this.points[0]].wobble;
var w1=vertices[this.points[1]].wobble;
var w2=vertices[this.points[2]].wobble;
var dx,dy;
var pct=animatePct/100;
dx=pt0.x-w0.x;
dy=pt0.y-w0.y;
var p0={x:pt0.x-w0.x*pct,y:pt0.y-w0.y*pct};
dx=pt1.x-w0.x;
dy=pt1.y-w0.y;
var p1={x:pt1.x-w1.x*pct,y:pt1.y-w1.y*pct};
dx=pt2.x-w0.x;
dy=pt2.y-w0.y;
var p2={x:pt2.x-w2.x*pct,y:pt2.y-w2.y*pct};
ctx.beginPath();
ctx.moveTo(p0.x,p0.y);
ctx.lineTo(p1.x,p1.y);
ctx.lineTo(p2.x,p2.y);
ctx.closePath();
ctx.fillStyle=this.color;
ctx.fill();
},
};
tris.push(tri);
}
var nextTime=0;
var delay=1000/60*3;
requestAnimationFrame(animate);
var animatePct;
var animateRate=5;
var wobbleDirection=1;
buildWobble();
function animate(time){
if(time<nextTime){requestAnimationFrame(animate);return;}
nextTime=time+delay;
drawAll();
animatePct+=animateRate;
if(animatePct>100){ animateRate*=-1; animatePct=100; }
if(animatePct<000){ animateRate*=-1; animatePct=0; }
requestAnimationFrame(animate);
}
function drawAll(){
// draw
ctx.clearRect(0,0,cw,ch);
ctx.translate(25,25);
for(var i=0;i<tris.length;i++){
tris[i].draw();
}
ctx.translate(-25,-25);
}
function buildWobble(){
animatePct=0;
for(var i=0;i<vertices.length;i++){
vertices[i].wobble={x:Math.random()*40-20,y:Math.random()*40-20};
}
}
<canvas id="canvas" width=510 height=260></canvas>