]>
Commit | Line | Data |
---|---|---|
6527f429 DM |
1 | /**\r |
2 | * @class Ext.draw.sprite.Path\r | |
3 | * @extends Ext.draw.sprite.Sprite\r | |
4 | *\r | |
5 | * A sprite that represents a path.\r | |
6 | *\r | |
7 | * @example\r | |
8 | * Ext.create({\r | |
9 | * xtype: 'draw', \r | |
10 | * renderTo: document.body,\r | |
11 | * width: 600,\r | |
12 | * height: 400,\r | |
13 | * sprites: [{\r | |
14 | * type: 'path',\r | |
15 | * path: 'M20,30 c0,-50 75,50 75,0 c0,-50 -75,50 -75,0',\r | |
16 | * fillStyle: '#1F6D91'\r | |
17 | * }]\r | |
18 | * });\r | |
19 | */\r | |
20 | Ext.define('Ext.draw.sprite.Path', {\r | |
21 | extend: 'Ext.draw.sprite.Sprite',\r | |
22 | requires: [\r | |
23 | 'Ext.draw.Draw',\r | |
24 | 'Ext.draw.Path'\r | |
25 | ],\r | |
26 | alias: [\r | |
27 | 'sprite.path',\r | |
28 | 'Ext.draw.Sprite'\r | |
29 | ],\r | |
30 | type: 'path',\r | |
31 | isPath: true,\r | |
32 | \r | |
33 | inheritableStatics: {\r | |
34 | def: {\r | |
35 | processors: {\r | |
36 | /**\r | |
37 | * @cfg {String} path The SVG based path string used by the sprite.\r | |
38 | */\r | |
39 | path: function (n, o) {\r | |
40 | if (!(n instanceof Ext.draw.Path)) {\r | |
41 | n = new Ext.draw.Path(n);\r | |
42 | }\r | |
43 | return n;\r | |
44 | }\r | |
45 | },\r | |
46 | aliases: {\r | |
47 | d: 'path'\r | |
48 | },\r | |
49 | triggers: {\r | |
50 | path: 'bbox'\r | |
51 | },\r | |
52 | updaters: {\r | |
53 | path: function (attr) {\r | |
54 | var path = attr.path;\r | |
55 | if (!path || path.bindAttr !== attr) {\r | |
56 | path = new Ext.draw.Path();\r | |
57 | path.bindAttr = attr;\r | |
58 | attr.path = path;\r | |
59 | }\r | |
60 | path.clear();\r | |
61 | this.updatePath(path, attr);\r | |
62 | this.scheduleUpdater(attr, 'bbox', ['path']);\r | |
63 | }\r | |
64 | }\r | |
65 | }\r | |
66 | },\r | |
67 | \r | |
68 | updatePlainBBox: function (plain) {\r | |
69 | if (this.attr.path) {\r | |
70 | this.attr.path.getDimension(plain);\r | |
71 | }\r | |
72 | },\r | |
73 | \r | |
74 | updateTransformedBBox: function (transform) {\r | |
75 | if (this.attr.path) {\r | |
76 | this.attr.path.getDimensionWithTransform(this.attr.matrix, transform);\r | |
77 | }\r | |
78 | },\r | |
79 | \r | |
80 | render: function (surface, ctx) {\r | |
81 | var mat = this.attr.matrix,\r | |
82 | attr = this.attr;\r | |
83 | \r | |
84 | if (!attr.path || attr.path.params.length === 0) {\r | |
85 | return;\r | |
86 | }\r | |
87 | mat.toContext(ctx);\r | |
88 | ctx.appendPath(attr.path);\r | |
89 | ctx.fillStroke(attr);\r | |
90 | \r | |
91 | //<debug>\r | |
92 | var debug = attr.debug || this.statics().debug || Ext.draw.sprite.Sprite.debug;\r | |
93 | if (debug) {\r | |
94 | debug.bbox && this.renderBBox(surface, ctx);\r | |
95 | debug.xray && this.renderXRay(surface, ctx);\r | |
96 | }\r | |
97 | //</debug>\r | |
98 | },\r | |
99 | \r | |
100 | //<debug>\r | |
101 | renderXRay: function (surface, ctx) {\r | |
102 | var attr = this.attr,\r | |
103 | mat = attr.matrix,\r | |
104 | imat = attr.inverseMatrix,\r | |
105 | path = attr.path,\r | |
106 | commands = path.commands,\r | |
107 | params = path.params,\r | |
108 | ln = commands.length,\r | |
109 | twoPi = Math.PI * 2,\r | |
110 | size = 2,\r | |
111 | i, j;\r | |
112 | \r | |
113 | mat.toContext(ctx);\r | |
114 | ctx.beginPath();\r | |
115 | for (i = 0, j = 0; i < ln; i++) {\r | |
116 | switch (commands[i]) {\r | |
117 | case 'M':\r | |
118 | ctx.moveTo(params[j] - size, params[j + 1] - size);\r | |
119 | ctx.rect(params[j] - size, params[j + 1] - size, size * 2, size * 2);\r | |
120 | j += 2;\r | |
121 | break;\r | |
122 | case 'L':\r | |
123 | ctx.moveTo(params[j] - size, params[j + 1] - size);\r | |
124 | ctx.rect(params[j] - size, params[j + 1] - size, size * 2, size * 2);\r | |
125 | j += 2;\r | |
126 | break;\r | |
127 | case 'C':\r | |
128 | ctx.moveTo(params[j] + size, params[j + 1]);\r | |
129 | ctx.arc(params[j], params[j + 1], size, 0, twoPi, true);\r | |
130 | j += 2;\r | |
131 | ctx.moveTo(params[j] + size, params[j + 1]);\r | |
132 | ctx.arc(params[j], params[j + 1], size, 0, twoPi, true);\r | |
133 | j += 2;\r | |
134 | ctx.moveTo(params[j] + size * 2, params[j + 1]);\r | |
135 | ctx.rect(params[j] - size, params[j + 1] - size, size * 2, size * 2);\r | |
136 | j += 2;\r | |
137 | break;\r | |
138 | default:\r | |
139 | }\r | |
140 | }\r | |
141 | imat.toContext(ctx);\r | |
142 | ctx.strokeStyle = 'black';\r | |
143 | ctx.strokeOpacity = 1;\r | |
144 | ctx.lineWidth = 1;\r | |
145 | ctx.stroke();\r | |
146 | \r | |
147 | mat.toContext(ctx);\r | |
148 | ctx.beginPath();\r | |
149 | for (i = 0, j = 0; i < ln; i++) {\r | |
150 | switch (commands[i]) {\r | |
151 | case 'M':\r | |
152 | ctx.moveTo(params[j], params[j + 1]);\r | |
153 | j += 2;\r | |
154 | break;\r | |
155 | case 'L':\r | |
156 | ctx.moveTo(params[j], params[j + 1]);\r | |
157 | j += 2;\r | |
158 | break;\r | |
159 | case 'C':\r | |
160 | ctx.lineTo(params[j], params[j + 1]);\r | |
161 | j += 2;\r | |
162 | ctx.moveTo(params[j], params[j + 1]);\r | |
163 | j += 2;\r | |
164 | ctx.lineTo(params[j], params[j + 1]);\r | |
165 | j += 2;\r | |
166 | break;\r | |
167 | default:\r | |
168 | }\r | |
169 | }\r | |
170 | imat.toContext(ctx);\r | |
171 | ctx.lineWidth = 0.5;\r | |
172 | ctx.stroke();\r | |
173 | },\r | |
174 | //</debug>\r | |
175 | \r | |
176 | /**\r | |
177 | * Update the path.\r | |
178 | * @param {Ext.draw.Path} path An empty path to draw on using path API.\r | |
179 | * @param {Object} attr The attribute object. Note: DO NOT use the `sprite.attr` instead of this\r | |
180 | * if you want to work with instancing.\r | |
181 | */\r | |
182 | updatePath: function (path, attr) {}\r | |
183 | }); |