<!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,
|
<span id='Ext-draw-Sprite-property-dirtyHidden'> dirtyHidden: false,
|
</span><span id='Ext-draw-Sprite-property-dirtyTransform'> dirtyTransform: false,
|
</span><span id='Ext-draw-Sprite-property-dirtyPath'> dirtyPath: true,
|
</span><span id='Ext-draw-Sprite-property-dirtyFont'> dirtyFont: true,
|
</span><span id='Ext-draw-Sprite-property-zIndexDirty'> zIndexDirty: true,
|
</span>
|
<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,
|
<span id='Ext-draw-Sprite-property-zIndex'> zIndex: 0,
|
</span><span id='Ext-draw-Sprite-property-fontProperties'> fontProperties: [
|
</span> 'font',
|
'font-size',
|
'font-weight',
|
'font-style',
|
'font-family',
|
'text-anchor',
|
'text'
|
],
|
<span id='Ext-draw-Sprite-property-pathProperties'> pathProperties: [
|
</span> 'x',
|
'y',
|
'd',
|
'path',
|
'height',
|
'width',
|
'radius',
|
'r',
|
'rx',
|
'ry',
|
'cx',
|
'cy'
|
],
|
<span id='Ext-draw-Sprite-method-constructor'> constructor: function(config) {
|
</span> 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;
|
//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);
|
},
|
|
<span id='Ext-draw-Sprite-method-setText'> setText: function(text) {
|
</span> 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;
|
},
|
|
<span id='Ext-draw-Sprite-method-onRemove'> onRemove: function() {
|
</span> 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>
|