| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678 | <!DOCTYPE html><html><head>  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  <title>The source code</title>  <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 type="text/javascript">    function highlight() {      document.getElementById(location.hash.replace(/#/, "")).className = "highlight";    }  </script></head><body onload="prettyPrint(); highlight();">  <pre class="prettyprint lang-js"><span id='Ext-draw-Sprite'>/**</span> * A Sprite is an object rendered in a Drawing surface. * * ## Types * * The following sprite types are supported: * * ### Rect * * Rectangle requires `width` and `height` attributes: * *     @example *     Ext.create('Ext.draw.Component', { *         renderTo: Ext.getBody(), *         width: 200, *         height: 200, *         items: [{ *             type: 'rect', *             width: 100, *             height: 50, *             radius: 10, *             fill: 'green', *             opacity: 0.5, *             stroke: 'red', *             'stroke-width': 2 *         }] *     }); * * ### Circle * * Circle requires `x`, `y` and `radius` attributes: * *     @example *     Ext.create('Ext.draw.Component', { *         renderTo: Ext.getBody(), *         width: 200, *         height: 200, *         items: [{ *             type: 'circle', *             radius: 90, *             x: 100, *             y: 100, *             fill: 'blue', *         }] *     }); * * ### Ellipse * * Ellipse requires `x`, `y`, `radiusX` and `radiusY` attributes: * *     @example *     Ext.create('Ext.draw.Component', { *         renderTo: Ext.getBody(), *         width: 200, *         height: 200, *         items: [{ *             type: "ellipse", *             radiusX: 100, *             radiusY: 50, *             x: 100, *             y: 100, *             fill: 'red' *         }] *     }); * * ### Path * * Path requires the `path` attribute: * *     @example *     Ext.create('Ext.draw.Component', { *         renderTo: Ext.getBody(), *         width: 200, *         height: 200, *         items: [{ *             type: "path", *             path: "M-66.6 26C-66.6 26 -75 22 -78.2 18.4C-81.4 14.8 -80.948 19.966 " + *                   "-85.8 19.6C-91.647 19.159 -90.6 3.2 -90.6 3.2L-94.6 10.8C-94.6 " + *                   "10.8 -95.8 25.2 -87.8 22.8C-83.893 21.628 -82.6 23.2 -84.2 " + *                   "24C-85.8 24.8 -78.6 25.2 -81.4 26.8C-84.2 28.4 -69.8 23.2 -72.2 " + *                   "33.6L-66.6 26z", *             fill: "purple" *         }] *     }); * * ### Text * * Text requires the `text` attribute: * *     @example *     Ext.create('Ext.draw.Component', { *         renderTo: Ext.getBody(), *         width: 200, *         height: 200, *         items: [{ *             type: "text", *             text: "Hello, Sprite!", *             fill: "green", *             font: "18px monospace" *         }] *     }); * * ### Image * * Image requires `width`, `height` and `src` attributes: * *     @example *     Ext.create('Ext.draw.Component', { *         renderTo: Ext.getBody(), *         width: 200, *         height: 200, *         items: [{ *             type: "image", *             src: "http://www.sencha.com/img/apple-touch-icon.png", *             width: 200, *             height: 200 *         }] *     }); * * ## Creating and adding a Sprite to a Surface * * See {@link Ext.draw.Surface} documentation. * * ## Transforming sprites * * See {@link #setAttributes} method documentation for examples on how to translate, scale and rotate the sprites. * */Ext.define('Ext.draw.Sprite', {    /* Begin Definitions */    mixins: {        observable: 'Ext.util.Observable',        animate: 'Ext.util.Animate'    },    requires: ['Ext.draw.SpriteDD'],    /* End Definitions */<span id='Ext-draw-Sprite-cfg-type'>    /**</span>     * @cfg {String} type The type of the sprite.     * Possible options are 'circle', 'ellipse', 'path', 'rect', 'text', 'image'.     *     * See {@link Ext.draw.Sprite} class documentation for examples of all types.     */<span id='Ext-draw-Sprite-cfg-width'>    /**</span>     * @cfg {Number} width The width of the rect or image sprite.     */<span id='Ext-draw-Sprite-cfg-height'>    /**</span>     * @cfg {Number} height The height of the rect or image sprite.     */<span id='Ext-draw-Sprite-cfg-radius'>    /**</span>     * @cfg {Number} radius The radius of the circle sprite. Or in case of rect sprite, the border radius.     */<span id='Ext-draw-Sprite-cfg-radiusX'>    /**</span>     * @cfg {Number} radiusX The radius of the ellipse sprite along x-axis.     */<span id='Ext-draw-Sprite-cfg-radiusY'>    /**</span>     * @cfg {Number} radiusY The radius of the ellipse sprite along y-axis.     */<span id='Ext-draw-Sprite-cfg-x'>    /**</span>     * @cfg {Number} x Sprite position along the x-axis.     */<span id='Ext-draw-Sprite-cfg-y'>    /**</span>     * @cfg {Number} y Sprite position along the y-axis.     */<span id='Ext-draw-Sprite-cfg-path'>    /**</span>     * @cfg {String} path The path of the path sprite written in SVG-like path syntax.     */<span id='Ext-draw-Sprite-cfg-opacity'>    /**</span>     * @cfg {Number} opacity The opacity of the sprite. A number between 0 and 1.     */<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-width'>    /**</span>     * @cfg {Number} stroke-width The width of the stroke.     *     * Note that this attribute needs to be quoted when used.  Like so:     *     *     "stroke-width": 12,     */<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 The actual text to render in text sprites.     */<span id='Ext-draw-Sprite-cfg-src'>    /**</span>     * @cfg {String} src Path to the image to show in image sprites.     */<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 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,<span id='Ext-draw-Sprite-property-isSprite'>    /**</span>     * @property {Boolean} isSprite     * `true` in this class to identify an object as an instantiated Sprite, or subclass thereof.     */    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 = Ext.merge({}, 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(<span id='Ext-draw-Sprite-event-beforedestroy'>            /**</span>             * @event             * Fires before the sprite is destroyed. Return false from an event handler to stop the destroy.             * @param {Ext.draw.Sprite} this             */            'beforedestroy',<span id='Ext-draw-Sprite-event-destroy'>            /**</span>             * @event             * Fires after the sprite is destroyed.             * @param {Ext.draw.Sprite} this             */            'destroy',<span id='Ext-draw-Sprite-event-render'>            /**</span>             * @event             * Fires after the sprite markup is rendered.             * @param {Ext.draw.Sprite} this             */            'render',<span id='Ext-draw-Sprite-event-mousedown'>            /**</span>             * @event             * @inheritdoc Ext.dom.Element#mousedown             */            'mousedown',<span id='Ext-draw-Sprite-event-mouseup'>            /**</span>             * @event             * @inheritdoc Ext.dom.Element#mouseup             */            'mouseup',<span id='Ext-draw-Sprite-event-mouseover'>            /**</span>             * @event             * @inheritdoc Ext.dom.Element#mouseover             */            'mouseover',<span id='Ext-draw-Sprite-event-mouseout'>            /**</span>             * @event             * @inheritdoc Ext.dom.Element#mouseout             */            'mouseout',<span id='Ext-draw-Sprite-event-mousemove'>            /**</span>             * @event             * @inheritdoc Ext.dom.Element#mousemove             */            'mousemove',<span id='Ext-draw-Sprite-event-click'>            /**</span>             * @event             * @inheritdoc Ext.dom.Element#click             */            '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 = new 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.     *     * ## 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.     *     * @param {Object} attrs attributes to be changed on the sprite.     * @param {Boolean} redraw Flag to immediately 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,            dirtyBBox = false,            attr, i, newTranslation, translation, newRotate, rotation, newScaling, 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;                dirtyBBox = true;                break;            }        }        // Flag zIndex change        if ('zIndex' in attrs) {            me.zIndexDirty = true;        }        // Flag font/text change        if ('text' in attrs) {            me.dirtyFont = true;            dirtyBBox = true;        }        for (i = 0; i < fontPropsLength; i++) {            attr = fontProps[i];            if (attr in attrs && attrs[attr] !== spriteAttrs[attr]) {                me.dirtyFont = true;                dirtyBBox = true;                break;            }        }        newTranslation = attrs.translation || attrs.translate;        delete attrs.translate;        delete attrs.translation;        translation = spriteAttrs.translation;        if (newTranslation) {            if (('x' in newTranslation && newTranslation.x !== translation.x) ||                ('y' in newTranslation && newTranslation.y !== translation.y)) {                me.dirtyTransform = true;                translation.x = newTranslation.x;                translation.y = newTranslation.y;            }        }        newRotate = attrs.rotation || attrs.rotate;        rotation = spriteAttrs.rotation;        delete attrs.rotate;        delete attrs.rotation;        if (newRotate) {            if (('x' in newRotate && newRotate.x !== rotation.x) ||                ('y' in newRotate && newRotate.y !== rotation.y) ||                ('degrees' in newRotate && newRotate.degrees !== rotation.degrees)) {                me.dirtyTransform = true;                rotation.x = newRotate.x;                rotation.y = newRotate.y;                rotation.degrees = newRotate.degrees;            }        }        newScaling = attrs.scaling || attrs.scale;        scaling = spriteAttrs.scaling;        delete attrs.scale;        delete attrs.scaling;        if (newScaling) {            if (('x' in newScaling && newScaling.x !== scaling.x) ||                ('y' in newScaling && newScaling.y !== scaling.y) ||                ('cx' in newScaling && newScaling.cx !== scaling.cx) ||                ('cy' in newScaling && newScaling.cy !== scaling.cy)) {                me.dirtyTransform = true;                scaling.x = newScaling.x;                scaling.y = newScaling.y;                scaling.cx = newScaling.cx;                scaling.cy = newScaling.cy;            }        }        // If the bbox is changed, then the bbox based transforms should be invalidated.        if (!me.dirtyTransform && dirtyBBox) {            if (spriteAttrs.scaling.x === null ||                spriteAttrs.scaling.y === null ||                spriteAttrs.rotation.y === null ||                spriteAttrs.rotation.y === null) {                me.dirtyTransform = true;            }        }        Ext.apply(spriteAttrs, attrs);        me.dirty = true;        if (redraw === true && hasSurface) {            me.redraw();        }        return this;    },<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);    },    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 immediately 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 immediately 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.     * @return {Boolean} True if sprite was successfully removed.     * False when there was no surface to remove it from.     */    remove: function() {        if (this.surface) {            this.surface.remove(this);            return true;        }        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');        }    },<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></body></html>
 |