graphics.js 110 KB

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