graphics.mjs 110 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913
  1. /*!
  2. * @pixi/graphics - v6.5.10
  3. * Compiled Thu, 06 Jul 2023 15:25:11 UTC
  4. *
  5. * @pixi/graphics is licensed under the MIT License.
  6. * http://www.opensource.org/licenses/mit-license
  7. */
  8. import { Texture, BaseTexture, BatchDrawCall, BatchTextureArray, BatchGeometry, UniformGroup, Shader, State } from '@pixi/core';
  9. import { SHAPES, Point, PI_2, Polygon, Rectangle, RoundedRectangle, Circle, Ellipse, Matrix } from '@pixi/math';
  10. import { earcut, premultiplyTint, hex2rgb } from '@pixi/utils';
  11. import { WRAP_MODES, DRAW_MODES, BLEND_MODES } from '@pixi/constants';
  12. import { Bounds, Container } from '@pixi/display';
  13. /**
  14. * Supported line joints in `PIXI.LineStyle` for graphics.
  15. * @see PIXI.Graphics#lineStyle
  16. * @see https://graphicdesign.stackexchange.com/questions/59018/what-is-a-bevel-join-of-two-lines-exactly-illustrator
  17. * @name LINE_JOIN
  18. * @memberof PIXI
  19. * @static
  20. * @enum {string}
  21. * @property {string} MITER - 'miter': make a sharp corner where outer part of lines meet
  22. * @property {string} BEVEL - 'bevel': add a square butt at each end of line segment and fill the triangle at turn
  23. * @property {string} ROUND - 'round': add an arc at the joint
  24. */
  25. var LINE_JOIN;
  26. (function (LINE_JOIN) {
  27. LINE_JOIN["MITER"] = "miter";
  28. LINE_JOIN["BEVEL"] = "bevel";
  29. LINE_JOIN["ROUND"] = "round";
  30. })(LINE_JOIN || (LINE_JOIN = {}));
  31. /**
  32. * Support line caps in `PIXI.LineStyle` for graphics.
  33. * @see PIXI.Graphics#lineStyle
  34. * @name LINE_CAP
  35. * @memberof PIXI
  36. * @static
  37. * @enum {string}
  38. * @property {string} BUTT - 'butt': don't add any cap at line ends (leaves orthogonal edges)
  39. * @property {string} ROUND - 'round': add semicircle at ends
  40. * @property {string} SQUARE - 'square': add square at end (like `BUTT` except more length at end)
  41. */
  42. var LINE_CAP;
  43. (function (LINE_CAP) {
  44. LINE_CAP["BUTT"] = "butt";
  45. LINE_CAP["ROUND"] = "round";
  46. LINE_CAP["SQUARE"] = "square";
  47. })(LINE_CAP || (LINE_CAP = {}));
  48. /**
  49. * Graphics curves resolution settings. If `adaptive` flag is set to `true`,
  50. * the resolution is calculated based on the curve's length to ensure better visual quality.
  51. * Adaptive draw works with `bezierCurveTo` and `quadraticCurveTo`.
  52. * @static
  53. * @constant
  54. * @memberof PIXI
  55. * @name GRAPHICS_CURVES
  56. * @type {object}
  57. * @property {boolean} [adaptive=true] - flag indicating if the resolution should be adaptive
  58. * @property {number} [maxLength=10] - maximal length of a single segment of the curve (if adaptive = false, ignored)
  59. * @property {number} [minSegments=8] - minimal number of segments in the curve (if adaptive = false, ignored)
  60. * @property {number} [maxSegments=2048] - maximal number of segments in the curve (if adaptive = false, ignored)
  61. */
  62. var GRAPHICS_CURVES = {
  63. adaptive: true,
  64. maxLength: 10,
  65. minSegments: 8,
  66. maxSegments: 2048,
  67. epsilon: 0.0001,
  68. _segmentsCount: function (length, defaultSegments) {
  69. if (defaultSegments === void 0) { defaultSegments = 20; }
  70. if (!this.adaptive || !length || isNaN(length)) {
  71. return defaultSegments;
  72. }
  73. var result = Math.ceil(length / this.maxLength);
  74. if (result < this.minSegments) {
  75. result = this.minSegments;
  76. }
  77. else if (result > this.maxSegments) {
  78. result = this.maxSegments;
  79. }
  80. return result;
  81. },
  82. };
  83. /**
  84. * Fill style object for Graphics.
  85. * @memberof PIXI
  86. */
  87. var FillStyle = /** @class */ (function () {
  88. function FillStyle() {
  89. /**
  90. * The hex color value used when coloring the Graphics object.
  91. * @default 0xFFFFFF
  92. */
  93. this.color = 0xFFFFFF;
  94. /** The alpha value used when filling the Graphics object. */
  95. this.alpha = 1.0;
  96. /**
  97. * The texture to be used for the fill.
  98. * @default 0
  99. */
  100. this.texture = Texture.WHITE;
  101. /**
  102. * The transform applied to the texture.
  103. * @default null
  104. */
  105. this.matrix = null;
  106. /** If the current fill is visible. */
  107. this.visible = false;
  108. this.reset();
  109. }
  110. /** Clones the object */
  111. FillStyle.prototype.clone = function () {
  112. var obj = new FillStyle();
  113. obj.color = this.color;
  114. obj.alpha = this.alpha;
  115. obj.texture = this.texture;
  116. obj.matrix = this.matrix;
  117. obj.visible = this.visible;
  118. return obj;
  119. };
  120. /** Reset */
  121. FillStyle.prototype.reset = function () {
  122. this.color = 0xFFFFFF;
  123. this.alpha = 1;
  124. this.texture = Texture.WHITE;
  125. this.matrix = null;
  126. this.visible = false;
  127. };
  128. /** Destroy and don't use after this. */
  129. FillStyle.prototype.destroy = function () {
  130. this.texture = null;
  131. this.matrix = null;
  132. };
  133. return FillStyle;
  134. }());
  135. /*! *****************************************************************************
  136. Copyright (c) Microsoft Corporation.
  137. Permission to use, copy, modify, and/or distribute this software for any
  138. purpose with or without fee is hereby granted.
  139. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
  140. REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  141. AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
  142. INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  143. LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
  144. OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  145. PERFORMANCE OF THIS SOFTWARE.
  146. ***************************************************************************** */
  147. /* global Reflect, Promise */
  148. var extendStatics = function(d, b) {
  149. extendStatics = Object.setPrototypeOf ||
  150. ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
  151. function (d, b) { for (var p in b) { if (b.hasOwnProperty(p)) { d[p] = b[p]; } } };
  152. return extendStatics(d, b);
  153. };
  154. function __extends(d, b) {
  155. extendStatics(d, b);
  156. function __() { this.constructor = d; }
  157. d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
  158. }
  159. function fixOrientation(points, hole) {
  160. var _a, _b;
  161. if (hole === void 0) { hole = false; }
  162. var m = points.length;
  163. if (m < 6) {
  164. return;
  165. }
  166. var area = 0;
  167. for (var i = 0, x1 = points[m - 2], y1 = points[m - 1]; i < m; i += 2) {
  168. var x2 = points[i];
  169. var y2 = points[i + 1];
  170. area += (x2 - x1) * (y2 + y1);
  171. x1 = x2;
  172. y1 = y2;
  173. }
  174. if ((!hole && area > 0) || (hole && area <= 0)) {
  175. var n = m / 2;
  176. for (var i = n + (n % 2); i < m; i += 2) {
  177. var i1 = m - i - 2;
  178. var i2 = m - i - 1;
  179. var i3 = i;
  180. var i4 = i + 1;
  181. _a = [points[i3], points[i1]], points[i1] = _a[0], points[i3] = _a[1];
  182. _b = [points[i4], points[i2]], points[i2] = _b[0], points[i4] = _b[1];
  183. }
  184. }
  185. }
  186. /**
  187. * Builds a polygon to draw
  188. *
  189. * Ignored from docs since it is not directly exposed.
  190. * @ignore
  191. * @private
  192. * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object containing all the necessary properties
  193. * @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
  194. * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
  195. */
  196. var buildPoly = {
  197. build: function (graphicsData) {
  198. graphicsData.points = graphicsData.shape.points.slice();
  199. },
  200. triangulate: function (graphicsData, graphicsGeometry) {
  201. var points = graphicsData.points;
  202. var holes = graphicsData.holes;
  203. var verts = graphicsGeometry.points;
  204. var indices = graphicsGeometry.indices;
  205. if (points.length >= 6) {
  206. fixOrientation(points, false);
  207. var holeArray = [];
  208. // Process holes..
  209. for (var i = 0; i < holes.length; i++) {
  210. var hole = holes[i];
  211. fixOrientation(hole.points, true);
  212. holeArray.push(points.length / 2);
  213. points = points.concat(hole.points);
  214. }
  215. // sort color
  216. var triangles = earcut(points, holeArray, 2);
  217. if (!triangles) {
  218. return;
  219. }
  220. var vertPos = verts.length / 2;
  221. for (var i = 0; i < triangles.length; i += 3) {
  222. indices.push(triangles[i] + vertPos);
  223. indices.push(triangles[i + 1] + vertPos);
  224. indices.push(triangles[i + 2] + vertPos);
  225. }
  226. for (var i = 0; i < points.length; i++) {
  227. verts.push(points[i]);
  228. }
  229. }
  230. },
  231. };
  232. // for type only
  233. /**
  234. * Builds a circle to draw
  235. *
  236. * Ignored from docs since it is not directly exposed.
  237. * @ignore
  238. * @private
  239. * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object to draw
  240. * @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
  241. * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
  242. */
  243. var buildCircle = {
  244. build: function (graphicsData) {
  245. // need to convert points to a nice regular data
  246. var points = graphicsData.points;
  247. var x;
  248. var y;
  249. var dx;
  250. var dy;
  251. var rx;
  252. var ry;
  253. if (graphicsData.type === SHAPES.CIRC) {
  254. var circle = graphicsData.shape;
  255. x = circle.x;
  256. y = circle.y;
  257. rx = ry = circle.radius;
  258. dx = dy = 0;
  259. }
  260. else if (graphicsData.type === SHAPES.ELIP) {
  261. var ellipse = graphicsData.shape;
  262. x = ellipse.x;
  263. y = ellipse.y;
  264. rx = ellipse.width;
  265. ry = ellipse.height;
  266. dx = dy = 0;
  267. }
  268. else {
  269. var roundedRect = graphicsData.shape;
  270. var halfWidth = roundedRect.width / 2;
  271. var halfHeight = roundedRect.height / 2;
  272. x = roundedRect.x + halfWidth;
  273. y = roundedRect.y + halfHeight;
  274. rx = ry = Math.max(0, Math.min(roundedRect.radius, Math.min(halfWidth, halfHeight)));
  275. dx = halfWidth - rx;
  276. dy = halfHeight - ry;
  277. }
  278. if (!(rx >= 0 && ry >= 0 && dx >= 0 && dy >= 0)) {
  279. points.length = 0;
  280. return;
  281. }
  282. // Choose a number of segments such that the maximum absolute deviation from the circle is approximately 0.029
  283. var n = Math.ceil(2.3 * Math.sqrt(rx + ry));
  284. var m = (n * 8) + (dx ? 4 : 0) + (dy ? 4 : 0);
  285. points.length = m;
  286. if (m === 0) {
  287. return;
  288. }
  289. if (n === 0) {
  290. points.length = 8;
  291. points[0] = points[6] = x + dx;
  292. points[1] = points[3] = y + dy;
  293. points[2] = points[4] = x - dx;
  294. points[5] = points[7] = y - dy;
  295. return;
  296. }
  297. var j1 = 0;
  298. var j2 = (n * 4) + (dx ? 2 : 0) + 2;
  299. var j3 = j2;
  300. var j4 = m;
  301. {
  302. var x0 = dx + rx;
  303. var y0 = dy;
  304. var x1 = x + x0;
  305. var x2 = x - x0;
  306. var y1 = y + y0;
  307. points[j1++] = x1;
  308. points[j1++] = y1;
  309. points[--j2] = y1;
  310. points[--j2] = x2;
  311. if (dy) {
  312. var y2 = y - y0;
  313. points[j3++] = x2;
  314. points[j3++] = y2;
  315. points[--j4] = y2;
  316. points[--j4] = x1;
  317. }
  318. }
  319. for (var i = 1; i < n; i++) {
  320. var a = Math.PI / 2 * (i / n);
  321. var x0 = dx + (Math.cos(a) * rx);
  322. var y0 = dy + (Math.sin(a) * ry);
  323. var x1 = x + x0;
  324. var x2 = x - x0;
  325. var y1 = y + y0;
  326. var y2 = y - y0;
  327. points[j1++] = x1;
  328. points[j1++] = y1;
  329. points[--j2] = y1;
  330. points[--j2] = x2;
  331. points[j3++] = x2;
  332. points[j3++] = y2;
  333. points[--j4] = y2;
  334. points[--j4] = x1;
  335. }
  336. {
  337. var x0 = dx;
  338. var y0 = dy + ry;
  339. var x1 = x + x0;
  340. var x2 = x - x0;
  341. var y1 = y + y0;
  342. var y2 = y - y0;
  343. points[j1++] = x1;
  344. points[j1++] = y1;
  345. points[--j4] = y2;
  346. points[--j4] = x1;
  347. if (dx) {
  348. points[j1++] = x2;
  349. points[j1++] = y1;
  350. points[--j4] = y2;
  351. points[--j4] = x2;
  352. }
  353. }
  354. },
  355. triangulate: function (graphicsData, graphicsGeometry) {
  356. var points = graphicsData.points;
  357. var verts = graphicsGeometry.points;
  358. var indices = graphicsGeometry.indices;
  359. if (points.length === 0) {
  360. return;
  361. }
  362. var vertPos = verts.length / 2;
  363. var center = vertPos;
  364. var x;
  365. var y;
  366. if (graphicsData.type !== SHAPES.RREC) {
  367. var circle = graphicsData.shape;
  368. x = circle.x;
  369. y = circle.y;
  370. }
  371. else {
  372. var roundedRect = graphicsData.shape;
  373. x = roundedRect.x + (roundedRect.width / 2);
  374. y = roundedRect.y + (roundedRect.height / 2);
  375. }
  376. var matrix = graphicsData.matrix;
  377. // Push center (special point)
  378. verts.push(graphicsData.matrix ? (matrix.a * x) + (matrix.c * y) + matrix.tx : x, graphicsData.matrix ? (matrix.b * x) + (matrix.d * y) + matrix.ty : y);
  379. vertPos++;
  380. verts.push(points[0], points[1]);
  381. for (var i = 2; i < points.length; i += 2) {
  382. verts.push(points[i], points[i + 1]);
  383. // add some uvs
  384. indices.push(vertPos++, center, vertPos);
  385. }
  386. indices.push(center + 1, center, vertPos);
  387. },
  388. };
  389. /**
  390. * Builds a rectangle to draw
  391. *
  392. * Ignored from docs since it is not directly exposed.
  393. * @ignore
  394. * @private
  395. * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object containing all the necessary properties
  396. * @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
  397. * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
  398. */
  399. var buildRectangle = {
  400. build: function (graphicsData) {
  401. // --- //
  402. // need to convert points to a nice regular data
  403. //
  404. var rectData = graphicsData.shape;
  405. var x = rectData.x;
  406. var y = rectData.y;
  407. var width = rectData.width;
  408. var height = rectData.height;
  409. var points = graphicsData.points;
  410. points.length = 0;
  411. points.push(x, y, x + width, y, x + width, y + height, x, y + height);
  412. },
  413. triangulate: function (graphicsData, graphicsGeometry) {
  414. var points = graphicsData.points;
  415. var verts = graphicsGeometry.points;
  416. var vertPos = verts.length / 2;
  417. verts.push(points[0], points[1], points[2], points[3], points[6], points[7], points[4], points[5]);
  418. graphicsGeometry.indices.push(vertPos, vertPos + 1, vertPos + 2, vertPos + 1, vertPos + 2, vertPos + 3);
  419. },
  420. };
  421. /**
  422. * Calculate a single point for a quadratic bezier curve.
  423. * Utility function used by quadraticBezierCurve.
  424. * Ignored from docs since it is not directly exposed.
  425. * @ignore
  426. * @private
  427. * @param {number} n1 - first number
  428. * @param {number} n2 - second number
  429. * @param {number} perc - percentage
  430. * @returns {number} the result
  431. */
  432. function getPt(n1, n2, perc) {
  433. var diff = n2 - n1;
  434. return n1 + (diff * perc);
  435. }
  436. /**
  437. * Calculate the points for a quadratic bezier curve. (helper function..)
  438. * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c
  439. *
  440. * Ignored from docs since it is not directly exposed.
  441. * @ignore
  442. * @private
  443. * @param {number} fromX - Origin point x
  444. * @param {number} fromY - Origin point x
  445. * @param {number} cpX - Control point x
  446. * @param {number} cpY - Control point y
  447. * @param {number} toX - Destination point x
  448. * @param {number} toY - Destination point y
  449. * @param {number[]} [out=[]] - The output array to add points into. If not passed, a new array is created.
  450. * @returns {number[]} an array of points
  451. */
  452. function quadraticBezierCurve(fromX, fromY, cpX, cpY, toX, toY, out) {
  453. if (out === void 0) { out = []; }
  454. var n = 20;
  455. var points = out;
  456. var xa = 0;
  457. var ya = 0;
  458. var xb = 0;
  459. var yb = 0;
  460. var x = 0;
  461. var y = 0;
  462. for (var i = 0, j = 0; i <= n; ++i) {
  463. j = i / n;
  464. // The Green Line
  465. xa = getPt(fromX, cpX, j);
  466. ya = getPt(fromY, cpY, j);
  467. xb = getPt(cpX, toX, j);
  468. yb = getPt(cpY, toY, j);
  469. // The Black Dot
  470. x = getPt(xa, xb, j);
  471. y = getPt(ya, yb, j);
  472. // Handle case when first curve points overlaps and earcut fails to triangulate
  473. if (i === 0 && points[points.length - 2] === x && points[points.length - 1] === y) {
  474. continue;
  475. }
  476. points.push(x, y);
  477. }
  478. return points;
  479. }
  480. /**
  481. * Builds a rounded rectangle to draw
  482. *
  483. * Ignored from docs since it is not directly exposed.
  484. * @ignore
  485. * @private
  486. * @param {PIXI.WebGLGraphicsData} graphicsData - The graphics object containing all the necessary properties
  487. * @param {object} webGLData - an object containing all the WebGL-specific information to create this shape
  488. * @param {object} webGLDataNativeLines - an object containing all the WebGL-specific information to create nativeLines
  489. */
  490. var buildRoundedRectangle = {
  491. build: function (graphicsData) {
  492. if (Graphics.nextRoundedRectBehavior) {
  493. buildCircle.build(graphicsData);
  494. return;
  495. }
  496. var rrectData = graphicsData.shape;
  497. var points = graphicsData.points;
  498. var x = rrectData.x;
  499. var y = rrectData.y;
  500. var width = rrectData.width;
  501. var height = rrectData.height;
  502. // Don't allow negative radius or greater than half the smallest width
  503. var radius = Math.max(0, Math.min(rrectData.radius, Math.min(width, height) / 2));
  504. points.length = 0;
  505. // No radius, do a simple rectangle
  506. if (!radius) {
  507. points.push(x, y, x + width, y, x + width, y + height, x, y + height);
  508. }
  509. else {
  510. quadraticBezierCurve(x, y + radius, x, y, x + radius, y, points);
  511. quadraticBezierCurve(x + width - radius, y, x + width, y, x + width, y + radius, points);
  512. quadraticBezierCurve(x + width, y + height - radius, x + width, y + height, x + width - radius, y + height, points);
  513. quadraticBezierCurve(x + radius, y + height, x, y + height, x, y + height - radius, points);
  514. }
  515. },
  516. triangulate: function (graphicsData, graphicsGeometry) {
  517. if (Graphics.nextRoundedRectBehavior) {
  518. buildCircle.triangulate(graphicsData, graphicsGeometry);
  519. return;
  520. }
  521. var points = graphicsData.points;
  522. var verts = graphicsGeometry.points;
  523. var indices = graphicsGeometry.indices;
  524. var vecPos = verts.length / 2;
  525. var triangles = earcut(points, null, 2);
  526. for (var i = 0, j = triangles.length; i < j; i += 3) {
  527. indices.push(triangles[i] + vecPos);
  528. // indices.push(triangles[i] + vecPos);
  529. indices.push(triangles[i + 1] + vecPos);
  530. // indices.push(triangles[i + 2] + vecPos);
  531. indices.push(triangles[i + 2] + vecPos);
  532. }
  533. for (var i = 0, j = points.length; i < j; i++) {
  534. verts.push(points[i], points[++i]);
  535. }
  536. },
  537. };
  538. /**
  539. * Buffers vertices to draw a square cap.
  540. *
  541. * Ignored from docs since it is not directly exposed.
  542. * @ignore
  543. * @private
  544. * @param {number} x - X-coord of end point
  545. * @param {number} y - Y-coord of end point
  546. * @param {number} nx - X-coord of line normal pointing inside
  547. * @param {number} ny - Y-coord of line normal pointing inside
  548. * @param {number} innerWeight - Weight of inner points
  549. * @param {number} outerWeight - Weight of outer points
  550. * @param {boolean} clockwise - Whether the cap is drawn clockwise
  551. * @param {Array<number>} verts - vertex buffer
  552. * @returns {number} - no. of vertices pushed
  553. */
  554. function square(x, y, nx, ny, innerWeight, outerWeight, clockwise, /* rotation for square (true at left end, false at right end) */ verts) {
  555. var ix = x - (nx * innerWeight);
  556. var iy = y - (ny * innerWeight);
  557. var ox = x + (nx * outerWeight);
  558. var oy = y + (ny * outerWeight);
  559. /* Rotate nx,ny for extension vector */
  560. var exx;
  561. var eyy;
  562. if (clockwise) {
  563. exx = ny;
  564. eyy = -nx;
  565. }
  566. else {
  567. exx = -ny;
  568. eyy = nx;
  569. }
  570. /* [i|0]x,y extended at cap */
  571. var eix = ix + exx;
  572. var eiy = iy + eyy;
  573. var eox = ox + exx;
  574. var eoy = oy + eyy;
  575. /* Square itself must be inserted clockwise*/
  576. verts.push(eix, eiy);
  577. verts.push(eox, eoy);
  578. return 2;
  579. }
  580. /**
  581. * Buffers vertices to draw an arc at the line joint or cap.
  582. *
  583. * Ignored from docs since it is not directly exposed.
  584. * @ignore
  585. * @private
  586. * @param {number} cx - X-coord of center
  587. * @param {number} cy - Y-coord of center
  588. * @param {number} sx - X-coord of arc start
  589. * @param {number} sy - Y-coord of arc start
  590. * @param {number} ex - X-coord of arc end
  591. * @param {number} ey - Y-coord of arc end
  592. * @param {Array<number>} verts - buffer of vertices
  593. * @param {boolean} clockwise - orientation of vertices
  594. * @returns {number} - no. of vertices pushed
  595. */
  596. function round(cx, cy, sx, sy, ex, ey, verts, clockwise) {
  597. var cx2p0x = sx - cx;
  598. var cy2p0y = sy - cy;
  599. var angle0 = Math.atan2(cx2p0x, cy2p0y);
  600. var angle1 = Math.atan2(ex - cx, ey - cy);
  601. if (clockwise && angle0 < angle1) {
  602. angle0 += Math.PI * 2;
  603. }
  604. else if (!clockwise && angle0 > angle1) {
  605. angle1 += Math.PI * 2;
  606. }
  607. var startAngle = angle0;
  608. var angleDiff = angle1 - angle0;
  609. var absAngleDiff = Math.abs(angleDiff);
  610. /* if (absAngleDiff >= PI_LBOUND && absAngleDiff <= PI_UBOUND)
  611. {
  612. const r1x = cx - nxtPx;
  613. const r1y = cy - nxtPy;
  614. if (r1x === 0)
  615. {
  616. if (r1y > 0)
  617. {
  618. angleDiff = -angleDiff;
  619. }
  620. }
  621. else if (r1x >= -GRAPHICS_CURVES.epsilon)
  622. {
  623. angleDiff = -angleDiff;
  624. }
  625. }*/
  626. var radius = Math.sqrt((cx2p0x * cx2p0x) + (cy2p0y * cy2p0y));
  627. var segCount = ((15 * absAngleDiff * Math.sqrt(radius) / Math.PI) >> 0) + 1;
  628. var angleInc = angleDiff / segCount;
  629. startAngle += angleInc;
  630. if (clockwise) {
  631. verts.push(cx, cy);
  632. verts.push(sx, sy);
  633. for (var i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
  634. verts.push(cx, cy);
  635. verts.push(cx + ((Math.sin(angle) * radius)), cy + ((Math.cos(angle) * radius)));
  636. }
  637. verts.push(cx, cy);
  638. verts.push(ex, ey);
  639. }
  640. else {
  641. verts.push(sx, sy);
  642. verts.push(cx, cy);
  643. for (var i = 1, angle = startAngle; i < segCount; i++, angle += angleInc) {
  644. verts.push(cx + ((Math.sin(angle) * radius)), cy + ((Math.cos(angle) * radius)));
  645. verts.push(cx, cy);
  646. }
  647. verts.push(ex, ey);
  648. verts.push(cx, cy);
  649. }
  650. return segCount * 2;
  651. }
  652. /**
  653. * Builds a line to draw using the polygon method.
  654. *
  655. * Ignored from docs since it is not directly exposed.
  656. * @ignore
  657. * @private
  658. * @param {PIXI.GraphicsData} graphicsData - The graphics object containing all the necessary properties
  659. * @param {PIXI.GraphicsGeometry} graphicsGeometry - Geometry where to append output
  660. */
  661. function buildNonNativeLine(graphicsData, graphicsGeometry) {
  662. var shape = graphicsData.shape;
  663. var points = graphicsData.points || shape.points.slice();
  664. var eps = graphicsGeometry.closePointEps;
  665. if (points.length === 0) {
  666. return;
  667. }
  668. // if the line width is an odd number add 0.5 to align to a whole pixel
  669. // commenting this out fixes #711 and #1620
  670. // if (graphicsData.lineWidth%2)
  671. // {
  672. // for (i = 0; i < points.length; i++)
  673. // {
  674. // points[i] += 0.5;
  675. // }
  676. // }
  677. var style = graphicsData.lineStyle;
  678. // get first and last point.. figure out the middle!
  679. var firstPoint = new Point(points[0], points[1]);
  680. var lastPoint = new Point(points[points.length - 2], points[points.length - 1]);
  681. var closedShape = shape.type !== SHAPES.POLY || shape.closeStroke;
  682. var closedPath = Math.abs(firstPoint.x - lastPoint.x) < eps
  683. && Math.abs(firstPoint.y - lastPoint.y) < eps;
  684. // if the first point is the last point - gonna have issues :)
  685. if (closedShape) {
  686. // need to clone as we are going to slightly modify the shape..
  687. points = points.slice();
  688. if (closedPath) {
  689. points.pop();
  690. points.pop();
  691. lastPoint.set(points[points.length - 2], points[points.length - 1]);
  692. }
  693. var midPointX = (firstPoint.x + lastPoint.x) * 0.5;
  694. var midPointY = (lastPoint.y + firstPoint.y) * 0.5;
  695. points.unshift(midPointX, midPointY);
  696. points.push(midPointX, midPointY);
  697. }
  698. var verts = graphicsGeometry.points;
  699. var length = points.length / 2;
  700. var indexCount = points.length;
  701. var indexStart = verts.length / 2;
  702. // Max. inner and outer width
  703. var width = style.width / 2;
  704. var widthSquared = width * width;
  705. var miterLimitSquared = style.miterLimit * style.miterLimit;
  706. /* Line segments of interest where (x1,y1) forms the corner. */
  707. var x0 = points[0];
  708. var y0 = points[1];
  709. var x1 = points[2];
  710. var y1 = points[3];
  711. var x2 = 0;
  712. var y2 = 0;
  713. /* perp[?](x|y) = the line normal with magnitude lineWidth. */
  714. var perpx = -(y0 - y1);
  715. var perpy = x0 - x1;
  716. var perp1x = 0;
  717. var perp1y = 0;
  718. var dist = Math.sqrt((perpx * perpx) + (perpy * perpy));
  719. perpx /= dist;
  720. perpy /= dist;
  721. perpx *= width;
  722. perpy *= width;
  723. var ratio = style.alignment; // 0.5;
  724. var innerWeight = (1 - ratio) * 2;
  725. var outerWeight = ratio * 2;
  726. if (!closedShape) {
  727. if (style.cap === LINE_CAP.ROUND) {
  728. indexCount += round(x0 - (perpx * (innerWeight - outerWeight) * 0.5), y0 - (perpy * (innerWeight - outerWeight) * 0.5), x0 - (perpx * innerWeight), y0 - (perpy * innerWeight), x0 + (perpx * outerWeight), y0 + (perpy * outerWeight), verts, true) + 2;
  729. }
  730. else if (style.cap === LINE_CAP.SQUARE) {
  731. indexCount += square(x0, y0, perpx, perpy, innerWeight, outerWeight, true, verts);
  732. }
  733. }
  734. // Push first point (below & above vertices)
  735. verts.push(x0 - (perpx * innerWeight), y0 - (perpy * innerWeight));
  736. verts.push(x0 + (perpx * outerWeight), y0 + (perpy * outerWeight));
  737. for (var i = 1; i < length - 1; ++i) {
  738. x0 = points[(i - 1) * 2];
  739. y0 = points[((i - 1) * 2) + 1];
  740. x1 = points[i * 2];
  741. y1 = points[(i * 2) + 1];
  742. x2 = points[(i + 1) * 2];
  743. y2 = points[((i + 1) * 2) + 1];
  744. perpx = -(y0 - y1);
  745. perpy = x0 - x1;
  746. dist = Math.sqrt((perpx * perpx) + (perpy * perpy));
  747. perpx /= dist;
  748. perpy /= dist;
  749. perpx *= width;
  750. perpy *= width;
  751. perp1x = -(y1 - y2);
  752. perp1y = x1 - x2;
  753. dist = Math.sqrt((perp1x * perp1x) + (perp1y * perp1y));
  754. perp1x /= dist;
  755. perp1y /= dist;
  756. perp1x *= width;
  757. perp1y *= width;
  758. /* d[x|y](0|1) = the component displacement between points p(0,1|1,2) */
  759. var dx0 = x1 - x0;
  760. var dy0 = y0 - y1;
  761. var dx1 = x1 - x2;
  762. var dy1 = y2 - y1;
  763. /* +ve if internal angle < 90 degree, -ve if internal angle > 90 degree. */
  764. var dot = (dx0 * dx1) + (dy0 * dy1);
  765. /* +ve if internal angle counterclockwise, -ve if internal angle clockwise. */
  766. var cross = (dy0 * dx1) - (dy1 * dx0);
  767. var clockwise = (cross < 0);
  768. /* Going nearly parallel? */
  769. /* atan(0.001) ~= 0.001 rad ~= 0.057 degree */
  770. if (Math.abs(cross) < 0.001 * Math.abs(dot)) {
  771. verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight));
  772. verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight));
  773. /* 180 degree corner? */
  774. if (dot >= 0) {
  775. if (style.join === LINE_JOIN.ROUND) {
  776. indexCount += round(x1, y1, x1 - (perpx * innerWeight), y1 - (perpy * innerWeight), x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight), verts, false) + 4;
  777. }
  778. else {
  779. indexCount += 2;
  780. }
  781. verts.push(x1 - (perp1x * outerWeight), y1 - (perp1y * outerWeight));
  782. verts.push(x1 + (perp1x * innerWeight), y1 + (perp1y * innerWeight));
  783. }
  784. continue;
  785. }
  786. /* p[x|y] is the miter point. pdist is the distance between miter point and p1. */
  787. var c1 = ((-perpx + x0) * (-perpy + y1)) - ((-perpx + x1) * (-perpy + y0));
  788. var c2 = ((-perp1x + x2) * (-perp1y + y1)) - ((-perp1x + x1) * (-perp1y + y2));
  789. var px = ((dx0 * c2) - (dx1 * c1)) / cross;
  790. var py = ((dy1 * c1) - (dy0 * c2)) / cross;
  791. var pdist = ((px - x1) * (px - x1)) + ((py - y1) * (py - y1));
  792. /* Inner miter point */
  793. var imx = x1 + ((px - x1) * innerWeight);
  794. var imy = y1 + ((py - y1) * innerWeight);
  795. /* Outer miter point */
  796. var omx = x1 - ((px - x1) * outerWeight);
  797. var omy = y1 - ((py - y1) * outerWeight);
  798. /* Is the inside miter point too far away, creating a spike? */
  799. var smallerInsideSegmentSq = Math.min((dx0 * dx0) + (dy0 * dy0), (dx1 * dx1) + (dy1 * dy1));
  800. var insideWeight = clockwise ? innerWeight : outerWeight;
  801. var smallerInsideDiagonalSq = smallerInsideSegmentSq + (insideWeight * insideWeight * widthSquared);
  802. var insideMiterOk = pdist <= smallerInsideDiagonalSq;
  803. if (insideMiterOk) {
  804. if (style.join === LINE_JOIN.BEVEL || pdist / widthSquared > miterLimitSquared) {
  805. if (clockwise) /* rotating at inner angle */ {
  806. verts.push(imx, imy); // inner miter point
  807. verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight)); // first segment's outer vertex
  808. verts.push(imx, imy); // inner miter point
  809. verts.push(x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight)); // second segment's outer vertex
  810. }
  811. else /* rotating at outer angle */ {
  812. verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight)); // first segment's inner vertex
  813. verts.push(omx, omy); // outer miter point
  814. verts.push(x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight)); // second segment's outer vertex
  815. verts.push(omx, omy); // outer miter point
  816. }
  817. indexCount += 2;
  818. }
  819. else if (style.join === LINE_JOIN.ROUND) {
  820. if (clockwise) /* arc is outside */ {
  821. verts.push(imx, imy);
  822. verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight));
  823. indexCount += round(x1, y1, x1 + (perpx * outerWeight), y1 + (perpy * outerWeight), x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight), verts, true) + 4;
  824. verts.push(imx, imy);
  825. verts.push(x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight));
  826. }
  827. else /* arc is inside */ {
  828. verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight));
  829. verts.push(omx, omy);
  830. indexCount += round(x1, y1, x1 - (perpx * innerWeight), y1 - (perpy * innerWeight), x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight), verts, false) + 4;
  831. verts.push(x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight));
  832. verts.push(omx, omy);
  833. }
  834. }
  835. else {
  836. verts.push(imx, imy);
  837. verts.push(omx, omy);
  838. }
  839. }
  840. else // inside miter is NOT ok
  841. {
  842. verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight)); // first segment's inner vertex
  843. verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight)); // first segment's outer vertex
  844. if (style.join === LINE_JOIN.ROUND) {
  845. if (clockwise) /* arc is outside */ {
  846. indexCount += round(x1, y1, x1 + (perpx * outerWeight), y1 + (perpy * outerWeight), x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight), verts, true) + 2;
  847. }
  848. else /* arc is inside */ {
  849. indexCount += round(x1, y1, x1 - (perpx * innerWeight), y1 - (perpy * innerWeight), x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight), verts, false) + 2;
  850. }
  851. }
  852. else if (style.join === LINE_JOIN.MITER && pdist / widthSquared <= miterLimitSquared) {
  853. if (clockwise) {
  854. verts.push(omx, omy); // inner miter point
  855. verts.push(omx, omy); // inner miter point
  856. }
  857. else {
  858. verts.push(imx, imy); // outer miter point
  859. verts.push(imx, imy); // outer miter point
  860. }
  861. indexCount += 2;
  862. }
  863. verts.push(x1 - (perp1x * innerWeight), y1 - (perp1y * innerWeight)); // second segment's inner vertex
  864. verts.push(x1 + (perp1x * outerWeight), y1 + (perp1y * outerWeight)); // second segment's outer vertex
  865. indexCount += 2;
  866. }
  867. }
  868. x0 = points[(length - 2) * 2];
  869. y0 = points[((length - 2) * 2) + 1];
  870. x1 = points[(length - 1) * 2];
  871. y1 = points[((length - 1) * 2) + 1];
  872. perpx = -(y0 - y1);
  873. perpy = x0 - x1;
  874. dist = Math.sqrt((perpx * perpx) + (perpy * perpy));
  875. perpx /= dist;
  876. perpy /= dist;
  877. perpx *= width;
  878. perpy *= width;
  879. verts.push(x1 - (perpx * innerWeight), y1 - (perpy * innerWeight));
  880. verts.push(x1 + (perpx * outerWeight), y1 + (perpy * outerWeight));
  881. if (!closedShape) {
  882. if (style.cap === LINE_CAP.ROUND) {
  883. indexCount += round(x1 - (perpx * (innerWeight - outerWeight) * 0.5), y1 - (perpy * (innerWeight - outerWeight) * 0.5), x1 - (perpx * innerWeight), y1 - (perpy * innerWeight), x1 + (perpx * outerWeight), y1 + (perpy * outerWeight), verts, false) + 2;
  884. }
  885. else if (style.cap === LINE_CAP.SQUARE) {
  886. indexCount += square(x1, y1, perpx, perpy, innerWeight, outerWeight, false, verts);
  887. }
  888. }
  889. var indices = graphicsGeometry.indices;
  890. var eps2 = GRAPHICS_CURVES.epsilon * GRAPHICS_CURVES.epsilon;
  891. // indices.push(indexStart);
  892. for (var i = indexStart; i < indexCount + indexStart - 2; ++i) {
  893. x0 = verts[(i * 2)];
  894. y0 = verts[(i * 2) + 1];
  895. x1 = verts[(i + 1) * 2];
  896. y1 = verts[((i + 1) * 2) + 1];
  897. x2 = verts[(i + 2) * 2];
  898. y2 = verts[((i + 2) * 2) + 1];
  899. /* Skip zero area triangles */
  900. if (Math.abs((x0 * (y1 - y2)) + (x1 * (y2 - y0)) + (x2 * (y0 - y1))) < eps2) {
  901. continue;
  902. }
  903. indices.push(i, i + 1, i + 2);
  904. }
  905. }
  906. /**
  907. * Builds a line to draw using the gl.drawArrays(gl.LINES) method
  908. *
  909. * Ignored from docs since it is not directly exposed.
  910. * @ignore
  911. * @private
  912. * @param {PIXI.GraphicsData} graphicsData - The graphics object containing all the necessary properties
  913. * @param {PIXI.GraphicsGeometry} graphicsGeometry - Geometry where to append output
  914. */
  915. function buildNativeLine(graphicsData, graphicsGeometry) {
  916. var i = 0;
  917. var shape = graphicsData.shape;
  918. var points = graphicsData.points || shape.points;
  919. var closedShape = shape.type !== SHAPES.POLY || shape.closeStroke;
  920. if (points.length === 0)
  921. { return; }
  922. var verts = graphicsGeometry.points;
  923. var indices = graphicsGeometry.indices;
  924. var length = points.length / 2;
  925. var startIndex = verts.length / 2;
  926. var currentIndex = startIndex;
  927. verts.push(points[0], points[1]);
  928. for (i = 1; i < length; i++) {
  929. verts.push(points[i * 2], points[(i * 2) + 1]);
  930. indices.push(currentIndex, currentIndex + 1);
  931. currentIndex++;
  932. }
  933. if (closedShape) {
  934. indices.push(currentIndex, startIndex);
  935. }
  936. }
  937. /**
  938. * Builds a line to draw
  939. *
  940. * Ignored from docs since it is not directly exposed.
  941. * @ignore
  942. * @private
  943. * @param {PIXI.GraphicsData} graphicsData - The graphics object containing all the necessary properties
  944. * @param {PIXI.GraphicsGeometry} graphicsGeometry - Geometry where to append output
  945. */
  946. function buildLine(graphicsData, graphicsGeometry) {
  947. if (graphicsData.lineStyle.native) {
  948. buildNativeLine(graphicsData, graphicsGeometry);
  949. }
  950. else {
  951. buildNonNativeLine(graphicsData, graphicsGeometry);
  952. }
  953. }
  954. /**
  955. * Utilities for arc curves.
  956. * @private
  957. */
  958. var ArcUtils = /** @class */ (function () {
  959. function ArcUtils() {
  960. }
  961. /**
  962. * The arcTo() method creates an arc/curve between two tangents on the canvas.
  963. *
  964. * "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google!
  965. * @private
  966. * @param x1 - The x-coordinate of the beginning of the arc
  967. * @param y1 - The y-coordinate of the beginning of the arc
  968. * @param x2 - The x-coordinate of the end of the arc
  969. * @param y2 - The y-coordinate of the end of the arc
  970. * @param radius - The radius of the arc
  971. * @param points -
  972. * @returns - If the arc length is valid, return center of circle, radius and other info otherwise `null`.
  973. */
  974. ArcUtils.curveTo = function (x1, y1, x2, y2, radius, points) {
  975. var fromX = points[points.length - 2];
  976. var fromY = points[points.length - 1];
  977. var a1 = fromY - y1;
  978. var b1 = fromX - x1;
  979. var a2 = y2 - y1;
  980. var b2 = x2 - x1;
  981. var mm = Math.abs((a1 * b2) - (b1 * a2));
  982. if (mm < 1.0e-8 || radius === 0) {
  983. if (points[points.length - 2] !== x1 || points[points.length - 1] !== y1) {
  984. points.push(x1, y1);
  985. }
  986. return null;
  987. }
  988. var dd = (a1 * a1) + (b1 * b1);
  989. var cc = (a2 * a2) + (b2 * b2);
  990. var tt = (a1 * a2) + (b1 * b2);
  991. var k1 = radius * Math.sqrt(dd) / mm;
  992. var k2 = radius * Math.sqrt(cc) / mm;
  993. var j1 = k1 * tt / dd;
  994. var j2 = k2 * tt / cc;
  995. var cx = (k1 * b2) + (k2 * b1);
  996. var cy = (k1 * a2) + (k2 * a1);
  997. var px = b1 * (k2 + j1);
  998. var py = a1 * (k2 + j1);
  999. var qx = b2 * (k1 + j2);
  1000. var qy = a2 * (k1 + j2);
  1001. var startAngle = Math.atan2(py - cy, px - cx);
  1002. var endAngle = Math.atan2(qy - cy, qx - cx);
  1003. return {
  1004. cx: (cx + x1),
  1005. cy: (cy + y1),
  1006. radius: radius,
  1007. startAngle: startAngle,
  1008. endAngle: endAngle,
  1009. anticlockwise: (b1 * a2 > b2 * a1),
  1010. };
  1011. };
  1012. /* eslint-disable max-len */
  1013. /**
  1014. * The arc method creates an arc/curve (used to create circles, or parts of circles).
  1015. * @private
  1016. * @param _startX - Start x location of arc
  1017. * @param _startY - Start y location of arc
  1018. * @param cx - The x-coordinate of the center of the circle
  1019. * @param cy - The y-coordinate of the center of the circle
  1020. * @param radius - The radius of the circle
  1021. * @param startAngle - The starting angle, in radians (0 is at the 3 o'clock position
  1022. * of the arc's circle)
  1023. * @param endAngle - The ending angle, in radians
  1024. * @param _anticlockwise - Specifies whether the drawing should be
  1025. * counter-clockwise or clockwise. False is default, and indicates clockwise, while true
  1026. * indicates counter-clockwise.
  1027. * @param points - Collection of points to add to
  1028. */
  1029. ArcUtils.arc = function (_startX, _startY, cx, cy, radius, startAngle, endAngle, _anticlockwise, points) {
  1030. var sweep = endAngle - startAngle;
  1031. var n = GRAPHICS_CURVES._segmentsCount(Math.abs(sweep) * radius, Math.ceil(Math.abs(sweep) / PI_2) * 40);
  1032. var theta = (sweep) / (n * 2);
  1033. var theta2 = theta * 2;
  1034. var cTheta = Math.cos(theta);
  1035. var sTheta = Math.sin(theta);
  1036. var segMinus = n - 1;
  1037. var remainder = (segMinus % 1) / segMinus;
  1038. for (var i = 0; i <= segMinus; ++i) {
  1039. var real = i + (remainder * i);
  1040. var angle = ((theta) + startAngle + (theta2 * real));
  1041. var c = Math.cos(angle);
  1042. var s = -Math.sin(angle);
  1043. points.push((((cTheta * c) + (sTheta * s)) * radius) + cx, (((cTheta * -s) + (sTheta * c)) * radius) + cy);
  1044. }
  1045. };
  1046. return ArcUtils;
  1047. }());
  1048. /**
  1049. * Utilities for bezier curves
  1050. * @private
  1051. */
  1052. var BezierUtils = /** @class */ (function () {
  1053. function BezierUtils() {
  1054. }
  1055. /**
  1056. * Calculate length of bezier curve.
  1057. * Analytical solution is impossible, since it involves an integral that does not integrate in general.
  1058. * Therefore numerical solution is used.
  1059. * @private
  1060. * @param fromX - Starting point x
  1061. * @param fromY - Starting point y
  1062. * @param cpX - Control point x
  1063. * @param cpY - Control point y
  1064. * @param cpX2 - Second Control point x
  1065. * @param cpY2 - Second Control point y
  1066. * @param toX - Destination point x
  1067. * @param toY - Destination point y
  1068. * @returns - Length of bezier curve
  1069. */
  1070. BezierUtils.curveLength = function (fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY) {
  1071. var n = 10;
  1072. var result = 0.0;
  1073. var t = 0.0;
  1074. var t2 = 0.0;
  1075. var t3 = 0.0;
  1076. var nt = 0.0;
  1077. var nt2 = 0.0;
  1078. var nt3 = 0.0;
  1079. var x = 0.0;
  1080. var y = 0.0;
  1081. var dx = 0.0;
  1082. var dy = 0.0;
  1083. var prevX = fromX;
  1084. var prevY = fromY;
  1085. for (var i = 1; i <= n; ++i) {
  1086. t = i / n;
  1087. t2 = t * t;
  1088. t3 = t2 * t;
  1089. nt = (1.0 - t);
  1090. nt2 = nt * nt;
  1091. nt3 = nt2 * nt;
  1092. x = (nt3 * fromX) + (3.0 * nt2 * t * cpX) + (3.0 * nt * t2 * cpX2) + (t3 * toX);
  1093. y = (nt3 * fromY) + (3.0 * nt2 * t * cpY) + (3 * nt * t2 * cpY2) + (t3 * toY);
  1094. dx = prevX - x;
  1095. dy = prevY - y;
  1096. prevX = x;
  1097. prevY = y;
  1098. result += Math.sqrt((dx * dx) + (dy * dy));
  1099. }
  1100. return result;
  1101. };
  1102. /**
  1103. * Calculate the points for a bezier curve and then draws it.
  1104. *
  1105. * Ignored from docs since it is not directly exposed.
  1106. * @ignore
  1107. * @param cpX - Control point x
  1108. * @param cpY - Control point y
  1109. * @param cpX2 - Second Control point x
  1110. * @param cpY2 - Second Control point y
  1111. * @param toX - Destination point x
  1112. * @param toY - Destination point y
  1113. * @param points - Path array to push points into
  1114. */
  1115. BezierUtils.curveTo = function (cpX, cpY, cpX2, cpY2, toX, toY, points) {
  1116. var fromX = points[points.length - 2];
  1117. var fromY = points[points.length - 1];
  1118. points.length -= 2;
  1119. var n = GRAPHICS_CURVES._segmentsCount(BezierUtils.curveLength(fromX, fromY, cpX, cpY, cpX2, cpY2, toX, toY));
  1120. var dt = 0;
  1121. var dt2 = 0;
  1122. var dt3 = 0;
  1123. var t2 = 0;
  1124. var t3 = 0;
  1125. points.push(fromX, fromY);
  1126. for (var i = 1, j = 0; i <= n; ++i) {
  1127. j = i / n;
  1128. dt = (1 - j);
  1129. dt2 = dt * dt;
  1130. dt3 = dt2 * dt;
  1131. t2 = j * j;
  1132. t3 = t2 * j;
  1133. points.push((dt3 * fromX) + (3 * dt2 * j * cpX) + (3 * dt * t2 * cpX2) + (t3 * toX), (dt3 * fromY) + (3 * dt2 * j * cpY) + (3 * dt * t2 * cpY2) + (t3 * toY));
  1134. }
  1135. };
  1136. return BezierUtils;
  1137. }());
  1138. /**
  1139. * Utilities for quadratic curves.
  1140. * @private
  1141. */
  1142. var QuadraticUtils = /** @class */ (function () {
  1143. function QuadraticUtils() {
  1144. }
  1145. /**
  1146. * Calculate length of quadratic curve
  1147. * @see {@link http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/}
  1148. * for the detailed explanation of math behind this.
  1149. * @private
  1150. * @param fromX - x-coordinate of curve start point
  1151. * @param fromY - y-coordinate of curve start point
  1152. * @param cpX - x-coordinate of curve control point
  1153. * @param cpY - y-coordinate of curve control point
  1154. * @param toX - x-coordinate of curve end point
  1155. * @param toY - y-coordinate of curve end point
  1156. * @returns - Length of quadratic curve
  1157. */
  1158. QuadraticUtils.curveLength = function (fromX, fromY, cpX, cpY, toX, toY) {
  1159. var ax = fromX - (2.0 * cpX) + toX;
  1160. var ay = fromY - (2.0 * cpY) + toY;
  1161. var bx = (2.0 * cpX) - (2.0 * fromX);
  1162. var by = (2.0 * cpY) - (2.0 * fromY);
  1163. var a = 4.0 * ((ax * ax) + (ay * ay));
  1164. var b = 4.0 * ((ax * bx) + (ay * by));
  1165. var c = (bx * bx) + (by * by);
  1166. var s = 2.0 * Math.sqrt(a + b + c);
  1167. var a2 = Math.sqrt(a);
  1168. var a32 = 2.0 * a * a2;
  1169. var c2 = 2.0 * Math.sqrt(c);
  1170. var ba = b / a2;
  1171. return ((a32 * s)
  1172. + (a2 * b * (s - c2))
  1173. + (((4.0 * c * a) - (b * b))
  1174. * Math.log(((2.0 * a2) + ba + s) / (ba + c2)))) / (4.0 * a32);
  1175. };
  1176. /**
  1177. * Calculate the points for a quadratic bezier curve and then draws it.
  1178. * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c
  1179. * @private
  1180. * @param cpX - Control point x
  1181. * @param cpY - Control point y
  1182. * @param toX - Destination point x
  1183. * @param toY - Destination point y
  1184. * @param points - Points to add segments to.
  1185. */
  1186. QuadraticUtils.curveTo = function (cpX, cpY, toX, toY, points) {
  1187. var fromX = points[points.length - 2];
  1188. var fromY = points[points.length - 1];
  1189. var n = GRAPHICS_CURVES._segmentsCount(QuadraticUtils.curveLength(fromX, fromY, cpX, cpY, toX, toY));
  1190. var xa = 0;
  1191. var ya = 0;
  1192. for (var i = 1; i <= n; ++i) {
  1193. var j = i / n;
  1194. xa = fromX + ((cpX - fromX) * j);
  1195. ya = fromY + ((cpY - fromY) * j);
  1196. points.push(xa + (((cpX + ((toX - cpX) * j)) - xa) * j), ya + (((cpY + ((toY - cpY) * j)) - ya) * j));
  1197. }
  1198. };
  1199. return QuadraticUtils;
  1200. }());
  1201. /**
  1202. * A structure to hold interim batch objects for Graphics.
  1203. * @memberof PIXI.graphicsUtils
  1204. */
  1205. var BatchPart = /** @class */ (function () {
  1206. function BatchPart() {
  1207. this.reset();
  1208. }
  1209. /**
  1210. * Begin batch part.
  1211. * @param style
  1212. * @param startIndex
  1213. * @param attribStart
  1214. */
  1215. BatchPart.prototype.begin = function (style, startIndex, attribStart) {
  1216. this.reset();
  1217. this.style = style;
  1218. this.start = startIndex;
  1219. this.attribStart = attribStart;
  1220. };
  1221. /**
  1222. * End batch part.
  1223. * @param endIndex
  1224. * @param endAttrib
  1225. */
  1226. BatchPart.prototype.end = function (endIndex, endAttrib) {
  1227. this.attribSize = endAttrib - this.attribStart;
  1228. this.size = endIndex - this.start;
  1229. };
  1230. BatchPart.prototype.reset = function () {
  1231. this.style = null;
  1232. this.size = 0;
  1233. this.start = 0;
  1234. this.attribStart = 0;
  1235. this.attribSize = 0;
  1236. };
  1237. return BatchPart;
  1238. }());
  1239. /**
  1240. * Generalized convenience utilities for Graphics.
  1241. * @namespace graphicsUtils
  1242. * @memberof PIXI
  1243. */
  1244. var _a;
  1245. /**
  1246. * Map of fill commands for each shape type.
  1247. * @memberof PIXI.graphicsUtils
  1248. * @member {object} FILL_COMMANDS
  1249. */
  1250. var FILL_COMMANDS = (_a = {},
  1251. _a[SHAPES.POLY] = buildPoly,
  1252. _a[SHAPES.CIRC] = buildCircle,
  1253. _a[SHAPES.ELIP] = buildCircle,
  1254. _a[SHAPES.RECT] = buildRectangle,
  1255. _a[SHAPES.RREC] = buildRoundedRectangle,
  1256. _a);
  1257. /**
  1258. * Batch pool, stores unused batches for preventing allocations.
  1259. * @memberof PIXI.graphicsUtils
  1260. * @member {Array<PIXI.graphicsUtils.BatchPart>} BATCH_POOL
  1261. */
  1262. var BATCH_POOL = [];
  1263. /**
  1264. * Draw call pool, stores unused draw calls for preventing allocations.
  1265. * @memberof PIXI.graphicsUtils
  1266. * @member {Array<PIXI.BatchDrawCall>} DRAW_CALL_POOL
  1267. */
  1268. var DRAW_CALL_POOL = [];
  1269. /**
  1270. * A class to contain data useful for Graphics objects
  1271. * @memberof PIXI
  1272. */
  1273. var GraphicsData = /** @class */ (function () {
  1274. /**
  1275. * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw.
  1276. * @param fillStyle - the width of the line to draw
  1277. * @param lineStyle - the color of the line to draw
  1278. * @param matrix - Transform matrix
  1279. */
  1280. function GraphicsData(shape, fillStyle, lineStyle, matrix) {
  1281. if (fillStyle === void 0) { fillStyle = null; }
  1282. if (lineStyle === void 0) { lineStyle = null; }
  1283. if (matrix === void 0) { matrix = null; }
  1284. /** The collection of points. */
  1285. this.points = [];
  1286. /** The collection of holes. */
  1287. this.holes = [];
  1288. this.shape = shape;
  1289. this.lineStyle = lineStyle;
  1290. this.fillStyle = fillStyle;
  1291. this.matrix = matrix;
  1292. this.type = shape.type;
  1293. }
  1294. /**
  1295. * Creates a new GraphicsData object with the same values as this one.
  1296. * @returns - Cloned GraphicsData object
  1297. */
  1298. GraphicsData.prototype.clone = function () {
  1299. return new GraphicsData(this.shape, this.fillStyle, this.lineStyle, this.matrix);
  1300. };
  1301. /** Destroys the Graphics data. */
  1302. GraphicsData.prototype.destroy = function () {
  1303. this.shape = null;
  1304. this.holes.length = 0;
  1305. this.holes = null;
  1306. this.points.length = 0;
  1307. this.points = null;
  1308. this.lineStyle = null;
  1309. this.fillStyle = null;
  1310. };
  1311. return GraphicsData;
  1312. }());
  1313. var tmpPoint = new Point();
  1314. /**
  1315. * The Graphics class contains methods used to draw primitive shapes such as lines, circles and
  1316. * rectangles to the display, and to color and fill them.
  1317. *
  1318. * GraphicsGeometry is designed to not be continually updating the geometry since it's expensive
  1319. * to re-tesselate using **earcut**. Consider using {@link PIXI.Mesh} for this use-case, it's much faster.
  1320. * @memberof PIXI
  1321. */
  1322. var GraphicsGeometry = /** @class */ (function (_super) {
  1323. __extends(GraphicsGeometry, _super);
  1324. // eslint-disable-next-line @typescript-eslint/no-useless-constructor
  1325. function GraphicsGeometry() {
  1326. var _this = _super.call(this) || this;
  1327. /** Minimal distance between points that are considered different. Affects line tesselation. */
  1328. _this.closePointEps = 1e-4;
  1329. /** Padding to add to the bounds. */
  1330. _this.boundsPadding = 0;
  1331. _this.uvsFloat32 = null;
  1332. _this.indicesUint16 = null;
  1333. _this.batchable = false;
  1334. /** An array of points to draw, 2 numbers per point */
  1335. _this.points = [];
  1336. /** The collection of colors */
  1337. _this.colors = [];
  1338. /** The UVs collection */
  1339. _this.uvs = [];
  1340. /** The indices of the vertices */
  1341. _this.indices = [];
  1342. /** Reference to the texture IDs. */
  1343. _this.textureIds = [];
  1344. /**
  1345. * The collection of drawn shapes.
  1346. * @member {PIXI.GraphicsData[]}
  1347. */
  1348. _this.graphicsData = [];
  1349. /**
  1350. * List of current draw calls drived from the batches.
  1351. * @member {PIXI.BatchDrawCall[]}
  1352. */
  1353. _this.drawCalls = [];
  1354. /** Batches need to regenerated if the geometry is updated. */
  1355. _this.batchDirty = -1;
  1356. /**
  1357. * Intermediate abstract format sent to batch system.
  1358. * Can be converted to drawCalls or to batchable objects.
  1359. * @member {PIXI.graphicsUtils.BatchPart[]}
  1360. */
  1361. _this.batches = [];
  1362. /** Used to detect if the graphics object has changed. */
  1363. _this.dirty = 0;
  1364. /** Used to check if the cache is dirty. */
  1365. _this.cacheDirty = -1;
  1366. /** Used to detect if we cleared the graphicsData. */
  1367. _this.clearDirty = 0;
  1368. /** Index of the last batched shape in the stack of calls. */
  1369. _this.shapeIndex = 0;
  1370. /** Cached bounds. */
  1371. _this._bounds = new Bounds();
  1372. /** The bounds dirty flag. */
  1373. _this.boundsDirty = -1;
  1374. return _this;
  1375. }
  1376. Object.defineProperty(GraphicsGeometry.prototype, "bounds", {
  1377. /**
  1378. * Get the current bounds of the graphic geometry.
  1379. * @readonly
  1380. */
  1381. get: function () {
  1382. this.updateBatches();
  1383. if (this.boundsDirty !== this.dirty) {
  1384. this.boundsDirty = this.dirty;
  1385. this.calculateBounds();
  1386. }
  1387. return this._bounds;
  1388. },
  1389. enumerable: false,
  1390. configurable: true
  1391. });
  1392. /** Call if you changed graphicsData manually. Empties all batch buffers. */
  1393. GraphicsGeometry.prototype.invalidate = function () {
  1394. this.boundsDirty = -1;
  1395. this.dirty++;
  1396. this.batchDirty++;
  1397. this.shapeIndex = 0;
  1398. this.points.length = 0;
  1399. this.colors.length = 0;
  1400. this.uvs.length = 0;
  1401. this.indices.length = 0;
  1402. this.textureIds.length = 0;
  1403. for (var i = 0; i < this.drawCalls.length; i++) {
  1404. this.drawCalls[i].texArray.clear();
  1405. DRAW_CALL_POOL.push(this.drawCalls[i]);
  1406. }
  1407. this.drawCalls.length = 0;
  1408. for (var i = 0; i < this.batches.length; i++) {
  1409. var batchPart = this.batches[i];
  1410. batchPart.reset();
  1411. BATCH_POOL.push(batchPart);
  1412. }
  1413. this.batches.length = 0;
  1414. };
  1415. /**
  1416. * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
  1417. * @returns - This GraphicsGeometry object. Good for chaining method calls
  1418. */
  1419. GraphicsGeometry.prototype.clear = function () {
  1420. if (this.graphicsData.length > 0) {
  1421. this.invalidate();
  1422. this.clearDirty++;
  1423. this.graphicsData.length = 0;
  1424. }
  1425. return this;
  1426. };
  1427. /**
  1428. * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon.
  1429. * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw.
  1430. * @param fillStyle - Defines style of the fill.
  1431. * @param lineStyle - Defines style of the lines.
  1432. * @param matrix - Transform applied to the points of the shape.
  1433. * @returns - Returns geometry for chaining.
  1434. */
  1435. GraphicsGeometry.prototype.drawShape = function (shape, fillStyle, lineStyle, matrix) {
  1436. if (fillStyle === void 0) { fillStyle = null; }
  1437. if (lineStyle === void 0) { lineStyle = null; }
  1438. if (matrix === void 0) { matrix = null; }
  1439. var data = new GraphicsData(shape, fillStyle, lineStyle, matrix);
  1440. this.graphicsData.push(data);
  1441. this.dirty++;
  1442. return this;
  1443. };
  1444. /**
  1445. * Draws the given shape to this Graphics object. Can be any of Circle, Rectangle, Ellipse, Line or Polygon.
  1446. * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - The shape object to draw.
  1447. * @param matrix - Transform applied to the points of the shape.
  1448. * @returns - Returns geometry for chaining.
  1449. */
  1450. GraphicsGeometry.prototype.drawHole = function (shape, matrix) {
  1451. if (matrix === void 0) { matrix = null; }
  1452. if (!this.graphicsData.length) {
  1453. return null;
  1454. }
  1455. var data = new GraphicsData(shape, null, null, matrix);
  1456. var lastShape = this.graphicsData[this.graphicsData.length - 1];
  1457. data.lineStyle = lastShape.lineStyle;
  1458. lastShape.holes.push(data);
  1459. this.dirty++;
  1460. return this;
  1461. };
  1462. /** Destroys the GraphicsGeometry object. */
  1463. GraphicsGeometry.prototype.destroy = function () {
  1464. _super.prototype.destroy.call(this);
  1465. // destroy each of the GraphicsData objects
  1466. for (var i = 0; i < this.graphicsData.length; ++i) {
  1467. this.graphicsData[i].destroy();
  1468. }
  1469. this.points.length = 0;
  1470. this.points = null;
  1471. this.colors.length = 0;
  1472. this.colors = null;
  1473. this.uvs.length = 0;
  1474. this.uvs = null;
  1475. this.indices.length = 0;
  1476. this.indices = null;
  1477. this.indexBuffer.destroy();
  1478. this.indexBuffer = null;
  1479. this.graphicsData.length = 0;
  1480. this.graphicsData = null;
  1481. this.drawCalls.length = 0;
  1482. this.drawCalls = null;
  1483. this.batches.length = 0;
  1484. this.batches = null;
  1485. this._bounds = null;
  1486. };
  1487. /**
  1488. * Check to see if a point is contained within this geometry.
  1489. * @param point - Point to check if it's contained.
  1490. * @returns {boolean} `true` if the point is contained within geometry.
  1491. */
  1492. GraphicsGeometry.prototype.containsPoint = function (point) {
  1493. var graphicsData = this.graphicsData;
  1494. for (var i = 0; i < graphicsData.length; ++i) {
  1495. var data = graphicsData[i];
  1496. if (!data.fillStyle.visible) {
  1497. continue;
  1498. }
  1499. // only deal with fills..
  1500. if (data.shape) {
  1501. if (data.matrix) {
  1502. data.matrix.applyInverse(point, tmpPoint);
  1503. }
  1504. else {
  1505. tmpPoint.copyFrom(point);
  1506. }
  1507. if (data.shape.contains(tmpPoint.x, tmpPoint.y)) {
  1508. var hitHole = false;
  1509. if (data.holes) {
  1510. for (var i_1 = 0; i_1 < data.holes.length; i_1++) {
  1511. var hole = data.holes[i_1];
  1512. if (hole.shape.contains(tmpPoint.x, tmpPoint.y)) {
  1513. hitHole = true;
  1514. break;
  1515. }
  1516. }
  1517. }
  1518. if (!hitHole) {
  1519. return true;
  1520. }
  1521. }
  1522. }
  1523. }
  1524. return false;
  1525. };
  1526. /**
  1527. * Generates intermediate batch data. Either gets converted to drawCalls
  1528. * or used to convert to batch objects directly by the Graphics object.
  1529. */
  1530. GraphicsGeometry.prototype.updateBatches = function () {
  1531. if (!this.graphicsData.length) {
  1532. this.batchable = true;
  1533. return;
  1534. }
  1535. if (!this.validateBatching()) {
  1536. return;
  1537. }
  1538. this.cacheDirty = this.dirty;
  1539. var uvs = this.uvs;
  1540. var graphicsData = this.graphicsData;
  1541. var batchPart = null;
  1542. var currentStyle = null;
  1543. if (this.batches.length > 0) {
  1544. batchPart = this.batches[this.batches.length - 1];
  1545. currentStyle = batchPart.style;
  1546. }
  1547. for (var i = this.shapeIndex; i < graphicsData.length; i++) {
  1548. this.shapeIndex++;
  1549. var data = graphicsData[i];
  1550. var fillStyle = data.fillStyle;
  1551. var lineStyle = data.lineStyle;
  1552. var command = FILL_COMMANDS[data.type];
  1553. // build out the shapes points..
  1554. command.build(data);
  1555. if (data.matrix) {
  1556. this.transformPoints(data.points, data.matrix);
  1557. }
  1558. if (fillStyle.visible || lineStyle.visible) {
  1559. this.processHoles(data.holes);
  1560. }
  1561. for (var j = 0; j < 2; j++) {
  1562. var style = (j === 0) ? fillStyle : lineStyle;
  1563. if (!style.visible)
  1564. { continue; }
  1565. var nextTexture = style.texture.baseTexture;
  1566. var index_1 = this.indices.length;
  1567. var attribIndex = this.points.length / 2;
  1568. nextTexture.wrapMode = WRAP_MODES.REPEAT;
  1569. if (j === 0) {
  1570. this.processFill(data);
  1571. }
  1572. else {
  1573. this.processLine(data);
  1574. }
  1575. var size = (this.points.length / 2) - attribIndex;
  1576. if (size === 0)
  1577. { continue; }
  1578. // close batch if style is different
  1579. if (batchPart && !this._compareStyles(currentStyle, style)) {
  1580. batchPart.end(index_1, attribIndex);
  1581. batchPart = null;
  1582. }
  1583. // spawn new batch if its first batch or previous was closed
  1584. if (!batchPart) {
  1585. batchPart = BATCH_POOL.pop() || new BatchPart();
  1586. batchPart.begin(style, index_1, attribIndex);
  1587. this.batches.push(batchPart);
  1588. currentStyle = style;
  1589. }
  1590. this.addUvs(this.points, uvs, style.texture, attribIndex, size, style.matrix);
  1591. }
  1592. }
  1593. var index = this.indices.length;
  1594. var attrib = this.points.length / 2;
  1595. if (batchPart) {
  1596. batchPart.end(index, attrib);
  1597. }
  1598. if (this.batches.length === 0) {
  1599. // there are no visible styles in GraphicsData
  1600. // its possible that someone wants Graphics just for the bounds
  1601. this.batchable = true;
  1602. return;
  1603. }
  1604. var need32 = attrib > 0xffff;
  1605. // prevent allocation when length is same as buffer
  1606. if (this.indicesUint16 && this.indices.length === this.indicesUint16.length
  1607. && need32 === (this.indicesUint16.BYTES_PER_ELEMENT > 2)) {
  1608. this.indicesUint16.set(this.indices);
  1609. }
  1610. else {
  1611. this.indicesUint16 = need32 ? new Uint32Array(this.indices) : new Uint16Array(this.indices);
  1612. }
  1613. // TODO make this a const..
  1614. this.batchable = this.isBatchable();
  1615. if (this.batchable) {
  1616. this.packBatches();
  1617. }
  1618. else {
  1619. this.buildDrawCalls();
  1620. }
  1621. };
  1622. /**
  1623. * Affinity check
  1624. * @param styleA
  1625. * @param styleB
  1626. */
  1627. GraphicsGeometry.prototype._compareStyles = function (styleA, styleB) {
  1628. if (!styleA || !styleB) {
  1629. return false;
  1630. }
  1631. if (styleA.texture.baseTexture !== styleB.texture.baseTexture) {
  1632. return false;
  1633. }
  1634. if (styleA.color + styleA.alpha !== styleB.color + styleB.alpha) {
  1635. return false;
  1636. }
  1637. if (!!styleA.native !== !!styleB.native) {
  1638. return false;
  1639. }
  1640. return true;
  1641. };
  1642. /** Test geometry for batching process. */
  1643. GraphicsGeometry.prototype.validateBatching = function () {
  1644. if (this.dirty === this.cacheDirty || !this.graphicsData.length) {
  1645. return false;
  1646. }
  1647. for (var i = 0, l = this.graphicsData.length; i < l; i++) {
  1648. var data = this.graphicsData[i];
  1649. var fill = data.fillStyle;
  1650. var line = data.lineStyle;
  1651. if (fill && !fill.texture.baseTexture.valid)
  1652. { return false; }
  1653. if (line && !line.texture.baseTexture.valid)
  1654. { return false; }
  1655. }
  1656. return true;
  1657. };
  1658. /** Offset the indices so that it works with the batcher. */
  1659. GraphicsGeometry.prototype.packBatches = function () {
  1660. this.batchDirty++;
  1661. this.uvsFloat32 = new Float32Array(this.uvs);
  1662. var batches = this.batches;
  1663. for (var i = 0, l = batches.length; i < l; i++) {
  1664. var batch = batches[i];
  1665. for (var j = 0; j < batch.size; j++) {
  1666. var index = batch.start + j;
  1667. this.indicesUint16[index] = this.indicesUint16[index] - batch.attribStart;
  1668. }
  1669. }
  1670. };
  1671. /**
  1672. * Checks to see if this graphics geometry can be batched.
  1673. * Currently it needs to be small enough and not contain any native lines.
  1674. */
  1675. GraphicsGeometry.prototype.isBatchable = function () {
  1676. // prevent heavy mesh batching
  1677. if (this.points.length > 0xffff * 2) {
  1678. return false;
  1679. }
  1680. var batches = this.batches;
  1681. for (var i = 0; i < batches.length; i++) {
  1682. if (batches[i].style.native) {
  1683. return false;
  1684. }
  1685. }
  1686. return (this.points.length < GraphicsGeometry.BATCHABLE_SIZE * 2);
  1687. };
  1688. /** Converts intermediate batches data to drawCalls. */
  1689. GraphicsGeometry.prototype.buildDrawCalls = function () {
  1690. var TICK = ++BaseTexture._globalBatch;
  1691. for (var i = 0; i < this.drawCalls.length; i++) {
  1692. this.drawCalls[i].texArray.clear();
  1693. DRAW_CALL_POOL.push(this.drawCalls[i]);
  1694. }
  1695. this.drawCalls.length = 0;
  1696. var colors = this.colors;
  1697. var textureIds = this.textureIds;
  1698. var currentGroup = DRAW_CALL_POOL.pop();
  1699. if (!currentGroup) {
  1700. currentGroup = new BatchDrawCall();
  1701. currentGroup.texArray = new BatchTextureArray();
  1702. }
  1703. currentGroup.texArray.count = 0;
  1704. currentGroup.start = 0;
  1705. currentGroup.size = 0;
  1706. currentGroup.type = DRAW_MODES.TRIANGLES;
  1707. var textureCount = 0;
  1708. var currentTexture = null;
  1709. var textureId = 0;
  1710. var native = false;
  1711. var drawMode = DRAW_MODES.TRIANGLES;
  1712. var index = 0;
  1713. this.drawCalls.push(currentGroup);
  1714. // TODO - this can be simplified
  1715. for (var i = 0; i < this.batches.length; i++) {
  1716. var data = this.batches[i];
  1717. // TODO add some full on MAX_TEXTURE CODE..
  1718. var MAX_TEXTURES = 8;
  1719. // Forced cast for checking `native` without errors
  1720. var style = data.style;
  1721. var nextTexture = style.texture.baseTexture;
  1722. if (native !== !!style.native) {
  1723. native = !!style.native;
  1724. drawMode = native ? DRAW_MODES.LINES : DRAW_MODES.TRIANGLES;
  1725. // force the batch to break!
  1726. currentTexture = null;
  1727. textureCount = MAX_TEXTURES;
  1728. TICK++;
  1729. }
  1730. if (currentTexture !== nextTexture) {
  1731. currentTexture = nextTexture;
  1732. if (nextTexture._batchEnabled !== TICK) {
  1733. if (textureCount === MAX_TEXTURES) {
  1734. TICK++;
  1735. textureCount = 0;
  1736. if (currentGroup.size > 0) {
  1737. currentGroup = DRAW_CALL_POOL.pop();
  1738. if (!currentGroup) {
  1739. currentGroup = new BatchDrawCall();
  1740. currentGroup.texArray = new BatchTextureArray();
  1741. }
  1742. this.drawCalls.push(currentGroup);
  1743. }
  1744. currentGroup.start = index;
  1745. currentGroup.size = 0;
  1746. currentGroup.texArray.count = 0;
  1747. currentGroup.type = drawMode;
  1748. }
  1749. // TODO add this to the render part..
  1750. // Hack! Because texture has protected `touched`
  1751. nextTexture.touched = 1; // touch;
  1752. nextTexture._batchEnabled = TICK;
  1753. nextTexture._batchLocation = textureCount;
  1754. nextTexture.wrapMode = WRAP_MODES.REPEAT;
  1755. currentGroup.texArray.elements[currentGroup.texArray.count++] = nextTexture;
  1756. textureCount++;
  1757. }
  1758. }
  1759. currentGroup.size += data.size;
  1760. index += data.size;
  1761. textureId = nextTexture._batchLocation;
  1762. this.addColors(colors, style.color, style.alpha, data.attribSize, data.attribStart);
  1763. this.addTextureIds(textureIds, textureId, data.attribSize, data.attribStart);
  1764. }
  1765. BaseTexture._globalBatch = TICK;
  1766. // upload..
  1767. // merge for now!
  1768. this.packAttributes();
  1769. };
  1770. /** Packs attributes to single buffer. */
  1771. GraphicsGeometry.prototype.packAttributes = function () {
  1772. var verts = this.points;
  1773. var uvs = this.uvs;
  1774. var colors = this.colors;
  1775. var textureIds = this.textureIds;
  1776. // verts are 2 positions.. so we * by 3 as there are 6 properties.. then 4 cos its bytes
  1777. var glPoints = new ArrayBuffer(verts.length * 3 * 4);
  1778. var f32 = new Float32Array(glPoints);
  1779. var u32 = new Uint32Array(glPoints);
  1780. var p = 0;
  1781. for (var i = 0; i < verts.length / 2; i++) {
  1782. f32[p++] = verts[i * 2];
  1783. f32[p++] = verts[(i * 2) + 1];
  1784. f32[p++] = uvs[i * 2];
  1785. f32[p++] = uvs[(i * 2) + 1];
  1786. u32[p++] = colors[i];
  1787. f32[p++] = textureIds[i];
  1788. }
  1789. this._buffer.update(glPoints);
  1790. this._indexBuffer.update(this.indicesUint16);
  1791. };
  1792. /**
  1793. * Process fill part of Graphics.
  1794. * @param data
  1795. */
  1796. GraphicsGeometry.prototype.processFill = function (data) {
  1797. if (data.holes.length) {
  1798. buildPoly.triangulate(data, this);
  1799. }
  1800. else {
  1801. var command = FILL_COMMANDS[data.type];
  1802. command.triangulate(data, this);
  1803. }
  1804. };
  1805. /**
  1806. * Process line part of Graphics.
  1807. * @param data
  1808. */
  1809. GraphicsGeometry.prototype.processLine = function (data) {
  1810. buildLine(data, this);
  1811. for (var i = 0; i < data.holes.length; i++) {
  1812. buildLine(data.holes[i], this);
  1813. }
  1814. };
  1815. /**
  1816. * Process the holes data.
  1817. * @param holes
  1818. */
  1819. GraphicsGeometry.prototype.processHoles = function (holes) {
  1820. for (var i = 0; i < holes.length; i++) {
  1821. var hole = holes[i];
  1822. var command = FILL_COMMANDS[hole.type];
  1823. command.build(hole);
  1824. if (hole.matrix) {
  1825. this.transformPoints(hole.points, hole.matrix);
  1826. }
  1827. }
  1828. };
  1829. /** Update the local bounds of the object. Expensive to use performance-wise. */
  1830. GraphicsGeometry.prototype.calculateBounds = function () {
  1831. var bounds = this._bounds;
  1832. bounds.clear();
  1833. bounds.addVertexData(this.points, 0, this.points.length);
  1834. bounds.pad(this.boundsPadding, this.boundsPadding);
  1835. };
  1836. /**
  1837. * Transform points using matrix.
  1838. * @param points - Points to transform
  1839. * @param matrix - Transform matrix
  1840. */
  1841. GraphicsGeometry.prototype.transformPoints = function (points, matrix) {
  1842. for (var i = 0; i < points.length / 2; i++) {
  1843. var x = points[(i * 2)];
  1844. var y = points[(i * 2) + 1];
  1845. points[(i * 2)] = (matrix.a * x) + (matrix.c * y) + matrix.tx;
  1846. points[(i * 2) + 1] = (matrix.b * x) + (matrix.d * y) + matrix.ty;
  1847. }
  1848. };
  1849. /**
  1850. * Add colors.
  1851. * @param colors - List of colors to add to
  1852. * @param color - Color to add
  1853. * @param alpha - Alpha to use
  1854. * @param size - Number of colors to add
  1855. * @param offset
  1856. */
  1857. GraphicsGeometry.prototype.addColors = function (colors, color, alpha, size, offset) {
  1858. if (offset === void 0) { offset = 0; }
  1859. // TODO use the premultiply bits Ivan added
  1860. var rgb = (color >> 16) + (color & 0xff00) + ((color & 0xff) << 16);
  1861. var rgba = premultiplyTint(rgb, alpha);
  1862. colors.length = Math.max(colors.length, offset + size);
  1863. for (var i = 0; i < size; i++) {
  1864. colors[offset + i] = rgba;
  1865. }
  1866. };
  1867. /**
  1868. * Add texture id that the shader/fragment wants to use.
  1869. * @param textureIds
  1870. * @param id
  1871. * @param size
  1872. * @param offset
  1873. */
  1874. GraphicsGeometry.prototype.addTextureIds = function (textureIds, id, size, offset) {
  1875. if (offset === void 0) { offset = 0; }
  1876. textureIds.length = Math.max(textureIds.length, offset + size);
  1877. for (var i = 0; i < size; i++) {
  1878. textureIds[offset + i] = id;
  1879. }
  1880. };
  1881. /**
  1882. * Generates the UVs for a shape.
  1883. * @param verts - Vertices
  1884. * @param uvs - UVs
  1885. * @param texture - Reference to Texture
  1886. * @param start - Index buffer start index.
  1887. * @param size - The size/length for index buffer.
  1888. * @param matrix - Optional transform for all points.
  1889. */
  1890. GraphicsGeometry.prototype.addUvs = function (verts, uvs, texture, start, size, matrix) {
  1891. if (matrix === void 0) { matrix = null; }
  1892. var index = 0;
  1893. var uvsStart = uvs.length;
  1894. var frame = texture.frame;
  1895. while (index < size) {
  1896. var x = verts[(start + index) * 2];
  1897. var y = verts[((start + index) * 2) + 1];
  1898. if (matrix) {
  1899. var nx = (matrix.a * x) + (matrix.c * y) + matrix.tx;
  1900. y = (matrix.b * x) + (matrix.d * y) + matrix.ty;
  1901. x = nx;
  1902. }
  1903. index++;
  1904. uvs.push(x / frame.width, y / frame.height);
  1905. }
  1906. var baseTexture = texture.baseTexture;
  1907. if (frame.width < baseTexture.width
  1908. || frame.height < baseTexture.height) {
  1909. this.adjustUvs(uvs, texture, uvsStart, size);
  1910. }
  1911. };
  1912. /**
  1913. * Modify uvs array according to position of texture region
  1914. * Does not work with rotated or trimmed textures
  1915. * @param uvs - array
  1916. * @param texture - region
  1917. * @param start - starting index for uvs
  1918. * @param size - how many points to adjust
  1919. */
  1920. GraphicsGeometry.prototype.adjustUvs = function (uvs, texture, start, size) {
  1921. var baseTexture = texture.baseTexture;
  1922. var eps = 1e-6;
  1923. var finish = start + (size * 2);
  1924. var frame = texture.frame;
  1925. var scaleX = frame.width / baseTexture.width;
  1926. var scaleY = frame.height / baseTexture.height;
  1927. var offsetX = frame.x / frame.width;
  1928. var offsetY = frame.y / frame.height;
  1929. var minX = Math.floor(uvs[start] + eps);
  1930. var minY = Math.floor(uvs[start + 1] + eps);
  1931. for (var i = start + 2; i < finish; i += 2) {
  1932. minX = Math.min(minX, Math.floor(uvs[i] + eps));
  1933. minY = Math.min(minY, Math.floor(uvs[i + 1] + eps));
  1934. }
  1935. offsetX -= minX;
  1936. offsetY -= minY;
  1937. for (var i = start; i < finish; i += 2) {
  1938. uvs[i] = (uvs[i] + offsetX) * scaleX;
  1939. uvs[i + 1] = (uvs[i + 1] + offsetY) * scaleY;
  1940. }
  1941. };
  1942. /**
  1943. * The maximum number of points to consider an object "batchable",
  1944. * able to be batched by the renderer's batch system.
  1945. \
  1946. */
  1947. GraphicsGeometry.BATCHABLE_SIZE = 100;
  1948. return GraphicsGeometry;
  1949. }(BatchGeometry));
  1950. /**
  1951. * Represents the line style for Graphics.
  1952. * @memberof PIXI
  1953. */
  1954. var LineStyle = /** @class */ (function (_super) {
  1955. __extends(LineStyle, _super);
  1956. function LineStyle() {
  1957. var _this = _super !== null && _super.apply(this, arguments) || this;
  1958. /** The width (thickness) of any lines drawn. */
  1959. _this.width = 0;
  1960. /** The alignment of any lines drawn (0.5 = middle, 1 = outer, 0 = inner). WebGL only. */
  1961. _this.alignment = 0.5;
  1962. /** If true the lines will be draw using LINES instead of TRIANGLE_STRIP. */
  1963. _this.native = false;
  1964. /**
  1965. * Line cap style.
  1966. * @member {PIXI.LINE_CAP}
  1967. * @default PIXI.LINE_CAP.BUTT
  1968. */
  1969. _this.cap = LINE_CAP.BUTT;
  1970. /**
  1971. * Line join style.
  1972. * @member {PIXI.LINE_JOIN}
  1973. * @default PIXI.LINE_JOIN.MITER
  1974. */
  1975. _this.join = LINE_JOIN.MITER;
  1976. /** Miter limit. */
  1977. _this.miterLimit = 10;
  1978. return _this;
  1979. }
  1980. /** Clones the object. */
  1981. LineStyle.prototype.clone = function () {
  1982. var obj = new LineStyle();
  1983. obj.color = this.color;
  1984. obj.alpha = this.alpha;
  1985. obj.texture = this.texture;
  1986. obj.matrix = this.matrix;
  1987. obj.visible = this.visible;
  1988. obj.width = this.width;
  1989. obj.alignment = this.alignment;
  1990. obj.native = this.native;
  1991. obj.cap = this.cap;
  1992. obj.join = this.join;
  1993. obj.miterLimit = this.miterLimit;
  1994. return obj;
  1995. };
  1996. /** Reset the line style to default. */
  1997. LineStyle.prototype.reset = function () {
  1998. _super.prototype.reset.call(this);
  1999. // Override default line style color
  2000. this.color = 0x0;
  2001. this.alignment = 0.5;
  2002. this.width = 0;
  2003. this.native = false;
  2004. };
  2005. return LineStyle;
  2006. }(FillStyle));
  2007. var temp = new Float32Array(3);
  2008. // a default shaders map used by graphics..
  2009. var DEFAULT_SHADERS = {};
  2010. /**
  2011. * The Graphics class is primarily used to render primitive shapes such as lines, circles and
  2012. * rectangles to the display, and to color and fill them. However, you can also use a Graphics
  2013. * object to build a list of primitives to use as a mask, or as a complex hitArea.
  2014. *
  2015. * Please note that due to legacy naming conventions, the behavior of some functions in this class
  2016. * can be confusing. Each call to `drawRect()`, `drawPolygon()`, etc. actually stores that primitive
  2017. * in the Geometry class's GraphicsGeometry object for later use in rendering or hit testing - the
  2018. * functions do not directly draw anything to the screen. Similarly, the `clear()` function doesn't
  2019. * change the screen, it simply resets the list of primitives, which can be useful if you want to
  2020. * rebuild the contents of an existing Graphics object.
  2021. *
  2022. * Once a GraphicsGeometry list is built, you can re-use it in other Geometry objects as
  2023. * an optimization, by passing it into a new Geometry object's constructor. Because of this
  2024. * ability, it's important to call `destroy()` on Geometry objects once you are done with them, to
  2025. * properly dereference each GraphicsGeometry and prevent memory leaks.
  2026. * @memberof PIXI
  2027. */
  2028. var Graphics = /** @class */ (function (_super) {
  2029. __extends(Graphics, _super);
  2030. /**
  2031. * @param geometry - Geometry to use, if omitted will create a new GraphicsGeometry instance.
  2032. */
  2033. function Graphics(geometry) {
  2034. if (geometry === void 0) { geometry = null; }
  2035. var _this = _super.call(this) || this;
  2036. /**
  2037. * Represents the vertex and fragment shaders that processes the geometry and runs on the GPU.
  2038. * Can be shared between multiple Graphics objects.
  2039. */
  2040. _this.shader = null;
  2041. /** Renderer plugin for batching */
  2042. _this.pluginName = 'batch';
  2043. /**
  2044. * Current path
  2045. * @readonly
  2046. */
  2047. _this.currentPath = null;
  2048. /** A collections of batches! These can be drawn by the renderer batch system. */
  2049. _this.batches = [];
  2050. /** Update dirty for limiting calculating tints for batches. */
  2051. _this.batchTint = -1;
  2052. /** Update dirty for limiting calculating batches.*/
  2053. _this.batchDirty = -1;
  2054. /** Copy of the object vertex data. */
  2055. _this.vertexData = null;
  2056. /** Current fill style. */
  2057. _this._fillStyle = new FillStyle();
  2058. /** Current line style. */
  2059. _this._lineStyle = new LineStyle();
  2060. /** Current shape transform matrix. */
  2061. _this._matrix = null;
  2062. /** Current hole mode is enabled. */
  2063. _this._holeMode = false;
  2064. /**
  2065. * Represents the WebGL state the Graphics required to render, excludes shader and geometry. E.g.,
  2066. * blend mode, culling, depth testing, direction of rendering triangles, backface, etc.
  2067. */
  2068. _this.state = State.for2d();
  2069. _this._geometry = geometry || new GraphicsGeometry();
  2070. _this._geometry.refCount++;
  2071. /**
  2072. * When cacheAsBitmap is set to true the graphics object will be rendered as if it was a sprite.
  2073. * This is useful if your graphics element does not change often, as it will speed up the rendering
  2074. * of the object in exchange for taking up texture memory. It is also useful if you need the graphics
  2075. * object to be anti-aliased, because it will be rendered using canvas. This is not recommended if
  2076. * you are constantly redrawing the graphics element.
  2077. * @name cacheAsBitmap
  2078. * @member {boolean}
  2079. * @memberof PIXI.Graphics#
  2080. * @default false
  2081. */
  2082. _this._transformID = -1;
  2083. // Set default
  2084. _this.tint = 0xFFFFFF;
  2085. _this.blendMode = BLEND_MODES.NORMAL;
  2086. return _this;
  2087. }
  2088. Object.defineProperty(Graphics.prototype, "geometry", {
  2089. /**
  2090. * Includes vertex positions, face indices, normals, colors, UVs, and
  2091. * custom attributes within buffers, reducing the cost of passing all
  2092. * this data to the GPU. Can be shared between multiple Mesh or Graphics objects.
  2093. * @readonly
  2094. */
  2095. get: function () {
  2096. return this._geometry;
  2097. },
  2098. enumerable: false,
  2099. configurable: true
  2100. });
  2101. /**
  2102. * Creates a new Graphics object with the same values as this one.
  2103. * Note that only the geometry of the object is cloned, not its transform (position,scale,etc)
  2104. * @returns - A clone of the graphics object
  2105. */
  2106. Graphics.prototype.clone = function () {
  2107. this.finishPoly();
  2108. return new Graphics(this._geometry);
  2109. };
  2110. Object.defineProperty(Graphics.prototype, "blendMode", {
  2111. get: function () {
  2112. return this.state.blendMode;
  2113. },
  2114. /**
  2115. * The blend mode to be applied to the graphic shape. Apply a value of
  2116. * `PIXI.BLEND_MODES.NORMAL` to reset the blend mode. Note that, since each
  2117. * primitive in the GraphicsGeometry list is rendered sequentially, modes
  2118. * such as `PIXI.BLEND_MODES.ADD` and `PIXI.BLEND_MODES.MULTIPLY` will
  2119. * be applied per-primitive.
  2120. * @default PIXI.BLEND_MODES.NORMAL
  2121. */
  2122. set: function (value) {
  2123. this.state.blendMode = value;
  2124. },
  2125. enumerable: false,
  2126. configurable: true
  2127. });
  2128. Object.defineProperty(Graphics.prototype, "tint", {
  2129. /**
  2130. * The tint applied to each graphic shape. This is a hex value. A value of
  2131. * 0xFFFFFF will remove any tint effect.
  2132. * @default 0xFFFFFF
  2133. */
  2134. get: function () {
  2135. return this._tint;
  2136. },
  2137. set: function (value) {
  2138. this._tint = value;
  2139. },
  2140. enumerable: false,
  2141. configurable: true
  2142. });
  2143. Object.defineProperty(Graphics.prototype, "fill", {
  2144. /**
  2145. * The current fill style.
  2146. * @readonly
  2147. */
  2148. get: function () {
  2149. return this._fillStyle;
  2150. },
  2151. enumerable: false,
  2152. configurable: true
  2153. });
  2154. Object.defineProperty(Graphics.prototype, "line", {
  2155. /**
  2156. * The current line style.
  2157. * @readonly
  2158. */
  2159. get: function () {
  2160. return this._lineStyle;
  2161. },
  2162. enumerable: false,
  2163. configurable: true
  2164. });
  2165. Graphics.prototype.lineStyle = function (options, color, alpha, alignment, native) {
  2166. if (options === void 0) { options = null; }
  2167. if (color === void 0) { color = 0x0; }
  2168. if (alpha === void 0) { alpha = 1; }
  2169. if (alignment === void 0) { alignment = 0.5; }
  2170. if (native === void 0) { native = false; }
  2171. // Support non-object params: (width, color, alpha, alignment, native)
  2172. if (typeof options === 'number') {
  2173. options = { width: options, color: color, alpha: alpha, alignment: alignment, native: native };
  2174. }
  2175. return this.lineTextureStyle(options);
  2176. };
  2177. /**
  2178. * Like line style but support texture for line fill.
  2179. * @param [options] - Collection of options for setting line style.
  2180. * @param {number} [options.width=0] - width of the line to draw, will update the objects stored style
  2181. * @param {PIXI.Texture} [options.texture=PIXI.Texture.WHITE] - Texture to use
  2182. * @param {number} [options.color=0x0] - color of the line to draw, will update the objects stored style.
  2183. * Default 0xFFFFFF if texture present.
  2184. * @param {number} [options.alpha=1] - alpha of the line to draw, will update the objects stored style
  2185. * @param {PIXI.Matrix} [options.matrix=null] - Texture matrix to transform texture
  2186. * @param {number} [options.alignment=0.5] - alignment of the line to draw, (0 = inner, 0.5 = middle, 1 = outer).
  2187. * WebGL only.
  2188. * @param {boolean} [options.native=false] - If true the lines will be draw using LINES instead of TRIANGLE_STRIP
  2189. * @param {PIXI.LINE_CAP}[options.cap=PIXI.LINE_CAP.BUTT] - line cap style
  2190. * @param {PIXI.LINE_JOIN}[options.join=PIXI.LINE_JOIN.MITER] - line join style
  2191. * @param {number}[options.miterLimit=10] - miter limit ratio
  2192. * @returns {PIXI.Graphics} This Graphics object. Good for chaining method calls
  2193. */
  2194. Graphics.prototype.lineTextureStyle = function (options) {
  2195. // Apply defaults
  2196. options = Object.assign({
  2197. width: 0,
  2198. texture: Texture.WHITE,
  2199. color: (options && options.texture) ? 0xFFFFFF : 0x0,
  2200. alpha: 1,
  2201. matrix: null,
  2202. alignment: 0.5,
  2203. native: false,
  2204. cap: LINE_CAP.BUTT,
  2205. join: LINE_JOIN.MITER,
  2206. miterLimit: 10,
  2207. }, options);
  2208. if (this.currentPath) {
  2209. this.startPoly();
  2210. }
  2211. var visible = options.width > 0 && options.alpha > 0;
  2212. if (!visible) {
  2213. this._lineStyle.reset();
  2214. }
  2215. else {
  2216. if (options.matrix) {
  2217. options.matrix = options.matrix.clone();
  2218. options.matrix.invert();
  2219. }
  2220. Object.assign(this._lineStyle, { visible: visible }, options);
  2221. }
  2222. return this;
  2223. };
  2224. /**
  2225. * Start a polygon object internally.
  2226. * @protected
  2227. */
  2228. Graphics.prototype.startPoly = function () {
  2229. if (this.currentPath) {
  2230. var points = this.currentPath.points;
  2231. var len = this.currentPath.points.length;
  2232. if (len > 2) {
  2233. this.drawShape(this.currentPath);
  2234. this.currentPath = new Polygon();
  2235. this.currentPath.closeStroke = false;
  2236. this.currentPath.points.push(points[len - 2], points[len - 1]);
  2237. }
  2238. }
  2239. else {
  2240. this.currentPath = new Polygon();
  2241. this.currentPath.closeStroke = false;
  2242. }
  2243. };
  2244. /**
  2245. * Finish the polygon object.
  2246. * @protected
  2247. */
  2248. Graphics.prototype.finishPoly = function () {
  2249. if (this.currentPath) {
  2250. if (this.currentPath.points.length > 2) {
  2251. this.drawShape(this.currentPath);
  2252. this.currentPath = null;
  2253. }
  2254. else {
  2255. this.currentPath.points.length = 0;
  2256. }
  2257. }
  2258. };
  2259. /**
  2260. * Moves the current drawing position to x, y.
  2261. * @param x - the X coordinate to move to
  2262. * @param y - the Y coordinate to move to
  2263. * @returns - This Graphics object. Good for chaining method calls
  2264. */
  2265. Graphics.prototype.moveTo = function (x, y) {
  2266. this.startPoly();
  2267. this.currentPath.points[0] = x;
  2268. this.currentPath.points[1] = y;
  2269. return this;
  2270. };
  2271. /**
  2272. * Draws a line using the current line style from the current drawing position to (x, y);
  2273. * The current drawing position is then set to (x, y).
  2274. * @param x - the X coordinate to draw to
  2275. * @param y - the Y coordinate to draw to
  2276. * @returns - This Graphics object. Good for chaining method calls
  2277. */
  2278. Graphics.prototype.lineTo = function (x, y) {
  2279. if (!this.currentPath) {
  2280. this.moveTo(0, 0);
  2281. }
  2282. // remove duplicates..
  2283. var points = this.currentPath.points;
  2284. var fromX = points[points.length - 2];
  2285. var fromY = points[points.length - 1];
  2286. if (fromX !== x || fromY !== y) {
  2287. points.push(x, y);
  2288. }
  2289. return this;
  2290. };
  2291. /**
  2292. * Initialize the curve
  2293. * @param x
  2294. * @param y
  2295. */
  2296. Graphics.prototype._initCurve = function (x, y) {
  2297. if (x === void 0) { x = 0; }
  2298. if (y === void 0) { y = 0; }
  2299. if (this.currentPath) {
  2300. if (this.currentPath.points.length === 0) {
  2301. this.currentPath.points = [x, y];
  2302. }
  2303. }
  2304. else {
  2305. this.moveTo(x, y);
  2306. }
  2307. };
  2308. /**
  2309. * Calculate the points for a quadratic bezier curve and then draws it.
  2310. * Based on: https://stackoverflow.com/questions/785097/how-do-i-implement-a-bezier-curve-in-c
  2311. * @param cpX - Control point x
  2312. * @param cpY - Control point y
  2313. * @param toX - Destination point x
  2314. * @param toY - Destination point y
  2315. * @returns - This Graphics object. Good for chaining method calls
  2316. */
  2317. Graphics.prototype.quadraticCurveTo = function (cpX, cpY, toX, toY) {
  2318. this._initCurve();
  2319. var points = this.currentPath.points;
  2320. if (points.length === 0) {
  2321. this.moveTo(0, 0);
  2322. }
  2323. QuadraticUtils.curveTo(cpX, cpY, toX, toY, points);
  2324. return this;
  2325. };
  2326. /**
  2327. * Calculate the points for a bezier curve and then draws it.
  2328. * @param cpX - Control point x
  2329. * @param cpY - Control point y
  2330. * @param cpX2 - Second Control point x
  2331. * @param cpY2 - Second Control point y
  2332. * @param toX - Destination point x
  2333. * @param toY - Destination point y
  2334. * @returns This Graphics object. Good for chaining method calls
  2335. */
  2336. Graphics.prototype.bezierCurveTo = function (cpX, cpY, cpX2, cpY2, toX, toY) {
  2337. this._initCurve();
  2338. BezierUtils.curveTo(cpX, cpY, cpX2, cpY2, toX, toY, this.currentPath.points);
  2339. return this;
  2340. };
  2341. /**
  2342. * The arcTo() method creates an arc/curve between two tangents on the canvas.
  2343. *
  2344. * "borrowed" from https://code.google.com/p/fxcanvas/ - thanks google!
  2345. * @param x1 - The x-coordinate of the first tangent point of the arc
  2346. * @param y1 - The y-coordinate of the first tangent point of the arc
  2347. * @param x2 - The x-coordinate of the end of the arc
  2348. * @param y2 - The y-coordinate of the end of the arc
  2349. * @param radius - The radius of the arc
  2350. * @returns - This Graphics object. Good for chaining method calls
  2351. */
  2352. Graphics.prototype.arcTo = function (x1, y1, x2, y2, radius) {
  2353. this._initCurve(x1, y1);
  2354. var points = this.currentPath.points;
  2355. var result = ArcUtils.curveTo(x1, y1, x2, y2, radius, points);
  2356. if (result) {
  2357. var cx = result.cx, cy = result.cy, radius_1 = result.radius, startAngle = result.startAngle, endAngle = result.endAngle, anticlockwise = result.anticlockwise;
  2358. this.arc(cx, cy, radius_1, startAngle, endAngle, anticlockwise);
  2359. }
  2360. return this;
  2361. };
  2362. /**
  2363. * The arc method creates an arc/curve (used to create circles, or parts of circles).
  2364. * @param cx - The x-coordinate of the center of the circle
  2365. * @param cy - The y-coordinate of the center of the circle
  2366. * @param radius - The radius of the circle
  2367. * @param startAngle - The starting angle, in radians (0 is at the 3 o'clock position
  2368. * of the arc's circle)
  2369. * @param endAngle - The ending angle, in radians
  2370. * @param anticlockwise - Specifies whether the drawing should be
  2371. * counter-clockwise or clockwise. False is default, and indicates clockwise, while true
  2372. * indicates counter-clockwise.
  2373. * @returns - This Graphics object. Good for chaining method calls
  2374. */
  2375. Graphics.prototype.arc = function (cx, cy, radius, startAngle, endAngle, anticlockwise) {
  2376. if (anticlockwise === void 0) { anticlockwise = false; }
  2377. if (startAngle === endAngle) {
  2378. return this;
  2379. }
  2380. if (!anticlockwise && endAngle <= startAngle) {
  2381. endAngle += PI_2;
  2382. }
  2383. else if (anticlockwise && startAngle <= endAngle) {
  2384. startAngle += PI_2;
  2385. }
  2386. var sweep = endAngle - startAngle;
  2387. if (sweep === 0) {
  2388. return this;
  2389. }
  2390. var startX = cx + (Math.cos(startAngle) * radius);
  2391. var startY = cy + (Math.sin(startAngle) * radius);
  2392. var eps = this._geometry.closePointEps;
  2393. // If the currentPath exists, take its points. Otherwise call `moveTo` to start a path.
  2394. var points = this.currentPath ? this.currentPath.points : null;
  2395. if (points) {
  2396. // TODO: make a better fix.
  2397. // We check how far our start is from the last existing point
  2398. var xDiff = Math.abs(points[points.length - 2] - startX);
  2399. var yDiff = Math.abs(points[points.length - 1] - startY);
  2400. if (xDiff < eps && yDiff < eps) ;
  2401. else {
  2402. points.push(startX, startY);
  2403. }
  2404. }
  2405. else {
  2406. this.moveTo(startX, startY);
  2407. points = this.currentPath.points;
  2408. }
  2409. ArcUtils.arc(startX, startY, cx, cy, radius, startAngle, endAngle, anticlockwise, points);
  2410. return this;
  2411. };
  2412. /**
  2413. * Specifies a simple one-color fill that subsequent calls to other Graphics methods
  2414. * (such as lineTo() or drawCircle()) use when drawing.
  2415. * @param color - the color of the fill
  2416. * @param alpha - the alpha of the fill
  2417. * @returns - This Graphics object. Good for chaining method calls
  2418. */
  2419. Graphics.prototype.beginFill = function (color, alpha) {
  2420. if (color === void 0) { color = 0; }
  2421. if (alpha === void 0) { alpha = 1; }
  2422. return this.beginTextureFill({ texture: Texture.WHITE, color: color, alpha: alpha });
  2423. };
  2424. /**
  2425. * Begin the texture fill
  2426. * @param options - Object object.
  2427. * @param {PIXI.Texture} [options.texture=PIXI.Texture.WHITE] - Texture to fill
  2428. * @param {number} [options.color=0xffffff] - Background to fill behind texture
  2429. * @param {number} [options.alpha=1] - Alpha of fill
  2430. * @param {PIXI.Matrix} [options.matrix=null] - Transform matrix
  2431. * @returns {PIXI.Graphics} This Graphics object. Good for chaining method calls
  2432. */
  2433. Graphics.prototype.beginTextureFill = function (options) {
  2434. // Apply defaults
  2435. options = Object.assign({
  2436. texture: Texture.WHITE,
  2437. color: 0xFFFFFF,
  2438. alpha: 1,
  2439. matrix: null,
  2440. }, options);
  2441. if (this.currentPath) {
  2442. this.startPoly();
  2443. }
  2444. var visible = options.alpha > 0;
  2445. if (!visible) {
  2446. this._fillStyle.reset();
  2447. }
  2448. else {
  2449. if (options.matrix) {
  2450. options.matrix = options.matrix.clone();
  2451. options.matrix.invert();
  2452. }
  2453. Object.assign(this._fillStyle, { visible: visible }, options);
  2454. }
  2455. return this;
  2456. };
  2457. /**
  2458. * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method.
  2459. * @returns - This Graphics object. Good for chaining method calls
  2460. */
  2461. Graphics.prototype.endFill = function () {
  2462. this.finishPoly();
  2463. this._fillStyle.reset();
  2464. return this;
  2465. };
  2466. /**
  2467. * Draws a rectangle shape.
  2468. * @param x - The X coord of the top-left of the rectangle
  2469. * @param y - The Y coord of the top-left of the rectangle
  2470. * @param width - The width of the rectangle
  2471. * @param height - The height of the rectangle
  2472. * @returns - This Graphics object. Good for chaining method calls
  2473. */
  2474. Graphics.prototype.drawRect = function (x, y, width, height) {
  2475. return this.drawShape(new Rectangle(x, y, width, height));
  2476. };
  2477. /**
  2478. * Draw a rectangle shape with rounded/beveled corners.
  2479. * @param x - The X coord of the top-left of the rectangle
  2480. * @param y - The Y coord of the top-left of the rectangle
  2481. * @param width - The width of the rectangle
  2482. * @param height - The height of the rectangle
  2483. * @param radius - Radius of the rectangle corners
  2484. * @returns - This Graphics object. Good for chaining method calls
  2485. */
  2486. Graphics.prototype.drawRoundedRect = function (x, y, width, height, radius) {
  2487. return this.drawShape(new RoundedRectangle(x, y, width, height, radius));
  2488. };
  2489. /**
  2490. * Draws a circle.
  2491. * @param x - The X coordinate of the center of the circle
  2492. * @param y - The Y coordinate of the center of the circle
  2493. * @param radius - The radius of the circle
  2494. * @returns - This Graphics object. Good for chaining method calls
  2495. */
  2496. Graphics.prototype.drawCircle = function (x, y, radius) {
  2497. return this.drawShape(new Circle(x, y, radius));
  2498. };
  2499. /**
  2500. * Draws an ellipse.
  2501. * @param x - The X coordinate of the center of the ellipse
  2502. * @param y - The Y coordinate of the center of the ellipse
  2503. * @param width - The half width of the ellipse
  2504. * @param height - The half height of the ellipse
  2505. * @returns - This Graphics object. Good for chaining method calls
  2506. */
  2507. Graphics.prototype.drawEllipse = function (x, y, width, height) {
  2508. return this.drawShape(new Ellipse(x, y, width, height));
  2509. };
  2510. /**
  2511. * Draws a polygon using the given path.
  2512. * @param {number[]|PIXI.IPointData[]|PIXI.Polygon} path - The path data used to construct the polygon.
  2513. * @returns - This Graphics object. Good for chaining method calls
  2514. */
  2515. Graphics.prototype.drawPolygon = function () {
  2516. var arguments$1 = arguments;
  2517. var path = [];
  2518. for (var _i = 0; _i < arguments.length; _i++) {
  2519. path[_i] = arguments$1[_i];
  2520. }
  2521. var points;
  2522. var closeStroke = true; // !!this._fillStyle;
  2523. var poly = path[0];
  2524. // check if data has points..
  2525. if (poly.points) {
  2526. closeStroke = poly.closeStroke;
  2527. points = poly.points;
  2528. }
  2529. else if (Array.isArray(path[0])) {
  2530. points = path[0];
  2531. }
  2532. else {
  2533. points = path;
  2534. }
  2535. var shape = new Polygon(points);
  2536. shape.closeStroke = closeStroke;
  2537. this.drawShape(shape);
  2538. return this;
  2539. };
  2540. /**
  2541. * Draw any shape.
  2542. * @param {PIXI.Circle|PIXI.Ellipse|PIXI.Polygon|PIXI.Rectangle|PIXI.RoundedRectangle} shape - Shape to draw
  2543. * @returns - This Graphics object. Good for chaining method calls
  2544. */
  2545. Graphics.prototype.drawShape = function (shape) {
  2546. if (!this._holeMode) {
  2547. this._geometry.drawShape(shape, this._fillStyle.clone(), this._lineStyle.clone(), this._matrix);
  2548. }
  2549. else {
  2550. this._geometry.drawHole(shape, this._matrix);
  2551. }
  2552. return this;
  2553. };
  2554. /**
  2555. * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings.
  2556. * @returns - This Graphics object. Good for chaining method calls
  2557. */
  2558. Graphics.prototype.clear = function () {
  2559. this._geometry.clear();
  2560. this._lineStyle.reset();
  2561. this._fillStyle.reset();
  2562. this._boundsID++;
  2563. this._matrix = null;
  2564. this._holeMode = false;
  2565. this.currentPath = null;
  2566. return this;
  2567. };
  2568. /**
  2569. * True if graphics consists of one rectangle, and thus, can be drawn like a Sprite and
  2570. * masked with gl.scissor.
  2571. * @returns - True if only 1 rect.
  2572. */
  2573. Graphics.prototype.isFastRect = function () {
  2574. var data = this._geometry.graphicsData;
  2575. return data.length === 1
  2576. && data[0].shape.type === SHAPES.RECT
  2577. && !data[0].matrix
  2578. && !data[0].holes.length
  2579. && !(data[0].lineStyle.visible && data[0].lineStyle.width);
  2580. };
  2581. /**
  2582. * Renders the object using the WebGL renderer
  2583. * @param renderer - The renderer
  2584. */
  2585. Graphics.prototype._render = function (renderer) {
  2586. this.finishPoly();
  2587. var geometry = this._geometry;
  2588. // batch part..
  2589. // batch it!
  2590. geometry.updateBatches();
  2591. if (geometry.batchable) {
  2592. if (this.batchDirty !== geometry.batchDirty) {
  2593. this._populateBatches();
  2594. }
  2595. this._renderBatched(renderer);
  2596. }
  2597. else {
  2598. // no batching...
  2599. renderer.batch.flush();
  2600. this._renderDirect(renderer);
  2601. }
  2602. };
  2603. /** Populating batches for rendering. */
  2604. Graphics.prototype._populateBatches = function () {
  2605. var geometry = this._geometry;
  2606. var blendMode = this.blendMode;
  2607. var len = geometry.batches.length;
  2608. this.batchTint = -1;
  2609. this._transformID = -1;
  2610. this.batchDirty = geometry.batchDirty;
  2611. this.batches.length = len;
  2612. this.vertexData = new Float32Array(geometry.points);
  2613. for (var i = 0; i < len; i++) {
  2614. var gI = geometry.batches[i];
  2615. var color = gI.style.color;
  2616. var vertexData = new Float32Array(this.vertexData.buffer, gI.attribStart * 4 * 2, gI.attribSize * 2);
  2617. var uvs = new Float32Array(geometry.uvsFloat32.buffer, gI.attribStart * 4 * 2, gI.attribSize * 2);
  2618. var indices = new Uint16Array(geometry.indicesUint16.buffer, gI.start * 2, gI.size);
  2619. var batch = {
  2620. vertexData: vertexData,
  2621. blendMode: blendMode,
  2622. indices: indices,
  2623. uvs: uvs,
  2624. _batchRGB: hex2rgb(color),
  2625. _tintRGB: color,
  2626. _texture: gI.style.texture,
  2627. alpha: gI.style.alpha,
  2628. worldAlpha: 1
  2629. };
  2630. this.batches[i] = batch;
  2631. }
  2632. };
  2633. /**
  2634. * Renders the batches using the BathedRenderer plugin
  2635. * @param renderer - The renderer
  2636. */
  2637. Graphics.prototype._renderBatched = function (renderer) {
  2638. if (!this.batches.length) {
  2639. return;
  2640. }
  2641. renderer.batch.setObjectRenderer(renderer.plugins[this.pluginName]);
  2642. this.calculateVertices();
  2643. this.calculateTints();
  2644. for (var i = 0, l = this.batches.length; i < l; i++) {
  2645. var batch = this.batches[i];
  2646. batch.worldAlpha = this.worldAlpha * batch.alpha;
  2647. renderer.plugins[this.pluginName].render(batch);
  2648. }
  2649. };
  2650. /**
  2651. * Renders the graphics direct
  2652. * @param renderer - The renderer
  2653. */
  2654. Graphics.prototype._renderDirect = function (renderer) {
  2655. var shader = this._resolveDirectShader(renderer);
  2656. var geometry = this._geometry;
  2657. var tint = this.tint;
  2658. var worldAlpha = this.worldAlpha;
  2659. var uniforms = shader.uniforms;
  2660. var drawCalls = geometry.drawCalls;
  2661. // lets set the transfomr
  2662. uniforms.translationMatrix = this.transform.worldTransform;
  2663. // and then lets set the tint..
  2664. uniforms.tint[0] = (((tint >> 16) & 0xFF) / 255) * worldAlpha;
  2665. uniforms.tint[1] = (((tint >> 8) & 0xFF) / 255) * worldAlpha;
  2666. uniforms.tint[2] = ((tint & 0xFF) / 255) * worldAlpha;
  2667. uniforms.tint[3] = worldAlpha;
  2668. // the first draw call, we can set the uniforms of the shader directly here.
  2669. // this means that we can tack advantage of the sync function of pixi!
  2670. // bind and sync uniforms..
  2671. // there is a way to optimise this..
  2672. renderer.shader.bind(shader);
  2673. renderer.geometry.bind(geometry, shader);
  2674. // set state..
  2675. renderer.state.set(this.state);
  2676. // then render the rest of them...
  2677. for (var i = 0, l = drawCalls.length; i < l; i++) {
  2678. this._renderDrawCallDirect(renderer, geometry.drawCalls[i]);
  2679. }
  2680. };
  2681. /**
  2682. * Renders specific DrawCall
  2683. * @param renderer
  2684. * @param drawCall
  2685. */
  2686. Graphics.prototype._renderDrawCallDirect = function (renderer, drawCall) {
  2687. var texArray = drawCall.texArray, type = drawCall.type, size = drawCall.size, start = drawCall.start;
  2688. var groupTextureCount = texArray.count;
  2689. for (var j = 0; j < groupTextureCount; j++) {
  2690. renderer.texture.bind(texArray.elements[j], j);
  2691. }
  2692. renderer.geometry.draw(type, size, start);
  2693. };
  2694. /**
  2695. * Resolves shader for direct rendering
  2696. * @param renderer - The renderer
  2697. */
  2698. Graphics.prototype._resolveDirectShader = function (renderer) {
  2699. var shader = this.shader;
  2700. var pluginName = this.pluginName;
  2701. if (!shader) {
  2702. // if there is no shader here, we can use the default shader.
  2703. // and that only gets created if we actually need it..
  2704. // but may be more than one plugins for graphics
  2705. if (!DEFAULT_SHADERS[pluginName]) {
  2706. var MAX_TEXTURES = renderer.plugins[pluginName].MAX_TEXTURES;
  2707. var sampleValues = new Int32Array(MAX_TEXTURES);
  2708. for (var i = 0; i < MAX_TEXTURES; i++) {
  2709. sampleValues[i] = i;
  2710. }
  2711. var uniforms = {
  2712. tint: new Float32Array([1, 1, 1, 1]),
  2713. translationMatrix: new Matrix(),
  2714. default: UniformGroup.from({ uSamplers: sampleValues }, true),
  2715. };
  2716. var program = renderer.plugins[pluginName]._shader.program;
  2717. DEFAULT_SHADERS[pluginName] = new Shader(program, uniforms);
  2718. }
  2719. shader = DEFAULT_SHADERS[pluginName];
  2720. }
  2721. return shader;
  2722. };
  2723. /** Retrieves the bounds of the graphic shape as a rectangle object. */
  2724. Graphics.prototype._calculateBounds = function () {
  2725. this.finishPoly();
  2726. var geometry = this._geometry;
  2727. // skipping when graphics is empty, like a container
  2728. if (!geometry.graphicsData.length) {
  2729. return;
  2730. }
  2731. var _a = geometry.bounds, minX = _a.minX, minY = _a.minY, maxX = _a.maxX, maxY = _a.maxY;
  2732. this._bounds.addFrame(this.transform, minX, minY, maxX, maxY);
  2733. };
  2734. /**
  2735. * Tests if a point is inside this graphics object
  2736. * @param point - the point to test
  2737. * @returns - the result of the test
  2738. */
  2739. Graphics.prototype.containsPoint = function (point) {
  2740. this.worldTransform.applyInverse(point, Graphics._TEMP_POINT);
  2741. return this._geometry.containsPoint(Graphics._TEMP_POINT);
  2742. };
  2743. /** Recalculate the tint by applying tint to batches using Graphics tint. */
  2744. Graphics.prototype.calculateTints = function () {
  2745. if (this.batchTint !== this.tint) {
  2746. this.batchTint = this.tint;
  2747. var tintRGB = hex2rgb(this.tint, temp);
  2748. for (var i = 0; i < this.batches.length; i++) {
  2749. var batch = this.batches[i];
  2750. var batchTint = batch._batchRGB;
  2751. var r = (tintRGB[0] * batchTint[0]) * 255;
  2752. var g = (tintRGB[1] * batchTint[1]) * 255;
  2753. var b = (tintRGB[2] * batchTint[2]) * 255;
  2754. // TODO Ivan, can this be done in one go?
  2755. var color = (r << 16) + (g << 8) + (b | 0);
  2756. batch._tintRGB = (color >> 16)
  2757. + (color & 0xff00)
  2758. + ((color & 0xff) << 16);
  2759. }
  2760. }
  2761. };
  2762. /** If there's a transform update or a change to the shape of the geometry, recalculate the vertices. */
  2763. Graphics.prototype.calculateVertices = function () {
  2764. var wtID = this.transform._worldID;
  2765. if (this._transformID === wtID) {
  2766. return;
  2767. }
  2768. this._transformID = wtID;
  2769. var wt = this.transform.worldTransform;
  2770. var a = wt.a;
  2771. var b = wt.b;
  2772. var c = wt.c;
  2773. var d = wt.d;
  2774. var tx = wt.tx;
  2775. var ty = wt.ty;
  2776. var data = this._geometry.points; // batch.vertexDataOriginal;
  2777. var vertexData = this.vertexData;
  2778. var count = 0;
  2779. for (var i = 0; i < data.length; i += 2) {
  2780. var x = data[i];
  2781. var y = data[i + 1];
  2782. vertexData[count++] = (a * x) + (c * y) + tx;
  2783. vertexData[count++] = (d * y) + (b * x) + ty;
  2784. }
  2785. };
  2786. /**
  2787. * Closes the current path.
  2788. * @returns - Returns itself.
  2789. */
  2790. Graphics.prototype.closePath = function () {
  2791. var currentPath = this.currentPath;
  2792. if (currentPath) {
  2793. // we don't need to add extra point in the end because buildLine will take care of that
  2794. currentPath.closeStroke = true;
  2795. // ensure that the polygon is completed, and is available for hit detection
  2796. // (even if the graphics is not rendered yet)
  2797. this.finishPoly();
  2798. }
  2799. return this;
  2800. };
  2801. /**
  2802. * Apply a matrix to the positional data.
  2803. * @param matrix - Matrix to use for transform current shape.
  2804. * @returns - Returns itself.
  2805. */
  2806. Graphics.prototype.setMatrix = function (matrix) {
  2807. this._matrix = matrix;
  2808. return this;
  2809. };
  2810. /**
  2811. * Begin adding holes to the last draw shape
  2812. * IMPORTANT: holes must be fully inside a shape to work
  2813. * Also weirdness ensues if holes overlap!
  2814. * Ellipses, Circles, Rectangles and Rounded Rectangles cannot be holes or host for holes in CanvasRenderer,
  2815. * please use `moveTo` `lineTo`, `quadraticCurveTo` if you rely on pixi-legacy bundle.
  2816. * @returns - Returns itself.
  2817. */
  2818. Graphics.prototype.beginHole = function () {
  2819. this.finishPoly();
  2820. this._holeMode = true;
  2821. return this;
  2822. };
  2823. /**
  2824. * End adding holes to the last draw shape.
  2825. * @returns - Returns itself.
  2826. */
  2827. Graphics.prototype.endHole = function () {
  2828. this.finishPoly();
  2829. this._holeMode = false;
  2830. return this;
  2831. };
  2832. /**
  2833. * Destroys the Graphics object.
  2834. * @param options - Options parameter. A boolean will act as if all
  2835. * options have been set to that value
  2836. * @param {boolean} [options.children=false] - if set to true, all the children will have
  2837. * their destroy method called as well. 'options' will be passed on to those calls.
  2838. * @param {boolean} [options.texture=false] - Only used for child Sprites if options.children is set to true
  2839. * Should it destroy the texture of the child sprite
  2840. * @param {boolean} [options.baseTexture=false] - Only used for child Sprites if options.children is set to true
  2841. * Should it destroy the base texture of the child sprite
  2842. */
  2843. Graphics.prototype.destroy = function (options) {
  2844. this._geometry.refCount--;
  2845. if (this._geometry.refCount === 0) {
  2846. this._geometry.dispose();
  2847. }
  2848. this._matrix = null;
  2849. this.currentPath = null;
  2850. this._lineStyle.destroy();
  2851. this._lineStyle = null;
  2852. this._fillStyle.destroy();
  2853. this._fillStyle = null;
  2854. this._geometry = null;
  2855. this.shader = null;
  2856. this.vertexData = null;
  2857. this.batches.length = 0;
  2858. this.batches = null;
  2859. _super.prototype.destroy.call(this, options);
  2860. };
  2861. /**
  2862. * New rendering behavior for rounded rectangles: circular arcs instead of quadratic bezier curves.
  2863. * In the next major release, we'll enable this by default.
  2864. */
  2865. Graphics.nextRoundedRectBehavior = false;
  2866. /**
  2867. * Temporary point to use for containsPoint.
  2868. * @private
  2869. */
  2870. Graphics._TEMP_POINT = new Point();
  2871. return Graphics;
  2872. }(Container));
  2873. var graphicsUtils = {
  2874. buildPoly: buildPoly,
  2875. buildCircle: buildCircle,
  2876. buildRectangle: buildRectangle,
  2877. buildRoundedRectangle: buildRoundedRectangle,
  2878. buildLine: buildLine,
  2879. ArcUtils: ArcUtils,
  2880. BezierUtils: BezierUtils,
  2881. QuadraticUtils: QuadraticUtils,
  2882. BatchPart: BatchPart,
  2883. FILL_COMMANDS: FILL_COMMANDS,
  2884. BATCH_POOL: BATCH_POOL,
  2885. DRAW_CALL_POOL: DRAW_CALL_POOL
  2886. };
  2887. export { FillStyle, GRAPHICS_CURVES, Graphics, GraphicsData, GraphicsGeometry, LINE_CAP, LINE_JOIN, LineStyle, graphicsUtils };
  2888. //# sourceMappingURL=graphics.mjs.map