196 lines
5.5 KiB
JavaScript
196 lines
5.5 KiB
JavaScript
/**
|
|
* @class Ext.draw.engine.Svg
|
|
* @extends Ext.draw.Surface
|
|
*
|
|
* SVG engine.
|
|
*/
|
|
Ext.define('Ext.draw.engine.Svg', {
|
|
extend: 'Ext.draw.Surface',
|
|
requires: ['Ext.draw.engine.SvgContext'],
|
|
|
|
statics: {
|
|
BBoxTextCache: {}
|
|
},
|
|
|
|
config: {
|
|
/**
|
|
* Nothing needs to be done in high precision mode.
|
|
*/
|
|
highPrecision: false
|
|
},
|
|
|
|
getElementConfig: function () {
|
|
return {
|
|
reference: 'element',
|
|
style: {
|
|
position: 'absolute'
|
|
},
|
|
children: [
|
|
{
|
|
reference: 'innerElement',
|
|
style: {
|
|
width: '100%',
|
|
height: '100%',
|
|
position: 'relative'
|
|
},
|
|
children: [
|
|
{
|
|
tag: 'svg',
|
|
reference: 'svgElement',
|
|
namespace: "http://www.w3.org/2000/svg",
|
|
version: 1.1,
|
|
cls: 'x-surface'
|
|
}
|
|
]
|
|
}
|
|
]
|
|
};
|
|
},
|
|
|
|
constructor: function (config) {
|
|
var me = this;
|
|
me.callSuper([config]);
|
|
me.mainGroup = me.createSvgNode("g");
|
|
me.defElement = me.createSvgNode("defs");
|
|
// me.svgElement is assigned in element creation of Ext.Component.
|
|
me.svgElement.appendChild(me.mainGroup);
|
|
me.svgElement.appendChild(me.defElement);
|
|
me.ctx = new Ext.draw.engine.SvgContext(me);
|
|
},
|
|
|
|
/**
|
|
* Creates a DOM element under the SVG namespace of the given type.
|
|
* @param {String} type The type of the SVG DOM element.
|
|
* @return {*} The created element.
|
|
*/
|
|
createSvgNode: function (type) {
|
|
var node = document.createElementNS("http://www.w3.org/2000/svg", type);
|
|
return Ext.get(node);
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
* Returns the SVG DOM element at the given position. If it does not already exist or is a different element tag
|
|
* it will be created and inserted into the DOM.
|
|
* @param {Ext.dom.Element} group The parent DOM element.
|
|
* @param {String} tag The SVG element tag.
|
|
* @param {Number} position The position of the element in the DOM.
|
|
* @return {Ext.dom.Element} The SVG element.
|
|
*/
|
|
getSvgElement: function (group, tag, position) {
|
|
var element;
|
|
if (group.dom.childNodes.length > position) {
|
|
element = group.dom.childNodes[position];
|
|
if (element.tagName === tag) {
|
|
return Ext.get(element);
|
|
} else {
|
|
Ext.destroy(element);
|
|
}
|
|
}
|
|
|
|
element = Ext.get(this.createSvgNode(tag));
|
|
if (position === 0) {
|
|
group.insertFirst(element);
|
|
} else {
|
|
element.insertAfter(Ext.fly(group.dom.childNodes[position - 1]));
|
|
}
|
|
element.cache = {};
|
|
return element;
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
* Applies attributes to the given element.
|
|
* @param {Ext.dom.Element} element The DOM element to be applied.
|
|
* @param {Object} attributes The attributes to apply to the element.
|
|
*/
|
|
setElementAttributes: function (element, attributes) {
|
|
var dom = element.dom,
|
|
cache = element.cache,
|
|
name, value;
|
|
for (name in attributes) {
|
|
value = attributes[name];
|
|
if (cache[name] !== value) {
|
|
cache[name] = value;
|
|
dom.setAttribute(name, value);
|
|
}
|
|
}
|
|
},
|
|
|
|
/**
|
|
* @private
|
|
* Gets the next reference element under the SVG 'defs' tag.
|
|
* @param {String} tagName The type of reference element.
|
|
* @return {Ext.dom.Element} The reference element.
|
|
*/
|
|
getNextDef: function (tagName) {
|
|
return this.getSvgElement(this.defElement, tagName, this.defPosition++);
|
|
},
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
clearTransform: function () {
|
|
var me = this;
|
|
me.mainGroup.set({transform: me.matrix.toSvg()});
|
|
},
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
clear: function () {
|
|
this.ctx.clear();
|
|
this.defPosition = 0;
|
|
},
|
|
|
|
/**
|
|
* @inheritdoc
|
|
*/
|
|
renderSprite: function (sprite) {
|
|
var me = this,
|
|
region = me.getRegion(),
|
|
ctx = me.ctx;
|
|
if (sprite.attr.hidden || sprite.attr.opacity === 0) {
|
|
ctx.save();
|
|
ctx.restore();
|
|
return;
|
|
}
|
|
try {
|
|
sprite.element = ctx.save();
|
|
sprite.preRender(this);
|
|
sprite.useAttributes(ctx, region);
|
|
if (false === sprite.render(this, ctx, [0, 0, region[2], region[3]])) {
|
|
return false;
|
|
}
|
|
sprite.setDirty(false);
|
|
} finally {
|
|
ctx.restore();
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Destroys the Canvas element and prepares it for Garbage Collection.
|
|
*/
|
|
destroy: function (path, matrix, band) {
|
|
var me = this;
|
|
me.ctx.destroy();
|
|
me.mainGroup.destroy();
|
|
delete me.mainGroup;
|
|
delete me.ctx;
|
|
me.callSuper(arguments);
|
|
},
|
|
|
|
remove: function (sprite, destroySprite) {
|
|
if (sprite && sprite.element) {
|
|
//if sprite has an associated svg element remove it from the surface
|
|
if (this.ctx) {
|
|
this.ctx.removeElement(sprite.element);
|
|
} else {
|
|
sprite.element.destroy();
|
|
}
|
|
sprite.element = null;
|
|
}
|
|
this.callSuper(arguments);
|
|
}
|
|
});
|