web-apps/vendor/touch/src/draw/engine/Svg.js
2016-09-15 17:14:43 +03:00

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);
}
});