From 26e784aede0cb01cc47b57579a4ca5ffdd593bf4 Mon Sep 17 00:00:00 2001 From: Kienz Date: Sat, 14 Sep 2013 17:10:49 +0200 Subject: [PATCH] Move `setColor`from `fabric.Text` to `fabric.Object` Fixed "enum" notation `fabric.Object.setGradient` is now chainable Doc additions Add `fabric.Object.setPatternFill`unit test Add chainable tests to some methods --- src/mixins/object_origin.mixin.js | 16 ++-- src/shapes/object.class.js | 27 ++++-- src/shapes/text.class.js | 11 --- test/unit/object.js | 144 +++++++++++++++++++++++++----- test/unit/text.js | 9 +- 5 files changed, 152 insertions(+), 55 deletions(-) diff --git a/src/mixins/object_origin.mixin.js b/src/mixins/object_origin.mixin.js index 612ae721..15d79068 100644 --- a/src/mixins/object_origin.mixin.js +++ b/src/mixins/object_origin.mixin.js @@ -7,8 +7,8 @@ /** * Translates the coordinates from origin to center coordinates (based on the object's dimensions) * @param {fabric.Point} point The point which corresponds to the originX and originY params - * @param {string} enum('left', 'center', 'right') Horizontal origin - * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @param {String} originX Horizontal origin: 'left', 'center' or 'right' + * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' * @return {fabric.Point} */ translateToCenterPoint: function(point, originX, originY) { @@ -35,8 +35,8 @@ /** * Translates the coordinates from center to origin coordinates (based on the object's dimensions) * @param {fabric.Point} point The point which corresponds to center of the object - * @param {string} enum('left', 'center', 'right') Horizontal origin - * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @param {String} originX Horizontal origin: 'left', 'center' or 'right' + * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' * @return {fabric.Point} */ translateToOriginPoint: function(center, originX, originY) { @@ -80,8 +80,8 @@ /** * Returns the coordinates of the object as if it has a different origin - * @param {string} enum('left', 'center', 'right') Horizontal origin - * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @param {String} originX Horizontal origin: 'left', 'center' or 'right' + * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' * @return {fabric.Point} */ // getPointByOrigin: function(originX, originY) { @@ -140,8 +140,8 @@ /** * Sets the position of the object taking into consideration the object's origin * @param {fabric.Point} point The new position of the object - * @param {string} enum('left', 'center', 'right') Horizontal origin - * @param {string} enum('top', 'center', 'bottom') Vertical origin + * @param {String} originX Horizontal origin: 'left', 'center' or 'right' + * @param {String} originY Vertical origin: 'top', 'center' or 'bottom' * @return {void} */ setPositionByOrigin: function(pos, originX, originY) { diff --git a/src/shapes/object.class.js b/src/shapes/object.class.js index 37ae0855..146d0f3a 100644 --- a/src/shapes/object.class.js +++ b/src/shapes/object.class.js @@ -612,7 +612,7 @@ /** * Basic getter - * @param {String} property + * @param {String} property Property name * @return {Any} value of a property */ get: function(property) { @@ -621,8 +621,8 @@ /** * Sets property to a given value. When changing position/dimension -related properties (left, top, scale, angle, etc.) `set` does not update position of object's borders/controls. If you need to update those, call `setCoords()`. - * @param {String|Object} key (if object, iterate over the object properties) - * @param {Object|Function} value (if function, the value is passed into it and its return value is used as a new one) + * @param {String|Object} key Property name or object (if object, iterate over the object properties) + * @param {Object|Function} value Property value (if function, the value is passed into it and its return value is used as a new one) * @return {fabric.Object} thisArg * @chainable */ @@ -677,7 +677,7 @@ /** * Toggles specified property from `true` to `false` or from `false` to `true` - * @param {String} property property to toggle + * @param {String} property Property to toggle * @return {fabric.Object} thisArg * @chainable */ @@ -702,7 +702,7 @@ /** * Renders an object on a specified context - * @param {CanvasRenderingContext2D} ctx context to render on + * @param {CanvasRenderingContext2D} ctx Context to render on * @param {Boolean} [noTransform] When true, context is not transformed */ render: function(ctx, noTransform) { @@ -908,7 +908,7 @@ /** * Returns true if specified type is identical to the type of an instance - * @param type {String} type to check against + * @param type {String} type Type to check against * @return {Boolean} */ isType: function(type) { @@ -950,6 +950,7 @@ * Backwards incompatibility note: This method was named "setGradientFill" until v1.1.0 * @param {String} property Property name 'stroke' or 'fill' * @param {Object} [options] Options object + * @chainable */ setGradient: function(property, options) { options || (options = { }); @@ -974,7 +975,7 @@ gradient.colorStops.push({offset: position, color: color.toRgb(), opacity: color.getAlpha()}); } - this.set(property, fabric.Gradient.forObject(this, gradient)); + return this.set(property, fabric.Gradient.forObject(this, gradient)); }, /** @@ -997,10 +998,22 @@ return this.set('shadow', new fabric.Shadow(options)); }, + /** + * Sets "color" of an instance (alias of `set('fill', …)`) + * @param {String} color Color value + * @return {fabric.Text} thisArg + * @chainable + */ + setColor: function(color) { + this.set('fill', color); + return this; + }, + /** * Centers object horizontally on canvas to which it was added last. * You might need to call `setCoords` on an object after centering, to update controls area. * @return {fabric.Object} thisArg + * @chainable */ centerH: function () { this.canvas.centerObjectH(this); diff --git a/src/shapes/text.class.js b/src/shapes/text.class.js index 8358daa7..3b57e24e 100644 --- a/src/shapes/text.class.js +++ b/src/shapes/text.class.js @@ -973,17 +973,6 @@ }, /* _TO_SVG_END_ */ - /** - * Sets "color" of an instance (alias of `set('fill', …)`) - * @param {String} value - * @return {fabric.Text} thisArg - * @chainable - */ - setColor: function(value) { - this.set('fill', value); - return this; - }, - /** * Sets specified property to a specified value * @param {String} key diff --git a/test/unit/object.js b/test/unit/object.js index d333cf91..1e8472af 100644 --- a/test/unit/object.js +++ b/test/unit/object.js @@ -2,6 +2,47 @@ var canvas = this.canvas = fabric.isLikelyNode ? fabric.createCanvasForNode() : new fabric.StaticCanvas(); + function getAbsolutePath(path) { + var isAbsolute = /^https?:/.test(path); + if (isAbsolute) return path; + var imgEl = _createImageElement(); + imgEl.src = path; + var src = imgEl.src; + imgEl = null; + return src; + } + + var IMG_SRC = fabric.isLikelyNode ? (__dirname + '/../fixtures/test_image.gif') : getAbsolutePath('../fixtures/test_image.gif'), + IMG_WIDTH = 276, + IMG_HEIGHT = 110; + + function _createImageElement() { + return fabric.isLikelyNode ? new (require('canvas').Image) : fabric.document.createElement('img'); + } + + function createImageObject(callback) { + var elImage = _createImageElement(); + elImage.width = IMG_WIDTH; + elImage.height = IMG_HEIGHT; + setSrc(elImage, IMG_SRC, function() { + callback(elImage); + }); + } + + function setSrc(img, src, callback) { + if (fabric.isLikelyNode) { + require('fs').readFile(src, function(err, imgData) { + if (err) throw err; + img.src = imgData; + callback && callback(); + }); + } + else { + img.src = src; + callback && callback(); + } + } + QUnit.module('fabric.Object', { teardown: function() { canvas.clear(); @@ -845,7 +886,7 @@ ok(typeof object.remove == 'function'); canvas.add(object); - object.remove(); + equal(object.remove(), object, 'should be chainable'); equal(canvas.getObjects().length, 0); }); @@ -856,7 +897,7 @@ ok(typeof object.center == 'function'); canvas.add(object); - object.center(); + equal(object.center(), object, 'should be chainable'); equal(object.getLeft(), canvas.getWidth() / 2); equal(object.getTop(), canvas.getHeight() / 2); @@ -868,7 +909,7 @@ ok(typeof object.centerH == 'function'); canvas.add(object); - object.centerH(); + equal(object.centerH(), object, 'should be chainable'); equal(object.getLeft(), canvas.getWidth() / 2); }); @@ -879,7 +920,7 @@ ok(typeof object.centerV == 'function'); canvas.add(object); - object.centerV(); + equal(object.centerV(), object, 'should be chainable'); equal(object.getTop(), canvas.getHeight() / 2); }); @@ -888,36 +929,53 @@ var object = new fabric.Object(); ok(typeof object.sendToBack == 'function'); + + canvas.add(object); + equal(object.sendToBack(), object, 'should be chainable'); }); test('bringToFront', function() { var object = new fabric.Object(); ok(typeof object.bringToFront == 'function'); + + canvas.add(object); + equal(object.bringToFront(), object, 'should be chainable'); }); test('sendBackwards', function() { var object = new fabric.Object(); - ok(typeof object.bringToFront == 'function'); + ok(typeof object.sendBackwards == 'function'); + + canvas.add(object); + equal(object.sendBackwards(), object, 'should be chainable'); }); test('bringForward', function() { var object = new fabric.Object(); - ok(typeof object.bringToFront == 'function'); + ok(typeof object.bringForward == 'function'); + + canvas.add(object); + equal(object.bringForward(), object, 'should be chainable'); }); test('moveTo', function() { var object = new fabric.Object(); ok(typeof object.moveTo == 'function'); + + canvas.add(object); + equal(object.moveTo(), object, 'should be chainable'); }); - test('gradient serialization', function() { + test('setGradient', function() { var object = new fabric.Object(); - object.setGradient('fill', { + ok(typeof object.setGradient == 'function'); + + equal(object.setGradient('fill', { x1: 0, y1: 0, x2: 100, @@ -926,34 +984,70 @@ '0': 'rgb(255,0,0)', '1': 'rgb(0,128,0)' } - }); + }), object, 'should be chainable'); ok(typeof object.toObject().fill == 'object'); + ok(object.fill instanceof fabric.Gradient); - equal(object.toObject().fill.type, 'linear'); + var fill = object.fill; - equal(object.toObject().fill.coords.x1, 0); - equal(object.toObject().fill.coords.y1, 0); + equal(fill.type, 'linear'); - equal(object.toObject().fill.coords.x2, 100); - equal(object.toObject().fill.coords.y2, 100); + equal(fill.coords.x1, 0); + equal(fill.coords.y1, 0); - equal(object.toObject().fill.colorStops[0].offset, 0); - equal(object.toObject().fill.colorStops[1].offset, 1); - equal(object.toObject().fill.colorStops[0].color, 'rgb(255,0,0)'); - equal(object.toObject().fill.colorStops[1].color, 'rgb(0,128,0)'); + equal(fill.coords.x2, 100); + equal(fill.coords.y2, 100); + + equal(fill.colorStops[0].offset, 0); + equal(fill.colorStops[1].offset, 1); + equal(fill.colorStops[0].color, 'rgb(255,0,0)'); + equal(fill.colorStops[1].color, 'rgb(0,128,0)'); + }); + + asyncTest('setPatternFill', function() { + var object = new fabric.Object(); + + ok(typeof object.setPatternFill == 'function'); + + createImageObject(function(img) { + equal(object.setPatternFill({source: img}), object, 'should be chainable'); + + ok(typeof object.toObject().fill == 'object'); + ok(object.fill instanceof fabric.Pattern); + + equal(object.fill.source, img); + equal(object.fill.repeat, 'repeat'); + equal(object.fill.offsetX, 0); + equal(object.fill.offsetY, 0); + + equal(object.setPatternFill({source: img, repeat: 'repeat-y', offsetX: 100, offsetY: 50}), object, 'should be chainable'); + + ok(typeof object.fill == 'object'); + ok(object.fill instanceof fabric.Pattern); + + equal(object.fill.source, img); + equal(object.fill.repeat, 'repeat-y'); + equal(object.fill.offsetX, 100); + equal(object.fill.offsetY, 50); + + start(); + }); }); test('setShadow', function() { var object = new fabric.Object(); - object.setShadow({ + ok(typeof object.setShadow == 'function'); + + equal(object.setShadow({ color: 'red', blur: 10, offsetX: 5, offsetY: 15 - }); + }), object, 'should be chainable'); + ok(typeof object.toObject().shadow == 'object'); ok(object.shadow instanceof fabric.Shadow); equal(object.shadow.color, 'red'); @@ -962,7 +1056,6 @@ equal(object.shadow.offsetY, 15); }); - test('set shadow', function() { var object = new fabric.Object(); @@ -982,6 +1075,15 @@ equal(object.shadow, null); }); + test('setColor', function(){ + var object = new fabric.Object(); + + ok(typeof object.setColor == 'function'); + + equal(object.setColor('123456'), object, 'should be chainable'); + equal(object.get('fill'), '123456'); + }); + test('intersectsWithRect', function() { var object = new fabric.Object({ left: 20, top: 30, width: 40, height: 50, angle: 160 }), point1 = new fabric.Point(0, 0), diff --git a/test/unit/text.js b/test/unit/text.js index e5a60661..f4df8ee0 100644 --- a/test/unit/text.js +++ b/test/unit/text.js @@ -111,17 +111,10 @@ equal(text.shadow.blur, 2); }); - test('setColor', function(){ - var text = createTextObject(); - ok(typeof text.setColor == 'function'); - equal(text.setColor('123456'), text, 'should be chainable'); - equal(text.get('fill'), '123456'); - }); - test('setFontSize', function(){ var text = createTextObject(); ok(typeof text.setFontSize == 'function'); - equal(text.setFontSize(12), text); + equal(text.setFontSize(12), text, 'should be chainable'); equal(text.get('fontSize'), 12); });