;(function(undefined) { 'use strict'; var shapes = []; var register = function(name,drawShape,drawBorder) { shapes.push({ 'name': name, 'drawShape': drawShape, 'drawBorder': drawBorder }); } var enumerateShapes = function() { return shapes; } /** * For the standard closed shapes - the shape fill and border are drawn the * same, with some minor differences for fill and border. To facilitate this we * create the generic draw functions, that take a shape drawing func and * return a shape-renderer/border-renderer * ---------- */ var genericDrawShape = function(shapeFunc) { return function(node,x,y,size,color,context) { context.fillStyle = color; context.beginPath(); shapeFunc(node,x,y,size,context); context.closePath(); context.fill(); }; } var genericDrawBorder = function(shapeFunc) { return function(node,x,y,size,color,context) { context.strokeStyle = color; context.lineWidth = size / 5; context.beginPath(); shapeFunc(node,x,y,size,context); context.closePath(); context.stroke(); }; } /** * We now proced to use the generics to define our standard shape/border * drawers: square, diamond, equilateral (polygon), and star * ---------- */ var drawSquare = function(node,x,y,size,context) { var rotate = Math.PI*45/180; // 45 deg rotation of a diamond shape context.moveTo(x+size*Math.sin(rotate), y-size*Math.cos(rotate)); // first point on outer radius, dwangle 'rotate' for(var i=1; i<4; i++) { context.lineTo(x+Math.sin(rotate+2*Math.PI*i/4)*size, y-Math.cos(rotate+2*Math.PI*i/4)*size); } } register("square",genericDrawShape(drawSquare),genericDrawBorder(drawSquare)); var drawCircle = function(node,x,y,size,context) { context.arc(x,y,size,0,Math.PI*2,true); } register("circle",genericDrawShape(drawCircle),genericDrawBorder(drawCircle)); var drawDiamond = function(node,x,y,size,context) { context.moveTo(x-size, y); context.lineTo(x, y-size); context.lineTo(x+size, y); context.lineTo(x, y+size); } register("diamond",genericDrawShape(drawDiamond),genericDrawBorder(drawDiamond)); var drawCross = function(node,x,y,size,context) { var lineWeight = (node.cross && node.cross.lineWeight) || 5; context.moveTo(x-size, y-lineWeight); context.lineTo(x-size, y+lineWeight); context.lineTo(x-lineWeight, y+lineWeight); context.lineTo(x-lineWeight, y+size); context.lineTo(x+lineWeight, y+size); context.lineTo(x+lineWeight, y+lineWeight); context.lineTo(x+size, y+lineWeight); context.lineTo(x+size, y-lineWeight); context.lineTo(x+lineWeight, y-lineWeight); context.lineTo(x+lineWeight, y-size); context.lineTo(x-lineWeight, y-size); context.lineTo(x-lineWeight, y-lineWeight); } register("cross",genericDrawShape(drawCross),genericDrawBorder(drawCross)); var drawEquilateral = function(node,x,y,size,context) { var pcount = (node.equilateral && node.equilateral.numPoints) || 5; var rotate = ((node.equilateral && node.equilateral.rotate) || 0)*Math.PI/180; var radius = size; context.moveTo(x+radius*Math.sin(rotate), y-radius*Math.cos(rotate)); // first point on outer radius, angle 'rotate' for(var i=1; i