Skip to content

Instantly share code, notes, and snippets.

@benkehoe
Created May 15, 2014 19:50
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save benkehoe/f7f9154105a6358a9c29 to your computer and use it in GitHub Desktop.
Save benkehoe/f7f9154105a6358a9c29 to your computer and use it in GitHub Desktop.
<!DOCTYPE html>
<html>
<head>
<title>Draw Polygon</title>
<script type="text/javascript" src="http://lib.ivank.net/ivank.js"></script>
<script type="text/javascript" src="http://polyk.ivank.net/polyk.js"></script>
<script type="text/javascript">
var stage, s, dragged, complete, stopClick, rmv, cent, jsonText, cvs, sbt, area, centX, centY;
var remove = false;
//dragged is set to true if a Dot is being dragged
//complete is set to true if the shape is completed
//stopClick allows the Dot listener to return so
//that the stage listener is not called.
//jsonText refers to the html text box object
//cvs is the canvas object
//rmv and sbt refer to the Remove Vertices and Submit buttons
//cent holds the Centroid sprite
//centX and centY hold the Centroid coordinates.
var polyX = []; //Dot x coordinates
var polyY = []; //Dot y coordinates
var dots = []; //holds Dot objects
var jsonObj = { "centroid" : [], "vertices" : [] };
function Go(canvas_id,remove_id,submit_id,json_text_id) //setup
{
cvs = document.getElementById(canvas_id);
rmv = document.getElementById(remove_id); //"Remove Vertices" button element
sbt = document.getElementById(submit_id); //"Submit" button element
jsonText = document.getElementById(json_text_id);
rmv.style.backgroundColor='#fcfcfc';
sbt.disabled = true; //submit button is initially unusable
jsonText.value = JSON.stringify(jsonObj);
stage = new Stage("c");
s = new Sprite();
stage.addChild(s);
stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownStage);
stage.addEventListener(MouseEvent.MOUSE_UP, onMouseUpStage);
stage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseMoveStage);
redraw();
//s.alpha = PolyK.ContainsPoint(poly, stage.mouseX, stage.mouseY)?1:0.4;
}
/* Dot() creates a dot object.
and draws it on the canvas using
the Sprite graphics object.
NOTE: This is currently broken because of
a problem with rendering graphics with
the canvas offset.
*/
function Dot()
{
Sprite.apply(this); // inherits from Sprite
this.graphics.beginFill(0x000000, 0.15);
this.graphics.drawCircle(0-cvs.offsetLeft,0-cvs.offsetTop,13);
this.graphics.beginFill(0xffffff, 1.0);
this.graphics.drawCircle(0-cvs.offsetLeft,0-cvs.offsetTop,6);
this.graphics.beginFill(0x00ff00, 0.01);
this.graphics.drawCircle(0,0,6);
this.buttonMode = true;
}
Dot.prototype = new Sprite();
/* Centroid() creates a Centroid object.
and draws it on the canvas using
the Sprite graphics object.
NOTE: This is currently broken because of
a problem with rendering graphics with
the canvas offset.
*/
function Centroid()
{
Sprite.apply(this); // inherits from Sprite
this.graphics.beginFill(0x000000, 0.15);
this.graphics.drawCircle(0-cvs.offsetLeft,0-cvs.offsetTop,7);
this.graphics.beginFill(0x00ff00, 0.01);
this.graphics.drawCircle(0,0,6);
this.buttonMode = true;
}
Centroid.prototype = new Sprite();
/* calcArea() calculates the area
of a polygon in order to
calculate the centroid x
and y coordinates
*/
function calcArea()
{ //assumes polyY and polyX are same length
area = 0;
var len = polyX.length;
for(var i = 0; i < len;i++)
{
area += polyX[i] * polyY[(i+1) % len] - polyX[(i+1) % len] * polyY[i]
}
area = (1/2)*area;
}
/* calcCentroid() sets the centX
and centY coordinates to the
coordinates of the centroid.
*/
function calcCentroid()
{
calcArea();
centX = 0;
centY = 0;
var term;
var len = polyY.length;
for (var i=0; i < len;i++)
{
term = polyX[i] * polyY[(i+1) % len] - polyX[(i+1) % len] * polyY[i];
centX += (polyX[i] + polyX[(i+1) % len]) * term;
centY += (polyY[i] + polyY[(i+1) % len]) * term;
}
centX = (1/(6 * area)) * centX;
centY = (1/(6 * area)) * centY;
}
/* callback() is a skeleton
that will eventually submit
the JSON data to the server.
*/
function callback()
{
window.alert("Your submission has been recorded " + JSON.stringify(jsonObj));
}
/* toggleSubmit() enables/disables
the submit button based on whether
the shape is completed or not.
*/
function toggleSubmit()
{
sbt.disabled = !complete;
}
/* onMouseDownDot() checks whether the mouse click
occurs on the first dot, and if so it sets
the shape as complete.
*/
function onMouseDownDot(e)
{
stopClick = true;
dragged = e.target;
if (remove) //delete dot and update centroid
{
deleteDot(dragged);
}
if (e.target.x-cvs.offsetLeft == polyX[0] && e.target.y-cvs.offsetTop == polyY[0]) //shape is being completed
{
complete = true;
if (polyX.length >= 3)
{
toggleSubmit();
}
redraw();
}
}
/* updateCentroid() calls deleteCentroid
and createCentroid() to replace the centroid.
Called from redraw().
*/
function updateCentroid()
{
if (cent != null)
{
deleteCentroid();
}
if (polyX.length >= 3 && complete)
{
calcCentroid();
createCentroid(centX,centY);
}
}
/* deleteDot removes the graphics
for a given Dot and updates the
Dot and coordinate arrays.
*/
function deleteDot(dot)
{
var i = dots.indexOf(dragged);
dots[i].graphics.clear();
dots.splice(i,1);
polyX.splice(i,1);
polyY.splice(i,1);
redraw();
//update JSON
jsonObj["vertices"].splice(i,1);
jsonText.value = JSON.stringify(jsonObj);
}
/* deleteCentroid removes the graphics
for the centroid and updates
the JSON object
*/
function deleteCentroid()
{
if (cent != null) {
cent.graphics.clear();
}
//update JSON
jsonObj.centroid = [];
jsonText.value = JSON.stringify(jsonObj);
}
/* onMouseDownStage() creates a new Dot and adds it to the
dots array if a mouse click occurs in the stage
area.
*/
function onMouseDownStage(e)
{
if (dragged != null)
{
return;
}
if (stopClick)
{
stopClick = false;
return;
}
complete = false;
toggleSubmit();
if (!remove) {
createDot(e,stage.mouseX,stage.mouseY); //updates JSON
}
redraw();
}
/* createDot creates a new dot
object at the given coordinates
and updates the Dot
and coordinate arrays
*/
function createDot(e,x,y)
{
var dot = new Dot();
dot.x = x;
dot.y = y;
dots.push(dot);
dot.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDownDot);
stage.addChild(dot);
polyX.push(dot.x-cvs.offsetLeft);
polyY.push(dot.y-cvs.offsetTop);
//update JSON
jsonObj.vertices.push([dot.x-cvs.offsetLeft,dot.y-cvs.offsetTop]);
jsonText.value = JSON.stringify(jsonObj);
}
/* createCentroid creates a new centroid
object at the given coordinates
and updates the centroid array
in the JSON object.
*/
function createCentroid(x,y)
{
cent = new Centroid();
cent.x = x+cvs.offsetLeft;
cent.y = y+cvs.offsetTop;
//cent.push(dot);
stage.addChild(cent);
//update JSON
jsonObj.centroid.push([cent.x-cvs.offsetLeft,cent.y-cvs.offsetTop]);
jsonText.value = JSON.stringify(jsonObj);
}
/* onMouseUpStage() handles the mouse up movement,
at this point no Dot() is being dragged.
*/
function onMouseUpStage(e){dragged = null; stopClick = false;}
/* onMouseMoveStage() handles the mouse movement
on the stage, and updates the position
of a Dot if it is being dragged.
*/
function onMouseMoveStage(e)
{
if(dragged != null)
{
dragged.x = stage.mouseX+cvs.offsetLeft; dragged.y = stage.mouseY+cvs.offsetTop;
var i = dots.indexOf(dragged);
polyX[i] = stage.mouseX;
polyY[i] = stage.mouseY;
redraw();
//update JSON
jsonObj.vertices[i] = [polyX[i],polyY[i]];
jsonText.value = JSON.stringify(jsonObj);
}
//s.alpha = PolyK.ContainsPoint(poly, stage.mouseX, stage.mouseY)?1:0.4;
}
/* toggleRemove() handles
setting the remove vertices
button background color
and text.
*/
function toggleRemove() {
if (remove) {
remove = false;
rmv.style.backgroundColor='#fcfcfc';
rmv.value = "Remove Vertices OFF";
}
else {
remove = true;
rmv.style.backgroundColor='#ff0000';
rmv.value = "Remove Vertices ON";
}
}
/* redraw() clears the lines drawn so far on the stage
and then calls strokePoly() to redraw these lines.
Also updates the centroid.
*/
function redraw()
{
s.graphics.clear();
updateCentroid();
strokePoly(polyX,polyY,s);
}
/* strokePoly draws the lines between each of
the Dot objects. Takes in the x-coordinates
and y-coordinates of each dot as well as the
stage s.
*/
function strokePoly(polyX,polyY, s)
{
var n = polyX.length;
s.graphics.lineStyle(6, 0xff0000);
s.graphics.moveTo(polyX[0], polyY[0]);
for(var i=1; i<n; i++) s.graphics.lineTo(polyX[i], polyY[i]);
if (complete && n > 2) //n > 2 ensures that lines are not drawn over each other.
{
s.graphics.lineTo(polyX[0], polyY[0]);
}
}
/* clearDrawing() clears all dots using each Dot graphic object,
and sets the coordinate arrays to empty.
*/
function clearDrawing()
{
for (var i=0; i<polyX.length;i++) dots[i].graphics.clear();
polyX = [];
polyY = [];
dots = [];
redraw();
//update JSON
jsonObj["vertices"] = [];
jsonText.value = JSON.stringify(jsonObj);
}
</script>
</head>
<body>
<form>
<input id="jsonText" type="text" style="width:500px;">
<input type="button" id="submit" onclick="callback()" value="Submit">
<input type="button" id="clear" onclick="clearDrawing();" value="Clear Shape">
<input type="button" id="remove" onclick="toggleRemove()" value="Remove Vertices OFF">
</form>
<canvas id="c" width="400" height="120"></canvas>
<script>
Go("c","remove","submit","jsonText");
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment