From 76161e1cabb97d5701e259d5228df2e32989226a Mon Sep 17 00:00:00 2001 From: DouG Date: Sat, 5 Mar 2016 12:13:19 +1300 Subject: [PATCH] Convert tabs to spaces --- Winwheel.js | 1956 +++++++++++++++++++++++++-------------------------- 1 file changed, 978 insertions(+), 978 deletions(-) diff --git a/Winwheel.js b/Winwheel.js index ca076cb..891b558 100644 --- a/Winwheel.js +++ b/Winwheel.js @@ -1,28 +1,28 @@ /* - Winwheel.js, by Douglas McKechie @ www.dougtesting.net - See website for tutorials and other documentation. - - The MIT License (MIT) + Winwheel.js, by Douglas McKechie @ www.dougtesting.net + See website for tutorials and other documentation. + + The MIT License (MIT) - Copyright (c) 2016 Douglas McKechie + Copyright (c) 2016 Douglas McKechie - Permission is hereby granted, free of charge, to any person obtaining a copy - of this software and associated documentation files (the "Software"), to deal - in the Software without restriction, including without limitation the rights - to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - copies of the Software, and to permit persons to whom the Software is - furnished to do so, subject to the following conditions: + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: - The above copyright notice and this permission notice shall be included in all - copies or substantial portions of the Software. + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - SOFTWARE. + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. */ // ==================================================================================================================== @@ -31,49 +31,49 @@ // ==================================================================================================================== function Winwheel(options, drawWheel) { - defaultOptions = { - 'canvasId' : 'canvas', // Id of the canvas which the wheel is to draw on to. - 'centerX' : null, // X position of the center of the wheel. The default of these are null which means will be placed in center of the canvas. - 'centerY' : null, // Y position of the wheel center. If left null at time of construct the center of the canvas is used. - 'outerRadius' : null, // The radius of the outside of the wheel. If left null it will be set to the radius from the center of the canvas to its shortest side. - 'innerRadius' : 0, // Normally 0. Allows the creation of rings / doughnuts if set to value > 0. Should not exceed outer radius. - 'numSegments' : 1, // The number of segments. Need at least one to draw. - 'drawMode' : 'code', // The draw mode. Possible values are 'code' and 'image'. Default is code which means segments are drawn using canvas arc() function. - 'rotationAngle' : 0, // The angle of rotation of the wheel - 0 is 12 o'clock position. - 'textFontFamily' : 'Arial', // Segment text font, you should use web safe fonts. - 'textFontSize' : 20, // Size of the segment text. - 'textFontWeight' : 'bold', // Font weight. - 'textOrientation' : 'horizontal', // Either horizontal, vertical, or curved. - 'textAlignment' : 'center', // Either center, inner, or outer. - 'textDirection' : 'normal', // Either normal or reversed. In normal mode for horizontal text in segment at 3 o'clock is correct way up, in reversed text at 9 o'clock segment is correct way up. - 'textMargin' : null, // Margin between the inner or outer of the wheel (depends on textAlignment). - 'textFillStyle' : 'black', // This is basically the text colour. - 'textStrokeStyle' : null, // Basically the line colour for segment text, only looks good for large text so off by default. - 'textLineWidth' : 1, // Width of the lines around the text. Even though this defaults to 1, a line is only drawn if textStrokeStyle specified. - 'fillStyle' : 'silver', // The segment background colour. - 'strokeStyle' : 'black', // Segment line colour. Again segment lines only drawn if this is specified. - 'lineWidth' : 1, // Width of lines around segments. - 'clearTheCanvas' : true, // When set to true the canvas will be cleared before the wheel is drawn. - 'imageOverlay' : false, // If set to true in image drawing mode the outline of the segments will be displayed over the image. Does nothing in code drawMode. - 'drawText' : true, // By default the text of the segments is rendered in code drawMode and not in image drawMode. - 'pointerAngle' : 0, // Location of the pointer that indicates the prize when wheel has stopped. Default is 0 so the (corrected) 12 o'clock position. - 'wheelImage' : null // Must be set to image data in order to use image to draw the wheel - drawMode must also be 'image'. - }; - + defaultOptions = { + 'canvasId' : 'canvas', // Id of the canvas which the wheel is to draw on to. + 'centerX' : null, // X position of the center of the wheel. The default of these are null which means will be placed in center of the canvas. + 'centerY' : null, // Y position of the wheel center. If left null at time of construct the center of the canvas is used. + 'outerRadius' : null, // The radius of the outside of the wheel. If left null it will be set to the radius from the center of the canvas to its shortest side. + 'innerRadius' : 0, // Normally 0. Allows the creation of rings / doughnuts if set to value > 0. Should not exceed outer radius. + 'numSegments' : 1, // The number of segments. Need at least one to draw. + 'drawMode' : 'code', // The draw mode. Possible values are 'code' and 'image'. Default is code which means segments are drawn using canvas arc() function. + 'rotationAngle' : 0, // The angle of rotation of the wheel - 0 is 12 o'clock position. + 'textFontFamily' : 'Arial', // Segment text font, you should use web safe fonts. + 'textFontSize' : 20, // Size of the segment text. + 'textFontWeight' : 'bold', // Font weight. + 'textOrientation' : 'horizontal', // Either horizontal, vertical, or curved. + 'textAlignment' : 'center', // Either center, inner, or outer. + 'textDirection' : 'normal', // Either normal or reversed. In normal mode for horizontal text in segment at 3 o'clock is correct way up, in reversed text at 9 o'clock segment is correct way up. + 'textMargin' : null, // Margin between the inner or outer of the wheel (depends on textAlignment). + 'textFillStyle' : 'black', // This is basically the text colour. + 'textStrokeStyle' : null, // Basically the line colour for segment text, only looks good for large text so off by default. + 'textLineWidth' : 1, // Width of the lines around the text. Even though this defaults to 1, a line is only drawn if textStrokeStyle specified. + 'fillStyle' : 'silver', // The segment background colour. + 'strokeStyle' : 'black', // Segment line colour. Again segment lines only drawn if this is specified. + 'lineWidth' : 1, // Width of lines around segments. + 'clearTheCanvas' : true, // When set to true the canvas will be cleared before the wheel is drawn. + 'imageOverlay' : false, // If set to true in image drawing mode the outline of the segments will be displayed over the image. Does nothing in code drawMode. + 'drawText' : true, // By default the text of the segments is rendered in code drawMode and not in image drawMode. + 'pointerAngle' : 0, // Location of the pointer that indicates the prize when wheel has stopped. Default is 0 so the (corrected) 12 o'clock position. + 'wheelImage' : null // Must be set to image data in order to use image to draw the wheel - drawMode must also be 'image'. + }; + // ----------------------------------------- // Loop through the default options and create properties of this class set to the value for the option passed in - // or if not value for the option was passed in then to the default. - for (var key in defaultOptions) - { - if ((options != null) && (typeof(options[key]) !== 'undefined')) + // or if not value for the option was passed in then to the default. + for (var key in defaultOptions) + { + if ((options != null) && (typeof(options[key]) !== 'undefined')) { - this[key] = options[key]; + this[key] = options[key]; } - else + else { - this[key] = defaultOptions[key]; + this[key] = defaultOptions[key]; } - } + } // Also loop though the passed in options and add anything specified not part of the class in to it as a property. if (options != null) @@ -86,80 +86,80 @@ function Winwheel(options, drawWheel) } } } - - + + // ------------------------------------------ - // If the id of the canvas is set, try to get the canvas as we need it for drawing. - if (this.canvasId) - { + // If the id of the canvas is set, try to get the canvas as we need it for drawing. + if (this.canvasId) + { this.canvas = document.getElementById(this.canvasId); - if (this.canvas) - { - // If the centerX and centerY have not been specified in the options then default to center of the canvas + if (this.canvas) + { + // If the centerX and centerY have not been specified in the options then default to center of the canvas // and make the outerRadius half of the canvas width - this means the wheel will fill the canvas. - if (this.centerX == null) + if (this.centerX == null) { - this.centerX = this.canvas.width / 2; + this.centerX = this.canvas.width / 2; } - - if (this.centerY == null) + + if (this.centerY == null) { - this.centerY = this.canvas.height / 2; + this.centerY = this.canvas.height / 2; } - - if (this.outerRadius == null) - { - // Need to set to half the width of the shortest dimension of the canvas as the canvas may not be square. - // Minus the line segment line width otherwise the lines around the segments on the top,left,bottom,right + + if (this.outerRadius == null) + { + // Need to set to half the width of the shortest dimension of the canvas as the canvas may not be square. + // Minus the line segment line width otherwise the lines around the segments on the top,left,bottom,right // side are chopped by the edge of the canvas. - if (this.canvas.width < this.canvas.height) + if (this.canvas.width < this.canvas.height) { - this.outerRadius = (this.canvas.width / 2) - this.lineWidth; + this.outerRadius = (this.canvas.width / 2) - this.lineWidth; } - else + else { - this.outerRadius = (this.canvas.height / 2) - this.lineWidth; + this.outerRadius = (this.canvas.height / 2) - this.lineWidth; } - } + } // Also get a 2D context to the canvas as we need this to draw with. this.ctx = this.canvas.getContext('2d'); - } - else - { - this.canvas = null; + } + else + { + this.canvas = null; this.ctx = null; - } - } - else - { + } + } + else + { this.cavnas = null; this.ctx = null; - } - - + } + + // ------------------------------------------ - // Add array of segments to the wheel, then populate with segments if number of segments is specified for this object. - this.segments = new Array(null); - - for (x = 1; x <= this.numSegments; x++) - { - // If options for the segments have been specified then create a segment sending these options so - // the specified values are used instead of the defaults. - if ((options != null) && (options['segments']) && (typeof(options['segments'][x-1]) !== 'undefined')) + // Add array of segments to the wheel, then populate with segments if number of segments is specified for this object. + this.segments = new Array(null); + + for (x = 1; x <= this.numSegments; x++) + { + // If options for the segments have been specified then create a segment sending these options so + // the specified values are used instead of the defaults. + if ((options != null) && (options['segments']) && (typeof(options['segments'][x-1]) !== 'undefined')) { - this.segments[x] = new Segment(options['segments'][x-1]); + this.segments[x] = new Segment(options['segments'][x-1]); } - else + else { - this.segments[x] = new Segment(); + this.segments[x] = new Segment(); } - } - - // ------------------------------------------ - // Call function to update the segment sizes setting the starting and ending angles. - this.updateSegmentSizes(); + } + + // ------------------------------------------ + // Call function to update the segment sizes setting the starting and ending angles. + this.updateSegmentSizes(); // If the text margin is null then set to same as font size as we want some by default. @@ -232,11 +232,11 @@ function Winwheel(options, drawWheel) { this.pointerGuide = new PointerGuide(); } - - // Finally if drawWheel is true then call function to render the wheel, segment text, overlay etc. + + // Finally if drawWheel is true then call function to render the wheel, segment text, overlay etc. if (drawWheel == true) { - this.draw(this.clearTheCanvas); + this.draw(this.clearTheCanvas); } } @@ -246,56 +246,56 @@ function Winwheel(options, drawWheel) // ==================================================================================================================== Winwheel.prototype.updateSegmentSizes = function() { - // If this object actually contains some segments - if (this.segments) - { - // First add up the arc used for the segments where the size has been set. - var arcUsed = 0; - var numSet = 0; - - // Remember, to make it easy to access segments, the position of the segments in the array starts from 1 (not 0). - for (x = 1; x <= this.numSegments; x ++) - { - if (this.segments[x].size !== null) - { - arcUsed += this.segments[x].size; - numSet ++; - } - } - - var arcLeft = (360 - arcUsed); - - // Create variable to hold how much each segment with non-set size will get in terms of degrees. - var degreesEach = 0; - - if (arcLeft > 0) + // If this object actually contains some segments + if (this.segments) + { + // First add up the arc used for the segments where the size has been set. + var arcUsed = 0; + var numSet = 0; + + // Remember, to make it easy to access segments, the position of the segments in the array starts from 1 (not 0). + for (x = 1; x <= this.numSegments; x ++) + { + if (this.segments[x].size !== null) + { + arcUsed += this.segments[x].size; + numSet ++; + } + } + + var arcLeft = (360 - arcUsed); + + // Create variable to hold how much each segment with non-set size will get in terms of degrees. + var degreesEach = 0; + + if (arcLeft > 0) { - degreesEach = (arcLeft / (this.numSegments - numSet)); + degreesEach = (arcLeft / (this.numSegments - numSet)); } - - // ------------------------------------------ - // Now loop though and set the start and end angle of each segment. - var currentDegree = 0; + + // ------------------------------------------ + // Now loop though and set the start and end angle of each segment. + var currentDegree = 0; - for (x = 1; x <= this.numSegments; x ++) - { - // Set start angle. - this.segments[x].startAngle = currentDegree; - - // If the size is set then add this to the current degree to get the end, else add the degreesEach to it. - if (this.segments[x].size) + for (x = 1; x <= this.numSegments; x ++) + { + // Set start angle. + this.segments[x].startAngle = currentDegree; + + // If the size is set then add this to the current degree to get the end, else add the degreesEach to it. + if (this.segments[x].size) { - currentDegree += this.segments[x].size; + currentDegree += this.segments[x].size; } - else + else { - currentDegree += degreesEach; + currentDegree += degreesEach; } - - // Set end angle. - this.segments[x].endAngle = currentDegree; - } - } + + // Set end angle. + this.segments[x].endAngle = currentDegree; + } + } } // ==================================================================================================================== @@ -304,7 +304,7 @@ Winwheel.prototype.updateSegmentSizes = function() Winwheel.prototype.clearCanvas = function() { if (this.ctx) - { + { this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height); } } @@ -314,10 +314,10 @@ Winwheel.prototype.clearCanvas = function() // ==================================================================================================================== Winwheel.prototype.draw = function(clearTheCanvas) { - // If have the canvas context. - if (this.ctx) - { - // Clear the canvas, unless told not to. + // If have the canvas context. + if (this.ctx) + { + // Clear the canvas, unless told not to. if (typeof(clearTheCanvas) !== 'undefined') { if (clearTheCanvas == true) @@ -329,10 +329,10 @@ Winwheel.prototype.draw = function(clearTheCanvas) { this.clearCanvas(); } - - // Call functions to draw the segments and then segment text. + + // Call functions to draw the segments and then segment text. if (this.drawMode == 'image') - { + { // Draw the wheel by loading and drawing an image such as a png on the canvas. this.drawWheelImage(); @@ -349,19 +349,19 @@ Winwheel.prototype.draw = function(clearTheCanvas) { this.drawSegments(); } - } - else - { - // The default operation is to draw the segments using code via the canvas arc() method. - this.drawSegments(); + } + else + { + // The default operation is to draw the segments using code via the canvas arc() method. + this.drawSegments(); // The text is drawn on top. if (this.drawText == true) { this.drawSegmentText(); } - } - + } + // If pointer guide is display property is set to true then call function to draw the pointer guide. if (this.pointerGuide.display == true) { @@ -380,8 +380,8 @@ Winwheel.prototype.drawPointerGuide = function() { this.ctx.save(); this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2); - this.ctx.rotate(this.degToRad(this.pointerAngle)); - this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2); + this.ctx.rotate(this.degToRad(this.pointerAngle)); + this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2); this.ctx.strokeStyle = this.pointerGuide.strokeStyle; this.ctx.lineWidth = this.pointerGuide.lineWidth; @@ -415,8 +415,8 @@ Winwheel.prototype.drawWheelImage = function() // image wheels will spin. this.ctx.save(); this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2); - this.ctx.rotate(this.degToRad(this.rotationAngle)); - this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2); + this.ctx.rotate(this.degToRad(this.rotationAngle)); + this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2); this.ctx.drawImage(this.wheelImage, imageLeft, imageTop); @@ -429,46 +429,46 @@ Winwheel.prototype.drawWheelImage = function() // ==================================================================================================================== Winwheel.prototype.drawSegments = function() { - // Again check have context in case this function was called directly and not via draw function. - if (this.ctx) - { + // Again check have context in case this function was called directly and not via draw function. + if (this.ctx) + { // Draw the segments if there is at least one in the segments array. - if (this.segments) - { - // Loop though and output all segments - position 0 of the array is not used, so start loop from index 1 - // this is to avoid confusion when talking about the first segment. - for (x = 1; x <= this.numSegments; x ++) - { + if (this.segments) + { + // Loop though and output all segments - position 0 of the array is not used, so start loop from index 1 + // this is to avoid confusion when talking about the first segment. + for (x = 1; x <= this.numSegments; x ++) + { // Get the segment object as we need it to read options from. - seg = this.segments[x]; - - var fillStyle; - var lineWidth; - var strokeStyle; - - // Set the variables that defined in the segment, or use the default options. - if (seg.fillStyle !== null) - fillStyle = seg.fillStyle; - else - fillStyle = this.fillStyle; - - this.ctx.fillStyle = fillStyle; - - if (seg.lineWidth !== null) - lineWidth = seg.lineWidth; - else - lineWidth = this.lineWidth; - - this.ctx.lineWidth = lineWidth; - - if (seg.strokeStyle !== null) - strokeStyle = seg.strokeStyle; - else - strokeStyle = this.strokeStyle; - - this.ctx.strokeStyle = strokeStyle; - - + seg = this.segments[x]; + + var fillStyle; + var lineWidth; + var strokeStyle; + + // Set the variables that defined in the segment, or use the default options. + if (seg.fillStyle !== null) + fillStyle = seg.fillStyle; + else + fillStyle = this.fillStyle; + + this.ctx.fillStyle = fillStyle; + + if (seg.lineWidth !== null) + lineWidth = seg.lineWidth; + else + lineWidth = this.lineWidth; + + this.ctx.lineWidth = lineWidth; + + if (seg.strokeStyle !== null) + strokeStyle = seg.strokeStyle; + else + strokeStyle = this.strokeStyle; + + this.ctx.strokeStyle = strokeStyle; + + // Check there is a strokeStyle or fillStyle, if either the the segment is invisible so should not // try to draw it otherwise a path is began but not ended. if ((strokeStyle) || (fillStyle)) @@ -517,265 +517,265 @@ Winwheel.prototype.drawSegments = function() if (strokeStyle) this.ctx.stroke(); } - } - } - } + } + } + } } // ==================================================================================================================== // This draws the text on the segments using the specified text options. // ==================================================================================================================== Winwheel.prototype.drawSegmentText = function() -{ - // Again only draw the text if have a canvas context. - if (this.ctx) - { - // Declare variables to hold the values. These are populated either with the value for the specific segment, - // or if not specified then the global default value. - var fontFamily; - var fontSize; - var fontWeight; - var orientation; - var alignment; - var direction; - var margin; - var fillStyle; - var strokeStyle; - var lineWidth; - var fontSetting; +{ + // Again only draw the text if have a canvas context. + if (this.ctx) + { + // Declare variables to hold the values. These are populated either with the value for the specific segment, + // or if not specified then the global default value. + var fontFamily; + var fontSize; + var fontWeight; + var orientation; + var alignment; + var direction; + var margin; + var fillStyle; + var strokeStyle; + var lineWidth; + var fontSetting; - // Loop though all the segments. - for (x = 1; x <= this.numSegments; x ++) - { - // Save the context so it is certain that each segment text option will not affect the other. - this.ctx.save(); - - // Get the segment object as we need it to read options from. - seg = this.segments[x]; - - // Check is text as no point trying to draw if there is no text to render. - if (seg.text) - { - // Set values to those for the specific segment or use global default if null. - if (seg.textFontFamily !== null) fontFamily = seg.textFontFamily; else fontFamily = this.textFontFamily; - if (seg.textFontSize !== null) fontSize = seg.textFontSize; else fontSize = this.textFontSize; - if (seg.textFontWeight !== null) fontWeight = seg.textFontWeight; else fontWeight = this.textFontWeight; - if (seg.textOrientation !== null) orientation = seg.textOrientation; else orientation = this.textOrientation; - if (seg.textAlignment !== null) alignment = seg.textAlignment; else alignment = this.textAlignment; - if (seg.textDirection !== null) direction = seg.textDirection; else direction = this.textDirection; - if (seg.textMargin !== null) margin = seg.textMargin; else margin = this.textMargin; - if (seg.textFillStyle !== null) fillStyle = seg.textFillStyle; else fillStyle = this.textFillStyle; - if (seg.textStrokeStyle !== null) strokeStyle = seg.textStrokeStyle; else strokeStyle = this.textStrokeStyle; - if (seg.textLineWidth !== null) lineWidth = seg.textLineWidth; else lineWidth = this.textLineWidth; - - // ------------------------------ - // We need to put the font bits together in to one string. - fontSetting = ''; - - if (fontWeight != null) - fontSetting += fontWeight + ' '; - - if (fontSize != null) - fontSetting += fontSize + 'px '; // Fonts on canvas are always a px value. - - if (fontFamily != null) - fontSetting += fontFamily; - - // Now set the canvas context to the decided values. - this.ctx.font = fontSetting; - this.ctx.fillStyle = fillStyle; - this.ctx.strokeStyle = strokeStyle; - this.ctx.lineWidth = lineWidth; - - // --------------------------------- - // If direction is reversed then do things differently than if normal (which is the default - see further down) - if (direction == 'reversed') - { - // When drawing reversed or 'upside down' we need to do some trickery on our part. - // The canvas text rendering function still draws the text left to right and the correct way up, - // so we need to overcome this with rotating the opposite side of the wheel the correct way up then pulling the text - // through the center point to the correct segment it is supposed to be on. - if (orientation == 'horizontal') - { - if (alignment == 'inner') - this.ctx.textAlign = 'right'; - else if (alignment == 'outer') - this.ctx.textAlign = 'left'; - else - this.ctx.textAlign = 'center'; - - this.ctx.textBaseline = 'middle'; - - // Work out the angle to rotate the wheel, this is in the center of the segment but on the opposite side of the wheel which is why do -180. - var textAngle = this.degToRad((seg.endAngle - ((seg.endAngle - seg.startAngle) / 2) + this.rotationAngle - 90) - 180); - - this.ctx.save(); - this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2); - this.ctx.rotate(textAngle); - this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2); - - if (alignment == 'inner') - { - // In reversed state the margin is subtracted from the innerX. - // When inner the inner radius also comes in to play. - if (fillStyle) - this.ctx.fillText(seg.text, this.centerX - this.innerRadius - margin, this.centerY); - - if (strokeStyle) - this.ctx.strokeText(seg.text, this.centerX - this.innerRadius - margin, this.centerY); - } - else if (alignment == 'outer') - { - // In reversed state the position is the center minus the radius + the margin for outer aligned text. - if (fillStyle) - this.ctx.fillText(seg.text, this.centerX - this.outerRadius + margin, this.centerY); - - if (strokeStyle) - this.ctx.strokeText(seg.text, this.centerX - this.outerRadius + margin, this.centerY); - } - else - { - // In reversed state the everything in minused. - if (fillStyle) - this.ctx.fillText(seg.text, this.centerX - this.innerRadius - ((this.outerRadius - this.innerRadius) / 2) - margin, this.centerY); - - if (strokeStyle) - this.ctx.strokeText(seg.text, this.centerX - this.innerRadius - ((this.outerRadius - this.innerRadius) / 2) - margin, this.centerY); - } - - this.ctx.restore(); - } - else if (orientation == 'vertical') - { - // See normal code further down for comments on how it works, this is similar by plus/minus is reversed. - this.ctx.textAlign = 'center'; - - // In reversed mode this are reversed. - if (alignment == 'inner') - this.ctx.textBaseline = 'top'; - else if (alignment == 'outer') - this.ctx.textBaseline = 'bottom'; - else - this.ctx.textBaseline = 'middle'; - - var textAngle = (seg.endAngle - ((seg.endAngle - seg.startAngle) / 2) - 180); + // Loop though all the segments. + for (x = 1; x <= this.numSegments; x ++) + { + // Save the context so it is certain that each segment text option will not affect the other. + this.ctx.save(); + + // Get the segment object as we need it to read options from. + seg = this.segments[x]; + + // Check is text as no point trying to draw if there is no text to render. + if (seg.text) + { + // Set values to those for the specific segment or use global default if null. + if (seg.textFontFamily !== null) fontFamily = seg.textFontFamily; else fontFamily = this.textFontFamily; + if (seg.textFontSize !== null) fontSize = seg.textFontSize; else fontSize = this.textFontSize; + if (seg.textFontWeight !== null) fontWeight = seg.textFontWeight; else fontWeight = this.textFontWeight; + if (seg.textOrientation !== null) orientation = seg.textOrientation; else orientation = this.textOrientation; + if (seg.textAlignment !== null) alignment = seg.textAlignment; else alignment = this.textAlignment; + if (seg.textDirection !== null) direction = seg.textDirection; else direction = this.textDirection; + if (seg.textMargin !== null) margin = seg.textMargin; else margin = this.textMargin; + if (seg.textFillStyle !== null) fillStyle = seg.textFillStyle; else fillStyle = this.textFillStyle; + if (seg.textStrokeStyle !== null) strokeStyle = seg.textStrokeStyle; else strokeStyle = this.textStrokeStyle; + if (seg.textLineWidth !== null) lineWidth = seg.textLineWidth; else lineWidth = this.textLineWidth; + + // ------------------------------ + // We need to put the font bits together in to one string. + fontSetting = ''; + + if (fontWeight != null) + fontSetting += fontWeight + ' '; + + if (fontSize != null) + fontSetting += fontSize + 'px '; // Fonts on canvas are always a px value. + + if (fontFamily != null) + fontSetting += fontFamily; + + // Now set the canvas context to the decided values. + this.ctx.font = fontSetting; + this.ctx.fillStyle = fillStyle; + this.ctx.strokeStyle = strokeStyle; + this.ctx.lineWidth = lineWidth; + + // --------------------------------- + // If direction is reversed then do things differently than if normal (which is the default - see further down) + if (direction == 'reversed') + { + // When drawing reversed or 'upside down' we need to do some trickery on our part. + // The canvas text rendering function still draws the text left to right and the correct way up, + // so we need to overcome this with rotating the opposite side of the wheel the correct way up then pulling the text + // through the center point to the correct segment it is supposed to be on. + if (orientation == 'horizontal') + { + if (alignment == 'inner') + this.ctx.textAlign = 'right'; + else if (alignment == 'outer') + this.ctx.textAlign = 'left'; + else + this.ctx.textAlign = 'center'; + + this.ctx.textBaseline = 'middle'; + + // Work out the angle to rotate the wheel, this is in the center of the segment but on the opposite side of the wheel which is why do -180. + var textAngle = this.degToRad((seg.endAngle - ((seg.endAngle - seg.startAngle) / 2) + this.rotationAngle - 90) - 180); + + this.ctx.save(); + this.ctx.translate(this.canvas.width / 2, this.canvas.height / 2); + this.ctx.rotate(textAngle); + this.ctx.translate(-this.canvas.width / 2, -this.canvas.height / 2); + + if (alignment == 'inner') + { + // In reversed state the margin is subtracted from the innerX. + // When inner the inner radius also comes in to play. + if (fillStyle) + this.ctx.fillText(seg.text, this.centerX - this.innerRadius - margin, this.centerY); + + if (strokeStyle) + this.ctx.strokeText(seg.text, this.centerX - this.innerRadius - margin, this.centerY); + } + else if (alignment == 'outer') + { + // In reversed state the position is the center minus the radius + the margin for outer aligned text. + if (fillStyle) + this.ctx.fillText(seg.text, this.centerX - this.outerRadius + margin, this.centerY); + + if (strokeStyle) + this.ctx.strokeText(seg.text, this.centerX - this.outerRadius + margin, this.centerY); + } + else + { + // In reversed state the everything in minused. + if (fillStyle) + this.ctx.fillText(seg.text, this.centerX - this.innerRadius - ((this.outerRadius - this.innerRadius) / 2) - margin, this.centerY); + + if (strokeStyle) + this.ctx.strokeText(seg.text, this.centerX - this.innerRadius - ((this.outerRadius - this.innerRadius) / 2) - margin, this.centerY); + } + + this.ctx.restore(); + } + else if (orientation == 'vertical') + { + // See normal code further down for comments on how it works, this is similar by plus/minus is reversed. + this.ctx.textAlign = 'center'; + + // In reversed mode this are reversed. + if (alignment == 'inner') + this.ctx.textBaseline = 'top'; + else if (alignment == 'outer') + this.ctx.textBaseline = 'bottom'; + else + this.ctx.textBaseline = 'middle'; + + var textAngle = (seg.endAngle - ((seg.endAngle - seg.startAngle) / 2) - 180); textAngle += this.rotationAngle; - this.ctx.save(); - this.ctx.translate(this.centerX, this.centerY); - this.ctx.rotate(this.degToRad(textAngle)); - this.ctx.translate(-this.centerX, -this.centerY); - - if (alignment == 'outer') - var yPos = (this.centerY + this.outerRadius - margin); - else if (alignment == 'inner') - var yPos = (this.centerY + this.innerRadius + margin); - - // I have found that the text looks best when a fraction of the font size is shaved off. + this.ctx.save(); + this.ctx.translate(this.centerX, this.centerY); + this.ctx.rotate(this.degToRad(textAngle)); + this.ctx.translate(-this.centerX, -this.centerY); + + if (alignment == 'outer') + var yPos = (this.centerY + this.outerRadius - margin); + else if (alignment == 'inner') + var yPos = (this.centerY + this.innerRadius + margin); + + // I have found that the text looks best when a fraction of the font size is shaved off. var yInc = (fontSize - (fontSize / 9)); - - // Loop though and output the characters. - if (alignment == 'outer') - { - // In reversed mode outer means text in 6 o'clock segment sits at bottom of the wheel and we draw up. - for (var c = (seg.text.length -1); c >= 0; c--) - { - character = seg.text.charAt(c); - - if (fillStyle) - this.ctx.fillText(character, this.centerX, yPos); - - if (strokeStyle) - this.ctx.strokeText(character, this.centerX, yPos); - - yPos -= yInc; - } - } - else if (alignment == 'inner') - { - // In reversed mode inner text is drawn from top of segment at 6 o'clock position to bottom of the wheel. - for (var c = 0; c < seg.text.length; c++) - { - character = seg.text.charAt(c); - - if (fillStyle) - this.ctx.fillText(character, this.centerX, yPos); - - if (strokeStyle) - this.ctx.strokeText(character, this.centerX, yPos); - - yPos += yInc; - } - } - else if (alignment == 'center') - { - // Again for reversed this is the opposite of before. - // If there is more than one character in the text then an adjustment to the position needs to be done. - // What we are aiming for is to position the center of the text at the center point between the inner and outer radius. - var centerAdjustment = 0; - - if (seg.text.length > 1) - { - centerAdjustment = (yInc * (seg.text.length -1) / 2); - } - - var yPos = (this.centerY + this.innerRadius + ((this.outerRadius - this.innerRadius) / 2)) + centerAdjustment + margin; - - for (var c = (seg.text.length -1); c >= 0; c--) - { - character = seg.text.charAt(c); - - if (fillStyle) - this.ctx.fillText(character, this.centerX, yPos); - - if (strokeStyle) - this.ctx.strokeText(character, this.centerX, yPos); - - yPos -= yInc; - } - } - - this.ctx.restore(); - } - else if (orientation == 'curved') - { - // There is no built in canvas function to draw text around an arc, + + // Loop though and output the characters. + if (alignment == 'outer') + { + // In reversed mode outer means text in 6 o'clock segment sits at bottom of the wheel and we draw up. + for (var c = (seg.text.length -1); c >= 0; c--) + { + character = seg.text.charAt(c); + + if (fillStyle) + this.ctx.fillText(character, this.centerX, yPos); + + if (strokeStyle) + this.ctx.strokeText(character, this.centerX, yPos); + + yPos -= yInc; + } + } + else if (alignment == 'inner') + { + // In reversed mode inner text is drawn from top of segment at 6 o'clock position to bottom of the wheel. + for (var c = 0; c < seg.text.length; c++) + { + character = seg.text.charAt(c); + + if (fillStyle) + this.ctx.fillText(character, this.centerX, yPos); + + if (strokeStyle) + this.ctx.strokeText(character, this.centerX, yPos); + + yPos += yInc; + } + } + else if (alignment == 'center') + { + // Again for reversed this is the opposite of before. + // If there is more than one character in the text then an adjustment to the position needs to be done. + // What we are aiming for is to position the center of the text at the center point between the inner and outer radius. + var centerAdjustment = 0; + + if (seg.text.length > 1) + { + centerAdjustment = (yInc * (seg.text.length -1) / 2); + } + + var yPos = (this.centerY + this.innerRadius + ((this.outerRadius - this.innerRadius) / 2)) + centerAdjustment + margin; + + for (var c = (seg.text.length -1); c >= 0; c--) + { + character = seg.text.charAt(c); + + if (fillStyle) + this.ctx.fillText(character, this.centerX, yPos); + + if (strokeStyle) + this.ctx.strokeText(character, this.centerX, yPos); + + yPos -= yInc; + } + } + + this.ctx.restore(); + } + else if (orientation == 'curved') + { + // There is no built in canvas function to draw text around an arc, // so we need to do this ourselves. - var radius = 0; - - // Set the alignment of the text - inner, outer, or center by calculating + var radius = 0; + + // Set the alignment of the text - inner, outer, or center by calculating // how far out from the center point of the wheel the text is drawn. - if (alignment == 'inner') - { - // When alignment is inner the radius is the innerRadius plus any margin. - radius = this.innerRadius + margin; + if (alignment == 'inner') + { + // When alignment is inner the radius is the innerRadius plus any margin. + radius = this.innerRadius + margin; this.ctx.textBaseline = 'top'; - } - else if (alignment == 'outer') - { - // Outer it is the outerRadius minus any margin. - radius = this.outerRadius - margin; + } + else if (alignment == 'outer') + { + // Outer it is the outerRadius minus any margin. + radius = this.outerRadius - margin; this.ctx.textBaseline = 'bottom'; - } - else if (alignment == 'center') - { - // When center we want the text halfway between the inner and outer radius. - radius = this.innerRadius + margin + ((this.outerRadius - this.innerRadius) / 2); - this.ctx.textBaseline = 'middle'; - } - - // Set the angle to increment by when looping though and outputting the characters in the text + } + else if (alignment == 'center') + { + // When center we want the text halfway between the inner and outer radius. + radius = this.innerRadius + margin + ((this.outerRadius - this.innerRadius) / 2); + this.ctx.textBaseline = 'middle'; + } + + // Set the angle to increment by when looping though and outputting the characters in the text // as we do this by rotating the wheel small amounts adding each character. - var anglePerChar = 0; - var drawAngle = 0; - - // If more than one character in the text then... + var anglePerChar = 0; + var drawAngle = 0; + + // If more than one character in the text then... if (seg.text.length > 1) - { - // Text is drawn from the left. - this.ctx.textAlign = 'left'; - - // Work out how much angle the text rendering loop below needs to rotate by for each character to render them next to each other. + { + // Text is drawn from the left. + this.ctx.textAlign = 'left'; + + // Work out how much angle the text rendering loop below needs to rotate by for each character to render them next to each other. // I have discovered that 4 * the font size / 10 at 100px radius is the correct spacing for between the characters // using a monospace font, non monospace may look a little odd as in there will appear to be extra spaces between chars. anglePerChar = (4 * (fontSize / 10)); @@ -794,16 +794,16 @@ Winwheel.prototype.drawSegmentText = function() totalArc = (anglePerChar * seg.text.length); // Now set initial draw angle to half way between the start and end of the segment. - drawAngle = seg.startAngle + (((seg.endAngle - seg.startAngle) / 2) - (totalArc / 2)); - } - else - { - // The initial draw angle is the center of the segment when only one character. - drawAngle = (seg.startAngle + ((seg.endAngle - seg.startAngle) / 2)); - - // To ensure is dead-center the text alignment also needs to be centered. - this.ctx.textAlign = 'center'; - } + drawAngle = seg.startAngle + (((seg.endAngle - seg.startAngle) / 2) - (totalArc / 2)); + } + else + { + // The initial draw angle is the center of the segment when only one character. + drawAngle = (seg.startAngle + ((seg.endAngle - seg.startAngle) / 2)); + + // To ensure is dead-center the text alignment also needs to be centered. + this.ctx.textAlign = 'center'; + } // ---------------------- // Adjust the initial draw angle as needed to take in to account the rotationAngle of the wheel. @@ -812,272 +812,272 @@ Winwheel.prototype.drawSegmentText = function() // And as with other 'reverse' text direction functions we need to subtract 180 degrees from the angle // because when it comes to draw the characters in the loop below we add the radius instead of subtract it. drawAngle -= 180; - - // ---------------------- - // Now the drawing itself. + + // ---------------------- + // Now the drawing itself. // In reversed direction mode we loop through the characters in the text backwards in order for them to appear on screen correctly - for (c = seg.text.length; c >= 0; c--) - { - this.ctx.save(); + for (c = seg.text.length; c >= 0; c--) + { + this.ctx.save(); character = seg.text.charAt(c); - - // Rotate the wheel to the draw angle as we need to add the character at this location. + + // Rotate the wheel to the draw angle as we need to add the character at this location. this.ctx.translate(this.centerX, this.centerY); - this.ctx.rotate(this.degToRad(drawAngle)); - this.ctx.translate(-this.centerX, -this.centerY); - - // Now draw the character directly below the center point of the wheel at the appropriate radius. + this.ctx.rotate(this.degToRad(drawAngle)); + this.ctx.translate(-this.centerX, -this.centerY); + + // Now draw the character directly below the center point of the wheel at the appropriate radius. // Note in the reversed mode we add the radius to the this.centerY instead of subtract. - if (strokeStyle) - this.ctx.strokeText(character, this.centerX, this.centerY + radius); - - if (fillStyle) - this.ctx.fillText(character, this.centerX, this.centerY + radius); - - // Increment the drawAngle by the angle per character so next loop we rotate + if (strokeStyle) + this.ctx.strokeText(character, this.centerX, this.centerY + radius); + + if (fillStyle) + this.ctx.fillText(character, this.centerX, this.centerY + radius); + + // Increment the drawAngle by the angle per character so next loop we rotate // to the next angle required to draw the character at. - drawAngle += anglePerChar; + drawAngle += anglePerChar; this.ctx.restore(); - } - } - } - else - { - // Normal direction so do things normally. - // Check text orientation, of horizontal then reasonably straight forward, if vertical then a bit more work to do. - if (orientation == 'horizontal') - { - // Based on the text alignment, set the correct value in the context. - if (alignment == 'inner') - this.ctx.textAlign = 'left'; - else if (alignment == 'outer') - this.ctx.textAlign = 'right'; - else - this.ctx.textAlign = 'center'; - - // Set this too. - this.ctx.textBaseline = 'middle'; - - // Work out the angle around the wheel to draw the text at, which is simply in the middle of the segment the text is for. - // The rotation angle is added in to correct the annoyance with the canvas arc drawing functions which put the 0 degrees at the 3 oclock - var textAngle = this.degToRad(seg.endAngle - ((seg.endAngle - seg.startAngle) / 2) + this.rotationAngle - 90); - - // We need to rotate in order to draw the text because it is output horizontally, so to - // place correctly around the wheel for all but a segment at 3 o'clock we need to rotate. - this.ctx.save(); - this.ctx.translate(this.centerX, this.centerY); - this.ctx.rotate(textAngle); - this.ctx.translate(-this.centerX, -this.centerY); - - // -------------------------- - // Draw the text based on its alignment adding margin if inner or outer. - if (alignment == 'inner') - { - // Inner means that the text is aligned with the inner of the wheel. If looking at a segment in in the 3 o'clock position - // it would look like the text is left aligned within the segment. - - // Because the segments are smaller towards the inner of the wheel, in order for the text to fit is is a good idea that - // a margin is added which pushes the text towards the outer a bit. - - // The inner radius also needs to be taken in to account as when inner aligned. - - // If fillstyle is set the draw the text filled in. - if (fillStyle) - this.ctx.fillText(seg.text, this.centerX + this.innerRadius + margin, this.centerY); - - // If stroke style is set draw the text outline. - if (strokeStyle) - this.ctx.strokeText(seg.text, this.centerX + this.innerRadius + margin, this.centerY); - } - else if (alignment == 'outer') - { - // Outer means the text is aligned with the outside of the wheel, so if looking at a segment in the 3 o'clock position - // it would appear the text is right aligned. To position we add the radius of the wheel in to the equation - // and subtract the margin this time, rather than add it. - - // I don't understand why, but in order of the text to render correctly with stroke and fill, the stroke needs to - // come first when drawing outer, rather than second when doing inner. - if (fillStyle) - this.ctx.fillText(seg.text, this.centerX + this.outerRadius - margin, this.centerY); - - // If fillstyle the fill the text. - if (strokeStyle) - this.ctx.strokeText(seg.text, this.centerX + this.outerRadius - margin, this.centerY); - } - else - { - // In this case the text is to drawn centred in the segment. - // Typically no margin is required, however even though centred the text can look closer to the inner of the wheel - // due to the way the segments narrow in (is optical effect), so if a margin is specified it is placed on the inner - // side so the text is pushed towards the outer. - - // If stoke style the stroke the text. - if (fillStyle) - this.ctx.fillText(seg.text, this.centerX + this.innerRadius + ((this.outerRadius - this.innerRadius) / 2) + margin, this.centerY); - - // If fillstyle the fill the text. - if (strokeStyle) - this.ctx.strokeText(seg.text, this.centerX + this.innerRadius + ((this.outerRadius - this.innerRadius) / 2) + margin, this.centerY); - } - - // Restore the context so that wheel is returned to original position. - this.ctx.restore(); - } - else if (orientation == 'vertical') - { - // If vertical then we need to do this ourselves because as far as I am aware there is no option built in to html canvas - // which causes the text to draw downwards or upwards one character after another. - - // In this case the textAlign is always center, but the baseline is either top or bottom - // depending on if inner or outer alignment has been specified. - this.ctx.textAlign = 'center'; - - if (alignment == 'inner') - this.ctx.textBaseline = 'bottom'; - else if (alignment == 'outer') - this.ctx.textBaseline = 'top'; - else - this.ctx.textBaseline = 'middle'; - - // The angle to draw the text at is halfway between the end and the starting angle of the segment. - var textAngle = seg.endAngle - ((seg.endAngle - seg.startAngle) / 2); + } + } + } + else + { + // Normal direction so do things normally. + // Check text orientation, of horizontal then reasonably straight forward, if vertical then a bit more work to do. + if (orientation == 'horizontal') + { + // Based on the text alignment, set the correct value in the context. + if (alignment == 'inner') + this.ctx.textAlign = 'left'; + else if (alignment == 'outer') + this.ctx.textAlign = 'right'; + else + this.ctx.textAlign = 'center'; + + // Set this too. + this.ctx.textBaseline = 'middle'; + + // Work out the angle around the wheel to draw the text at, which is simply in the middle of the segment the text is for. + // The rotation angle is added in to correct the annoyance with the canvas arc drawing functions which put the 0 degrees at the 3 oclock + var textAngle = this.degToRad(seg.endAngle - ((seg.endAngle - seg.startAngle) / 2) + this.rotationAngle - 90); + + // We need to rotate in order to draw the text because it is output horizontally, so to + // place correctly around the wheel for all but a segment at 3 o'clock we need to rotate. + this.ctx.save(); + this.ctx.translate(this.centerX, this.centerY); + this.ctx.rotate(textAngle); + this.ctx.translate(-this.centerX, -this.centerY); + + // -------------------------- + // Draw the text based on its alignment adding margin if inner or outer. + if (alignment == 'inner') + { + // Inner means that the text is aligned with the inner of the wheel. If looking at a segment in in the 3 o'clock position + // it would look like the text is left aligned within the segment. + + // Because the segments are smaller towards the inner of the wheel, in order for the text to fit is is a good idea that + // a margin is added which pushes the text towards the outer a bit. + + // The inner radius also needs to be taken in to account as when inner aligned. + + // If fillstyle is set the draw the text filled in. + if (fillStyle) + this.ctx.fillText(seg.text, this.centerX + this.innerRadius + margin, this.centerY); + + // If stroke style is set draw the text outline. + if (strokeStyle) + this.ctx.strokeText(seg.text, this.centerX + this.innerRadius + margin, this.centerY); + } + else if (alignment == 'outer') + { + // Outer means the text is aligned with the outside of the wheel, so if looking at a segment in the 3 o'clock position + // it would appear the text is right aligned. To position we add the radius of the wheel in to the equation + // and subtract the margin this time, rather than add it. + + // I don't understand why, but in order of the text to render correctly with stroke and fill, the stroke needs to + // come first when drawing outer, rather than second when doing inner. + if (fillStyle) + this.ctx.fillText(seg.text, this.centerX + this.outerRadius - margin, this.centerY); + + // If fillstyle the fill the text. + if (strokeStyle) + this.ctx.strokeText(seg.text, this.centerX + this.outerRadius - margin, this.centerY); + } + else + { + // In this case the text is to drawn centred in the segment. + // Typically no margin is required, however even though centred the text can look closer to the inner of the wheel + // due to the way the segments narrow in (is optical effect), so if a margin is specified it is placed on the inner + // side so the text is pushed towards the outer. + + // If stoke style the stroke the text. + if (fillStyle) + this.ctx.fillText(seg.text, this.centerX + this.innerRadius + ((this.outerRadius - this.innerRadius) / 2) + margin, this.centerY); + + // If fillstyle the fill the text. + if (strokeStyle) + this.ctx.strokeText(seg.text, this.centerX + this.innerRadius + ((this.outerRadius - this.innerRadius) / 2) + margin, this.centerY); + } + + // Restore the context so that wheel is returned to original position. + this.ctx.restore(); + } + else if (orientation == 'vertical') + { + // If vertical then we need to do this ourselves because as far as I am aware there is no option built in to html canvas + // which causes the text to draw downwards or upwards one character after another. + + // In this case the textAlign is always center, but the baseline is either top or bottom + // depending on if inner or outer alignment has been specified. + this.ctx.textAlign = 'center'; + + if (alignment == 'inner') + this.ctx.textBaseline = 'bottom'; + else if (alignment == 'outer') + this.ctx.textBaseline = 'top'; + else + this.ctx.textBaseline = 'middle'; + + // The angle to draw the text at is halfway between the end and the starting angle of the segment. + var textAngle = seg.endAngle - ((seg.endAngle - seg.startAngle) / 2); // Ensure the rotation angle of the wheel is added in, otherwise the test placement won't match // the segments they are supposed to be for. textAngle += this.rotationAngle; - - // Rotate so can begin to place the text. - this.ctx.save(); - this.ctx.translate(this.centerX, this.centerY); - this.ctx.rotate(this.degToRad(textAngle)); - this.ctx.translate(-this.centerX, -this.centerY); - - // Work out the position to start drawing in based on the alignment. - // If outer then when considering a segment at the 12 o'clock position want to start drawing down from the top of the wheel. - if (alignment == 'outer') - var yPos = (this.centerY - this.outerRadius + margin); - else if (alignment == 'inner') - var yPos = (this.centerY - this.innerRadius - margin); - - // We need to know how much to move the y axis each time. + + // Rotate so can begin to place the text. + this.ctx.save(); + this.ctx.translate(this.centerX, this.centerY); + this.ctx.rotate(this.degToRad(textAngle)); + this.ctx.translate(-this.centerX, -this.centerY); + + // Work out the position to start drawing in based on the alignment. + // If outer then when considering a segment at the 12 o'clock position want to start drawing down from the top of the wheel. + if (alignment == 'outer') + var yPos = (this.centerY - this.outerRadius + margin); + else if (alignment == 'inner') + var yPos = (this.centerY - this.innerRadius - margin); + + // We need to know how much to move the y axis each time. // This is not quite simply the font size as that puts a larger gap in between the letters // than expected, especially with monospace fonts. I found that shaving a little off makes it look "right". - var yInc = (fontSize - (fontSize / 9)); - - // Loop though and output the characters. - if (alignment == 'outer') - { - // For this alignment we draw down from the top of a segment at the 12 o'clock position to simply - // loop though the characters in order. - for (var c = 0; c < seg.text.length; c++) - { - character = seg.text.charAt(c); - - if (fillStyle) - this.ctx.fillText(character, this.centerX, yPos); - - if (strokeStyle) - this.ctx.strokeText(character, this.centerX, yPos); - - yPos += yInc; - } - } - else if (alignment == 'inner') - { - // Here we draw from the inner of the wheel up, but in order for the letters in the text text to - // remain in the correct order when reading, we actually need to loop though the text characters backwards. - for (var c = (seg.text.length -1); c >= 0; c--) - { - character = seg.text.charAt(c); - - if (fillStyle) - this.ctx.fillText(character, this.centerX, yPos); - - if (strokeStyle) - this.ctx.strokeText(character, this.centerX, yPos); - - yPos -= yInc; - } - } - else if (alignment == 'center') - { - // This is the most complex of the three as we need to draw the text top down centred between the inner and outer of the wheel. - // So logically we have to put the middle character of the text in the center then put the others each side of it. - // In reality that is a really bad way to do it, we can achieve the same if not better positioning using a - // variation on the method used for the rendering of outer aligned text once we have figured out the height of the text. - - // If there is more than one character in the text then an adjustment to the position needs to be done. - // What we are aiming for is to position the center of the text at the center point between the inner and outer radius. - var centerAdjustment = 0; - - if (seg.text.length > 1) - { - centerAdjustment = (yInc * (seg.text.length -1) / 2); - } - - // Now work out where to start rendering the string. This is half way between the inner and outer of the wheel, with the - // centerAdjustment included to correctly position texts with more than one character over the center. - // If there is a margin it is used to push the text away from the center of the wheel. - var yPos = (this.centerY - this.innerRadius - ((this.outerRadius - this.innerRadius) / 2)) - centerAdjustment - margin; - - // Now loop and draw just like outer text rendering. - for (var c = 0; c < seg.text.length; c++) - { - character = seg.text.charAt(c); - - if (fillStyle) - this.ctx.fillText(character, this.centerX, yPos); - - if (strokeStyle) - this.ctx.strokeText(character, this.centerX, yPos); - - yPos += yInc; - } - } - - this.ctx.restore(); - } - else if (orientation == 'curved') - { - // There is no built in canvas function to draw text around an arc, so + var yInc = (fontSize - (fontSize / 9)); + + // Loop though and output the characters. + if (alignment == 'outer') + { + // For this alignment we draw down from the top of a segment at the 12 o'clock position to simply + // loop though the characters in order. + for (var c = 0; c < seg.text.length; c++) + { + character = seg.text.charAt(c); + + if (fillStyle) + this.ctx.fillText(character, this.centerX, yPos); + + if (strokeStyle) + this.ctx.strokeText(character, this.centerX, yPos); + + yPos += yInc; + } + } + else if (alignment == 'inner') + { + // Here we draw from the inner of the wheel up, but in order for the letters in the text text to + // remain in the correct order when reading, we actually need to loop though the text characters backwards. + for (var c = (seg.text.length -1); c >= 0; c--) + { + character = seg.text.charAt(c); + + if (fillStyle) + this.ctx.fillText(character, this.centerX, yPos); + + if (strokeStyle) + this.ctx.strokeText(character, this.centerX, yPos); + + yPos -= yInc; + } + } + else if (alignment == 'center') + { + // This is the most complex of the three as we need to draw the text top down centred between the inner and outer of the wheel. + // So logically we have to put the middle character of the text in the center then put the others each side of it. + // In reality that is a really bad way to do it, we can achieve the same if not better positioning using a + // variation on the method used for the rendering of outer aligned text once we have figured out the height of the text. + + // If there is more than one character in the text then an adjustment to the position needs to be done. + // What we are aiming for is to position the center of the text at the center point between the inner and outer radius. + var centerAdjustment = 0; + + if (seg.text.length > 1) + { + centerAdjustment = (yInc * (seg.text.length -1) / 2); + } + + // Now work out where to start rendering the string. This is half way between the inner and outer of the wheel, with the + // centerAdjustment included to correctly position texts with more than one character over the center. + // If there is a margin it is used to push the text away from the center of the wheel. + var yPos = (this.centerY - this.innerRadius - ((this.outerRadius - this.innerRadius) / 2)) - centerAdjustment - margin; + + // Now loop and draw just like outer text rendering. + for (var c = 0; c < seg.text.length; c++) + { + character = seg.text.charAt(c); + + if (fillStyle) + this.ctx.fillText(character, this.centerX, yPos); + + if (strokeStyle) + this.ctx.strokeText(character, this.centerX, yPos); + + yPos += yInc; + } + } + + this.ctx.restore(); + } + else if (orientation == 'curved') + { + // There is no built in canvas function to draw text around an arc, so // we need to do this ourselves. - var radius = 0; - - // Set the alignment of the text - inner, outer, or center by calculating + var radius = 0; + + // Set the alignment of the text - inner, outer, or center by calculating // how far out from the center point of the wheel the text is drawn. - if (alignment == 'inner') - { - // When alignment is inner the radius is the innerRadius plus any margin. - radius = this.innerRadius + margin; + if (alignment == 'inner') + { + // When alignment is inner the radius is the innerRadius plus any margin. + radius = this.innerRadius + margin; this.ctx.textBaseline = 'bottom'; - } - else if (alignment == 'outer') - { - // Outer it is the outerRadius minus any margin. - radius = this.outerRadius - margin; + } + else if (alignment == 'outer') + { + // Outer it is the outerRadius minus any margin. + radius = this.outerRadius - margin; this.ctx.textBaseline = 'top'; - } - else if (alignment == 'center') - { - // When center we want the text halfway between the inner and outer radius. - radius = this.innerRadius + margin + ((this.outerRadius - this.innerRadius) / 2); - this.ctx.textBaseline = 'middle'; - } - - // Set the angle to increment by when looping though and outputting the characters in the text + } + else if (alignment == 'center') + { + // When center we want the text halfway between the inner and outer radius. + radius = this.innerRadius + margin + ((this.outerRadius - this.innerRadius) / 2); + this.ctx.textBaseline = 'middle'; + } + + // Set the angle to increment by when looping though and outputting the characters in the text // as we do this by rotating the wheel small amounts adding each character. - var anglePerChar = 0; - var drawAngle = 0; - - // If more than one character in the text then... + var anglePerChar = 0; + var drawAngle = 0; + + // If more than one character in the text then... if (seg.text.length > 1) - { - // Text is drawn from the left. - this.ctx.textAlign = 'left'; - - // Work out how much angle the text rendering loop below needs to rotate by for each character to render them next to each other. + { + // Text is drawn from the left. + this.ctx.textAlign = 'left'; + + // Work out how much angle the text rendering loop below needs to rotate by for each character to render them next to each other. // I have discovered that 4 * the font size / 10 at 100px radius is the correct spacing for between the characters // using a monospace font, non monospace may look a little odd as in there will appear to be extra spaces between chars. anglePerChar = (4 * (fontSize / 10)); @@ -1096,56 +1096,56 @@ Winwheel.prototype.drawSegmentText = function() totalArc = (anglePerChar * seg.text.length); // Now set initial draw angle to half way between the start and end of the segment. - drawAngle = seg.startAngle + (((seg.endAngle - seg.startAngle) / 2) - (totalArc / 2)); - } - else - { - // The initial draw angle is the center of the segment when only one character. - drawAngle = (seg.startAngle + ((seg.endAngle - seg.startAngle) / 2)); - - // To ensure is dead-center the text alignment also needs to be centred. - this.ctx.textAlign = 'center'; - } + drawAngle = seg.startAngle + (((seg.endAngle - seg.startAngle) / 2) - (totalArc / 2)); + } + else + { + // The initial draw angle is the center of the segment when only one character. + drawAngle = (seg.startAngle + ((seg.endAngle - seg.startAngle) / 2)); + + // To ensure is dead-center the text alignment also needs to be centred. + this.ctx.textAlign = 'center'; + } // ---------------------- // Adjust the initial draw angle as needed to take in to account the rotationAngle of the wheel. drawAngle += this.rotationAngle; - - // ---------------------- - // Now the drawing itself. - // Loop for each character in the text. - for (c = 0; c < (seg.text.length); c++) - { - this.ctx.save(); + + // ---------------------- + // Now the drawing itself. + // Loop for each character in the text. + for (c = 0; c < (seg.text.length); c++) + { + this.ctx.save(); character = seg.text.charAt(c); - - // Rotate the wheel to the draw angle as we need to add the character at this location. + + // Rotate the wheel to the draw angle as we need to add the character at this location. this.ctx.translate(this.centerX, this.centerY); - this.ctx.rotate(this.degToRad(drawAngle)); - this.ctx.translate(-this.centerX, -this.centerY); - - // Now draw the character directly above the center point of the wheel at the appropriate radius. - if (strokeStyle) - this.ctx.strokeText(character, this.centerX, this.centerY - radius); - - if (fillStyle) - this.ctx.fillText(character, this.centerX, this.centerY - radius); - - // Increment the drawAngle by the angle per character so next loop we rotate + this.ctx.rotate(this.degToRad(drawAngle)); + this.ctx.translate(-this.centerX, -this.centerY); + + // Now draw the character directly above the center point of the wheel at the appropriate radius. + if (strokeStyle) + this.ctx.strokeText(character, this.centerX, this.centerY - radius); + + if (fillStyle) + this.ctx.fillText(character, this.centerX, this.centerY - radius); + + // Increment the drawAngle by the angle per character so next loop we rotate // to the next angle required to draw the character at. - drawAngle += anglePerChar; + drawAngle += anglePerChar; this.ctx.restore(); - } - } - } - } - - // Restore so all text options are reset ready for the next text. - this.ctx.restore(); - } - } + } + } + } + } + + // Restore so all text options are reset ready for the next text. + this.ctx.restore(); + } + } } // ==================================================================================================================== @@ -1153,7 +1153,7 @@ Winwheel.prototype.drawSegmentText = function() // ==================================================================================================================== Winwheel.prototype.degToRad = function(d) { - return d * 0.0174532925199432957; + return d * 0.0174532925199432957; } // ==================================================================================================================== @@ -1161,8 +1161,8 @@ Winwheel.prototype.degToRad = function(d) // ==================================================================================================================== Winwheel.prototype.setCenter = function(x, y) { - this.centerX = x; - this.centerY = y; + this.centerX = x; + this.centerY = y; } // ==================================================================================================================== @@ -1171,38 +1171,38 @@ Winwheel.prototype.setCenter = function(x, y) // ==================================================================================================================== Winwheel.prototype.addSegment = function(options, position) { - // Create a new segment object passing the options in. - newSegment = new Segment(options); - - // Increment the numSegments property of the class since new segment being added. - this.numSegments ++; - var segmentPos; - - // Work out where to place the segment, the default is simply as a new segment at the end of the wheel. - if (typeof position !== 'undefined') - { - // Because we need to insert the segment at this position, not overwrite it, we need to move all segments after this - // location along one in the segments array, before finally adding this new segment at the specified location. - for (var x = this.numSegments; x > position; x --) - { - this.segments[x] = this.segments[x -1]; - } - - this.segments[position] = newSegment; - segmentPos = position; - } - else - { - this.segments[this.numSegments] = newSegment; - segmentPos = this.numSegments; - } - - // Since a segment has been added the segment sizes need to be re-computed so call function to do this. - this.updateSegmentSizes(); - - // Return the segment object just created in the wheel (JavaScript will return it by reference), so that - // further things can be done with it by the calling code if desired. - return this.segments[segmentPos]; + // Create a new segment object passing the options in. + newSegment = new Segment(options); + + // Increment the numSegments property of the class since new segment being added. + this.numSegments ++; + var segmentPos; + + // Work out where to place the segment, the default is simply as a new segment at the end of the wheel. + if (typeof position !== 'undefined') + { + // Because we need to insert the segment at this position, not overwrite it, we need to move all segments after this + // location along one in the segments array, before finally adding this new segment at the specified location. + for (var x = this.numSegments; x > position; x --) + { + this.segments[x] = this.segments[x -1]; + } + + this.segments[position] = newSegment; + segmentPos = position; + } + else + { + this.segments[this.numSegments] = newSegment; + segmentPos = this.numSegments; + } + + // Since a segment has been added the segment sizes need to be re-computed so call function to do this. + this.updateSegmentSizes(); + + // Return the segment object just created in the wheel (JavaScript will return it by reference), so that + // further things can be done with it by the calling code if desired. + return this.segments[segmentPos]; } // ==================================================================================================================== @@ -1234,31 +1234,31 @@ Winwheel.prototype.setCanvasId = function(canvasId) // ==================================================================================================================== Winwheel.prototype.deleteSegment = function(position) { - // There needs to be at least one segment in order for the wheel to draw, so only allow delete if there - // is more than one segment currently left in the wheel. + // There needs to be at least one segment in order for the wheel to draw, so only allow delete if there + // is more than one segment currently left in the wheel. //++ check that specifying a position that does not exist - say 10 in a 6 segment wheel does not cause issues. - if (this.numSegments > 1) - { - // If the position of the segment to remove has been specified. - if (typeof position !== 'undefined') - { - // The array is to be shortened so we need to move all segments after the one - // to be removed down one so there is no gap. - for (var x = position; x < this.numSegments; x ++) - { - this.segments[x] = this.segments[x + 1]; - } - } - - // Unset the last item in the segments array since there is now one less. - this.segments[this.numSegments] = undefined; - - // Decrement the number of segments, - // then call function to update the segment sizes. - this.numSegments --; - this.updateSegmentSizes(); - } + if (this.numSegments > 1) + { + // If the position of the segment to remove has been specified. + if (typeof position !== 'undefined') + { + // The array is to be shortened so we need to move all segments after the one + // to be removed down one so there is no gap. + for (var x = position; x < this.numSegments; x ++) + { + this.segments[x] = this.segments[x + 1]; + } + } + + // Unset the last item in the segments array since there is now one less. + this.segments[this.numSegments] = undefined; + + // Decrement the number of segments, + // then call function to update the segment sizes. + this.numSegments --; + this.updateSegmentSizes(); + } } // ==================================================================================================================== @@ -1267,12 +1267,12 @@ Winwheel.prototype.deleteSegment = function(position) // ==================================================================================================================== Winwheel.prototype.windowToCanvas = function(x, y) { - var bbox = this.canvas.getBoundingClientRect(); - - return { - x: Math.floor(x - bbox.left * (this.canvas.width / bbox.width)), - y: Math.floor(y - bbox.top * (this.canvas.height / bbox.height)) - }; + var bbox = this.canvas.getBoundingClientRect(); + + return { + x: Math.floor(x - bbox.left * (this.canvas.width / bbox.width)), + y: Math.floor(y - bbox.top * (this.canvas.height / bbox.height)) + }; } // ==================================================================================================================== @@ -1281,7 +1281,7 @@ Winwheel.prototype.windowToCanvas = function(x, y) // ==================================================================================================================== Winwheel.prototype.getSegmentAt = function(x, y) { - var foundSegment = null; + var foundSegment = null; // Call function to return segment number. var segmentNumber = this.getSegmentNumberAt(x, y); @@ -1292,7 +1292,7 @@ Winwheel.prototype.getSegmentAt = function(x, y) foundSegment = this.segments[segmentNumber]; } - return foundSegment; + return foundSegment; } // ==================================================================================================================== @@ -1301,79 +1301,79 @@ Winwheel.prototype.getSegmentAt = function(x, y) Winwheel.prototype.getSegmentNumberAt = function(x, y) { // KNOWN ISSUE: this does not work correct if the canvas is scaled using css, or has padding, border. - // @TODO see if can find a solution at some point, check windowToCanvas working as needed, then below. - - // Call function above to convert the raw x and y from the user's browser to canvas coordinates - // i.e. top and left is top and left of canvas, not top and left of the user's browser. - var loc = this.windowToCanvas(x, y); - - // ------------------------------------------ - // Now start the process of working out the segment clicked. - // First we need to figure out the angle of an imaginary line between the centerX and centerY of the wheel and - // the X and Y of the location (for example a mouse click). - var topBottom; - var leftRight; - var adjacentSideLength; - var oppositeSideLength; - var hypotenuseSideLength; - - // We will use right triangle maths with the TAN function. - // The start of the triangle is the wheel center, the adjacent side is along the x axis, and the opposite side is along the y axis. - - // We only ever use positive numbers to work out the triangle and the center of the wheel needs to be considered as 0 for the numbers - // in the maths which is why there is the subtractions below. We also remember what quadrant of the wheel the location is in as we - // need this information later to add 90, 180, 270 degrees to the angle worked out from the triangle to get the position around a 360 degree wheel. - if (loc.x > this.centerX) - { - adjacentSideLength = (loc.x - this.centerX); - leftRight = 'R'; // Location is in the right half of the wheel. - } - else - { - adjacentSideLength = (this.centerX - loc.x); - leftRight = 'L'; // Location is in the left half of the wheel. - } - - if (loc.y > this.centerY) - { - oppositeSideLength = (loc.y - this.centerY); - topBottom = 'B'; // Bottom half of wheel. - } - else - { - oppositeSideLength = (this.centerY - loc.y); - topBottom = 'T'; // Top Half of wheel. - } - - // Now divide opposite by adjacent to get tan value. - var tanVal = oppositeSideLength / adjacentSideLength; - - // Use the tan function and convert results to degrees since that is what we work with. - var result = (Math.atan(tanVal) * 180/Math.PI); - var locationAngle = 0; - - // We also need the length of the hypotenuse as later on we need to compare this to the outerRadius of the segment / circle. - hypotenuseSideLength = Math.sqrt((oppositeSideLength * oppositeSideLength) + (adjacentSideLength * adjacentSideLength)); - - // ------------------------------------------ - // Now to make sense around the wheel we need to alter the values based on if the location was in top or bottom half - // and also right or left half of the wheel, by adding 90, 180, 270 etc. Also for some the initial locationAngle needs to be inverted. - if ((topBottom == 'T') && (leftRight == 'R')) - { - locationAngle = Math.round(90 - result); - } - else if ((topBottom == 'B') && (leftRight == 'R')) - { - locationAngle = Math.round(result + 90); - } - else if ((topBottom == 'B') && (leftRight == 'L')) - { - locationAngle = Math.round((90 - result) + 180); - } - else if ((topBottom == 'T') && (leftRight == 'L')) - { - locationAngle = Math.round(result + 270); - } + // @TODO see if can find a solution at some point, check windowToCanvas working as needed, then below. + + // Call function above to convert the raw x and y from the user's browser to canvas coordinates + // i.e. top and left is top and left of canvas, not top and left of the user's browser. + var loc = this.windowToCanvas(x, y); + + // ------------------------------------------ + // Now start the process of working out the segment clicked. + // First we need to figure out the angle of an imaginary line between the centerX and centerY of the wheel and + // the X and Y of the location (for example a mouse click). + var topBottom; + var leftRight; + var adjacentSideLength; + var oppositeSideLength; + var hypotenuseSideLength; + + // We will use right triangle maths with the TAN function. + // The start of the triangle is the wheel center, the adjacent side is along the x axis, and the opposite side is along the y axis. + + // We only ever use positive numbers to work out the triangle and the center of the wheel needs to be considered as 0 for the numbers + // in the maths which is why there is the subtractions below. We also remember what quadrant of the wheel the location is in as we + // need this information later to add 90, 180, 270 degrees to the angle worked out from the triangle to get the position around a 360 degree wheel. + if (loc.x > this.centerX) + { + adjacentSideLength = (loc.x - this.centerX); + leftRight = 'R'; // Location is in the right half of the wheel. + } + else + { + adjacentSideLength = (this.centerX - loc.x); + leftRight = 'L'; // Location is in the left half of the wheel. + } + + if (loc.y > this.centerY) + { + oppositeSideLength = (loc.y - this.centerY); + topBottom = 'B'; // Bottom half of wheel. + } + else + { + oppositeSideLength = (this.centerY - loc.y); + topBottom = 'T'; // Top Half of wheel. + } + + // Now divide opposite by adjacent to get tan value. + var tanVal = oppositeSideLength / adjacentSideLength; + + // Use the tan function and convert results to degrees since that is what we work with. + var result = (Math.atan(tanVal) * 180/Math.PI); + var locationAngle = 0; + + // We also need the length of the hypotenuse as later on we need to compare this to the outerRadius of the segment / circle. + hypotenuseSideLength = Math.sqrt((oppositeSideLength * oppositeSideLength) + (adjacentSideLength * adjacentSideLength)); + + // ------------------------------------------ + // Now to make sense around the wheel we need to alter the values based on if the location was in top or bottom half + // and also right or left half of the wheel, by adding 90, 180, 270 etc. Also for some the initial locationAngle needs to be inverted. + if ((topBottom == 'T') && (leftRight == 'R')) + { + locationAngle = Math.round(90 - result); + } + else if ((topBottom == 'B') && (leftRight == 'R')) + { + locationAngle = Math.round(result + 90); + } + else if ((topBottom == 'B') && (leftRight == 'L')) + { + locationAngle = Math.round((90 - result) + 180); + } + else if ((topBottom == 'T') && (leftRight == 'L')) + { + locationAngle = Math.round(result + 270); + } // ------------------------------------------ // And now we have to adjust to make sense when the wheel is rotated from the 0 degrees either @@ -1391,37 +1391,37 @@ Winwheel.prototype.getSegmentNumberAt = function(x, y) locationAngle = (360 - Math.abs(locationAngle)); } } - - // ------------------------------------------ - // OK, so after all of that we have the angle of a line between the centerX and centerY of the wheel and - // the X and Y of the location on the canvas where the mouse was clicked. Now time to work out the segment - // this corresponds to. We can use the segment start and end angles for this. - var foundSegmentNumber = null; - - for (var x = 1; x <= this.numSegments; x ++) - { - // Due to segments sharing start and end angles, if line is clicked will pick earlier segment. - if ((locationAngle >= this.segments[x].startAngle) && (locationAngle <= this.segments[x].endAngle)) - { + + // ------------------------------------------ + // OK, so after all of that we have the angle of a line between the centerX and centerY of the wheel and + // the X and Y of the location on the canvas where the mouse was clicked. Now time to work out the segment + // this corresponds to. We can use the segment start and end angles for this. + var foundSegmentNumber = null; + + for (var x = 1; x <= this.numSegments; x ++) + { + // Due to segments sharing start and end angles, if line is clicked will pick earlier segment. + if ((locationAngle >= this.segments[x].startAngle) && (locationAngle <= this.segments[x].endAngle)) + { // To ensure that a click anywhere on the canvas in the segment direction will not cause a - // segment to be matched, as well as the angles, we need to ensure the click was within the radius - // of the segment (or circle if no segment radius). - - // If the hypotenuseSideLength (length of location from the center of the wheel) is with the radius - // then we can assign the segment to the found segment and break out the loop. - - // Have to take in to account hollow wheels (doughnuts) so check is greater than innerRadius as + // segment to be matched, as well as the angles, we need to ensure the click was within the radius + // of the segment (or circle if no segment radius). + + // If the hypotenuseSideLength (length of location from the center of the wheel) is with the radius + // then we can assign the segment to the found segment and break out the loop. + + // Have to take in to account hollow wheels (doughnuts) so check is greater than innerRadius as // well as less than or equal to the outerRadius of the wheel. - if ((hypotenuseSideLength >= this.innerRadius) && (hypotenuseSideLength <= this.outerRadius)) + if ((hypotenuseSideLength >= this.innerRadius) && (hypotenuseSideLength <= this.outerRadius)) { foundSegmentNumber = x; break; } - } - } - - // Finally return the number. - return foundSegmentNumber; + } + } + + // Finally return the number. + return foundSegmentNumber; } // ==================================================================================================================== @@ -1513,10 +1513,10 @@ Winwheel.prototype.startAnimation = function() // Call function to compute the animation properties. this.computeAnimation(); - //++ when have multiple wheels and an animation for one or the other is played or stopped it affects the others - //++ on the screen. Is there a way to give each wheel its own instance of tweenmax not affected by the other??? - - // Set this global variable to this object as an external function is required to call the draw() function on the wheel + //++ when have multiple wheels and an animation for one or the other is played or stopped it affects the others + //++ on the screen. Is there a way to give each wheel its own instance of tweenmax not affected by the other??? + + // Set this global variable to this object as an external function is required to call the draw() function on the wheel // each loop of the animation as Greensock cannot call the draw function directly on this class. winwheelToDrawDuringAnimation = this; @@ -1544,10 +1544,10 @@ Winwheel.prototype.startAnimation = function() // ================================================================================================================================================== Winwheel.prototype.stopAnimation = function(canCallback) { - //++ @TODO re-check if kill is the correct thing here, and if there is more than one wheel object being animated (once sort how to do that) - //++ what is the effect on it? - - // We can kill the animation using our tween object. + //++ @TODO re-check if kill is the correct thing here, and if there is more than one wheel object being animated (once sort how to do that) + //++ what is the effect on it? + + // We can kill the animation using our tween object. winwheelToDrawDuringAnimation.tween.kill(); // We should still call the external function to stop the wheel being redrawn even click and also callback any function that is supposed to be. @@ -1796,14 +1796,14 @@ function Animation(options) }; // Now loop through the default options and create properties of this class set to the value for - // the option passed in if a value was, or if not then set the value of the default. - for (var key in defaultOptions) - { - if ((options != null) && (typeof(options[key]) !== 'undefined')) - this[key] = options[key]; - else - this[key] = defaultOptions[key]; - } + // the option passed in if a value was, or if not then set the value of the default. + for (var key in defaultOptions) + { + if ((options != null) && (typeof(options[key]) !== 'undefined')) + this[key] = options[key]; + else + this[key] = defaultOptions[key]; + } // Also loop though the passed in options and add anything specified not part of the class in to it as a property. if (options != null) @@ -1823,35 +1823,35 @@ function Animation(options) // ==================================================================================================================== function Segment(options) { - // Define default options for segments, most are null so that the global defaults for the wheel - // are used if the values for a particular segment are not specifically set. - defaultOptions = { - 'size' : null, // Leave null for automatic. Valid values are degrees 0-360. Use percentToDegrees function if needed to convert. - 'text' : '', // Default is blank. - 'fillStyle' : null, // If null for the rest the global default will be used. - 'strokeStyle' : null, - 'lineWidth' : null, - 'textFontFamily' : null, - 'textFontSize' : null, - 'textFontWeight' : null, - 'textOrientation' : null, - 'textAlignment' : null, - 'textDirection' : null, - 'textMargin' : null, - 'textFillStyle' : null, - 'textStrokeStyle' : null, - 'textLineWidth' : null - }; + // Define default options for segments, most are null so that the global defaults for the wheel + // are used if the values for a particular segment are not specifically set. + defaultOptions = { + 'size' : null, // Leave null for automatic. Valid values are degrees 0-360. Use percentToDegrees function if needed to convert. + 'text' : '', // Default is blank. + 'fillStyle' : null, // If null for the rest the global default will be used. + 'strokeStyle' : null, + 'lineWidth' : null, + 'textFontFamily' : null, + 'textFontSize' : null, + 'textFontWeight' : null, + 'textOrientation' : null, + 'textAlignment' : null, + 'textDirection' : null, + 'textMargin' : null, + 'textFillStyle' : null, + 'textStrokeStyle' : null, + 'textLineWidth' : null + }; - // Now loop through the default options and create properties of this class set to the value for - // the option passed in if a value was, or if not then set the value of the default. - for (var key in defaultOptions) - { - if ((options != null) && (typeof(options[key]) !== 'undefined')) - this[key] = options[key]; - else - this[key] = defaultOptions[key]; - } + // Now loop through the default options and create properties of this class set to the value for + // the option passed in if a value was, or if not then set the value of the default. + for (var key in defaultOptions) + { + if ((options != null) && (typeof(options[key]) !== 'undefined')) + this[key] = options[key]; + else + this[key] = defaultOptions[key]; + } // Also loop though the passed in options and add anything specified not part of the class in to it as a property. // This allows the developer to easily add properties to segments at construction time. @@ -1865,12 +1865,12 @@ function Segment(options) } } } - - // There are 2 additional properties which are set by the code, so need to define them here. - // They are not in the default options because they are not something that should be set by the user, - // the values are updated every time the updateSegmentSizes() function is called. - this.startAngle = 0; - this.endAngle = 0; + + // There are 2 additional properties which are set by the code, so need to define them here. + // They are not in the default options because they are not something that should be set by the user, + // the values are updated every time the updateSegmentSizes() function is called. + this.startAngle = 0; + this.endAngle = 0; } // ==================================================================================================================== @@ -1886,18 +1886,18 @@ function PointerGuide(options) }; // Now loop through the default options and create properties of this class set to the value for - // the option passed in if a value was, or if not then set the value of the default. - for (var key in defaultOptions) - { - if ((options != null) && (typeof(options[key]) !== 'undefined')) + // the option passed in if a value was, or if not then set the value of the default. + for (var key in defaultOptions) + { + if ((options != null) && (typeof(options[key]) !== 'undefined')) { - this[key] = options[key]; + this[key] = options[key]; } - else + else { - this[key] = defaultOptions[key]; + this[key] = defaultOptions[key]; } - } + } } // ==================================================================================================================== @@ -1927,19 +1927,19 @@ function winwheelAnimationLoop() if (winwheelToDrawDuringAnimation) { // Check if the clearTheCanvas is specified for this animation, if not or it is not false then clear the canvas. - if (winwheelToDrawDuringAnimation.animation.clearTheCanvas != false) + if (winwheelToDrawDuringAnimation.animation.clearTheCanvas != false) { - winwheelToDrawDuringAnimation.ctx.clearRect(0, 0, winwheelToDrawDuringAnimation.canvas.width, winwheelToDrawDuringAnimation.canvas.height); - } - - // If there is a callback function which is supposed to be called before the wheel is drawn then do that. + winwheelToDrawDuringAnimation.ctx.clearRect(0, 0, winwheelToDrawDuringAnimation.canvas.width, winwheelToDrawDuringAnimation.canvas.height); + } + + // If there is a callback function which is supposed to be called before the wheel is drawn then do that. if (winwheelToDrawDuringAnimation.animation.callbackBefore != null) { eval(winwheelToDrawDuringAnimation.animation.callbackBefore); } // Call code to draw the wheel, pass in false as we never want it to clear the canvas as that would wipe anything drawn in the callbackBefore. - winwheelToDrawDuringAnimation.draw(false); + winwheelToDrawDuringAnimation.draw(false); // If there is a callback function which is supposed to be called after the wheel has been drawn then do that. if (winwheelToDrawDuringAnimation.animation.callbackAfter != null) @@ -1959,7 +1959,7 @@ function winwheelStopAnimation(canCallback) TweenMax.ticker.removeEventListener("tick", winwheelAnimationLoop); // When the animation is stopped if canCallback is not false then try to call the callback. - // false can be passed in to stop the after happening if the animation has been stopped before it ended normally. + // false can be passed in to stop the after happening if the animation has been stopped before it ended normally. if (canCallback != false) { if (winwheelToDrawDuringAnimation.animation.callbackFinished != null)