2010-07-10 01:50:13 +00:00
|
|
|
//= require "object.class"
|
2010-06-11 23:37:06 +00:00
|
|
|
|
2010-10-22 02:54:00 +00:00
|
|
|
(function(global) {
|
2010-06-09 22:34:55 +00:00
|
|
|
|
2010-10-22 02:54:00 +00:00
|
|
|
"use strict";
|
|
|
|
|
|
|
|
|
|
var fabric = global.fabric || (global.fabric = { }),
|
2010-07-26 23:20:19 +00:00
|
|
|
extend = fabric.util.object.extend,
|
|
|
|
|
clone = fabric.util.object.clone;
|
2010-06-09 22:34:55 +00:00
|
|
|
|
2010-07-09 23:43:50 +00:00
|
|
|
if (fabric.Text) {
|
2010-10-11 18:45:06 +00:00
|
|
|
fabric.warn('fabric.Text is already defined');
|
2010-06-09 22:34:55 +00:00
|
|
|
return;
|
|
|
|
|
}
|
2010-07-09 23:43:50 +00:00
|
|
|
if (!fabric.Object) {
|
2010-10-11 18:45:06 +00:00
|
|
|
fabric.warn('fabric.Text requires fabric.Object');
|
2010-06-09 22:34:55 +00:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2010-10-14 21:42:39 +00:00
|
|
|
/**
|
|
|
|
|
* @class Text
|
|
|
|
|
* @extends fabric.Object
|
|
|
|
|
*/
|
|
|
|
|
fabric.Text = fabric.util.createClass(fabric.Object, /** @scope fabric.Text.prototype */ {
|
2010-06-09 22:34:55 +00:00
|
|
|
|
2011-07-21 18:53:48 +00:00
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type Number
|
|
|
|
|
*/
|
2011-07-22 00:32:02 +00:00
|
|
|
fontSize: 20,
|
2011-07-21 18:53:48 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type Number
|
|
|
|
|
*/
|
2011-07-22 00:32:02 +00:00
|
|
|
fontWeight: 100,
|
2011-07-21 18:53:48 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type String
|
|
|
|
|
*/
|
2011-07-22 00:32:02 +00:00
|
|
|
fontFamily: 'Modernist_One_400',
|
2011-07-21 18:53:48 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type String
|
|
|
|
|
*/
|
|
|
|
|
textDecoration: '',
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type String | null
|
|
|
|
|
*/
|
|
|
|
|
textShadow: null,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Determines text alignment. Possible values: "left", "center", or "right".
|
|
|
|
|
* @property
|
|
|
|
|
* @type String
|
|
|
|
|
*/
|
|
|
|
|
textAlign: 'left',
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type String
|
|
|
|
|
*/
|
|
|
|
|
fontStyle: '',
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type Number
|
|
|
|
|
*/
|
|
|
|
|
lineHeight: 1.6,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type String
|
|
|
|
|
*/
|
|
|
|
|
strokeStyle: '',
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type Number
|
|
|
|
|
*/
|
|
|
|
|
strokeWidth: 1,
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type String
|
|
|
|
|
*/
|
|
|
|
|
backgroundColor: '',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type String | null
|
|
|
|
|
*/
|
|
|
|
|
path: null,
|
2010-06-09 22:34:55 +00:00
|
|
|
|
2010-10-15 02:16:24 +00:00
|
|
|
/**
|
|
|
|
|
* @property
|
|
|
|
|
* @type String
|
|
|
|
|
*/
|
2011-07-21 18:53:48 +00:00
|
|
|
type: 'text',
|
2010-06-09 22:34:55 +00:00
|
|
|
|
2010-10-14 21:42:39 +00:00
|
|
|
/**
|
|
|
|
|
* Constructor
|
|
|
|
|
* @method initialize
|
|
|
|
|
* @param {String} text
|
|
|
|
|
* @param {Object} [options]
|
|
|
|
|
* @return {fabric.Text} thisArg
|
|
|
|
|
*/
|
2010-06-09 22:34:55 +00:00
|
|
|
initialize: function(text, options) {
|
2010-10-19 20:27:24 +00:00
|
|
|
this._initStateProperties();
|
2010-06-09 22:34:55 +00:00
|
|
|
this.text = text;
|
|
|
|
|
this.setOptions(options);
|
2011-02-09 23:21:45 +00:00
|
|
|
this.theta = this.angle * Math.PI / 180;
|
2010-06-09 22:34:55 +00:00
|
|
|
this.width = this.getWidth();
|
|
|
|
|
this.setCoords();
|
|
|
|
|
},
|
|
|
|
|
|
2010-10-14 21:42:39 +00:00
|
|
|
/**
|
2011-02-09 23:21:45 +00:00
|
|
|
* Creates `stateProperties` list on an instance, and adds `fabric.Text` -specific ones to it
|
2011-07-22 00:32:02 +00:00
|
|
|
* (such as "fontFamily", "fontWeight", etc.)
|
2010-10-19 20:27:24 +00:00
|
|
|
* @private
|
2011-03-02 00:08:38 +00:00
|
|
|
* @method _initStateProperties
|
2010-10-14 21:42:39 +00:00
|
|
|
*/
|
2010-10-19 20:27:24 +00:00
|
|
|
_initStateProperties: function() {
|
2011-03-02 00:08:38 +00:00
|
|
|
this.stateProperties = this.stateProperties.concat();
|
|
|
|
|
this.stateProperties.push(
|
2011-07-22 00:32:02 +00:00
|
|
|
'fontFamily',
|
|
|
|
|
'fontWeight',
|
2011-03-02 00:08:38 +00:00
|
|
|
'path',
|
|
|
|
|
'text',
|
|
|
|
|
'textDecoration',
|
|
|
|
|
'textShadow',
|
2011-07-21 18:53:48 +00:00
|
|
|
'textAlign',
|
2011-03-28 22:57:40 +00:00
|
|
|
'fontStyle',
|
2011-04-20 20:36:31 +00:00
|
|
|
'lineHeight',
|
2011-03-28 22:57:40 +00:00
|
|
|
'strokeStyle',
|
2011-05-13 18:34:24 +00:00
|
|
|
'strokeWidth',
|
|
|
|
|
'backgroundColor'
|
2011-03-02 00:08:38 +00:00
|
|
|
);
|
|
|
|
|
fabric.util.removeFromArray(this.stateProperties, 'width');
|
2010-06-09 22:34:55 +00:00
|
|
|
},
|
|
|
|
|
|
2010-10-14 21:42:39 +00:00
|
|
|
/**
|
|
|
|
|
* Returns string representation of an instance
|
|
|
|
|
* @method toString
|
|
|
|
|
* @return {String} String representation of text object
|
|
|
|
|
*/
|
2010-06-09 22:34:55 +00:00
|
|
|
toString: function() {
|
2011-07-15 22:16:14 +00:00
|
|
|
return '#<fabric.Text (' + this.complexity() +
|
2011-07-22 00:32:02 +00:00
|
|
|
'): { "text": "' + this.text + '", "fontFamily": "' + this.fontFamily + '" }>';
|
2010-06-09 22:34:55 +00:00
|
|
|
},
|
|
|
|
|
|
2010-10-14 21:42:39 +00:00
|
|
|
/**
|
|
|
|
|
* @private
|
|
|
|
|
* @method _render
|
|
|
|
|
* @param {CanvasRenderingContext2D} ctx Context to render on
|
|
|
|
|
*/
|
2010-06-09 22:34:55 +00:00
|
|
|
_render: function(context) {
|
|
|
|
|
var o = Cufon.textOptions || (Cufon.textOptions = { });
|
|
|
|
|
|
|
|
|
|
// export options to be used by cufon.js
|
|
|
|
|
o.left = this.left;
|
|
|
|
|
o.top = this.top;
|
|
|
|
|
o.context = context;
|
|
|
|
|
o.color = this.fill;
|
|
|
|
|
|
|
|
|
|
var el = this._initDummyElement();
|
|
|
|
|
|
|
|
|
|
// set "cursor" to top/left corner
|
|
|
|
|
this.transform(context);
|
|
|
|
|
|
|
|
|
|
// draw text
|
|
|
|
|
Cufon.replaceElement(el, {
|
|
|
|
|
separate: 'none',
|
2011-07-22 00:32:02 +00:00
|
|
|
fontFamily: this.fontFamily,
|
2011-02-02 00:57:01 +00:00
|
|
|
enableTextDecoration: true,
|
|
|
|
|
textDecoration: this.textDecoration,
|
2011-03-21 21:24:36 +00:00
|
|
|
textShadow: this.textShadow,
|
2011-07-21 18:53:48 +00:00
|
|
|
textAlign: this.textAlign,
|
2011-03-28 22:57:40 +00:00
|
|
|
fontStyle: this.fontStyle,
|
2011-04-20 20:36:31 +00:00
|
|
|
lineHeight: this.lineHeight,
|
2011-03-28 22:57:40 +00:00
|
|
|
strokeStyle: this.strokeStyle,
|
2011-05-13 18:34:24 +00:00
|
|
|
strokeWidth: this.strokeWidth,
|
|
|
|
|
backgroundColor: this.backgroundColor
|
2010-06-09 22:34:55 +00:00
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// update width, height
|
|
|
|
|
this.width = o.width;
|
|
|
|
|
this.height = o.height;
|
2011-02-09 23:21:45 +00:00
|
|
|
|
|
|
|
|
// need to set coords _after_ the width/height was retreived from Cufon
|
|
|
|
|
this.setCoords();
|
2010-06-09 22:34:55 +00:00
|
|
|
},
|
|
|
|
|
|
2011-06-30 18:37:39 +00:00
|
|
|
// _render: function(context) {
|
|
|
|
|
// context.fillStyle = this.fill;
|
2011-07-22 00:32:02 +00:00
|
|
|
// context.font = this.fontSize + 'px ' + this.fontFamily;
|
2011-06-30 18:37:39 +00:00
|
|
|
// this.transform(context);
|
|
|
|
|
// this.width = context.measureText(this.text).width;
|
2011-07-22 00:32:02 +00:00
|
|
|
// this.height = this.fontSize;
|
2011-06-30 18:37:39 +00:00
|
|
|
// context.fillText(this.text, -this.width / 2, 0);
|
|
|
|
|
// this.setCoords();
|
|
|
|
|
// },
|
|
|
|
|
|
2010-10-14 21:42:39 +00:00
|
|
|
/**
|
|
|
|
|
* @private
|
|
|
|
|
* @method _initDummyElement
|
|
|
|
|
*/
|
2010-06-09 22:34:55 +00:00
|
|
|
_initDummyElement: function() {
|
2011-02-02 00:57:01 +00:00
|
|
|
var el = document.createElement('div'),
|
|
|
|
|
container = document.createElement('div');
|
|
|
|
|
|
|
|
|
|
// Cufon doesn't play nice with textDecoration=underline if element doesn't have a parent
|
|
|
|
|
container.appendChild(el);
|
2010-06-09 22:34:55 +00:00
|
|
|
el.innerHTML = this.text;
|
|
|
|
|
|
|
|
|
|
// need to specify these manually, since Jaxer doesn't support retrieving computed style
|
|
|
|
|
el.style.fontSize = '40px';
|
|
|
|
|
el.style.fontWeight = '400';
|
|
|
|
|
el.style.letterSpacing = 'normal';
|
|
|
|
|
el.style.color = '#000000';
|
|
|
|
|
el.style.fontWeight = '600';
|
|
|
|
|
el.style.fontFamily = 'Verdana';
|
|
|
|
|
|
|
|
|
|
return el;
|
|
|
|
|
},
|
|
|
|
|
|
2010-10-14 21:42:39 +00:00
|
|
|
/**
|
2010-10-19 20:27:24 +00:00
|
|
|
* Renders text instance on a specified context
|
2010-10-14 21:42:39 +00:00
|
|
|
* @method render
|
|
|
|
|
* @param ctx {CanvasRenderingContext2D} context to render on
|
|
|
|
|
*/
|
2010-06-09 22:34:55 +00:00
|
|
|
render: function(context) {
|
|
|
|
|
context.save();
|
|
|
|
|
this._render(context);
|
|
|
|
|
if (this.active) {
|
|
|
|
|
this.drawBorders(context);
|
|
|
|
|
this.drawCorners(context);
|
|
|
|
|
}
|
|
|
|
|
context.restore();
|
|
|
|
|
},
|
2011-04-23 21:39:56 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns object representation of an instance
|
|
|
|
|
* @method toObject
|
|
|
|
|
* @return {Object} Object representation of text object
|
|
|
|
|
*/
|
|
|
|
|
toObject: function() {
|
|
|
|
|
return extend(this.callSuper('toObject'), {
|
|
|
|
|
text: this.text,
|
2011-07-22 00:32:02 +00:00
|
|
|
fontSize: this.fontSize,
|
|
|
|
|
fontWeight: this.fontWeight,
|
|
|
|
|
fontFamily: this.fontFamily,
|
2011-04-23 21:39:56 +00:00
|
|
|
fontStyle: this.fontStyle,
|
|
|
|
|
lineHeight: this.lineHeight,
|
|
|
|
|
textDecoration: this.textDecoration,
|
|
|
|
|
textShadow: this.textShadow,
|
2011-07-21 18:53:48 +00:00
|
|
|
textAlign: this.textAlign,
|
2011-04-23 21:39:56 +00:00
|
|
|
path: this.path,
|
|
|
|
|
strokeStyle: this.strokeStyle,
|
2011-05-13 18:34:24 +00:00
|
|
|
strokeWidth: this.strokeWidth,
|
|
|
|
|
backgroundColor: this.backgroundColor
|
2011-04-23 21:39:56 +00:00
|
|
|
});
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets "color" of an instance (alias of `set('fill', …)`)
|
|
|
|
|
* @method setColor
|
|
|
|
|
* @param {String} value
|
|
|
|
|
* @return {fabric.Text} thisArg
|
|
|
|
|
* @chainable
|
|
|
|
|
*/
|
|
|
|
|
setColor: function(value) {
|
|
|
|
|
this.set('fill', value);
|
|
|
|
|
return this;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
2011-07-22 00:32:02 +00:00
|
|
|
* Sets fontSize of an instance and updates its coordinates
|
2011-04-23 21:39:56 +00:00
|
|
|
* @method setFontsize
|
|
|
|
|
* @param {Number} value
|
|
|
|
|
* @return {fabric.Text} thisArg
|
|
|
|
|
* @chainable
|
|
|
|
|
*/
|
|
|
|
|
setFontsize: function(value) {
|
2011-07-22 00:32:02 +00:00
|
|
|
this.set('fontSize', value);
|
2011-04-23 21:39:56 +00:00
|
|
|
this.setCoords();
|
|
|
|
|
return this;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns actual text value of an instance
|
|
|
|
|
* @method getText
|
|
|
|
|
* @return {String}
|
|
|
|
|
*/
|
|
|
|
|
getText: function() {
|
|
|
|
|
return this.text;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets text of an instance, and updates its coordinates
|
|
|
|
|
* @method setText
|
|
|
|
|
* @param {String} value
|
|
|
|
|
* @return {fabric.Text} thisArg
|
|
|
|
|
* @chainable
|
|
|
|
|
*/
|
|
|
|
|
setText: function(value) {
|
|
|
|
|
this.set('text', value);
|
|
|
|
|
this.setCoords();
|
|
|
|
|
return this;
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sets specified property to a specified value
|
|
|
|
|
* @method set
|
|
|
|
|
* @param {String} name
|
|
|
|
|
* @param {Any} value
|
|
|
|
|
* @return {fabric.Text} thisArg
|
|
|
|
|
* @chainable
|
|
|
|
|
*/
|
|
|
|
|
set: function(name, value) {
|
|
|
|
|
this[name] = value;
|
2011-07-22 00:32:02 +00:00
|
|
|
if (name === 'fontFamily' && this.path) {
|
2011-04-23 21:39:56 +00:00
|
|
|
this.path = this.path.replace(/(.*?)([^\/]*)(\.font\.js)/, '$1' + value + '$3');
|
|
|
|
|
}
|
|
|
|
|
return this;
|
|
|
|
|
}
|
2010-06-09 22:34:55 +00:00
|
|
|
});
|
2011-04-23 21:39:56 +00:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns fabric.Text instance from an object representation
|
2010-06-09 22:34:55 +00:00
|
|
|
* @static
|
|
|
|
|
* @method fromObject
|
|
|
|
|
* @param {Object} object to create an instance from
|
2010-07-09 23:43:50 +00:00
|
|
|
* @return {fabric.Text} an instance
|
2010-06-09 22:34:55 +00:00
|
|
|
*/
|
2011-04-23 21:39:56 +00:00
|
|
|
fabric.Text.fromObject = function(object) {
|
|
|
|
|
return new fabric.Text(object.text, clone(object));
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns fabric.Text instance from an SVG element (<b>not yet implemented</b>)
|
2010-06-09 22:34:55 +00:00
|
|
|
* @static
|
2010-07-09 23:43:50 +00:00
|
|
|
* @method fabric.Text.fromElement
|
|
|
|
|
* @return {fabric.Text} an instance
|
2010-06-09 22:34:55 +00:00
|
|
|
*/
|
2011-04-23 21:39:56 +00:00
|
|
|
fabric.Text.fromElement = function(element) {
|
|
|
|
|
// TODO (kangax): implement this
|
|
|
|
|
};
|
2010-10-22 02:54:00 +00:00
|
|
|
})(this);
|