<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>The source code</title>
- <link href="../prettify/prettify.css" type="text/css" rel="stylesheet" />
- <script type="text/javascript" src="../prettify/prettify.js"></script>
+ <link href="../resources/prettify/prettify.css" type="text/css" rel="stylesheet" />
+ <script type="text/javascript" src="../resources/prettify/prettify.js"></script>
<style type="text/css">
.highlight { display: block; background-color: #ddd; }
</style>
</script>
</head>
<body onload="prettyPrint(); highlight();">
- <pre class="prettyprint lang-js"><span id='Ext-fx-target-Sprite'>/**
-</span> * @class Ext.fx.target.Sprite
- * @extends Ext.fx.target.Target
-
-This class represents a animation target for a {@link Ext.draw.Sprite}. In general this class will not be
-created directly, the {@link Ext.draw.Sprite} will be passed to the animation and
-and the appropriate target will be created.
-
- * @markdown
+ <pre class="prettyprint lang-js"><span id='Ext-draw-Sprite'>/**
+</span> * A Sprite is an object rendered in a Drawing surface.
+ *
+ * # Translation
+ *
+ * For translate, the configuration object contains x and y attributes that indicate where to
+ * translate the object. For example:
+ *
+ * sprite.setAttributes({
+ * translate: {
+ * x: 10,
+ * y: 10
+ * }
+ * }, true);
+ *
+ *
+ * # Rotation
+ *
+ * For rotation, the configuration object contains x and y attributes for the center of the rotation (which are optional),
+ * and a `degrees` attribute that specifies the rotation in degrees. For example:
+ *
+ * sprite.setAttributes({
+ * rotate: {
+ * degrees: 90
+ * }
+ * }, true);
+ *
+ * That example will create a 90 degrees rotation using the centroid of the Sprite as center of rotation, whereas:
+ *
+ * sprite.setAttributes({
+ * rotate: {
+ * x: 0,
+ * y: 0,
+ * degrees: 90
+ * }
+ * }, true);
+ *
+ * will create a rotation around the `(0, 0)` axis.
+ *
+ *
+ * # Scaling
+ *
+ * For scaling, the configuration object contains x and y attributes for the x-axis and y-axis scaling. For example:
+ *
+ * sprite.setAttributes({
+ * scale: {
+ * x: 10,
+ * y: 3
+ * }
+ * }, true);
+ *
+ * You can also specify the center of scaling by adding `cx` and `cy` as properties:
+ *
+ * sprite.setAttributes({
+ * scale: {
+ * cx: 0,
+ * cy: 0,
+ * x: 10,
+ * y: 3
+ * }
+ * }, true);
+ *
+ * That last example will scale a sprite taking as centers of scaling the `(0, 0)` coordinate.
+ *
+ *
+ * # Creating and adding a Sprite to a Surface
+ *
+ * Sprites can be created with a reference to a {@link Ext.draw.Surface}
+ *
+ * var drawComponent = Ext.create('Ext.draw.Component', options here...);
+ *
+ * var sprite = Ext.create('Ext.draw.Sprite', {
+ * type: 'circle',
+ * fill: '#ff0',
+ * surface: drawComponent.surface,
+ * radius: 5
+ * });
+ *
+ * Sprites can also be added to the surface as a configuration object:
+ *
+ * var sprite = drawComponent.surface.add({
+ * type: 'circle',
+ * fill: '#ff0',
+ * radius: 5
+ * });
+ *
+ * In order to properly apply properties and render the sprite we have to
+ * `show` the sprite setting the option `redraw` to `true`:
+ *
+ * sprite.show(true);
+ *
+ * The constructor configuration object of the Sprite can also be used and passed into the {@link Ext.draw.Surface}
+ * add method to append a new sprite to the canvas. For example:
+ *
+ * drawComponent.surface.add({
+ * type: 'circle',
+ * fill: '#ffc',
+ * radius: 100,
+ * x: 100,
+ * y: 100
+ * });
*/
-
-Ext.define('Ext.fx.target.Sprite', {
+Ext.define('Ext.draw.Sprite', {
/* Begin Definitions */
- extend: 'Ext.fx.target.Target',
+ mixins: {
+ observable: 'Ext.util.Observable',
+ animate: 'Ext.util.Animate'
+ },
+
+ requires: ['Ext.draw.SpriteDD'],
/* End Definitions */
- type: 'draw',
+<span id='Ext-draw-Sprite-cfg-type'> /**
+</span> * @cfg {String} type The type of the sprite. Possible options are 'circle', 'path', 'rect', 'text', 'square', 'image'
+ */
+
+<span id='Ext-draw-Sprite-cfg-width'> /**
+</span> * @cfg {Number} width Used in rectangle sprites, the width of the rectangle
+ */
+
+<span id='Ext-draw-Sprite-cfg-height'> /**
+</span> * @cfg {Number} height Used in rectangle sprites, the height of the rectangle
+ */
+
+<span id='Ext-draw-Sprite-cfg-size'> /**
+</span> * @cfg {Number} size Used in square sprites, the dimension of the square
+ */
+
+<span id='Ext-draw-Sprite-cfg-radius'> /**
+</span> * @cfg {Number} radius Used in circle sprites, the radius of the circle
+ */
+
+<span id='Ext-draw-Sprite-cfg-x'> /**
+</span> * @cfg {Number} x The position along the x-axis
+ */
+
+<span id='Ext-draw-Sprite-cfg-y'> /**
+</span> * @cfg {Number} y The position along the y-axis
+ */
+
+<span id='Ext-draw-Sprite-cfg-path'> /**
+</span> * @cfg {Array} path Used in path sprites, the path of the sprite written in SVG-like path syntax
+ */
+
+<span id='Ext-draw-Sprite-cfg-opacity'> /**
+</span> * @cfg {Number} opacity The opacity of the sprite
+ */
+
+<span id='Ext-draw-Sprite-cfg-fill'> /**
+</span> * @cfg {String} fill The fill color
+ */
+
+<span id='Ext-draw-Sprite-cfg-stroke'> /**
+</span> * @cfg {String} stroke The stroke color
+ */
+
+<span id='Ext-draw-Sprite-cfg-stroke'> /**
+</span> * @cfg {Number} stroke-width The width of the stroke
+ */
+
+<span id='Ext-draw-Sprite-cfg-font'> /**
+</span> * @cfg {String} font Used with text type sprites. The full font description. Uses the same syntax as the CSS font parameter
+ */
+
+<span id='Ext-draw-Sprite-cfg-text'> /**
+</span> * @cfg {String} text Used with text type sprites. The text itself
+ */
+
+<span id='Ext-draw-Sprite-cfg-group'> /**
+</span> * @cfg {String/String[]} group The group that this sprite belongs to, or an array of groups. Only relevant when added to a
+ * {@link Ext.draw.Surface}
+ */
+
+<span id='Ext-draw-Sprite-cfg-draggable'> /**
+</span> * @cfg {Boolean} draggable True to make the sprite draggable.
+ */
+
+ dirty: false,
+ dirtyHidden: false,
+ dirtyTransform: false,
+ dirtyPath: true,
+ dirtyFont: true,
+ zIndexDirty: true,
+ isSprite: true,
+ zIndex: 0,
+ fontProperties: [
+ 'font',
+ 'font-size',
+ 'font-weight',
+ 'font-style',
+ 'font-family',
+ 'text-anchor',
+ 'text'
+ ],
+ pathProperties: [
+ 'x',
+ 'y',
+ 'd',
+ 'path',
+ 'height',
+ 'width',
+ 'radius',
+ 'r',
+ 'rx',
+ 'ry',
+ 'cx',
+ 'cy'
+ ],
+ constructor: function(config) {
+ var me = this;
+ config = config || {};
+ me.id = Ext.id(null, 'ext-sprite-');
+ me.transformations = [];
+ Ext.copyTo(this, config, 'surface,group,type,draggable');
+ //attribute bucket
+ me.bbox = {};
+ me.attr = {
+ zIndex: 0,
+ translation: {
+ x: null,
+ y: null
+ },
+ rotation: {
+ degrees: null,
+ x: null,
+ y: null
+ },
+ scaling: {
+ x: null,
+ y: null,
+ cx: null,
+ cy: null
+ }
+ };
+ //delete not bucket attributes
+ delete config.surface;
+ delete config.group;
+ delete config.type;
+ delete config.draggable;
+ me.setAttributes(config);
+ me.addEvents(
+ 'beforedestroy',
+ 'destroy',
+ 'render',
+ 'mousedown',
+ 'mouseup',
+ 'mouseover',
+ 'mouseout',
+ 'mousemove',
+ 'click'
+ );
+ me.mixins.observable.constructor.apply(this, arguments);
+ },
+
+<span id='Ext-draw-Sprite-property-dd'> /**
+</span> * @property {Ext.dd.DragSource} dd
+ * If this Sprite is configured {@link #draggable}, this property will contain
+ * an instance of {@link Ext.dd.DragSource} which handles dragging the Sprite.
+ *
+ * The developer must provide implementations of the abstract methods of {@link Ext.dd.DragSource}
+ * in order to supply behaviour for each stage of the drag/drop process. See {@link #draggable}.
+ */
+
+ initDraggable: function() {
+ var me = this;
+ me.draggable = true;
+ //create element if it doesn't exist.
+ if (!me.el) {
+ me.surface.createSpriteElement(me);
+ }
+ me.dd = Ext.create('Ext.draw.SpriteDD', me, Ext.isBoolean(me.draggable) ? null : me.draggable);
+ me.on('beforedestroy', me.dd.destroy, me.dd);
+ },
+
+<span id='Ext-draw-Sprite-method-setAttributes'> /**
+</span> * Change the attributes of the sprite.
+ * @param {Object} attrs attributes to be changed on the sprite.
+ * @param {Boolean} redraw Flag to immediatly draw the change.
+ * @return {Ext.draw.Sprite} this
+ */
+ setAttributes: function(attrs, redraw) {
+ var me = this,
+ fontProps = me.fontProperties,
+ fontPropsLength = fontProps.length,
+ pathProps = me.pathProperties,
+ pathPropsLength = pathProps.length,
+ hasSurface = !!me.surface,
+ custom = hasSurface && me.surface.customAttributes || {},
+ spriteAttrs = me.attr,
+ attr, i, translate, translation, rotate, rotation, scale, scaling;
+
+ attrs = Ext.apply({}, attrs);
+ for (attr in custom) {
+ if (attrs.hasOwnProperty(attr) && typeof custom[attr] == "function") {
+ Ext.apply(attrs, custom[attr].apply(me, [].concat(attrs[attr])));
+ }
+ }
+
+ // Flag a change in hidden
+ if (!!attrs.hidden !== !!spriteAttrs.hidden) {
+ me.dirtyHidden = true;
+ }
+
+ // Flag path change
+ for (i = 0; i < pathPropsLength; i++) {
+ attr = pathProps[i];
+ if (attr in attrs && attrs[attr] !== spriteAttrs[attr]) {
+ me.dirtyPath = true;
+ break;
+ }
+ }
- getFromPrim: function(sprite, attr) {
- var o;
- if (attr == 'translate') {
- o = {
- x: sprite.attr.translation.x || 0,
- y: sprite.attr.translation.y || 0
- };
+ // Flag zIndex change
+ if ('zIndex' in attrs) {
+ me.zIndexDirty = true;
}
- else if (attr == 'rotate') {
- o = {
- degrees: sprite.attr.rotation.degrees || 0,
- x: sprite.attr.rotation.x,
- y: sprite.attr.rotation.y
- };
+
+ // Flag font/text change
+ for (i = 0; i < fontPropsLength; i++) {
+ attr = fontProps[i];
+ if (attr in attrs && attrs[attr] !== spriteAttrs[attr]) {
+ me.dirtyFont = true;
+ break;
+ }
}
- else {
- o = sprite.attr[attr];
+
+ translate = attrs.translate;
+ translation = spriteAttrs.translation;
+ if (translate) {
+ if ((translate.x && translate.x !== translation.x) ||
+ (translate.y && translate.y !== translation.y)) {
+ Ext.apply(translation, translate);
+ me.dirtyTransform = true;
+ }
+ delete attrs.translate;
+ }
+
+ rotate = attrs.rotate;
+ rotation = spriteAttrs.rotation;
+ if (rotate) {
+ if ((rotate.x && rotate.x !== rotation.x) ||
+ (rotate.y && rotate.y !== rotation.y) ||
+ (rotate.degrees && rotate.degrees !== rotation.degrees)) {
+ Ext.apply(rotation, rotate);
+ me.dirtyTransform = true;
+ }
+ delete attrs.rotate;
}
- return o;
+
+ scale = attrs.scale;
+ scaling = spriteAttrs.scaling;
+ if (scale) {
+ if ((scale.x && scale.x !== scaling.x) ||
+ (scale.y && scale.y !== scaling.y) ||
+ (scale.cx && scale.cx !== scaling.cx) ||
+ (scale.cy && scale.cy !== scaling.cy)) {
+ Ext.apply(scaling, scale);
+ me.dirtyTransform = true;
+ }
+ delete attrs.scale;
+ }
+
+ Ext.apply(spriteAttrs, attrs);
+ me.dirty = true;
+
+ if (redraw === true && hasSurface) {
+ me.redraw();
+ }
+ return this;
},
- getAttr: function(attr, val) {
- return [[this.target, val != undefined ? val : this.getFromPrim(this.target, attr)]];
+<span id='Ext-draw-Sprite-method-getBBox'> /**
+</span> * Retrieves the bounding box of the sprite.
+ * This will be returned as an object with x, y, width, and height properties.
+ * @return {Object} bbox
+ */
+ getBBox: function() {
+ return this.surface.getBBox(this);
},
- setAttr: function(targetData) {
- var ln = targetData.length,
- spriteArr = [],
- attrs, attr, attrArr, attPtr, spritePtr, idx, value, i, j, x, y, ln2;
- for (i = 0; i < ln; i++) {
- attrs = targetData[i].attrs;
- for (attr in attrs) {
- attrArr = attrs[attr];
- ln2 = attrArr.length;
- for (j = 0; j < ln2; j++) {
- spritePtr = attrArr[j][0];
- attPtr = attrArr[j][1];
- if (attr === 'translate') {
- value = {
- x: attPtr.x,
- y: attPtr.y
- };
- }
- else if (attr === 'rotate') {
- x = attPtr.x;
- if (isNaN(x)) {
- x = null;
- }
- y = attPtr.y;
- if (isNaN(y)) {
- y = null;
- }
- value = {
- degrees: attPtr.degrees,
- x: x,
- y: y
- };
- }
- else if (attr === 'width' || attr === 'height' || attr === 'x' || attr === 'y') {
- value = parseFloat(attPtr);
- }
- else {
- value = attPtr;
- }
- idx = Ext.Array.indexOf(spriteArr, spritePtr);
- if (idx == -1) {
- spriteArr.push([spritePtr, {}]);
- idx = spriteArr.length - 1;
- }
- spriteArr[idx][1][attr] = value;
- }
- }
+ setText: function(text) {
+ return this.surface.setText(this, text);
+ },
+
+<span id='Ext-draw-Sprite-method-hide'> /**
+</span> * Hides the sprite.
+ * @param {Boolean} redraw Flag to immediatly draw the change.
+ * @return {Ext.draw.Sprite} this
+ */
+ hide: function(redraw) {
+ this.setAttributes({
+ hidden: true
+ }, redraw);
+ return this;
+ },
+
+<span id='Ext-draw-Sprite-method-show'> /**
+</span> * Shows the sprite.
+ * @param {Boolean} redraw Flag to immediatly draw the change.
+ * @return {Ext.draw.Sprite} this
+ */
+ show: function(redraw) {
+ this.setAttributes({
+ hidden: false
+ }, redraw);
+ return this;
+ },
+
+<span id='Ext-draw-Sprite-method-remove'> /**
+</span> * Removes the sprite.
+ */
+ remove: function() {
+ if (this.surface) {
+ this.surface.remove(this);
+ return true;
}
- ln = spriteArr.length;
- for (i = 0; i < ln; i++) {
- spritePtr = spriteArr[i];
- spritePtr[0].setAttributes(spritePtr[1]);
+ return false;
+ },
+
+ onRemove: function() {
+ this.surface.onRemove(this);
+ },
+
+<span id='Ext-draw-Sprite-method-destroy'> /**
+</span> * Removes the sprite and clears all listeners.
+ */
+ destroy: function() {
+ var me = this;
+ if (me.fireEvent('beforedestroy', me) !== false) {
+ me.remove();
+ me.surface.onDestroy(me);
+ me.clearListeners();
+ me.fireEvent('destroy');
}
- this.target.redraw();
+ },
+
+<span id='Ext-draw-Sprite-method-redraw'> /**
+</span> * Redraws the sprite.
+ * @return {Ext.draw.Sprite} this
+ */
+ redraw: function() {
+ this.surface.renderItem(this);
+ return this;
+ },
+
+<span id='Ext-draw-Sprite-method-setStyle'> /**
+</span> * Wrapper for setting style properties, also takes single object parameter of multiple styles.
+ * @param {String/Object} property The style property to be set, or an object of multiple styles.
+ * @param {String} value (optional) The value to apply to the given property, or null if an object was passed.
+ * @return {Ext.draw.Sprite} this
+ */
+ setStyle: function() {
+ this.el.setStyle.apply(this.el, arguments);
+ return this;
+ },
+
+<span id='Ext-draw-Sprite-method-addCls'> /**
+</span> * Adds one or more CSS classes to the element. Duplicate classes are automatically filtered out. Note this method
+ * is severly limited in VML.
+ * @param {String/String[]} className The CSS class to add, or an array of classes
+ * @return {Ext.draw.Sprite} this
+ */
+ addCls: function(obj) {
+ this.surface.addCls(this, obj);
+ return this;
+ },
+
+<span id='Ext-draw-Sprite-method-removeCls'> /**
+</span> * Removes one or more CSS classes from the element.
+ * @param {String/String[]} className The CSS class to remove, or an array of classes. Note this method
+ * is severly limited in VML.
+ * @return {Ext.draw.Sprite} this
+ */
+ removeCls: function(obj) {
+ this.surface.removeCls(this, obj);
+ return this;
}
});
</pre>