diff --git a/Gruntfile.js b/Gruntfile.js index ac58660b..771b6f0b 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -34,6 +34,7 @@ module.exports = function(grunt) { 'src/plugins/RegularPolygon.js', 'src/plugins/Star.js', 'src/plugins/Label.js', + 'src/plugins/Crosshair.js', // filters 'src/filters/FilterWrapper.js', diff --git a/src/plugins/Crosshair.js b/src/plugins/Crosshair.js new file mode 100644 index 00000000..78afbc1f --- /dev/null +++ b/src/plugins/Crosshair.js @@ -0,0 +1,140 @@ +(function() { + /** + * Crosshair constructor + * @constructor + * @augments Kinetic.Shape + * @param {Object} config + * @param {Object} config.innerGap + * @param {Number} config.innerGapX + * @param {Number} config.innerGapY + * @param {Boolean} config.encircled + * @@shapeParams + * @@nodeParams + * @example + * var Crosshair = new Kinetic.Crosshair({
+ * width: 50,
+ * height: 70,
+ * fill: 'red',
+ * stroke: 'black',
+ * strokeWidth: 5,
+ * innerGap: {x: 5, y: 10},
+ * encircled: true
+ * }); + */ + Kinetic.Crosshair = function(config) { + this.___init(config); + }; + + Kinetic.Crosshair.prototype = { + ___init: function(config) { + // call super constructor + Kinetic.Shape.call(this, config); + this.className = 'Crosshair'; + this.setDrawFunc(this._drawFunc); + }, + _drawFunc: function(context) { + var width_over_2 = this.getWidth() / 2; + var height_over_2 = this.getHeight() / 2; + + context.beginPath(); + context.moveTo(this.getInnerGapX(), 0); + context.lineTo(width_over_2, 0); + context.moveTo(-this.getInnerGapX(), 0); + context.lineTo(-width_over_2, 0); + context.moveTo(0, this.getInnerGapY()); + context.lineTo(0, height_over_2); + context.moveTo(0, -this.getInnerGapY()); + context.lineTo(0, -height_over_2); + + if (this.getEncircled()) { + var width_two_thirds = this.getWidth() * 2 / 3; + context.moveTo(0, -height_over_2); + context.bezierCurveTo(width_two_thirds, -height_over_2, width_two_thirds, height_over_2, 0, height_over_2); + context.bezierCurveTo(-width_two_thirds, height_over_2, -width_two_thirds, -height_over_2, 0, -height_over_2); + } + + context.closePath(); + context.fillStrokeShape(this); + } + }; + Kinetic.Util.extend(Kinetic.Crosshair, Kinetic.Shape); + + // add getters setters + Kinetic.Factory.addPointGetterSetter(Kinetic.Crosshair, 'innerGap', 0); + + /** + * set innerGap. The innerGap is the distance between the center and the start of the crosshair line. + * @name setInnerGap + * @method + * @memberof Kinetic.Crosshair.prototype + * @param {Number} x + * @param {Number} y + * @returns {Kinetic.Crosshair} + * @example + * // set x and y
+ * shape.setInnerGap({
+ * x: 5
+ * y: 5
+ * });

+ */ + + /** + * get innerGap + * @name getInnerGap + * @method + * @memberof Kinetic.Crosshair.prototype + * @returns {Object} + */ + + /** + * set innerGap x + * @name setInnerGapX + * @method + * @memberof Kinetic.Crosshair.prototype + * @param {Number} x + * @returns {Kinetic.Crosshair} + */ + + /** + * get innerGap x + * @name getInnerGapX + * @method + * @memberof Kinetic.Crosshair.prototype + * @returns {Number} + */ + + /** + * set innerGap y + * @name setInnerGapY + * @method + * @memberof Kinetic.Crosshair.prototype + * @param {Number} y + * @returns {Kinetic.Crosshair} + */ + + /** + * get innerGap y + * @name getInnerGapY + * @method + * @memberof Kinetic.Crosshair.prototype + * @returns {Number} + */ + + Kinetic.Factory.addGetterSetter(Kinetic.Crosshair, 'encircled', false); + + /** + * set encircled + * @name setEncircled + * @method + * @memberof Kinetic.Crosshair.prototype + * @param {Boolean} + */ + + /** + * get encircled + * @name getEncircled + * @method + * @memberof Kinetic.Crosshair.prototype + * @returns {Boolean} + */ +})(); diff --git a/test/runner.html b/test/runner.html index 8ce6f4d6..80b42e3e 100644 --- a/test/runner.html +++ b/test/runner.html @@ -77,6 +77,7 @@

KineticJS Test

+ diff --git a/test/unit/plugins/Crosshair-test.js b/test/unit/plugins/Crosshair-test.js new file mode 100644 index 00000000..e6ff302e --- /dev/null +++ b/test/unit/plugins/Crosshair-test.js @@ -0,0 +1,108 @@ +suite('Crosshair', function() { + // ====================================================== + test('basic', function() { + var stage = addStage(); + + var layer = new Kinetic.Layer(); + + var crosshair = new Kinetic.Crosshair({ + x: 200, + y: 100, + width: 100, + height: 100, + fill: 'green', + stroke: 'black', + strokeWidth: 2 + }); + + layer.add(crosshair); + stage.add(layer); + + assert.equal(crosshair.getClassName(), 'Crosshair'); + }); + + // ====================================================== + test('with innerGap', function() { + var stage = addStage(); + + var layer = new Kinetic.Layer(); + + var crosshair = new Kinetic.Crosshair({ + x: 200, + y: 100, + width: 100, + height: 100, + fill: 'green', + stroke: 'black', + strokeWidth: 2, + innerGap: { x: 5, y: 5 } + }); + + layer.add(crosshair); + stage.add(layer); + }); + + // ====================================================== + test('varying innerGap and size', function() { + var stage = addStage(); + + var layer = new Kinetic.Layer(); + + var crosshair = new Kinetic.Crosshair({ + x: 200, + y: 100, + width: 150, + height: 100, + fill: 'green', + stroke: 'black', + strokeWidth: 2, + innerGap: { x: 5, y: 1 } + }); + + layer.add(crosshair); + stage.add(layer); + }); + + // ====================================================== + test('encircled', function() { + var stage = addStage(); + + var layer = new Kinetic.Layer(); + + var crosshair = new Kinetic.Crosshair({ + x: 200, + y: 100, + width: 100, + height: 100, + fill: 'green', + stroke: 'black', + strokeWidth: 2, + innerGap: { x: 5, y: 5 }, + encircled: true + }); + + layer.add(crosshair); + stage.add(layer); + }); + + // ====================================================== + test('encircled with varying size', function() { + var stage = addStage(); + + var layer = new Kinetic.Layer(); + + var crosshair = new Kinetic.Crosshair({ + x: 200, + y: 100, + width: 200, + height: 100, + fill: 'green', + stroke: 'black', + strokeWidth: 2, + encircled: true + }); + + layer.add(crosshair); + stage.add(layer); + }); +});