Reputation: 1386
I have drawn a polygon with the following code. Now I want to resize that polygon animatedly. In detail, I want to set an angular movement to one side of the polygon, such that it makes an arc, and so changes the size of polygon. I googled for everything regarding the polygon animation, but didn't get anything, though there is plenty of material for line animation.
<script>
$(function(){
var c=$('#myCanvas');
var ctx=c.getContext("2d");
ctx.fillStyle='#f00';
ctx.beginPath();
ctx.moveTo(0,40);
ctx.lineTo(80,200);
ctx.lineTo(100,200);
ctx.lineTo(40,0);
ctx.closePath();
ctx.fill();
</script>
</div>
Is it possible to pick a line of a polygon and animate it, to change the shape of the polygon?
Upvotes: 2
Views: 3315
Reputation: 105015
Here’s how to turn a triangle into a square, a square into a pentagon, etc ….
This code draws a regular polygon with the specified number of sides:
function drawPolygon(sideCount,size,centerX,centerY){
// draw a regular polygon with sideCount sides
ctx.save();
ctx.beginPath();
ctx.moveTo (centerX + size * Math.cos(0), centerY + size * Math.sin(0));
for (var i = 1; i <= sideCount;i += 1) {
var x=centerX + size * Math.cos(i * 2 * Math.PI / sideCount);
var y=centerY + size * Math.sin(i * 2 * Math.PI / sideCount);
ctx.lineTo (x, y);
}
ctx.stroke();
ctx.fill();
ctx.restore();
}
Animating odd-sided polygons into even-sided polygons
In this illustration, you can animate a triangle into a square by animating each colored vertex on the triangle to its corresponding position on the square. All odd-sided polygons are transformed into even-sided polygons that same way.
Animating even-sided polygons into odd-sided polygons
In this illustration, you can animate a square into a pentagon by animating each colored vertex on the square to its corresponding position on the pentagon. In this case, you have to also cut the left-most yellow vertex in two and animate the two portions to the two yellow vertices on the pentagon. All even-sided polygons are transformed into odd-sided polygons that same way.
Here’s code and a Fiddle: http://jsfiddle.net/m1erickson/DjV5f/
<!doctype html>
<html>
<head>
<link rel="stylesheet" type="text/css" media="all" href="css/reset.css" /> <!-- reset css -->
<script type="text/javascript" src="http://code.jquery.com/jquery.min.js"></script>
<style>
body{ background-color: ivory; padding:10px; }
canvas{border:1px solid red;}
p{font-size:24px;}
</style>
<script>
$(function(){
var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
//
var colors=["","blue","green","black"];
drawPolygon(3,50,70,70,2,"blue","red",colors,true);
colors=["","blue","yellow","green","black"];
drawPolygon(4,50,215,70,2,"blue","red",colors,false);
//
ctx.beginPath();
ctx.moveTo(0,162);
ctx.lineTo(300,162);
ctx.stroke();
//
var colors=["black","blue","yellow","green"];
drawPolygon(4,50,70,250,2,"blue","red",colors,true);
colors=["black","blue","yellow","yellow","green"];
drawPolygon(5,50,215,250,2,"blue","red",colors,false);
function drawPolygon(sideCount,size,centerX,centerY,strokeWidth,strokeColor,fillColor,colorPts,showBursePoint){
// draw a regular polygon with sideCount sides
ctx.save();
ctx.beginPath();
ctx.moveTo (centerX + size * Math.cos(0), centerY + size * Math.sin(0));
for (var i = 1; i <= sideCount;i += 1) {
var x=centerX + size * Math.cos(i * 2 * Math.PI / sideCount);
var y=centerY + size * Math.sin(i * 2 * Math.PI / sideCount);
ctx.lineTo (x, y);
}
ctx.fillStyle=fillColor;
ctx.strokeStyle = strokeColor;
ctx.lineWidth = strokeWidth;
ctx.stroke();
ctx.fill();
ctx.restore();
// draw vertex points
for (var i = 1; i <= sideCount;i += 1) {
var x=centerX + size * Math.cos(i * 2 * Math.PI / sideCount);
var y=centerY + size * Math.sin(i * 2 * Math.PI / sideCount);
drawPoint(x,y,colorPts[i]);
}
// draw point where this poly will "burst" to create next poly
if(showBursePoint){
var burstX= centerX + size * Math.cos( Math.floor(sideCount/2) * 2 * Math.PI / sideCount);
var burstY= centerY;
drawPoint(burstX, burstY, "yellow");
}
}
function drawPoint(x,y,fill){
ctx.save()
ctx.strokeStyle="black";
ctx.lineWidth=2;
ctx.fillStyle=fill;
ctx.beginPath();
ctx.arc(x,y,6,0,Math.PI*2,false);
ctx.fill();
ctx.stroke();
ctx.restore();
}
}); // end $(function(){});
</script>
</head>
<body>
<p>Regular polygons (3-8 sides)</p><br/>
<p>Unmoving anchor point is green</p><br/>
<p>Burst point is yellow</p><br/>
<canvas id="canvas" width=300 height=350></canvas>
</body>
</html>
Upvotes: 0
Reputation:
The trick is to store the coordinates of the polygon in an array and work on the numbers in that array instead.
Then render what you have in the array to canvas. Worry-free when it comes to translation and what-have-you.
See canvas as only a snapshot of whatever you have in the array at the moment.
Upvotes: 1
Reputation: 1386
Ok this is what I did and which has worked out:
<script>
var canvas = document.getElementById("myCanvas");
var dc = canvas.getContext("2d");
var angle = 0;
var x = canvas.width;
var y = canvas.height;
window.setInterval(function(){
angle = (angle + 1) % 360;
dc.clearRect(0, 0, canvas.width, canvas.height);
dc.save();
dc.fillStyle = "#DDDDDD";
dc.translate(x/2,y);
dc.rotate( angle*Math.PI/270 ); // rotate 90 degrees
dc.translate(0,0);
dc.beginPath();
dc.moveTo(-x/16, 0);
dc.lineTo(-x, y/2);
dc.lineTo(-x/2,y);
dc.lineTo(-0,y/16);
dc.closePath();
dc.fill();
dc.restore();
}, 20);
</script>
I referred to Bill's answer at https://stackoverflow.com/a/2767556/2163837 Thanks for your help also.
Upvotes: 0