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 * A Sprite is an object rendered in a Drawing surface.
20 * For translate, the configuration object contains x and y attributes that indicate where to
21 * translate the object. For example:
23 * sprite.setAttributes({
33 * For rotation, the configuration object contains x and y attributes for the center of the rotation (which are optional),
34 * and a `degrees` attribute that specifies the rotation in degrees. For example:
36 * sprite.setAttributes({
42 * That example will create a 90 degrees rotation using the centroid of the Sprite as center of rotation, whereas:
44 * sprite.setAttributes({
52 * will create a rotation around the `(0, 0)` axis.
57 * For scaling, the configuration object contains x and y attributes for the x-axis and y-axis scaling. For example:
59 * sprite.setAttributes({
66 * You can also specify the center of scaling by adding `cx` and `cy` as properties:
68 * sprite.setAttributes({
77 * That last example will scale a sprite taking as centers of scaling the `(0, 0)` coordinate.
80 * # Creating and adding a Sprite to a Surface
82 * Sprites can be created with a reference to a {@link Ext.draw.Surface}
84 * var drawComponent = Ext.create('Ext.draw.Component', options here...);
86 * var sprite = Ext.create('Ext.draw.Sprite', {
89 * surface: drawComponent.surface,
93 * Sprites can also be added to the surface as a configuration object:
95 * var sprite = drawComponent.surface.add({
101 * In order to properly apply properties and render the sprite we have to
102 * `show` the sprite setting the option `redraw` to `true`:
106 * The constructor configuration object of the Sprite can also be used and passed into the {@link Ext.draw.Surface}
107 * add method to append a new sprite to the canvas. For example:
109 * drawComponent.surface.add({
117 Ext.define('Ext.draw.Sprite', {
119 /* Begin Definitions */
122 observable: 'Ext.util.Observable',
123 animate: 'Ext.util.Animate'
126 requires: ['Ext.draw.SpriteDD'],
128 /* End Definitions */
131 * @cfg {String} type The type of the sprite. Possible options are 'circle', 'path', 'rect', 'text', 'square', 'image'
135 * @cfg {Number} width Used in rectangle sprites, the width of the rectangle
139 * @cfg {Number} height Used in rectangle sprites, the height of the rectangle
143 * @cfg {Number} size Used in square sprites, the dimension of the square
147 * @cfg {Number} radius Used in circle sprites, the radius of the circle
151 * @cfg {Number} x The position along the x-axis
155 * @cfg {Number} y The position along the y-axis
159 * @cfg {Array} path Used in path sprites, the path of the sprite written in SVG-like path syntax
163 * @cfg {Number} opacity The opacity of the sprite
167 * @cfg {String} fill The fill color
171 * @cfg {String} stroke The stroke color
175 * @cfg {Number} stroke-width The width of the stroke
179 * @cfg {String} font Used with text type sprites. The full font description. Uses the same syntax as the CSS font parameter
183 * @cfg {String} text Used with text type sprites. The text itself
187 * @cfg {String/String[]} group The group that this sprite belongs to, or an array of groups. Only relevant when added to a
188 * {@link Ext.draw.Surface}
192 * @cfg {Boolean} draggable True to make the sprite draggable.
197 dirtyTransform: false,
226 constructor: function(config) {
228 config = config || {};
229 me.id = Ext.id(null, 'ext-sprite-');
230 me.transformations = [];
231 Ext.copyTo(this, config, 'surface,group,type,draggable');
252 //delete not bucket attributes
253 delete config.surface;
256 delete config.draggable;
257 me.setAttributes(config);
269 me.mixins.observable.constructor.apply(this, arguments);
273 * @property {Ext.dd.DragSource} dd
274 * If this Sprite is configured {@link #draggable}, this property will contain
275 * an instance of {@link Ext.dd.DragSource} which handles dragging the Sprite.
277 * The developer must provide implementations of the abstract methods of {@link Ext.dd.DragSource}
278 * in order to supply behaviour for each stage of the drag/drop process. See {@link #draggable}.
281 initDraggable: function() {
284 //create element if it doesn't exist.
286 me.surface.createSpriteElement(me);
288 me.dd = Ext.create('Ext.draw.SpriteDD', me, Ext.isBoolean(me.draggable) ? null : me.draggable);
289 me.on('beforedestroy', me.dd.destroy, me.dd);
293 * Change the attributes of the sprite.
294 * @param {Object} attrs attributes to be changed on the sprite.
295 * @param {Boolean} redraw Flag to immediatly draw the change.
296 * @return {Ext.draw.Sprite} this
298 setAttributes: function(attrs, redraw) {
300 fontProps = me.fontProperties,
301 fontPropsLength = fontProps.length,
302 pathProps = me.pathProperties,
303 pathPropsLength = pathProps.length,
304 hasSurface = !!me.surface,
305 custom = hasSurface && me.surface.customAttributes || {},
306 spriteAttrs = me.attr,
307 attr, i, translate, translation, rotate, rotation, scale, scaling;
309 attrs = Ext.apply({}, attrs);
310 for (attr in custom) {
311 if (attrs.hasOwnProperty(attr) && typeof custom[attr] == "function") {
312 Ext.apply(attrs, custom[attr].apply(me, [].concat(attrs[attr])));
316 // Flag a change in hidden
317 if (!!attrs.hidden !== !!spriteAttrs.hidden) {
318 me.dirtyHidden = true;
322 for (i = 0; i < pathPropsLength; i++) {
324 if (attr in attrs && attrs[attr] !== spriteAttrs[attr]) {
330 // Flag zIndex change
331 if ('zIndex' in attrs) {
332 me.zIndexDirty = true;
335 // Flag font/text change
336 for (i = 0; i < fontPropsLength; i++) {
338 if (attr in attrs && attrs[attr] !== spriteAttrs[attr]) {
344 translate = attrs.translate;
345 translation = spriteAttrs.translation;
347 if ((translate.x && translate.x !== translation.x) ||
348 (translate.y && translate.y !== translation.y)) {
349 Ext.apply(translation, translate);
350 me.dirtyTransform = true;
352 delete attrs.translate;
355 rotate = attrs.rotate;
356 rotation = spriteAttrs.rotation;
358 if ((rotate.x && rotate.x !== rotation.x) ||
359 (rotate.y && rotate.y !== rotation.y) ||
360 (rotate.degrees && rotate.degrees !== rotation.degrees)) {
361 Ext.apply(rotation, rotate);
362 me.dirtyTransform = true;
368 scaling = spriteAttrs.scaling;
370 if ((scale.x && scale.x !== scaling.x) ||
371 (scale.y && scale.y !== scaling.y) ||
372 (scale.cx && scale.cx !== scaling.cx) ||
373 (scale.cy && scale.cy !== scaling.cy)) {
374 Ext.apply(scaling, scale);
375 me.dirtyTransform = true;
380 Ext.apply(spriteAttrs, attrs);
383 if (redraw === true && hasSurface) {
390 * Retrieves the bounding box of the sprite.
391 * This will be returned as an object with x, y, width, and height properties.
392 * @return {Object} bbox
394 getBBox: function() {
395 return this.surface.getBBox(this);
398 setText: function(text) {
399 return this.surface.setText(this, text);
404 * @param {Boolean} redraw Flag to immediatly draw the change.
405 * @return {Ext.draw.Sprite} this
407 hide: function(redraw) {
416 * @param {Boolean} redraw Flag to immediatly draw the change.
417 * @return {Ext.draw.Sprite} this
419 show: function(redraw) {
427 * Removes the sprite.
431 this.surface.remove(this);
437 onRemove: function() {
438 this.surface.onRemove(this);
442 * Removes the sprite and clears all listeners.
444 destroy: function() {
446 if (me.fireEvent('beforedestroy', me) !== false) {
448 me.surface.onDestroy(me);
450 me.fireEvent('destroy');
455 * Redraws the sprite.
456 * @return {Ext.draw.Sprite} this
459 this.surface.renderItem(this);
464 * Wrapper for setting style properties, also takes single object parameter of multiple styles.
465 * @param {String/Object} property The style property to be set, or an object of multiple styles.
466 * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
467 * @return {Ext.draw.Sprite} this
469 setStyle: function() {
470 this.el.setStyle.apply(this.el, arguments);
475 * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out. Note this method
476 * is severly limited in VML.
477 * @param {String/String[]} className The CSS class to add, or an array of classes
478 * @return {Ext.draw.Sprite} this
480 addCls: function(obj) {
481 this.surface.addCls(this, obj);
486 * Removes one or more CSS classes from the element.
487 * @param {String/String[]} className The CSS class to remove, or an array of classes. Note this method
488 * is severly limited in VML.
489 * @return {Ext.draw.Sprite} this
491 removeCls: function(obj) {
492 this.surface.removeCls(this, obj);