/** * @class Ext.draw.sprite.Path * @extends Ext.draw.sprite.Sprite * * A sprite that represents a path. * * @example * Ext.create({ * xtype: 'draw', * renderTo: document.body, * width: 600, * height: 400, * sprites: [{ * type: 'path', * path: 'M20,30 c0,-50 75,50 75,0 c0,-50 -75,50 -75,0', * fillStyle: '#1F6D91' * }] * }); * * ### Drawing with SVG Paths * You may use special SVG Path syntax to "describe" the drawing path. * Here are the SVG path commands: * * + M = moveto * + L = lineto * + H = horizontal lineto * + V = vertical lineto * + C = curveto * + S = smooth curveto * + Q = quadratic Bézier curve * + T = smooth quadratic Bézier curveto * + A = elliptical Arc * + Z = closepath * * **Note:** Capital letters indicate that the item should be absolutely positioned. * Use lower case letters for relative positioning. */Ext.define('Ext.draw.sprite.Path', { extend: 'Ext.draw.sprite.Sprite', requires: [ 'Ext.draw.Draw', 'Ext.draw.Path' ], alias: [ 'sprite.path', 'Ext.draw.Sprite' ], type: 'path', isPath: true, inheritableStatics: { def: { processors: { /** * @cfg {String} path The SVG based path string used by the sprite. */ path: function(n, o) { if (!(n instanceof Ext.draw.Path)) { n = new Ext.draw.Path(n); } return n; } }, aliases: { d: 'path' }, triggers: { path: 'bbox' }, updaters: { path: function(attr) { var path = attr.path; if (!path || path.bindAttr !== attr) { path = new Ext.draw.Path(); path.bindAttr = attr; attr.path = path; } path.clear(); this.updatePath(path, attr); this.scheduleUpdater(attr, 'bbox', ['path']); } } } }, updatePlainBBox: function(plain) { if (this.attr.path) { this.attr.path.getDimension(plain); } }, updateTransformedBBox: function(transform) { if (this.attr.path) { this.attr.path.getDimensionWithTransform(this.attr.matrix, transform); } }, render: function(surface, ctx) { var mat = this.attr.matrix, attr = this.attr; if (!attr.path || attr.path.params.length === 0) { return; } mat.toContext(ctx); ctx.appendPath(attr.path); ctx.fillStroke(attr); //<debug> // eslint-disable-next-line vars-on-top var debug = attr.debug || this.statics().debug || Ext.draw.sprite.Sprite.debug; if (debug) { debug.bbox && this.renderBBox(surface, ctx); debug.xray && this.renderXRay(surface, ctx); } //</debug> }, //<debug> renderXRay: function(surface, ctx) { var attr = this.attr, mat = attr.matrix, imat = attr.inverseMatrix, path = attr.path, commands = path.commands, params = path.params, ln = commands.length, twoPi = Math.PI * 2, size = 2, i, j; mat.toContext(ctx); ctx.beginPath(); for (i = 0, j = 0; i < ln; i++) { switch (commands[i]) { case 'M': ctx.moveTo(params[j] - size, params[j + 1] - size); ctx.rect(params[j] - size, params[j + 1] - size, size * 2, size * 2); j += 2; break; case 'L': ctx.moveTo(params[j] - size, params[j + 1] - size); ctx.rect(params[j] - size, params[j + 1] - size, size * 2, size * 2); j += 2; break; case 'C': ctx.moveTo(params[j] + size, params[j + 1]); ctx.arc(params[j], params[j + 1], size, 0, twoPi, true); j += 2; ctx.moveTo(params[j] + size, params[j + 1]); ctx.arc(params[j], params[j + 1], size, 0, twoPi, true); j += 2; ctx.moveTo(params[j] + size * 2, params[j + 1]); ctx.rect(params[j] - size, params[j + 1] - size, size * 2, size * 2); j += 2; break; default: } } imat.toContext(ctx); ctx.strokeStyle = 'black'; ctx.strokeOpacity = 1; ctx.lineWidth = 1; ctx.stroke(); mat.toContext(ctx); ctx.beginPath(); for (i = 0, j = 0; i < ln; i++) { switch (commands[i]) { case 'M': ctx.moveTo(params[j], params[j + 1]); j += 2; break; case 'L': ctx.moveTo(params[j], params[j + 1]); j += 2; break; case 'C': ctx.lineTo(params[j], params[j + 1]); j += 2; ctx.moveTo(params[j], params[j + 1]); j += 2; ctx.lineTo(params[j], params[j + 1]); j += 2; break; default: } } imat.toContext(ctx); ctx.lineWidth = 0.5; ctx.stroke(); }, //</debug> /** * Update the path. * @param {Ext.draw.Path} path An empty path to draw on using path API. * @param {Object} attr The attribute object. Note: DO NOT use the `sprite.attr` instead of this * if you want to work with instancing. */ updatePath: function(path, attr) {}});