CanvasDrawing.js revision 0fdefaa9ca017edfb76b736c825b34186f33045a
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * <a href="http://www.w3.org/TR/html5/the-canvas-element.html">Canvas</a> implementation of the <a href="Drawing.html">`Drawing`</a> class.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * `CanvasDrawing` is not intended to be used directly. Instead, use the <a href="Drawing.html">`Drawing`</a> class.
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync * If the browser lacks <a href="http://www.w3.org/TR/SVG/">SVG</a> capabilities but has
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync * <a href="http://www.w3.org/TR/html5/the-canvas-element.html">Canvas</a> capabilities, the <a href="Drawing.html">`Drawing`</a>
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * class will point to the `CanvasDrawing` class.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * @class CanvasDrawing
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * @constructor
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * Parses hex color string and alpha value to rgba
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * @method _toRGBA
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * @param {Object} val Color value to parse. Can be hex string, rgb or name.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync * @param {Number} alpha Numeric value between 0 and 1 representing the alpha level.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Converts color to rgb format
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @method _toRGB
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param val Color value to convert.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Sets the size of the graphics object.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @method setSize
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param w {Number} width to set for the instance.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param h {Number} height to set for the instance.
29099c2d04b11e614f1fa399fab9e9162f2788b9vboxsync setSize: function(w, h) {
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * Tracks coordinates. Used to calculate the start point of dashed lines.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @method _updateCoords
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param {Number} x x-coordinate
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param {Number} y y-coordinate
0c94a8282c9042b02f022302a3d987746140eab9vboxsync _updateCoords: function(x, y)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Clears the coordinate arrays. Called at the end of a drawing operation.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @method _clearAndUpdateCoords
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Moves the shape's dom node.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @method _updateNodePosition
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Queues up a method to be executed when a shape redraws.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @method _updateDrawingQueue
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Array} val An array containing data that can be parsed into a method and arguments. The value at zero-index of the array is a string reference of
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * the drawing method that will be called. All subsequent indices are argument for that method. For example, `lineTo(10, 100)` would be structured as:
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * `["lineTo", 10, 100]`.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Draws a line segment using the current line style from the current drawing position to the specified x and y coordinates.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @method lineTo
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Number} point1 x-coordinate for the end point.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} point2 y-coordinate for the end point.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync wt = this._stroke && this._strokeWeight ? this._strokeWeight : 0;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync if (typeof point1 === 'string' || typeof point1 === 'number') {
0c94a8282c9042b02f022302a3d987746140eab9vboxsync for (; i < len; ++i)
0c94a8282c9042b02f022302a3d987746140eab9vboxsync this._lineToMethods[this._lineToMethods.length] = this._methods[this._methods.length - 1];
0c94a8282c9042b02f022302a3d987746140eab9vboxsync return this;
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * Moves the current drawing position to specified x and y coordinates.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @method moveTo
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param {Number} x x-coordinate for the end point.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param {Number} y y-coordinate for the end point.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync moveTo: function(x, y) {
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync var wt = this._stroke && this._strokeWeight ? this._strokeWeight : 0;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return this;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Draws a bezier curve.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @method curveTo
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} cp1x x-coordinate for the first control point.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param {Number} cp1y y-coordinate for the first control point.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param {Number} cp2x x-coordinate for the second control point.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param {Number} cp2y y-coordinate for the second control point.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param {Number} x x-coordinate for the end point.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @param {Number} y y-coordinate for the end point.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync this._updateDrawingQueue(["bezierCurveTo", cp1x, cp1y, cp2x, cp2y, x, y]);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return this;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Draws a quadratic bezier curve.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @method quadraticCurveTo
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} cpx x-coordinate for the control point.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} cpy y-coordinate for the control point.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} x x-coordinate for the end point.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} y y-coordinate for the end point.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync wt = this._stroke && this._strokeWeight ? this._strokeWeight : 0;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync this._updateDrawingQueue(["quadraticCurveTo", cpx, cpy, x, y]);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return this;
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Draws a circle. Used internally by `CanvasCircle` class.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @method drawCircle
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} x y-coordinate
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} y x-coordinate
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} r radius
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @protected
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync wt = this._stroke & this._strokeWeight ? this._strokeWeight : 0,
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync this._updateDrawingQueue(["arc", x + radius, y + radius, radius, startAngle, endAngle, false]);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync return this;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Draws an ellipse. Used internally by `CanvasEllipse` class.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @method drawEllipse
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} x x-coordinate
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Number} y y-coordinate
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Number} w width
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Number} h height
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @protected
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync drawEllipse: function(x, y, w, h) {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync wt = this._stroke && this._strokeWeight ? this._strokeWeight : 0;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync for(; i < l; i++)
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync cx = centerX + Math.cos(angleMid) * (radius / Math.cos(theta / 2));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync cy = centerY + Math.sin(angleMid) * (yRadius / Math.cos(theta / 2));
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync this._updateDrawingQueue(["quadraticCurveTo", cx, cy, bx, by]);
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync return this;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * Draws a rectangle.
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @method drawRect
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Number} x x-coordinate
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Number} y y-coordinate
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Number} w width
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Number} h height
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync drawRect: function(x, y, w, h) {
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync var wt = this._stroke && this._strokeWeight ? this._strokeWeight : 0;
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync this._updateDrawingQueue(["lineTo", x + w, y + h]);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync return this;
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Draws a rectangle with rounded corners.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @method drawRect
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @param {Number} x x-coordinate
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @param {Number} y y-coordinate
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @param {Number} w width
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @param {Number} h height
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @param {Number} ew width of the ellipse used to draw the rounded corners
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @param {Number} eh height of the ellipse used to draw the rounded corners
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync var wt = this._stroke && this._strokeWeight ? this._strokeWeight : 0;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync this._updateDrawingQueue(["lineTo", x, y + h - eh]);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync this._updateDrawingQueue(["quadraticCurveTo", x, y + h, x + ew, y + h]);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync this._updateDrawingQueue(["lineTo", x + w - ew, y + h]);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync this._updateDrawingQueue(["quadraticCurveTo", x + w, y + h, x + w, y + h - eh]);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync this._updateDrawingQueue(["lineTo", x + w, y + eh]);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync this._updateDrawingQueue(["quadraticCurveTo", x + w, y, x + w - ew, y]);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync this._updateDrawingQueue(["quadraticCurveTo", x, y, x, y + eh]);
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync return this;
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * Draws a wedge.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @method drawWedge
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @param {Number} x x-coordinate of the wedge's center point
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @param {Number} y y-coordinate of the wedge's center point
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @param {Number} startAngle starting angle in degrees
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync * @param {Number} arc sweep of the wedge. Negative values draw clockwise.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param {Number} radius radius of wedge. If [optional] yRadius is defined, then radius is the x radius.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync * @param {Number} yRadius [optional] y radius for wedge.
0c94a8282c9042b02f022302a3d987746140eab9vboxsync drawWedge: function(x, y, startAngle, arc, radius, yRadius)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync // move to x,y position
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync // limit sweep to reasonable numbers
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync // First we calculate how many segments are needed
0c69348b58bb8eabb1bea8867ee932b667bd0d34vboxsync // for a smooth arc.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync // Now calculate the sweep of each segment.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync // The math requires radians rather than degrees. To convert from degrees
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync // use the formula (degrees/180)*Math.PI to get radians.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync // convert angle startAngle to radians
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync // draw the curve in segments no larger than 45 degrees.
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync // draw a line from the center to the start of the curve
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync ax = x + Math.cos(startAngle / 180 * Math.PI) * radius;
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync ay = y + Math.sin(startAngle / 180 * Math.PI) * yRadius;
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync // Loop for drawing curve segments
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync for(; i < segs; ++i)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync cx = x + Math.cos(angleMid) * (radius / Math.cos(theta / 2));
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync cy = y + Math.sin(angleMid) * (yRadius / Math.cos(theta / 2));
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync this._updateDrawingQueue(["quadraticCurveTo", cx, cy, bx, by]);
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync // close the wedge by drawing a line to the center
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync return this;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync * Completes a drawing operation.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @method end
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync end: function() {
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync return this;
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync * Clears the graphics object.
f9cdd92d151d9c28eb0f1aed25863fc04f85691dvboxsync * @method clear
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Returns a linear gradient fill
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @method _getLinearGradient
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @return CanvasGradient
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync tanRadians = parseFloat(parseFloat(Math.tan(r * radCon)).toFixed(8));
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if(r < 180)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync gradient = this._context.createLinearGradient(x1, y1, x2, y2);
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync for(; i < len; ++i)
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Returns a radial gradient fill
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * @method _getRadialGradient
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @return CanvasGradient
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync d = Math.sqrt( Math.pow(Math.abs(xc - x1), 2) + Math.pow(Math.abs(yc - y1), 2) );
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync //hack. gradient won't show if it is exactly on the edge of the arc
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync //If the gradient radius is greater than the circle's, adjusting the radius stretches the gradient properly.
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync //If the gradient radius is less than the circle's, adjusting the radius of the gradient will not work.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync //Instead, adjust the color stops to reflect the smaller radius.
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync if(r >= 0.5)
661bfa5aae55ac2f94fa1cb131ea2323e5f6e633vboxsync gradient = this._context.createRadialGradient(x1, y1, r, x2, y2, r * w);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync gradient = this._context.createRadialGradient(x1, y1, r, x2, y2, w/2);
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync for(; i < len; ++i)
66b58af085e22ee26be57f98127fb49ee2e91790vboxsync * Clears all values
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @method _initProps
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync _initProps: function() {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Indicates a drawing has completed.
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @property _drawingComplete
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @type Boolean
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * Creates canvas element
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @method _createGraphic
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync * @return HTMLCanvasElement
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync var graphic = Y.config.doc.createElement('canvas');
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * Updates the size of the graphics object
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @method _trackSize
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} w width
19320d55d1417c39b3b5673a53aaa5ef177242c8vboxsync * @param {Number} h height
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync _trackSize: function(w, h) {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (w > this._right) {
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if(w < this._left)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (h < this._top)
c66c4413faa5a72ce047742f9acfa85e94dec8afvboxsync if (h > this._bottom)