/**
|
|
* Canvas shapes used by Network
|
|
*/
|
|
if (typeof CanvasRenderingContext2D !== 'undefined') {
|
|
|
|
/**
|
|
* Draw a circle shape
|
|
*/
|
|
CanvasRenderingContext2D.prototype.circle = function (x, y, r) {
|
|
this.beginPath();
|
|
this.arc(x, y, r, 0, 2 * Math.PI, false);
|
|
this.closePath();
|
|
};
|
|
|
|
/**
|
|
* Draw a square shape
|
|
* @param {Number} x horizontal center
|
|
* @param {Number} y vertical center
|
|
* @param {Number} r size, width and height of the square
|
|
*/
|
|
CanvasRenderingContext2D.prototype.square = function (x, y, r) {
|
|
this.beginPath();
|
|
this.rect(x - r, y - r, r * 2, r * 2);
|
|
this.closePath();
|
|
};
|
|
|
|
/**
|
|
* Draw a triangle shape
|
|
* @param {Number} x horizontal center
|
|
* @param {Number} y vertical center
|
|
* @param {Number} r radius, half the length of the sides of the triangle
|
|
*/
|
|
CanvasRenderingContext2D.prototype.triangle = function (x, y, r) {
|
|
// http://en.wikipedia.org/wiki/Equilateral_triangle
|
|
this.beginPath();
|
|
|
|
// the change in radius and the offset is here to center the shape
|
|
r *= 1.15;
|
|
y += 0.275 * r;
|
|
|
|
var s = r * 2;
|
|
var s2 = s / 2;
|
|
var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
|
|
var h = Math.sqrt(s * s - s2 * s2); // height
|
|
|
|
|
|
this.moveTo(x, y - (h - ir));
|
|
this.lineTo(x + s2, y + ir);
|
|
this.lineTo(x - s2, y + ir);
|
|
this.lineTo(x, y - (h - ir));
|
|
this.closePath();
|
|
|
|
|
|
};
|
|
|
|
/**
|
|
* Draw a triangle shape in downward orientation
|
|
* @param {Number} x horizontal center
|
|
* @param {Number} y vertical center
|
|
* @param {Number} r radius
|
|
*/
|
|
CanvasRenderingContext2D.prototype.triangleDown = function (x, y, r) {
|
|
// http://en.wikipedia.org/wiki/Equilateral_triangle
|
|
this.beginPath();
|
|
|
|
// the change in radius and the offset is here to center the shape
|
|
r *= 1.15;
|
|
y -= 0.275 * r;
|
|
|
|
var s = r * 2;
|
|
var s2 = s / 2;
|
|
var ir = Math.sqrt(3) / 6 * s; // radius of inner circle
|
|
var h = Math.sqrt(s * s - s2 * s2); // height
|
|
|
|
this.moveTo(x, y + (h - ir));
|
|
this.lineTo(x + s2, y - ir);
|
|
this.lineTo(x - s2, y - ir);
|
|
this.lineTo(x, y + (h - ir));
|
|
this.closePath();
|
|
};
|
|
|
|
/**
|
|
* Draw a star shape, a star with 5 points
|
|
* @param {Number} x horizontal center
|
|
* @param {Number} y vertical center
|
|
* @param {Number} r radius, half the length of the sides of the triangle
|
|
*/
|
|
CanvasRenderingContext2D.prototype.star = function (x, y, r) {
|
|
// http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
|
|
this.beginPath();
|
|
|
|
// the change in radius and the offset is here to center the shape
|
|
r *= 0.82;
|
|
y += 0.1 * r;
|
|
|
|
for (var n = 0; n < 10; n++) {
|
|
var radius = (n % 2 === 0) ? r * 1.3 : r * 0.5;
|
|
this.lineTo(
|
|
x + radius * Math.sin(n * 2 * Math.PI / 10),
|
|
y - radius * Math.cos(n * 2 * Math.PI / 10)
|
|
);
|
|
}
|
|
|
|
this.closePath();
|
|
};
|
|
|
|
/**
|
|
* Draw a Diamond shape
|
|
* @param {Number} x horizontal center
|
|
* @param {Number} y vertical center
|
|
* @param {Number} r radius, half the length of the sides of the triangle
|
|
*/
|
|
CanvasRenderingContext2D.prototype.diamond = function (x, y, r) {
|
|
// http://www.html5canvastutorials.com/labs/html5-canvas-star-spinner/
|
|
this.beginPath();
|
|
|
|
this.lineTo(x, y + r);
|
|
this.lineTo(x + r, y);
|
|
this.lineTo(x, y - r);
|
|
this.lineTo(x - r, y);
|
|
|
|
|
|
this.closePath();
|
|
};
|
|
|
|
/**
|
|
* http://stackoverflow.com/questions/1255512/how-to-draw-a-rounded-rectangle-on-html-canvas
|
|
*/
|
|
CanvasRenderingContext2D.prototype.roundRect = function (x, y, w, h, r) {
|
|
var r2d = Math.PI / 180;
|
|
if (w - ( 2 * r ) < 0) {
|
|
r = ( w / 2 );
|
|
} //ensure that the radius isn't too large for x
|
|
if (h - ( 2 * r ) < 0) {
|
|
r = ( h / 2 );
|
|
} //ensure that the radius isn't too large for y
|
|
this.beginPath();
|
|
this.moveTo(x + r, y);
|
|
this.lineTo(x + w - r, y);
|
|
this.arc(x + w - r, y + r, r, r2d * 270, r2d * 360, false);
|
|
this.lineTo(x + w, y + h - r);
|
|
this.arc(x + w - r, y + h - r, r, 0, r2d * 90, false);
|
|
this.lineTo(x + r, y + h);
|
|
this.arc(x + r, y + h - r, r, r2d * 90, r2d * 180, false);
|
|
this.lineTo(x, y + r);
|
|
this.arc(x + r, y + r, r, r2d * 180, r2d * 270, false);
|
|
this.closePath();
|
|
};
|
|
|
|
/**
|
|
* http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
|
|
*
|
|
* Postfix '_vis' added to discern it from standard method ellipse().
|
|
*/
|
|
CanvasRenderingContext2D.prototype.ellipse_vis = function (x, y, w, h) {
|
|
var kappa = .5522848,
|
|
ox = (w / 2) * kappa, // control point offset horizontal
|
|
oy = (h / 2) * kappa, // control point offset vertical
|
|
xe = x + w, // x-end
|
|
ye = y + h, // y-end
|
|
xm = x + w / 2, // x-middle
|
|
ym = y + h / 2; // y-middle
|
|
|
|
this.beginPath();
|
|
this.moveTo(x, ym);
|
|
this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
|
|
this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
|
|
this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
|
|
this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
|
|
this.closePath();
|
|
};
|
|
|
|
|
|
/**
|
|
* http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
|
|
*/
|
|
CanvasRenderingContext2D.prototype.database = function (x, y, w, h) {
|
|
var f = 1 / 3;
|
|
var wEllipse = w;
|
|
var hEllipse = h * f;
|
|
|
|
var kappa = .5522848,
|
|
ox = (wEllipse / 2) * kappa, // control point offset horizontal
|
|
oy = (hEllipse / 2) * kappa, // control point offset vertical
|
|
xe = x + wEllipse, // x-end
|
|
ye = y + hEllipse, // y-end
|
|
xm = x + wEllipse / 2, // x-middle
|
|
ym = y + hEllipse / 2, // y-middle
|
|
ymb = y + (h - hEllipse / 2), // y-midlle, bottom ellipse
|
|
yeb = y + h; // y-end, bottom ellipse
|
|
|
|
this.beginPath();
|
|
this.moveTo(xe, ym);
|
|
|
|
this.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
|
|
this.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
|
|
|
|
this.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
|
|
this.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
|
|
|
|
this.lineTo(xe, ymb);
|
|
|
|
this.bezierCurveTo(xe, ymb + oy, xm + ox, yeb, xm, yeb);
|
|
this.bezierCurveTo(xm - ox, yeb, x, ymb + oy, x, ymb);
|
|
|
|
this.lineTo(x, ym);
|
|
};
|
|
|
|
|
|
/**
|
|
* Draw an arrow at the end of a line with the given angle.
|
|
*/
|
|
CanvasRenderingContext2D.prototype.arrowEndpoint = function (x, y, angle, length) {
|
|
// tail
|
|
var xt = x - length * Math.cos(angle);
|
|
var yt = y - length * Math.sin(angle);
|
|
|
|
// inner tail
|
|
var xi = x - length * 0.9 * Math.cos(angle);
|
|
var yi = y - length * 0.9 * Math.sin(angle);
|
|
|
|
// left
|
|
var xl = xt + length / 3 * Math.cos(angle + 0.5 * Math.PI);
|
|
var yl = yt + length / 3 * Math.sin(angle + 0.5 * Math.PI);
|
|
|
|
// right
|
|
var xr = xt + length / 3 * Math.cos(angle - 0.5 * Math.PI);
|
|
var yr = yt + length / 3 * Math.sin(angle - 0.5 * Math.PI);
|
|
|
|
this.beginPath();
|
|
this.moveTo(x, y);
|
|
this.lineTo(xl, yl);
|
|
this.lineTo(xi, yi);
|
|
this.lineTo(xr, yr);
|
|
this.closePath();
|
|
};
|
|
|
|
/**
|
|
* Draw an circle an the end of an line with the given angle.
|
|
*/
|
|
CanvasRenderingContext2D.prototype.circleEndpoint = function (x, y, angle, length) {
|
|
var radius = length * 0.4;
|
|
var xc = x - radius * Math.cos(angle);
|
|
var yc = y - radius * Math.sin(angle);
|
|
this.circle(xc, yc, radius);
|
|
};
|
|
|
|
/**
|
|
* Sets up the dashedLine functionality for drawing
|
|
* Original code came from http://stackoverflow.com/questions/4576724/dotted-stroke-in-canvas
|
|
* @author David Jordan
|
|
* @date 2012-08-08
|
|
*/
|
|
CanvasRenderingContext2D.prototype.dashedLine = function (x, y, x2, y2, pattern) {
|
|
this.beginPath();
|
|
this.moveTo(x, y);
|
|
|
|
var patternLength = pattern.length;
|
|
var dx = (x2 - x);
|
|
var dy = (y2 - y);
|
|
var slope = dy / dx;
|
|
var distRemaining = Math.sqrt(dx * dx + dy * dy);
|
|
var patternIndex = 0;
|
|
var draw = true;
|
|
var xStep = 0;
|
|
var dashLength = pattern[0];
|
|
|
|
while (distRemaining >= 0.1) {
|
|
dashLength = pattern[patternIndex++ % patternLength];
|
|
if (dashLength > distRemaining) {
|
|
dashLength = distRemaining;
|
|
}
|
|
|
|
xStep = Math.sqrt(dashLength * dashLength / (1 + slope * slope));
|
|
xStep = dx < 0 ? -xStep : xStep;
|
|
x += xStep;
|
|
y += slope * xStep;
|
|
|
|
if (draw === true) {this.lineTo(x,y);}
|
|
else {this.moveTo(x,y);}
|
|
|
|
distRemaining -= dashLength;
|
|
draw = !draw;
|
|
}
|
|
};
|
|
|
|
|
|
}
|