index.js 53 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366
  1. 'use strict';
  2. Object.defineProperty(exports, '__esModule', { value: true });
  3. var gLite = require('@antv/g-lite');
  4. var glMatrix = require('gl-matrix');
  5. var util = require('@antv/util');
  6. function _regeneratorRuntime() {
  7. _regeneratorRuntime = function () {
  8. return exports;
  9. };
  10. var exports = {},
  11. Op = Object.prototype,
  12. hasOwn = Op.hasOwnProperty,
  13. defineProperty = Object.defineProperty || function (obj, key, desc) {
  14. obj[key] = desc.value;
  15. },
  16. $Symbol = "function" == typeof Symbol ? Symbol : {},
  17. iteratorSymbol = $Symbol.iterator || "@@iterator",
  18. asyncIteratorSymbol = $Symbol.asyncIterator || "@@asyncIterator",
  19. toStringTagSymbol = $Symbol.toStringTag || "@@toStringTag";
  20. function define(obj, key, value) {
  21. return Object.defineProperty(obj, key, {
  22. value: value,
  23. enumerable: !0,
  24. configurable: !0,
  25. writable: !0
  26. }), obj[key];
  27. }
  28. try {
  29. define({}, "");
  30. } catch (err) {
  31. define = function (obj, key, value) {
  32. return obj[key] = value;
  33. };
  34. }
  35. function wrap(innerFn, outerFn, self, tryLocsList) {
  36. var protoGenerator = outerFn && outerFn.prototype instanceof Generator ? outerFn : Generator,
  37. generator = Object.create(protoGenerator.prototype),
  38. context = new Context(tryLocsList || []);
  39. return defineProperty(generator, "_invoke", {
  40. value: makeInvokeMethod(innerFn, self, context)
  41. }), generator;
  42. }
  43. function tryCatch(fn, obj, arg) {
  44. try {
  45. return {
  46. type: "normal",
  47. arg: fn.call(obj, arg)
  48. };
  49. } catch (err) {
  50. return {
  51. type: "throw",
  52. arg: err
  53. };
  54. }
  55. }
  56. exports.wrap = wrap;
  57. var ContinueSentinel = {};
  58. function Generator() {}
  59. function GeneratorFunction() {}
  60. function GeneratorFunctionPrototype() {}
  61. var IteratorPrototype = {};
  62. define(IteratorPrototype, iteratorSymbol, function () {
  63. return this;
  64. });
  65. var getProto = Object.getPrototypeOf,
  66. NativeIteratorPrototype = getProto && getProto(getProto(values([])));
  67. NativeIteratorPrototype && NativeIteratorPrototype !== Op && hasOwn.call(NativeIteratorPrototype, iteratorSymbol) && (IteratorPrototype = NativeIteratorPrototype);
  68. var Gp = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(IteratorPrototype);
  69. function defineIteratorMethods(prototype) {
  70. ["next", "throw", "return"].forEach(function (method) {
  71. define(prototype, method, function (arg) {
  72. return this._invoke(method, arg);
  73. });
  74. });
  75. }
  76. function AsyncIterator(generator, PromiseImpl) {
  77. function invoke(method, arg, resolve, reject) {
  78. var record = tryCatch(generator[method], generator, arg);
  79. if ("throw" !== record.type) {
  80. var result = record.arg,
  81. value = result.value;
  82. return value && "object" == typeof value && hasOwn.call(value, "__await") ? PromiseImpl.resolve(value.__await).then(function (value) {
  83. invoke("next", value, resolve, reject);
  84. }, function (err) {
  85. invoke("throw", err, resolve, reject);
  86. }) : PromiseImpl.resolve(value).then(function (unwrapped) {
  87. result.value = unwrapped, resolve(result);
  88. }, function (error) {
  89. return invoke("throw", error, resolve, reject);
  90. });
  91. }
  92. reject(record.arg);
  93. }
  94. var previousPromise;
  95. defineProperty(this, "_invoke", {
  96. value: function (method, arg) {
  97. function callInvokeWithMethodAndArg() {
  98. return new PromiseImpl(function (resolve, reject) {
  99. invoke(method, arg, resolve, reject);
  100. });
  101. }
  102. return previousPromise = previousPromise ? previousPromise.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg();
  103. }
  104. });
  105. }
  106. function makeInvokeMethod(innerFn, self, context) {
  107. var state = "suspendedStart";
  108. return function (method, arg) {
  109. if ("executing" === state) throw new Error("Generator is already running");
  110. if ("completed" === state) {
  111. if ("throw" === method) throw arg;
  112. return doneResult();
  113. }
  114. for (context.method = method, context.arg = arg;;) {
  115. var delegate = context.delegate;
  116. if (delegate) {
  117. var delegateResult = maybeInvokeDelegate(delegate, context);
  118. if (delegateResult) {
  119. if (delegateResult === ContinueSentinel) continue;
  120. return delegateResult;
  121. }
  122. }
  123. if ("next" === context.method) context.sent = context._sent = context.arg;else if ("throw" === context.method) {
  124. if ("suspendedStart" === state) throw state = "completed", context.arg;
  125. context.dispatchException(context.arg);
  126. } else "return" === context.method && context.abrupt("return", context.arg);
  127. state = "executing";
  128. var record = tryCatch(innerFn, self, context);
  129. if ("normal" === record.type) {
  130. if (state = context.done ? "completed" : "suspendedYield", record.arg === ContinueSentinel) continue;
  131. return {
  132. value: record.arg,
  133. done: context.done
  134. };
  135. }
  136. "throw" === record.type && (state = "completed", context.method = "throw", context.arg = record.arg);
  137. }
  138. };
  139. }
  140. function maybeInvokeDelegate(delegate, context) {
  141. var methodName = context.method,
  142. method = delegate.iterator[methodName];
  143. if (undefined === method) return context.delegate = null, "throw" === methodName && delegate.iterator.return && (context.method = "return", context.arg = undefined, maybeInvokeDelegate(delegate, context), "throw" === context.method) || "return" !== methodName && (context.method = "throw", context.arg = new TypeError("The iterator does not provide a '" + methodName + "' method")), ContinueSentinel;
  144. var record = tryCatch(method, delegate.iterator, context.arg);
  145. if ("throw" === record.type) return context.method = "throw", context.arg = record.arg, context.delegate = null, ContinueSentinel;
  146. var info = record.arg;
  147. return info ? info.done ? (context[delegate.resultName] = info.value, context.next = delegate.nextLoc, "return" !== context.method && (context.method = "next", context.arg = undefined), context.delegate = null, ContinueSentinel) : info : (context.method = "throw", context.arg = new TypeError("iterator result is not an object"), context.delegate = null, ContinueSentinel);
  148. }
  149. function pushTryEntry(locs) {
  150. var entry = {
  151. tryLoc: locs[0]
  152. };
  153. 1 in locs && (entry.catchLoc = locs[1]), 2 in locs && (entry.finallyLoc = locs[2], entry.afterLoc = locs[3]), this.tryEntries.push(entry);
  154. }
  155. function resetTryEntry(entry) {
  156. var record = entry.completion || {};
  157. record.type = "normal", delete record.arg, entry.completion = record;
  158. }
  159. function Context(tryLocsList) {
  160. this.tryEntries = [{
  161. tryLoc: "root"
  162. }], tryLocsList.forEach(pushTryEntry, this), this.reset(!0);
  163. }
  164. function values(iterable) {
  165. if (iterable) {
  166. var iteratorMethod = iterable[iteratorSymbol];
  167. if (iteratorMethod) return iteratorMethod.call(iterable);
  168. if ("function" == typeof iterable.next) return iterable;
  169. if (!isNaN(iterable.length)) {
  170. var i = -1,
  171. next = function next() {
  172. for (; ++i < iterable.length;) if (hasOwn.call(iterable, i)) return next.value = iterable[i], next.done = !1, next;
  173. return next.value = undefined, next.done = !0, next;
  174. };
  175. return next.next = next;
  176. }
  177. }
  178. return {
  179. next: doneResult
  180. };
  181. }
  182. function doneResult() {
  183. return {
  184. value: undefined,
  185. done: !0
  186. };
  187. }
  188. return GeneratorFunction.prototype = GeneratorFunctionPrototype, defineProperty(Gp, "constructor", {
  189. value: GeneratorFunctionPrototype,
  190. configurable: !0
  191. }), defineProperty(GeneratorFunctionPrototype, "constructor", {
  192. value: GeneratorFunction,
  193. configurable: !0
  194. }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, toStringTagSymbol, "GeneratorFunction"), exports.isGeneratorFunction = function (genFun) {
  195. var ctor = "function" == typeof genFun && genFun.constructor;
  196. return !!ctor && (ctor === GeneratorFunction || "GeneratorFunction" === (ctor.displayName || ctor.name));
  197. }, exports.mark = function (genFun) {
  198. return Object.setPrototypeOf ? Object.setPrototypeOf(genFun, GeneratorFunctionPrototype) : (genFun.__proto__ = GeneratorFunctionPrototype, define(genFun, toStringTagSymbol, "GeneratorFunction")), genFun.prototype = Object.create(Gp), genFun;
  199. }, exports.awrap = function (arg) {
  200. return {
  201. __await: arg
  202. };
  203. }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, asyncIteratorSymbol, function () {
  204. return this;
  205. }), exports.AsyncIterator = AsyncIterator, exports.async = function (innerFn, outerFn, self, tryLocsList, PromiseImpl) {
  206. void 0 === PromiseImpl && (PromiseImpl = Promise);
  207. var iter = new AsyncIterator(wrap(innerFn, outerFn, self, tryLocsList), PromiseImpl);
  208. return exports.isGeneratorFunction(outerFn) ? iter : iter.next().then(function (result) {
  209. return result.done ? result.value : iter.next();
  210. });
  211. }, defineIteratorMethods(Gp), define(Gp, toStringTagSymbol, "Generator"), define(Gp, iteratorSymbol, function () {
  212. return this;
  213. }), define(Gp, "toString", function () {
  214. return "[object Generator]";
  215. }), exports.keys = function (val) {
  216. var object = Object(val),
  217. keys = [];
  218. for (var key in object) keys.push(key);
  219. return keys.reverse(), function next() {
  220. for (; keys.length;) {
  221. var key = keys.pop();
  222. if (key in object) return next.value = key, next.done = !1, next;
  223. }
  224. return next.done = !0, next;
  225. };
  226. }, exports.values = values, Context.prototype = {
  227. constructor: Context,
  228. reset: function (skipTempReset) {
  229. if (this.prev = 0, this.next = 0, this.sent = this._sent = undefined, this.done = !1, this.delegate = null, this.method = "next", this.arg = undefined, this.tryEntries.forEach(resetTryEntry), !skipTempReset) for (var name in this) "t" === name.charAt(0) && hasOwn.call(this, name) && !isNaN(+name.slice(1)) && (this[name] = undefined);
  230. },
  231. stop: function () {
  232. this.done = !0;
  233. var rootRecord = this.tryEntries[0].completion;
  234. if ("throw" === rootRecord.type) throw rootRecord.arg;
  235. return this.rval;
  236. },
  237. dispatchException: function (exception) {
  238. if (this.done) throw exception;
  239. var context = this;
  240. function handle(loc, caught) {
  241. return record.type = "throw", record.arg = exception, context.next = loc, caught && (context.method = "next", context.arg = undefined), !!caught;
  242. }
  243. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  244. var entry = this.tryEntries[i],
  245. record = entry.completion;
  246. if ("root" === entry.tryLoc) return handle("end");
  247. if (entry.tryLoc <= this.prev) {
  248. var hasCatch = hasOwn.call(entry, "catchLoc"),
  249. hasFinally = hasOwn.call(entry, "finallyLoc");
  250. if (hasCatch && hasFinally) {
  251. if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
  252. if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
  253. } else if (hasCatch) {
  254. if (this.prev < entry.catchLoc) return handle(entry.catchLoc, !0);
  255. } else {
  256. if (!hasFinally) throw new Error("try statement without catch or finally");
  257. if (this.prev < entry.finallyLoc) return handle(entry.finallyLoc);
  258. }
  259. }
  260. }
  261. },
  262. abrupt: function (type, arg) {
  263. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  264. var entry = this.tryEntries[i];
  265. if (entry.tryLoc <= this.prev && hasOwn.call(entry, "finallyLoc") && this.prev < entry.finallyLoc) {
  266. var finallyEntry = entry;
  267. break;
  268. }
  269. }
  270. finallyEntry && ("break" === type || "continue" === type) && finallyEntry.tryLoc <= arg && arg <= finallyEntry.finallyLoc && (finallyEntry = null);
  271. var record = finallyEntry ? finallyEntry.completion : {};
  272. return record.type = type, record.arg = arg, finallyEntry ? (this.method = "next", this.next = finallyEntry.finallyLoc, ContinueSentinel) : this.complete(record);
  273. },
  274. complete: function (record, afterLoc) {
  275. if ("throw" === record.type) throw record.arg;
  276. return "break" === record.type || "continue" === record.type ? this.next = record.arg : "return" === record.type ? (this.rval = this.arg = record.arg, this.method = "return", this.next = "end") : "normal" === record.type && afterLoc && (this.next = afterLoc), ContinueSentinel;
  277. },
  278. finish: function (finallyLoc) {
  279. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  280. var entry = this.tryEntries[i];
  281. if (entry.finallyLoc === finallyLoc) return this.complete(entry.completion, entry.afterLoc), resetTryEntry(entry), ContinueSentinel;
  282. }
  283. },
  284. catch: function (tryLoc) {
  285. for (var i = this.tryEntries.length - 1; i >= 0; --i) {
  286. var entry = this.tryEntries[i];
  287. if (entry.tryLoc === tryLoc) {
  288. var record = entry.completion;
  289. if ("throw" === record.type) {
  290. var thrown = record.arg;
  291. resetTryEntry(entry);
  292. }
  293. return thrown;
  294. }
  295. }
  296. throw new Error("illegal catch attempt");
  297. },
  298. delegateYield: function (iterable, resultName, nextLoc) {
  299. return this.delegate = {
  300. iterator: values(iterable),
  301. resultName: resultName,
  302. nextLoc: nextLoc
  303. }, "next" === this.method && (this.arg = undefined), ContinueSentinel;
  304. }
  305. }, exports;
  306. }
  307. function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) {
  308. try {
  309. var info = gen[key](arg);
  310. var value = info.value;
  311. } catch (error) {
  312. reject(error);
  313. return;
  314. }
  315. if (info.done) {
  316. resolve(value);
  317. } else {
  318. Promise.resolve(value).then(_next, _throw);
  319. }
  320. }
  321. function _asyncToGenerator(fn) {
  322. return function () {
  323. var self = this,
  324. args = arguments;
  325. return new Promise(function (resolve, reject) {
  326. var gen = fn.apply(self, args);
  327. function _next(value) {
  328. asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value);
  329. }
  330. function _throw(err) {
  331. asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err);
  332. }
  333. _next(undefined);
  334. });
  335. };
  336. }
  337. function _inheritsLoose(subClass, superClass) {
  338. subClass.prototype = Object.create(superClass.prototype);
  339. subClass.prototype.constructor = subClass;
  340. _setPrototypeOf(subClass, superClass);
  341. }
  342. function _setPrototypeOf(o, p) {
  343. _setPrototypeOf = Object.setPrototypeOf ? Object.setPrototypeOf.bind() : function _setPrototypeOf(o, p) {
  344. o.__proto__ = p;
  345. return o;
  346. };
  347. return _setPrototypeOf(o, p);
  348. }
  349. function _unsupportedIterableToArray(o, minLen) {
  350. if (!o) return;
  351. if (typeof o === "string") return _arrayLikeToArray(o, minLen);
  352. var n = Object.prototype.toString.call(o).slice(8, -1);
  353. if (n === "Object" && o.constructor) n = o.constructor.name;
  354. if (n === "Map" || n === "Set") return Array.from(o);
  355. if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen);
  356. }
  357. function _arrayLikeToArray(arr, len) {
  358. if (len == null || len > arr.length) len = arr.length;
  359. for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i];
  360. return arr2;
  361. }
  362. function _createForOfIteratorHelperLoose(o, allowArrayLike) {
  363. var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"];
  364. if (it) return (it = it.call(o)).next.bind(it);
  365. if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") {
  366. if (it) o = it;
  367. var i = 0;
  368. return function () {
  369. if (i >= o.length) return {
  370. done: true
  371. };
  372. return {
  373. done: false,
  374. value: o[i++]
  375. };
  376. };
  377. }
  378. throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
  379. }
  380. var tmpVec3a = glMatrix.vec3.create();
  381. var tmpVec3b = glMatrix.vec3.create();
  382. var tmpVec3c = glMatrix.vec3.create();
  383. var tmpMat4 = glMatrix.mat4.create();
  384. /**
  385. * pick shape(s) with Mouse/Touch event
  386. *
  387. * 1. find AABB with r-tree
  388. * 2. do math calculation with geometry in an accurate way
  389. */
  390. var CanvasPickerPlugin = /*#__PURE__*/function () {
  391. function CanvasPickerPlugin() {
  392. var _this = this;
  393. this.context = void 0;
  394. this.runtime = void 0;
  395. this.isHit = function (displayObject, position, worldTransform, isClipPath) {
  396. // use picker for current shape's type
  397. var pick = _this.context.pointInPathPickerFactory[displayObject.nodeName];
  398. if (pick) {
  399. // invert with world matrix
  400. var invertWorldMat = glMatrix.mat4.invert(tmpMat4, worldTransform);
  401. // transform client position to local space, do picking in local space
  402. var localPosition = glMatrix.vec3.transformMat4(tmpVec3b, glMatrix.vec3.set(tmpVec3c, position[0], position[1], 0), invertWorldMat);
  403. // account for anchor
  404. var _displayObject$getGeo = displayObject.getGeometryBounds(),
  405. halfExtents = _displayObject$getGeo.halfExtents;
  406. var anchor = displayObject.parsedStyle.anchor;
  407. localPosition[0] += (anchor && anchor[0] || 0) * halfExtents[0] * 2;
  408. localPosition[1] += (anchor && anchor[1] || 0) * halfExtents[1] * 2;
  409. if (pick(displayObject, new gLite.Point(localPosition[0], localPosition[1]), isClipPath, _this.isPointInPath, _this.context, _this.runtime)) {
  410. return true;
  411. }
  412. }
  413. return false;
  414. };
  415. /**
  416. * use native picking method
  417. * @see https://developer.mozilla.org/zh-CN/docs/Web/API/CanvasRenderingContext2D/isPointInPath
  418. */
  419. this.isPointInPath = function (displayObject, position) {
  420. var context = _this.runtime.offscreenCanvas.getOrCreateContext(_this.context.config.offscreenCanvas);
  421. var generatePath = _this.context.pathGeneratorFactory[displayObject.nodeName];
  422. if (generatePath) {
  423. context.beginPath();
  424. generatePath(context, displayObject.parsedStyle);
  425. context.closePath();
  426. }
  427. return context.isPointInPath(position.x, position.y);
  428. };
  429. }
  430. var _proto = CanvasPickerPlugin.prototype;
  431. _proto.apply = function apply(context, runtime) {
  432. var _renderingContext$roo,
  433. _this2 = this;
  434. var renderingService = context.renderingService,
  435. renderingContext = context.renderingContext;
  436. this.context = context;
  437. this.runtime = runtime;
  438. var document = (_renderingContext$roo = renderingContext.root) === null || _renderingContext$roo === void 0 ? void 0 : _renderingContext$roo.ownerDocument;
  439. renderingService.hooks.pick.tapPromise(CanvasPickerPlugin.tag, /*#__PURE__*/function () {
  440. var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(result) {
  441. return _regeneratorRuntime().wrap(function _callee$(_context) {
  442. while (1) switch (_context.prev = _context.next) {
  443. case 0:
  444. return _context.abrupt("return", _this2.pick(document, result));
  445. case 1:
  446. case "end":
  447. return _context.stop();
  448. }
  449. }, _callee);
  450. }));
  451. return function (_x) {
  452. return _ref.apply(this, arguments);
  453. };
  454. }());
  455. renderingService.hooks.pickSync.tap(CanvasPickerPlugin.tag, function (result) {
  456. return _this2.pick(document, result);
  457. });
  458. };
  459. _proto.pick = function pick(document, result) {
  460. var topmost = result.topmost,
  461. _result$position = result.position,
  462. x = _result$position.x,
  463. y = _result$position.y;
  464. // position in world space
  465. var position = glMatrix.vec3.set(tmpVec3a, x, y, 0);
  466. // query by AABB first with spatial index(r-tree)
  467. var hitTestList = document.elementsFromBBox(position[0], position[1], position[0], position[1]);
  468. // test with clip path & origin shape
  469. // @see https://github.com/antvis/g/issues/1064
  470. var pickedDisplayObjects = [];
  471. for (var _iterator = _createForOfIteratorHelperLoose(hitTestList), _step; !(_step = _iterator()).done;) {
  472. var displayObject = _step.value;
  473. var worldTransform = displayObject.getWorldTransform();
  474. var isHitOriginShape = this.isHit(displayObject, position, worldTransform, false);
  475. if (isHitOriginShape) {
  476. // should look up in the ancestor node
  477. var clipped = gLite.findClosestClipPathTarget(displayObject);
  478. if (clipped) {
  479. var clipPath = clipped.parsedStyle.clipPath;
  480. var isHitClipPath = this.isHit(clipPath, position, clipPath.getWorldTransform(), true);
  481. if (isHitClipPath) {
  482. if (topmost) {
  483. result.picked = [displayObject];
  484. return result;
  485. } else {
  486. pickedDisplayObjects.push(displayObject);
  487. }
  488. }
  489. } else {
  490. if (topmost) {
  491. result.picked = [displayObject];
  492. return result;
  493. } else {
  494. pickedDisplayObjects.push(displayObject);
  495. }
  496. }
  497. }
  498. }
  499. result.picked = pickedDisplayObjects;
  500. return result;
  501. };
  502. return CanvasPickerPlugin;
  503. }();
  504. CanvasPickerPlugin.tag = 'CanvasPicker';
  505. /**
  506. * 两点之间的距离
  507. * @param {number} x1 起始点 x
  508. * @param {number} y1 起始点 y
  509. * @param {number} x2 结束点 x
  510. * @param {number} y2 结束点 y
  511. * @return {number} 距离
  512. */
  513. function distance(x1, y1, x2, y2) {
  514. var dx = x1 - x2;
  515. var dy = y1 - y2;
  516. return Math.sqrt(dx * dx + dy * dy);
  517. }
  518. function isNumberEqual(v1, v2) {
  519. return Math.abs(v1 - v2) < 0.001;
  520. }
  521. function getBBoxByArray(xArr, yArr) {
  522. var minX = Math.min.apply(Math, xArr);
  523. var minY = Math.min.apply(Math, yArr);
  524. var maxX = Math.max.apply(Math, xArr);
  525. var maxY = Math.max.apply(Math, yArr);
  526. return {
  527. x: minX,
  528. y: minY,
  529. width: maxX - minX,
  530. height: maxY - minY
  531. };
  532. }
  533. function piMod(angle) {
  534. return (angle + Math.PI * 2) % (Math.PI * 2);
  535. }
  536. var line = {
  537. /**
  538. * 计算线段的包围盒
  539. * @param {number} x1 起始点 x
  540. * @param {number} y1 起始点 y
  541. * @param {number} x2 结束点 x
  542. * @param {number} y2 结束点 y
  543. * @return {object} 包围盒对象
  544. */
  545. box: function box(x1, y1, x2, y2) {
  546. return getBBoxByArray([x1, x2], [y1, y2]);
  547. },
  548. /**
  549. * 线段的长度
  550. * @param {number} x1 起始点 x
  551. * @param {number} y1 起始点 y
  552. * @param {number} x2 结束点 x
  553. * @param {number} y2 结束点 y
  554. * @return {number} 距离
  555. */
  556. length: function length(x1, y1, x2, y2) {
  557. return distance(x1, y1, x2, y2);
  558. },
  559. /**
  560. * 根据比例获取点
  561. * @param {number} x1 起始点 x
  562. * @param {number} y1 起始点 y
  563. * @param {number} x2 结束点 x
  564. * @param {number} y2 结束点 y
  565. * @param {number} t 指定比例
  566. * @return {object} 包含 x, y 的点
  567. */
  568. pointAt: function pointAt(x1, y1, x2, y2, t) {
  569. return {
  570. x: (1 - t) * x1 + t * x2,
  571. y: (1 - t) * y1 + t * y2
  572. };
  573. },
  574. /**
  575. * 点到线段的距离
  576. * @param {number} x1 起始点 x
  577. * @param {number} y1 起始点 y
  578. * @param {number} x2 结束点 x
  579. * @param {number} y2 结束点 y
  580. * @param {number} x 测试点 x
  581. * @param {number} y 测试点 y
  582. * @return {number} 距离
  583. */
  584. pointDistance: function pointDistance(x1, y1, x2, y2, x, y) {
  585. // 投影距离 x1, y1 的向量,假设 p, p1, p2 三个点,投影点为 a
  586. // p1a = p1p.p1p2/|p1p2| * (p1p 的单位向量)
  587. var cross = (x2 - x1) * (x - x1) + (y2 - y1) * (y - y1);
  588. if (cross < 0) {
  589. return distance(x1, y1, x, y);
  590. }
  591. var lengthSquare = (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1);
  592. if (cross > lengthSquare) {
  593. return distance(x2, y2, x, y);
  594. }
  595. return this.pointToLine(x1, y1, x2, y2, x, y);
  596. },
  597. /**
  598. * 点到直线的距离,而不是点到线段的距离
  599. * @param {number} x1 起始点 x
  600. * @param {number} y1 起始点 y
  601. * @param {number} x2 结束点 x
  602. * @param {number} y2 结束点 y
  603. * @param {number} x 测试点 x
  604. * @param {number} y 测试点 y
  605. * @return {number} 距离
  606. */
  607. pointToLine: function pointToLine(x1, y1, x2, y2, x, y) {
  608. var d = [x2 - x1, y2 - y1];
  609. // 如果端点相等,则判定点到点的距离
  610. if (glMatrix.vec2.exactEquals(d, [0, 0])) {
  611. return Math.sqrt((x - x1) * (x - x1) + (y - y1) * (y - y1));
  612. }
  613. var u = [-d[1], d[0]];
  614. glMatrix.vec2.normalize(u, u);
  615. var a = [x - x1, y - y1];
  616. return Math.abs(glMatrix.vec2.dot(a, u));
  617. },
  618. /**
  619. * 线段的角度
  620. * @param {number} x1 起始点 x
  621. * @param {number} y1 起始点 y
  622. * @param {number} x2 结束点 x
  623. * @param {number} y2 结束点 y
  624. * @return {number} 导数
  625. */
  626. tangentAngle: function tangentAngle(x1, y1, x2, y2) {
  627. return Math.atan2(y2 - y1, x2 - x1);
  628. }
  629. };
  630. var EPSILON = 0.0001;
  631. /**
  632. * 使用牛顿切割法求最近的点
  633. * @param {number[]} xArr 点的 x 数组
  634. * @param {number[]} yArr 点的 y 数组
  635. * @param {number} x 指定的点 x
  636. * @param {number} y 指定的点 y
  637. * @param {Function} tCallback 差值函数
  638. */
  639. function nearestPoint(xArr, yArr, x, y, tCallback, length) {
  640. var t = -1;
  641. var d = Infinity;
  642. var v0 = [x, y];
  643. var segNum = 20;
  644. if (length && length > 200) {
  645. segNum = length / 10;
  646. }
  647. var increaseRate = 1 / segNum;
  648. var interval = increaseRate / 10;
  649. for (var i = 0; i <= segNum; i++) {
  650. var _t = i * increaseRate;
  651. var v1 = [tCallback.apply(void 0, xArr.concat([_t])), tCallback.apply(void 0, yArr.concat([_t]))];
  652. var d1 = distance(v0[0], v0[1], v1[0], v1[1]);
  653. if (d1 < d) {
  654. t = _t;
  655. d = d1;
  656. }
  657. }
  658. // 提前终止
  659. if (t === 0) {
  660. return {
  661. x: xArr[0],
  662. y: yArr[0]
  663. };
  664. }
  665. if (t === 1) {
  666. var count = xArr.length;
  667. return {
  668. x: xArr[count - 1],
  669. y: yArr[count - 1]
  670. };
  671. }
  672. d = Infinity;
  673. for (var _i = 0; _i < 32; _i++) {
  674. if (interval < EPSILON) {
  675. break;
  676. }
  677. var prev = t - interval;
  678. var next = t + interval;
  679. var _v = [tCallback.apply(void 0, xArr.concat([prev])), tCallback.apply(void 0, yArr.concat([prev]))];
  680. var _d = distance(v0[0], v0[1], _v[0], _v[1]);
  681. if (prev >= 0 && _d < d) {
  682. t = prev;
  683. d = _d;
  684. } else {
  685. var v2 = [tCallback.apply(void 0, xArr.concat([next])), tCallback.apply(void 0, yArr.concat([next]))];
  686. var d2 = distance(v0[0], v0[1], v2[0], v2[1]);
  687. if (next <= 1 && d2 < d) {
  688. t = next;
  689. d = d2;
  690. } else {
  691. interval *= 0.5;
  692. }
  693. }
  694. }
  695. return {
  696. x: tCallback.apply(void 0, xArr.concat([t])),
  697. y: tCallback.apply(void 0, yArr.concat([t]))
  698. };
  699. }
  700. // 近似求解 https://community.khronos.org/t/3d-cubic-bezier-segment-length/62363/2
  701. function snapLength(xArr, yArr) {
  702. var totalLength = 0;
  703. var count = xArr.length;
  704. for (var i = 0; i < count; i++) {
  705. var x = xArr[i];
  706. var y = yArr[i];
  707. var nextX = xArr[(i + 1) % count];
  708. var nextY = yArr[(i + 1) % count];
  709. totalLength += distance(x, y, nextX, nextY);
  710. }
  711. return totalLength / 2;
  712. }
  713. // 差值公式
  714. function quadraticAt(p0, p1, p2, t) {
  715. var onet = 1 - t;
  716. return onet * onet * p0 + 2 * t * onet * p1 + t * t * p2;
  717. }
  718. // 求极值
  719. function extrema(p0, p1, p2) {
  720. var a = p0 + p2 - 2 * p1;
  721. if (isNumberEqual(a, 0)) {
  722. return [0.5];
  723. }
  724. var rst = (p0 - p1) / a;
  725. if (rst <= 1 && rst >= 0) {
  726. return [rst];
  727. }
  728. return [];
  729. }
  730. function derivativeAt(p0, p1, p2, t) {
  731. return 2 * (1 - t) * (p1 - p0) + 2 * t * (p2 - p1);
  732. }
  733. // 分割贝塞尔曲线
  734. function divideQuadratic(x1, y1, x2, y2, x3, y3, t) {
  735. // 划分点
  736. var xt = quadraticAt(x1, x2, x3, t);
  737. var yt = quadraticAt(y1, y2, y3, t);
  738. // 分割的第一条曲线的控制点
  739. var controlPoint1 = line.pointAt(x1, y1, x2, y2, t);
  740. // 分割的第二条曲线的控制点
  741. var controlPoint2 = line.pointAt(x2, y2, x3, y3, t);
  742. return [[x1, y1, controlPoint1.x, controlPoint1.y, xt, yt], [xt, yt, controlPoint2.x, controlPoint2.y, x3, y3]];
  743. }
  744. // 使用迭代法取贝塞尔曲线的长度
  745. function quadraticLength(x1, y1, x2, y2, x3, y3, iterationCount) {
  746. if (iterationCount === 0) {
  747. return (distance(x1, y1, x2, y2) + distance(x2, y2, x3, y3) + distance(x1, y1, x3, y3)) / 2;
  748. }
  749. var quadratics = divideQuadratic(x1, y1, x2, y2, x3, y3, 0.5);
  750. var left = quadratics[0];
  751. var right = quadratics[1];
  752. left.push(iterationCount - 1);
  753. right.push(iterationCount - 1);
  754. return quadraticLength.apply(void 0, left) + quadraticLength.apply(void 0, right);
  755. }
  756. var quadratic = {
  757. box: function box(x1, y1, x2, y2, x3, y3) {
  758. var xExtrema = extrema(x1, x2, x3)[0];
  759. var yExtrema = extrema(y1, y2, y3)[0];
  760. // 控制点不加入 box 的计算
  761. var xArr = [x1, x3];
  762. var yArr = [y1, y3];
  763. if (xExtrema !== undefined) {
  764. xArr.push(quadraticAt(x1, x2, x3, xExtrema));
  765. }
  766. if (yExtrema !== undefined) {
  767. yArr.push(quadraticAt(y1, y2, y3, yExtrema));
  768. }
  769. return getBBoxByArray(xArr, yArr);
  770. },
  771. length: function length(x1, y1, x2, y2, x3, y3) {
  772. return quadraticLength(x1, y1, x2, y2, x3, y3, 3);
  773. },
  774. nearestPoint: function nearestPoint$1(x1, y1, x2, y2, x3, y3, x0, y0) {
  775. return nearestPoint([x1, x2, x3], [y1, y2, y3], x0, y0, quadraticAt);
  776. },
  777. pointDistance: function pointDistance(x1, y1, x2, y2, x3, y3, x0, y0) {
  778. var point = this.nearestPoint(x1, y1, x2, y2, x3, y3, x0, y0);
  779. return distance(point.x, point.y, x0, y0);
  780. },
  781. interpolationAt: quadraticAt,
  782. pointAt: function pointAt(x1, y1, x2, y2, x3, y3, t) {
  783. return {
  784. x: quadraticAt(x1, x2, x3, t),
  785. y: quadraticAt(y1, y2, y3, t)
  786. };
  787. },
  788. divide: function divide(x1, y1, x2, y2, x3, y3, t) {
  789. return divideQuadratic(x1, y1, x2, y2, x3, y3, t);
  790. },
  791. tangentAngle: function tangentAngle(x1, y1, x2, y2, x3, y3, t) {
  792. var dx = derivativeAt(x1, x2, x3, t);
  793. var dy = derivativeAt(y1, y2, y3, t);
  794. var angle = Math.atan2(dy, dx);
  795. return piMod(angle);
  796. }
  797. };
  798. function cubicAt(p0, p1, p2, p3, t) {
  799. var onet = 1 - t; // t * t * t 的性能大概是 Math.pow(t, 3) 的三倍
  800. return onet * onet * onet * p0 + 3 * p1 * t * onet * onet + 3 * p2 * t * t * onet + p3 * t * t * t;
  801. }
  802. function derivativeAt$1(p0, p1, p2, p3, t) {
  803. var onet = 1 - t;
  804. return 3 * (onet * onet * (p1 - p0) + 2 * onet * t * (p2 - p1) + t * t * (p3 - p2));
  805. }
  806. function extrema$1(p0, p1, p2, p3) {
  807. var a = -3 * p0 + 9 * p1 - 9 * p2 + 3 * p3;
  808. var b = 6 * p0 - 12 * p1 + 6 * p2;
  809. var c = 3 * p1 - 3 * p0;
  810. var extremas = [];
  811. var t1;
  812. var t2;
  813. var discSqrt;
  814. if (isNumberEqual(a, 0)) {
  815. if (!isNumberEqual(b, 0)) {
  816. t1 = -c / b;
  817. if (t1 >= 0 && t1 <= 1) {
  818. extremas.push(t1);
  819. }
  820. }
  821. } else {
  822. var disc = b * b - 4 * a * c;
  823. if (isNumberEqual(disc, 0)) {
  824. extremas.push(-b / (2 * a));
  825. } else if (disc > 0) {
  826. discSqrt = Math.sqrt(disc);
  827. t1 = (-b + discSqrt) / (2 * a);
  828. t2 = (-b - discSqrt) / (2 * a);
  829. if (t1 >= 0 && t1 <= 1) {
  830. extremas.push(t1);
  831. }
  832. if (t2 >= 0 && t2 <= 1) {
  833. extremas.push(t2);
  834. }
  835. }
  836. }
  837. return extremas;
  838. }
  839. // 分割贝塞尔曲线
  840. function divideCubic(x1, y1, x2, y2, x3, y3, x4, y4, t) {
  841. // 划分点
  842. var xt = cubicAt(x1, x2, x3, x4, t);
  843. var yt = cubicAt(y1, y2, y3, y4, t);
  844. // 计算两点之间的差值点
  845. var c1 = line.pointAt(x1, y1, x2, y2, t);
  846. var c2 = line.pointAt(x2, y2, x3, y3, t);
  847. var c3 = line.pointAt(x3, y3, x4, y4, t);
  848. var c12 = line.pointAt(c1.x, c1.y, c2.x, c2.y, t);
  849. var c23 = line.pointAt(c2.x, c2.y, c3.x, c3.y, t);
  850. return [[x1, y1, c1.x, c1.y, c12.x, c12.y, xt, yt], [xt, yt, c23.x, c23.y, c3.x, c3.y, x4, y4]];
  851. }
  852. // 使用迭代法取贝塞尔曲线的长度,二阶和三阶分开写,更清晰和便于调试
  853. function cubicLength(x1, y1, x2, y2, x3, y3, x4, y4, iterationCount) {
  854. if (iterationCount === 0) {
  855. return snapLength([x1, x2, x3, x4], [y1, y2, y3, y4]);
  856. }
  857. var cubics = divideCubic(x1, y1, x2, y2, x3, y3, x4, y4, 0.5);
  858. var left = [].concat(cubics[0], [iterationCount - 1]);
  859. var right = [].concat(cubics[1], [iterationCount - 1]);
  860. return cubicLength.apply(void 0, left) + cubicLength.apply(void 0, right);
  861. }
  862. var cubic = {
  863. extrema: extrema$1,
  864. box: function box(x1, y1, x2, y2, x3, y3, x4, y4) {
  865. var xArr = [x1, x4];
  866. var yArr = [y1, y4];
  867. var xExtrema = extrema$1(x1, x2, x3, x4);
  868. var yExtrema = extrema$1(y1, y2, y3, y4);
  869. for (var i = 0; i < xExtrema.length; i++) {
  870. xArr.push(cubicAt(x1, x2, x3, x4, xExtrema[i]));
  871. }
  872. for (var _i = 0; _i < yExtrema.length; _i++) {
  873. yArr.push(cubicAt(y1, y2, y3, y4, yExtrema[_i]));
  874. }
  875. return getBBoxByArray(xArr, yArr);
  876. },
  877. length: function length(x1, y1, x2, y2, x3, y3, x4, y4) {
  878. // 迭代三次,划分成 8 段求长度
  879. return cubicLength(x1, y1, x2, y2, x3, y3, x4, y4, 3);
  880. },
  881. nearestPoint: function nearestPoint$1(x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length) {
  882. return nearestPoint([x1, x2, x3, x4], [y1, y2, y3, y4], x0, y0, cubicAt, length);
  883. },
  884. pointDistance: function pointDistance(x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length) {
  885. var point = this.nearestPoint(x1, y1, x2, y2, x3, y3, x4, y4, x0, y0, length);
  886. return distance(point.x, point.y, x0, y0);
  887. },
  888. interpolationAt: cubicAt,
  889. pointAt: function pointAt(x1, y1, x2, y2, x3, y3, x4, y4, t) {
  890. return {
  891. x: cubicAt(x1, x2, x3, x4, t),
  892. y: cubicAt(y1, y2, y3, y4, t)
  893. };
  894. },
  895. divide: function divide(x1, y1, x2, y2, x3, y3, x4, y4, t) {
  896. return divideCubic(x1, y1, x2, y2, x3, y3, x4, y4, t);
  897. },
  898. tangentAngle: function tangentAngle(x1, y1, x2, y2, x3, y3, x4, y4, t) {
  899. var dx = derivativeAt$1(x1, x2, x3, x4, t);
  900. var dy = derivativeAt$1(y1, y2, y3, y4, t);
  901. return piMod(Math.atan2(dy, dx));
  902. }
  903. };
  904. function distance$1(x1, y1, x2, y2) {
  905. var dx = x1 - x2;
  906. var dy = y1 - y2;
  907. return Math.sqrt(dx * dx + dy * dy);
  908. }
  909. function inBox(minX, minY, width, height, x, y) {
  910. return x >= minX && x <= minX + width && y >= minY && y <= minY + height;
  911. }
  912. function inRect(minX, minY, width, height, lineWidth, x, y) {
  913. var halfWidth = lineWidth / 2;
  914. // 将四个边看做矩形来检测,比边的检测算法要快
  915. return inBox(minX - halfWidth, minY - halfWidth, width, lineWidth, x, y) ||
  916. // 上边
  917. inBox(minX + width - halfWidth, minY - halfWidth, lineWidth, height, x, y) ||
  918. // 右边
  919. inBox(minX + halfWidth, minY + height - halfWidth, width, lineWidth, x, y) ||
  920. // 下边
  921. inBox(minX - halfWidth, minY + halfWidth, lineWidth, height, x, y); // 左边
  922. }
  923. function inArc(cx, cy, r, startAngle, endAngle, lineWidth, x, y) {
  924. var angle = (Math.atan2(y - cy, x - cx) + Math.PI * 2) % (Math.PI * 2); // 转换到 0 - 2 * Math.PI 之间
  925. // if (angle < startAngle || angle > endAngle) {
  926. // return false;
  927. // }
  928. var point = {
  929. x: cx + r * Math.cos(angle),
  930. y: cy + r * Math.sin(angle)
  931. };
  932. return distance$1(point.x, point.y, x, y) <= lineWidth / 2;
  933. }
  934. function inLine(x1, y1, x2, y2, lineWidth, x, y) {
  935. var minX = Math.min(x1, x2);
  936. var maxX = Math.max(x1, x2);
  937. var minY = Math.min(y1, y2);
  938. var maxY = Math.max(y1, y2);
  939. var halfWidth = lineWidth / 2;
  940. // 因为目前的方案是计算点到直线的距离,而有可能会在延长线上,所以要先判断是否在包围盒内
  941. // 这种方案会在水平或者竖直的情况下载线的延长线上有半 lineWidth 的误差
  942. if (!(x >= minX - halfWidth && x <= maxX + halfWidth && y >= minY - halfWidth && y <= maxY + halfWidth)) {
  943. return false;
  944. }
  945. // 因为已经计算了包围盒,所以仅需要计算到直线的距离即可,可以显著提升性能
  946. return line.pointToLine(x1, y1, x2, y2, x, y) <= lineWidth / 2;
  947. }
  948. function inPolyline(points, lineWidth, x, y, isClose) {
  949. var count = points.length;
  950. if (count < 2) {
  951. return false;
  952. }
  953. for (var i = 0; i < count - 1; i++) {
  954. var x1 = points[i][0];
  955. var y1 = points[i][1];
  956. var x2 = points[i + 1][0];
  957. var y2 = points[i + 1][1];
  958. if (inLine(x1, y1, x2, y2, lineWidth, x, y)) {
  959. return true;
  960. }
  961. }
  962. // 如果封闭,则计算起始点和结束点的边
  963. if (isClose) {
  964. var first = points[0];
  965. var last = points[count - 1];
  966. if (inLine(first[0], first[1], last[0], last[1], lineWidth, x, y)) {
  967. return true;
  968. }
  969. }
  970. return false;
  971. }
  972. // 多边形的射线检测,参考:https://blog.csdn.net/WilliamSun0122/article/details/77994526
  973. var tolerance = 1e-6;
  974. // 三态函数,判断两个double在eps精度下的大小关系
  975. function dcmp(x) {
  976. if (Math.abs(x) < tolerance) {
  977. return 0;
  978. }
  979. return x < 0 ? -1 : 1;
  980. }
  981. // 判断点Q是否在p1和p2的线段上
  982. function onSegment(p1, p2, q) {
  983. if ((q[0] - p1[0]) * (p2[1] - p1[1]) === (p2[0] - p1[0]) * (q[1] - p1[1]) && Math.min(p1[0], p2[0]) <= q[0] && q[0] <= Math.max(p1[0], p2[0]) && Math.min(p1[1], p2[1]) <= q[1] && q[1] <= Math.max(p1[1], p2[1])) {
  984. return true;
  985. }
  986. return false;
  987. }
  988. // 判断点P在多边形内-射线法
  989. function inPolygon(points, x, y) {
  990. var isHit = false;
  991. var n = points.length;
  992. if (n <= 2) {
  993. // svg 中点小于 3 个时,不显示,也无法被拾取
  994. return false;
  995. }
  996. for (var i = 0; i < n; i++) {
  997. var p1 = points[i];
  998. var p2 = points[(i + 1) % n];
  999. if (onSegment(p1, p2, [x, y])) {
  1000. // 点在多边形一条边上
  1001. return true;
  1002. }
  1003. // 前一个判断min(p1[1],p2[1])<P.y<=max(p1[1],p2[1])
  1004. // 后一个判断被测点 在 射线与边交点 的左边
  1005. if (dcmp(p1[1] - y) > 0 !== dcmp(p2[1] - y) > 0 && dcmp(x - (y - p1[1]) * (p1[0] - p2[0]) / (p1[1] - p2[1]) - p1[0]) < 0) {
  1006. isHit = !isHit;
  1007. }
  1008. }
  1009. return isHit;
  1010. }
  1011. function inPolygons(polygons, x, y) {
  1012. var isHit = false;
  1013. for (var i = 0; i < polygons.length; i++) {
  1014. var points = polygons[i];
  1015. isHit = inPolygon(points, x, y);
  1016. if (isHit) {
  1017. break;
  1018. }
  1019. }
  1020. return isHit;
  1021. }
  1022. function isPointInPath(displayObject, position, isClipPath) {
  1023. var _displayObject$parsed = displayObject.parsedStyle,
  1024. r = _displayObject$parsed.r,
  1025. fill = _displayObject$parsed.fill,
  1026. stroke = _displayObject$parsed.stroke,
  1027. lineWidth = _displayObject$parsed.lineWidth,
  1028. increasedLineWidthForHitTesting = _displayObject$parsed.increasedLineWidthForHitTesting,
  1029. pointerEvents = _displayObject$parsed.pointerEvents;
  1030. var halfLineWidth = ((lineWidth || 0) + (increasedLineWidthForHitTesting || 0)) / 2;
  1031. var absDistance = distance$1(r, r, position.x, position.y);
  1032. var _isFillOrStrokeAffect = gLite.isFillOrStrokeAffected(pointerEvents, fill, stroke),
  1033. hasFill = _isFillOrStrokeAffect[0],
  1034. hasStroke = _isFillOrStrokeAffect[1];
  1035. if (hasFill && hasStroke || isClipPath) {
  1036. return absDistance <= r + halfLineWidth;
  1037. }
  1038. if (hasFill) {
  1039. return absDistance <= r;
  1040. }
  1041. if (hasStroke) {
  1042. return absDistance >= r - halfLineWidth && absDistance <= r + halfLineWidth;
  1043. }
  1044. return false;
  1045. }
  1046. function ellipseDistance(squareX, squareY, rx, ry) {
  1047. return squareX / (rx * rx) + squareY / (ry * ry);
  1048. }
  1049. function isPointInPath$1(displayObject, position, isClipPath) {
  1050. var _displayObject$parsed = displayObject.parsedStyle,
  1051. rx = _displayObject$parsed.rx,
  1052. ry = _displayObject$parsed.ry,
  1053. fill = _displayObject$parsed.fill,
  1054. stroke = _displayObject$parsed.stroke,
  1055. lineWidth = _displayObject$parsed.lineWidth,
  1056. increasedLineWidthForHitTesting = _displayObject$parsed.increasedLineWidthForHitTesting,
  1057. pointerEvents = _displayObject$parsed.pointerEvents;
  1058. var x = position.x,
  1059. y = position.y;
  1060. var _isFillOrStrokeAffect = gLite.isFillOrStrokeAffected(pointerEvents, fill, stroke),
  1061. hasFill = _isFillOrStrokeAffect[0],
  1062. hasStroke = _isFillOrStrokeAffect[1];
  1063. var halfLineWith = ((lineWidth || 0) + (increasedLineWidthForHitTesting || 0)) / 2;
  1064. var squareX = (x - rx) * (x - rx);
  1065. var squareY = (y - ry) * (y - ry);
  1066. // 使用椭圆的公式: x*x/rx*rx + y*y/ry*ry = 1;
  1067. if (hasFill && hasStroke || isClipPath) {
  1068. return ellipseDistance(squareX, squareY, rx + halfLineWith, ry + halfLineWith) <= 1;
  1069. }
  1070. if (hasFill) {
  1071. return ellipseDistance(squareX, squareY, rx, ry) <= 1;
  1072. }
  1073. if (hasStroke) {
  1074. return ellipseDistance(squareX, squareY, rx - halfLineWith, ry - halfLineWith) >= 1 && ellipseDistance(squareX, squareY, rx + halfLineWith, ry + halfLineWith) <= 1;
  1075. }
  1076. return false;
  1077. }
  1078. function isPointInPath$2(displayObject, position, isClipPath) {
  1079. var _displayObject$parsed = displayObject.parsedStyle,
  1080. x1 = _displayObject$parsed.x1,
  1081. y1 = _displayObject$parsed.y1,
  1082. x2 = _displayObject$parsed.x2,
  1083. y2 = _displayObject$parsed.y2,
  1084. lineWidth = _displayObject$parsed.lineWidth,
  1085. increasedLineWidthForHitTesting = _displayObject$parsed.increasedLineWidthForHitTesting,
  1086. _displayObject$parsed2 = _displayObject$parsed.defX,
  1087. x = _displayObject$parsed2 === void 0 ? 0 : _displayObject$parsed2,
  1088. _displayObject$parsed3 = _displayObject$parsed.defY,
  1089. y = _displayObject$parsed3 === void 0 ? 0 : _displayObject$parsed3,
  1090. pointerEvents = _displayObject$parsed.pointerEvents,
  1091. fill = _displayObject$parsed.fill,
  1092. stroke = _displayObject$parsed.stroke;
  1093. var _isFillOrStrokeAffect = gLite.isFillOrStrokeAffected(pointerEvents, fill, stroke),
  1094. hasStroke = _isFillOrStrokeAffect[1];
  1095. if (!hasStroke && !isClipPath || !lineWidth) {
  1096. return false;
  1097. }
  1098. return inLine(x1, y1, x2, y2, (lineWidth || 0) + (increasedLineWidthForHitTesting || 0), position.x + x, position.y + y);
  1099. }
  1100. // TODO: replace it with method in @antv/util
  1101. function isPointInStroke(segments, lineWidth, px, py, length) {
  1102. var isHit = false;
  1103. var halfWidth = lineWidth / 2;
  1104. for (var i = 0; i < segments.length; i++) {
  1105. var segment = segments[i];
  1106. var currentPoint = segment.currentPoint,
  1107. params = segment.params,
  1108. prePoint = segment.prePoint,
  1109. box = segment.box;
  1110. // 如果在前面已经生成过包围盒,直接按照包围盒计算
  1111. if (box && !inBox(box.x - halfWidth, box.y - halfWidth, box.width + lineWidth, box.height + lineWidth, px, py)) {
  1112. continue;
  1113. }
  1114. switch (segment.command) {
  1115. // L 和 Z 都是直线, M 不进行拾取
  1116. case 'L':
  1117. case 'Z':
  1118. isHit = inLine(prePoint[0], prePoint[1], currentPoint[0], currentPoint[1], lineWidth, px, py);
  1119. if (isHit) {
  1120. return true;
  1121. }
  1122. break;
  1123. case 'Q':
  1124. var qDistance = quadratic.pointDistance(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4], px, py);
  1125. isHit = qDistance <= lineWidth / 2;
  1126. if (isHit) {
  1127. return true;
  1128. }
  1129. break;
  1130. case 'C':
  1131. var cDistance = cubic.pointDistance(prePoint[0],
  1132. // 上一段结束位置, 即 C 的起始点
  1133. prePoint[1], params[1],
  1134. // 'C' 的参数,1、2 为第一个控制点,3、4 为第二个控制点,5、6 为结束点
  1135. params[2], params[3], params[4], params[5], params[6], px, py, length);
  1136. isHit = cDistance <= lineWidth / 2;
  1137. if (isHit) {
  1138. return true;
  1139. }
  1140. break;
  1141. case 'A':
  1142. // cache conversion result
  1143. if (!segment.cubicParams) {
  1144. segment.cubicParams = util.arcToCubic(prePoint[0], prePoint[1], params[1], params[2], params[3], params[4], params[5], params[6], params[7], undefined);
  1145. }
  1146. var args = segment.cubicParams;
  1147. // fixArc
  1148. var prePointInCubic = prePoint;
  1149. for (var _i = 0; _i < args.length; _i += 6) {
  1150. var _cDistance = cubic.pointDistance(prePointInCubic[0],
  1151. // 上一段结束位置, 即 C 的起始点
  1152. prePointInCubic[1], args[_i], args[_i + 1], args[_i + 2], args[_i + 3], args[_i + 4], args[_i + 5], px, py, length);
  1153. prePointInCubic = [args[_i + 4], args[_i + 5]];
  1154. isHit = _cDistance <= lineWidth / 2;
  1155. if (isHit) {
  1156. return true;
  1157. }
  1158. }
  1159. break;
  1160. }
  1161. }
  1162. return isHit;
  1163. }
  1164. function isPointInPath$3(displayObject, position, isClipPath, isPointInPath, renderingPluginContext, runtime) {
  1165. var _displayObject$parsed = displayObject.parsedStyle,
  1166. lineWidth = _displayObject$parsed.lineWidth,
  1167. increasedLineWidthForHitTesting = _displayObject$parsed.increasedLineWidthForHitTesting,
  1168. stroke = _displayObject$parsed.stroke,
  1169. fill = _displayObject$parsed.fill,
  1170. _displayObject$parsed2 = _displayObject$parsed.defX,
  1171. x = _displayObject$parsed2 === void 0 ? 0 : _displayObject$parsed2,
  1172. _displayObject$parsed3 = _displayObject$parsed.defY,
  1173. y = _displayObject$parsed3 === void 0 ? 0 : _displayObject$parsed3,
  1174. path = _displayObject$parsed.path,
  1175. pointerEvents = _displayObject$parsed.pointerEvents;
  1176. var segments = path.segments,
  1177. hasArc = path.hasArc,
  1178. polylines = path.polylines,
  1179. polygons = path.polygons;
  1180. var _isFillOrStrokeAffect = gLite.isFillOrStrokeAffected(pointerEvents,
  1181. // Only a closed path can be filled.
  1182. (polygons === null || polygons === void 0 ? void 0 : polygons.length) && fill, stroke),
  1183. hasFill = _isFillOrStrokeAffect[0],
  1184. hasStroke = _isFillOrStrokeAffect[1];
  1185. var totalLength = gLite.getOrCalculatePathTotalLength(displayObject);
  1186. var isHit = false;
  1187. if (hasFill || isClipPath) {
  1188. if (hasArc) {
  1189. // 存在曲线时,暂时使用 canvas 的 api 计算,后续可以进行多边形切割
  1190. isHit = isPointInPath(displayObject, position);
  1191. } else {
  1192. // 提取出来的多边形包含闭合的和非闭合的,在这里统一按照多边形处理
  1193. isHit = inPolygons(polygons, position.x + x, position.y + y) || inPolygons(polylines, position.x + x, position.y + y);
  1194. }
  1195. return isHit;
  1196. } else if (hasStroke || isClipPath) {
  1197. isHit = isPointInStroke(segments, (lineWidth || 0) + (increasedLineWidthForHitTesting || 0), position.x + x, position.y + y, totalLength);
  1198. }
  1199. return isHit;
  1200. }
  1201. function isPointInPath$4(displayObject, position, isClipPath) {
  1202. var _displayObject$parsed = displayObject.parsedStyle,
  1203. stroke = _displayObject$parsed.stroke,
  1204. fill = _displayObject$parsed.fill,
  1205. lineWidth = _displayObject$parsed.lineWidth,
  1206. increasedLineWidthForHitTesting = _displayObject$parsed.increasedLineWidthForHitTesting,
  1207. points = _displayObject$parsed.points,
  1208. _displayObject$parsed2 = _displayObject$parsed.defX,
  1209. x = _displayObject$parsed2 === void 0 ? 0 : _displayObject$parsed2,
  1210. _displayObject$parsed3 = _displayObject$parsed.defY,
  1211. y = _displayObject$parsed3 === void 0 ? 0 : _displayObject$parsed3,
  1212. pointerEvents = _displayObject$parsed.pointerEvents;
  1213. var _isFillOrStrokeAffect = gLite.isFillOrStrokeAffected(pointerEvents, fill, stroke),
  1214. hasFill = _isFillOrStrokeAffect[0],
  1215. hasStroke = _isFillOrStrokeAffect[1];
  1216. var isHit = false;
  1217. if (hasStroke || isClipPath) {
  1218. isHit = inPolyline(points.points, (lineWidth || 0) + (increasedLineWidthForHitTesting || 0), position.x + x, position.y + y, true);
  1219. }
  1220. if (!isHit && (hasFill || isClipPath)) {
  1221. isHit = inPolygon(points.points, position.x + x, position.y + y);
  1222. }
  1223. return isHit;
  1224. }
  1225. function isPointInPath$5(displayObject, position, isClipPath) {
  1226. var _displayObject$parsed = displayObject.parsedStyle,
  1227. lineWidth = _displayObject$parsed.lineWidth,
  1228. increasedLineWidthForHitTesting = _displayObject$parsed.increasedLineWidthForHitTesting,
  1229. points = _displayObject$parsed.points,
  1230. _displayObject$parsed2 = _displayObject$parsed.defX,
  1231. x = _displayObject$parsed2 === void 0 ? 0 : _displayObject$parsed2,
  1232. _displayObject$parsed3 = _displayObject$parsed.defY,
  1233. y = _displayObject$parsed3 === void 0 ? 0 : _displayObject$parsed3,
  1234. pointerEvents = _displayObject$parsed.pointerEvents,
  1235. fill = _displayObject$parsed.fill,
  1236. stroke = _displayObject$parsed.stroke;
  1237. var _isFillOrStrokeAffect = gLite.isFillOrStrokeAffected(pointerEvents, fill, stroke),
  1238. hasStroke = _isFillOrStrokeAffect[1];
  1239. if (!hasStroke && !isClipPath || !lineWidth) {
  1240. return false;
  1241. }
  1242. return inPolyline(points.points, (lineWidth || 0) + (increasedLineWidthForHitTesting || 0), position.x + x, position.y + y, false);
  1243. }
  1244. function isPointInPath$6(displayObject, position, isClipPath, isPointInPath, runtime) {
  1245. var _displayObject$parsed = displayObject.parsedStyle,
  1246. radius = _displayObject$parsed.radius,
  1247. fill = _displayObject$parsed.fill,
  1248. stroke = _displayObject$parsed.stroke,
  1249. lineWidth = _displayObject$parsed.lineWidth,
  1250. increasedLineWidthForHitTesting = _displayObject$parsed.increasedLineWidthForHitTesting,
  1251. width = _displayObject$parsed.width,
  1252. height = _displayObject$parsed.height,
  1253. pointerEvents = _displayObject$parsed.pointerEvents;
  1254. var _isFillOrStrokeAffect = gLite.isFillOrStrokeAffected(pointerEvents, fill, stroke),
  1255. hasFill = _isFillOrStrokeAffect[0],
  1256. hasStroke = _isFillOrStrokeAffect[1];
  1257. var hasRadius = radius && radius.some(function (r) {
  1258. return r !== 0;
  1259. });
  1260. var lineWidthForHitTesting = (lineWidth || 0) + (increasedLineWidthForHitTesting || 0);
  1261. // 无圆角时的策略
  1262. if (!hasRadius) {
  1263. var halfWidth = lineWidthForHitTesting / 2;
  1264. // 同时填充和带有边框
  1265. if (hasFill && hasStroke || isClipPath) {
  1266. return inBox(0 - halfWidth, 0 - halfWidth, width + halfWidth, height + halfWidth, position.x, position.y);
  1267. }
  1268. // 仅填充
  1269. if (hasFill) {
  1270. return inBox(0, 0, width, height, position.x, position.y);
  1271. }
  1272. if (hasStroke) {
  1273. return inRect(0, 0, width, height, lineWidthForHitTesting, position.x, position.y);
  1274. }
  1275. } else {
  1276. var isHit = false;
  1277. if (hasStroke || isClipPath) {
  1278. isHit = inRectWithRadius(0, 0, width, height, radius.map(function (r) {
  1279. return util.clamp(r, 0, Math.min(Math.abs(width) / 2, Math.abs(height) / 2));
  1280. }), lineWidthForHitTesting, position.x, position.y);
  1281. }
  1282. // 仅填充时带有圆角的矩形直接通过图形拾取
  1283. // 以后可以改成纯数学的近似拾取,将圆弧切割成多边形
  1284. if (!isHit && (hasFill || isClipPath)) {
  1285. isHit = isPointInPath(displayObject, position);
  1286. }
  1287. return isHit;
  1288. }
  1289. return false;
  1290. }
  1291. function inRectWithRadius(minX, minY, width, height, radiusArray, lineWidth, x, y) {
  1292. var tlr = radiusArray[0],
  1293. trr = radiusArray[1],
  1294. brr = radiusArray[2],
  1295. blr = radiusArray[3];
  1296. return inLine(minX + tlr, minY, minX + width - trr, minY, lineWidth, x, y) || inLine(minX + width, minY + trr, minX + width, minY + height - brr, lineWidth, x, y) || inLine(minX + width - brr, minY + height, minX + blr, minY + height, lineWidth, x, y) || inLine(minX, minY + height - blr, minX, minY + tlr, lineWidth, x, y) || inArc(minX + width - trr, minY + trr, trr, 1.5 * Math.PI, 2 * Math.PI, lineWidth, x, y) || inArc(minX + width - brr, minY + height - brr, brr, 0, 0.5 * Math.PI, lineWidth, x, y) || inArc(minX + blr, minY + height - blr, blr, 0.5 * Math.PI, Math.PI, lineWidth, x, y) || inArc(minX + tlr, minY + tlr, tlr, Math.PI, 1.5 * Math.PI, lineWidth, x, y);
  1297. }
  1298. function isPointInPath$7(displayObject, position, isClipPath, isPointInPath, renderingPluginContext, runtime) {
  1299. var _displayObject$parsed = displayObject.parsedStyle,
  1300. pointerEvents = _displayObject$parsed.pointerEvents,
  1301. width = _displayObject$parsed.width,
  1302. height = _displayObject$parsed.height;
  1303. if (pointerEvents === 'non-transparent-pixel') {
  1304. var offscreenCanvas = renderingPluginContext.config.offscreenCanvas;
  1305. var canvas = runtime.offscreenCanvas.getOrCreateCanvas(offscreenCanvas);
  1306. var context = runtime.offscreenCanvas.getOrCreateContext(offscreenCanvas, {
  1307. willReadFrequently: true
  1308. });
  1309. canvas.width = width;
  1310. canvas.height = height;
  1311. renderingPluginContext.defaultStyleRendererFactory[gLite.Shape.IMAGE].render(context, displayObject.parsedStyle, displayObject, undefined, undefined, undefined);
  1312. var imagedata = context.getImageData(position.x, position.y, 1, 1).data;
  1313. return imagedata.every(function (component) {
  1314. return component !== 0;
  1315. });
  1316. }
  1317. return true;
  1318. }
  1319. var Plugin = /*#__PURE__*/function (_AbstractRendererPlug) {
  1320. _inheritsLoose(Plugin, _AbstractRendererPlug);
  1321. function Plugin() {
  1322. var _this;
  1323. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  1324. args[_key] = arguments[_key];
  1325. }
  1326. _this = _AbstractRendererPlug.call.apply(_AbstractRendererPlug, [this].concat(args)) || this;
  1327. _this.name = 'canvas-picker';
  1328. return _this;
  1329. }
  1330. var _proto = Plugin.prototype;
  1331. _proto.init = function init() {
  1332. var _pointInPathPickerFac;
  1333. var trueFunc = function trueFunc() {
  1334. return true;
  1335. };
  1336. var pointInPathPickerFactory = (_pointInPathPickerFac = {}, _pointInPathPickerFac[gLite.Shape.CIRCLE] = isPointInPath, _pointInPathPickerFac[gLite.Shape.ELLIPSE] = isPointInPath$1, _pointInPathPickerFac[gLite.Shape.RECT] = isPointInPath$6, _pointInPathPickerFac[gLite.Shape.LINE] = isPointInPath$2, _pointInPathPickerFac[gLite.Shape.POLYLINE] = isPointInPath$5, _pointInPathPickerFac[gLite.Shape.POLYGON] = isPointInPath$4, _pointInPathPickerFac[gLite.Shape.PATH] = isPointInPath$3, _pointInPathPickerFac[gLite.Shape.TEXT] = trueFunc, _pointInPathPickerFac[gLite.Shape.GROUP] = null, _pointInPathPickerFac[gLite.Shape.IMAGE] = isPointInPath$7, _pointInPathPickerFac[gLite.Shape.HTML] = null, _pointInPathPickerFac[gLite.Shape.MESH] = null, _pointInPathPickerFac);
  1337. // @ts-ignore
  1338. this.context.pointInPathPickerFactory = pointInPathPickerFactory;
  1339. this.addRenderingPlugin(new CanvasPickerPlugin());
  1340. };
  1341. _proto.destroy = function destroy() {
  1342. // @ts-ignore
  1343. delete this.context.pointInPathPickerFactory;
  1344. this.removeAllRenderingPlugins();
  1345. };
  1346. return Plugin;
  1347. }(gLite.AbstractRendererPlugin);
  1348. exports.Plugin = Plugin;