3 This file is part of Ext JS 4
5 Copyright (c) 2011 Sencha Inc
7 Contact: http://www.sencha.com/contact
9 GNU General Public License Usage
10 This file may be used under the terms of the GNU General Public License version 3.0 as published by the Free Software Foundation and appearing in the file LICENSE included in the packaging of this file. Please review the following information to ensure the GNU General Public License version 3.0 requirements will be met: http://www.gnu.org/copyleft/gpl.html.
12 If you are unsure which license is appropriate for your use, please contact the sales department at http://www.sencha.com/contact.
16 * @class Ext.draw.Sprite
19 * A Sprite is an object rendered in a Drawing surface. There are different options and types of sprites.
20 * The configuration of a Sprite is an object with the following properties:
22 * - **type** - (String) The type of the sprite. Possible options are 'circle', 'path', 'rect', 'text', 'square', 'image'.
23 * - **group** - (String/Array) The group that this sprite belongs to, or an array of groups. Only relevant when added to a {@link Ext.draw.Surface}.
24 * - **width** - (Number) Used in rectangle sprites, the width of the rectangle.
25 * - **height** - (Number) Used in rectangle sprites, the height of the rectangle.
26 * - **size** - (Number) Used in square sprites, the dimension of the square.
27 * - **radius** - (Number) Used in circle sprites, the radius of the circle.
28 * - **x** - (Number) The position along the x-axis.
29 * - **y** - (Number) The position along the y-axis.
30 * - **path** - (Array) Used in path sprites, the path of the sprite written in SVG-like path syntax.
31 * - **opacity** - (Number) The opacity of the sprite.
32 * - **fill** - (String) The fill color.
33 * - **stroke** - (String) The stroke color.
34 * - **stroke-width** - (Number) The width of the stroke.
35 * - **font** - (String) Used with text type sprites. The full font description. Uses the same syntax as the CSS `font` parameter.
36 * - **text** - (String) Used with text type sprites. The text itself.
37 * - **translate** - (Object) Defines a translation for the Sprite. There's more information on this property below.
38 * - **rotate** - (Object) Defines a rotation for the Sprite. There's more information on this property below.
39 * - **scale** - (Object) Defines a scaling for the Sprite. There's more information on this property below.
44 * For translate, the configuration object contains x and y attributes that indicate where to
45 * translate the object. For example:
47 * sprite.setAttributes({
57 * For rotation, the configuration object contains x and y attributes for the center of the rotation (which are optional),
58 * and a `degrees` attribute that specifies the rotation in degrees. For example:
60 * sprite.setAttributes({
66 * That example will create a 90 degrees rotation using the centroid of the Sprite as center of rotation, whereas:
68 * sprite.setAttributes({
76 * will create a rotation around the `(0, 0)` axis.
81 * For scaling, the configuration object contains x and y attributes for the x-axis and y-axis scaling. For example:
83 * sprite.setAttributes({
90 * You can also specify the center of scaling by adding `cx` and `cy` as properties:
92 * sprite.setAttributes({
101 * That last example will scale a sprite taking as centers of scaling the `(0, 0)` coordinate.
104 * ## Creating and adding a Sprite to a Surface
106 * Sprites can be created with a reference to a {@link Ext.draw.Surface}
108 * var drawComponent = Ext.create('Ext.draw.Component', options here...);
110 * var sprite = Ext.create('Ext.draw.Sprite', {
113 * surface: drawComponent.surface,
117 * Sprites can also be added to the surface as a configuration object:
119 * var sprite = drawComponent.surface.add({
125 * In order to properly apply properties and render the sprite we have to
126 * `show` the sprite setting the option `redraw` to `true`:
130 * The constructor configuration object of the Sprite can also be used and passed into the {@link Ext.draw.Surface}
131 * add method to append a new sprite to the canvas. For example:
133 * drawComponent.surface.add({
141 Ext.define('Ext.draw.Sprite', {
144 * @cfg {String} type The type of the sprite. Possible options are 'circle', 'path', 'rect', 'text', 'square', 'image'
148 * @cfg {Number} width Used in rectangle sprites, the width of the rectangle
152 * @cfg {Number} height Used in rectangle sprites, the height of the rectangle
156 * @cfg {Number} size Used in square sprites, the dimension of the square
160 * @cfg {Number} radius Used in circle sprites, the radius of the circle
164 * @cfg {Number} x The position along the x-axis
168 * @cfg {Number} y The position along the y-axis
172 * @cfg {Array} path Used in path sprites, the path of the sprite written in SVG-like path syntax
176 * @cfg {Number} opacity The opacity of the sprite
180 * @cfg {String} fill The fill color
184 * @cfg {String} stroke The stroke color
188 * @cfg {Number} stroke-width The width of the stroke
192 * @cfg {String} font Used with text type sprites. The full font description. Uses the same syntax as the CSS font parameter
196 * @cfg {String} text Used with text type sprites. The text itself
200 * @cfg {String/Array} group The group that this sprite belongs to, or an array of groups. Only relevant when added to a
201 * {@link Ext.draw.Surface}
204 /* Begin Definitions */
207 observable: 'Ext.util.Observable',
208 animate: 'Ext.util.Animate'
211 requires: ['Ext.draw.SpriteDD'],
213 /* End Definitions */
217 dirtyTransform: false,
246 constructor: function(config) {
248 config = config || {};
249 me.id = Ext.id(null, 'ext-sprite-');
250 me.transformations = [];
251 Ext.copyTo(this, config, 'surface,group,type,draggable');
272 //delete not bucket attributes
273 delete config.surface;
276 delete config.draggable;
277 me.setAttributes(config);
289 me.mixins.observable.constructor.apply(this, arguments);
293 * <p>If this Sprite is configured {@link #draggable}, this property will contain
294 * an instance of {@link Ext.dd.DragSource} which handles dragging the Sprite.</p>
295 * The developer must provide implementations of the abstract methods of {@link Ext.dd.DragSource}
296 * in order to supply behaviour for each stage of the drag/drop process. See {@link #draggable}.
297 * @type Ext.dd.DragSource.
300 initDraggable: function() {
303 //create element if it doesn't exist.
305 me.surface.createSpriteElement(me);
307 me.dd = Ext.create('Ext.draw.SpriteDD', me, Ext.isBoolean(me.draggable) ? null : me.draggable);
308 me.on('beforedestroy', me.dd.destroy, me.dd);
312 * Change the attributes of the sprite.
313 * @param {Object} attrs attributes to be changed on the sprite.
314 * @param {Boolean} redraw Flag to immediatly draw the change.
315 * @return {Ext.draw.Sprite} this
317 setAttributes: function(attrs, redraw) {
319 fontProps = me.fontProperties,
320 fontPropsLength = fontProps.length,
321 pathProps = me.pathProperties,
322 pathPropsLength = pathProps.length,
323 hasSurface = !!me.surface,
324 custom = hasSurface && me.surface.customAttributes || {},
325 spriteAttrs = me.attr,
326 attr, i, translate, translation, rotate, rotation, scale, scaling;
328 attrs = Ext.apply({}, attrs);
329 for (attr in custom) {
330 if (attrs.hasOwnProperty(attr) && typeof custom[attr] == "function") {
331 Ext.apply(attrs, custom[attr].apply(me, [].concat(attrs[attr])));
335 // Flag a change in hidden
336 if (!!attrs.hidden !== !!spriteAttrs.hidden) {
337 me.dirtyHidden = true;
341 for (i = 0; i < pathPropsLength; i++) {
343 if (attr in attrs && attrs[attr] !== spriteAttrs[attr]) {
349 // Flag zIndex change
350 if ('zIndex' in attrs) {
351 me.zIndexDirty = true;
354 // Flag font/text change
355 for (i = 0; i < fontPropsLength; i++) {
357 if (attr in attrs && attrs[attr] !== spriteAttrs[attr]) {
363 translate = attrs.translate;
364 translation = spriteAttrs.translation;
366 if ((translate.x && translate.x !== translation.x) ||
367 (translate.y && translate.y !== translation.y)) {
368 Ext.apply(translation, translate);
369 me.dirtyTransform = true;
371 delete attrs.translate;
374 rotate = attrs.rotate;
375 rotation = spriteAttrs.rotation;
377 if ((rotate.x && rotate.x !== rotation.x) ||
378 (rotate.y && rotate.y !== rotation.y) ||
379 (rotate.degrees && rotate.degrees !== rotation.degrees)) {
380 Ext.apply(rotation, rotate);
381 me.dirtyTransform = true;
387 scaling = spriteAttrs.scaling;
389 if ((scale.x && scale.x !== scaling.x) ||
390 (scale.y && scale.y !== scaling.y) ||
391 (scale.cx && scale.cx !== scaling.cx) ||
392 (scale.cy && scale.cy !== scaling.cy)) {
393 Ext.apply(scaling, scale);
394 me.dirtyTransform = true;
399 Ext.apply(spriteAttrs, attrs);
402 if (redraw === true && hasSurface) {
409 * Retrieve the bounding box of the sprite. This will be returned as an object with x, y, width, and height properties.
410 * @return {Object} bbox
412 getBBox: function() {
413 return this.surface.getBBox(this);
416 setText: function(text) {
417 return this.surface.setText(this, text);
422 * @param {Boolean} redraw Flag to immediatly draw the change.
423 * @return {Ext.draw.Sprite} this
425 hide: function(redraw) {
434 * @param {Boolean} redraw Flag to immediatly draw the change.
435 * @return {Ext.draw.Sprite} this
437 show: function(redraw) {
449 this.surface.remove(this);
455 onRemove: function() {
456 this.surface.onRemove(this);
460 * Removes the sprite and clears all listeners.
462 destroy: function() {
464 if (me.fireEvent('beforedestroy', me) !== false) {
466 me.surface.onDestroy(me);
468 me.fireEvent('destroy');
474 * @return {Ext.draw.Sprite} this
477 this.surface.renderItem(this);
482 * Wrapper for setting style properties, also takes single object parameter of multiple styles.
483 * @param {String/Object} property The style property to be set, or an object of multiple styles.
484 * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
485 * @return {Ext.draw.Sprite} this
487 setStyle: function() {
488 this.el.setStyle.apply(this.el, arguments);
493 * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out. Note this method
494 * is severly limited in VML.
495 * @param {String/Array} className The CSS class to add, or an array of classes
496 * @return {Ext.draw.Sprite} this
498 addCls: function(obj) {
499 this.surface.addCls(this, obj);
504 * Removes one or more CSS classes from the element.
505 * @param {String/Array} className The CSS class to remove, or an array of classes. Note this method
506 * is severly limited in VML.
507 * @return {Ext.draw.Sprite} this
509 removeCls: function(obj) {
510 this.surface.removeCls(this, obj);