tm-render.vue 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. <template>
  2. <view class="tm-render" @touchmove.stop.prevent="">
  3. <!-- #ifdef MP-WEIXIN || MP-QQ || MP-KUAISHOU || MP-ALIPAY -->
  4. <canvas :style="{width:`${c_w}px`,height:`${c_h}px`}" @mouseup="touchend" @mousedown="touchstart"
  5. @mousemove="touchmove" @touchend="touchend" @touchmove="touchmove" @touchstart="touchstart" id="exid"
  6. canvas-id="exid" type="2d"></canvas>
  7. <!-- #endif -->
  8. <!-- #ifndef MP-WEIXIN || MP-QQ || MP-KUAISHOU || MP-ALIPAY || APP-PLUS -->
  9. <canvas :style="{width:`${c_w}px`,height:`${c_h}px`}"
  10. @mouseup="touchend"
  11. @mousedown="touchstart"
  12. @mousemove="touchmove"
  13. @touchend="touchend"
  14. @touchmove="touchmove"
  15. @touchstart="touchstart"
  16. id="exid"
  17. canvas-id="exid" ></canvas>
  18. <!-- #endif -->
  19. <!-- #ifdef APP-PLUS-->
  20. <canvas
  21. @mouseup="CRender.touchend_app"
  22. @mousedown="CRender.touchstart_app"
  23. @mousemove="CRender.touchmove_app"
  24. @touchend="CRender.touchend_app"
  25. @touchmove="CRender.touchmove_app"
  26. @touchstart="CRender.touchstart_app"
  27. :prop="app_opts" :change:prop="CRender.update_app_opts" :style="{width:`${c_w}px`,height:`${c_h}px`}" id="exid" canvas-id="exid" ></canvas>
  28. <!-- #endif -->
  29. </view>
  30. </template>
  31. <script>
  32. // #ifndef APP-PLUS
  33. import CRender from '@/tm-vuetify/tool/function/crender/class/crender.class'
  34. // #endif
  35. let render = null;
  36. export default {
  37. name: "tm-render",
  38. props: {
  39. width: {
  40. type: Number,
  41. default: 0
  42. },
  43. height: {
  44. type: Number,
  45. default: 600
  46. }
  47. },
  48. computed: {
  49. c_w: {
  50. get: function() {
  51. return this.cavan_width;
  52. },
  53. set: function(val) {
  54. this.cavan_width = val;
  55. },
  56. },
  57. c_h: function() {
  58. return uni.upx2px(this.height);
  59. }
  60. },
  61. created() {
  62. const dpr = uni.getSystemInfoSync().pixelRatio
  63. this.dpr = dpr;
  64. this.c_w = uni.upx2px(this.width);
  65. },
  66. data() {
  67. return {
  68. cavan_width: 0,
  69. canvaConfig: null,
  70. dragGrpahId: '',//当前正在拖动或者点击的项目id.
  71. old_x: 0,
  72. old_y: 0,
  73. isDrag: false,
  74. dpr: 1,
  75. app_opts:{
  76. render_app:null,
  77. graph:null,
  78. fun:[],
  79. canvaConfig:null
  80. }
  81. };
  82. },
  83. mounted() {
  84. this.$nextTick(async function() {
  85. // #ifndef APP-PLUS
  86. this.inits();
  87. // #endif
  88. // #ifdef APP-PLUS
  89. let res = await this.$Querey('.tm-render', this).catch(e => {})
  90. let p = res[0];
  91. this.$set(this.app_opts,'canvaConfig',p)
  92. // #endif
  93. })
  94. },
  95. destroyed() {
  96. render = null;
  97. clearTimeout(555)
  98. },
  99. methods: {
  100. async inits() {
  101. let t = this;
  102. let res = await this.$Querey('.tm-render', this).catch(e => {})
  103. let p = res[0];
  104. t.c_w = p.width || 300;
  105. t.canvaConfig = p;
  106. //#ifdef MP-WEIXIN || MP-QQ || MP-KUAISHOU
  107. uni.createSelectorQuery().in(t).select('#exid').fields({
  108. node: true,
  109. context: true,
  110. }, function(res) {
  111. let canvas = res.node;
  112. let ctx = canvas.getContext('2d')
  113. ctx['dpr'] = t.dpr;
  114. ctx['scaledpr'] = 10 / (10 * t.dpr);
  115. const w = ctx['width'] = t.c_w
  116. const h = ctx['height'] = t.c_h
  117. // canvas.width = res[0].width * dpr
  118. // canvas.height = res[0].height * dpr
  119. const dpr = uni.getSystemInfoSync().pixelRatio
  120. canvas.width = w * dpr
  121. canvas.height = h * dpr
  122. // 设置 canvas 坐标原点
  123. ctx.translate(0, 0);
  124. ctx.scale(dpr, dpr)
  125. render = new CRender(ctx, t, canvas)
  126. t.$nextTick(function() {
  127. // t.$emit('render', render.area);
  128. // 12296升级改造
  129. t.$emit('render', render.area);
  130. })
  131. }).exec()
  132. //#endif
  133. //#ifndef MP-WEIXIN || MP-QQ || MP-KUAISHOU || MP-ALIPAY || APP-PLUS
  134. let ctx = uni.createCanvasContext('exid', t)
  135. ctx['dpr'] = t.dpr;
  136. ctx['scaledpr'] = 10 / (10 * t.dpr);
  137. const w = ctx['width'] = t.c_w
  138. const h = ctx['height'] = t.c_h
  139. render = new CRender(ctx, t)
  140. t.$nextTick(function() {
  141. // 12296升级改造
  142. t.$emit('render', render.area);
  143. // t.$emit('render', render.area);
  144. })
  145. //#endif
  146. },
  147. wait(time) {
  148. return new Promise(resolve => setTimeout(resolve, time))
  149. },
  150. getTextWidthAndPos(shape) {
  151. // #ifdef APP-PLUS
  152. return [0,0,0,0];
  153. // #endif
  154. if (!render) return [0, 0, 0, 0];
  155. let {
  156. content,
  157. position,
  158. maxWidth,
  159. rowGap
  160. } = shape.shape
  161. const {
  162. textBaseline,
  163. fontSize,
  164. textAlign
  165. } = shape.style
  166. let [x, y] = position
  167. content = content.split('\n')
  168. const rowNum = content.length
  169. const lineHeight = fontSize + rowGap
  170. const allHeight = rowNum * lineHeight - rowGap
  171. const twidth = render.ctx.measureText(content + "").width;
  172. if (textBaseline === 'middle') {
  173. y -= allHeight * rowNum + fontSize / 2
  174. }
  175. if (textBaseline === 'bottom') {
  176. y += fontSize
  177. }
  178. if (textAlign === 'center') {
  179. x -= twidth / 2
  180. y += fontSize
  181. }
  182. return [x, y, twidth, allHeight]
  183. // measureText
  184. },
  185. getRender() {
  186. // #ifdef APP-PLUS
  187. return this.app_opts.render_app;
  188. // #endif
  189. return render;
  190. },
  191. renderCavans(e){
  192. render = e;
  193. //app触发这里。
  194. this.$emit('render', render.area);
  195. },
  196. //app-plus代理执行函数,参数一为函数名称,参数二为参数。
  197. appCallFun(funName,arg){
  198. // #ifdef APP-PLUS
  199. this.$set( this.app_opts,'fun',[funName,arg])
  200. // #endif
  201. // #ifndef APP-PLUS
  202. console.error("此函数为APP-PLUS专用,详见:https://jx2d.cn/guid/render/%E5%BC%80%E5%A7%8B%E4%BD%BF%E7%94%A8.html")
  203. // #endif
  204. },
  205. async addGraph(obj) {
  206. let t = this;
  207. let pf = obj;
  208. // #ifdef APP-PLUS
  209. this.$set( this.app_opts,'graph',obj)
  210. return
  211. // #endif
  212. if (typeof obj == 'object' && Array.isArray(obj)) {
  213. let c = obj.filter(el => {
  214. return {
  215. ...el,
  216. tmid: uni.$tm.guid()
  217. };
  218. })
  219. pf = c;
  220. } else if (typeof obj == 'object' && !Array.isArray(obj)) {
  221. pf = [{
  222. ...pf,
  223. tmid: uni.$tm.guid()
  224. }]
  225. }
  226. let graphs = pf.map(config => render.add(config))
  227. graphs.forEach((graph, i) => {
  228. const config = pf[i]
  229. t.updateGraphConfigByKey(graph, config)
  230. })
  231. await render.launchAnimation()
  232. //释放内存。
  233. // graphs = []
  234. return graphs.length == 1 ? graphs[0] : graphs;
  235. },
  236. //添加完毕需要更新下,才会显示。
  237. updateGraphConfigByKey(graph, config) {
  238. const keys = Object.keys(config)
  239. keys.forEach(async key => {
  240. if (key === 'shape' || key === 'style') {
  241. // graph.animation('shape', {x:config.shape.x+5}, true)
  242. await graph.animation(key, config[key], true)
  243. } else {
  244. graph[key] = config[key]
  245. }
  246. })
  247. },
  248. touchend(event) {
  249. let t = this;
  250. let evx = 0;
  251. let evy = 0;
  252. //触摸
  253. if (event.type.indexOf('mouse') == -1 && event.changedTouches.length == 1) {
  254. evx = event.changedTouches[0].x
  255. evy = event.changedTouches[0].y
  256. //电脑端。
  257. } else {
  258. evx = event.pageX - this.canvaConfig.left
  259. evy = event.pageY - this.canvaConfig.top;
  260. }
  261. let x = evx;
  262. let y = evy;
  263. this.dragGrpahId = "";
  264. this.isDrag = false
  265. //触发画板的事件。
  266. this.$emit('touchend', {
  267. x: x,
  268. y: y
  269. })
  270. //在那个元素上离开的。
  271. let gps = render.graphs;
  272. let isClickGrpahs = gps.filter((el, index) => {
  273. if (el.name == 'text') {
  274. let rect = t.getTextWidthAndPos(el);
  275. el.hoverRect = rect
  276. }
  277. return el.hoverCheck([x, y], el) || el.hoverCheckProcessor([x, y], el);
  278. });
  279. if (isClickGrpahs.length > 0) {
  280. let nowgap = isClickGrpahs[0];
  281. // 执行元素上绑定的事件。
  282. if (nowgap[event.type]) nowgap[event.type].call(nowgap, {
  283. x: x,
  284. y: y
  285. });
  286. }
  287. },
  288. touchmove(event) {
  289. let t = this;
  290. let evx = 0;
  291. let evy = 0;
  292. let isPc = false
  293. //触摸
  294. if (event.type.indexOf('mouse') == -1 && event.changedTouches.length == 1) {
  295. evx = event.changedTouches[0].x
  296. evy = event.changedTouches[0].y
  297. isPc = false
  298. //电脑端。
  299. } else {
  300. evx = event.pageX - this.canvaConfig.left
  301. evy = event.pageY - this.canvaConfig.top;
  302. isPc = true;
  303. }
  304. let movex = evx - this.old_x;
  305. let movey = evy - this.old_y;
  306. let x = evx;
  307. let y = evy;
  308. // 触发发画板的事件
  309. this.$emit('touchmove', {
  310. x: x,
  311. y: y
  312. })
  313. if(this.isDrag==false) return;
  314. //在哪个元素移动的。
  315. let gps = render.graphs;
  316. let isClickGrpahs = gps.filter((el, index) => {
  317. return (el.hoverCheck([x, y], el) || el.hoverCheckProcessor([x, y], el))&&el.tmid==t.dragGrpahId;
  318. });
  319. if (isClickGrpahs.length > 0) {
  320. let nowgap = isClickGrpahs[0];
  321. if (isPc) {
  322. movex = evx - this.old_x;
  323. movey = evy - this.old_y;
  324. }
  325. if ((nowgap.drag === true && this.isDrag == true) || (nowgap.drag === true && isPc == false)) {
  326. if (nowgap.name == "circle" || nowgap.name == "ellipse" ||
  327. nowgap.name == "ring" || nowgap.name == "arc" || nowgap.name == "regPolygon") {
  328. nowgap.attr('shape', {
  329. rx: movex,
  330. ry: movey
  331. })
  332. } else if (nowgap.name == "rect" ||nowgap.name == 'rectRound'|| nowgap.name == "path"|| nowgap.name == "image"|| nowgap.name == "star" || nowgap.name =='arrow') {
  333. nowgap.attr('shape', {
  334. x: movex,
  335. y: movey
  336. })
  337. } else if (nowgap.name == "text") {
  338. nowgap.attr('shape', {
  339. position: [movex, movey]
  340. })
  341. }
  342. // 执行元素上绑定的事件。
  343. if (nowgap[event.type]) nowgap[event.type].call(nowgap, {
  344. x: movex,
  345. y: movey
  346. });
  347. // if(nowgap['mousemove']||nowgap['touchmove']){
  348. // if (nowgap['mousemove']) nowgap.mousemove.call(nowgap,{x:movex,y:movey})
  349. // if (nowgap['touchmove']) nowgap.touchmove.call(nowgap,{x:movex,y:movey})
  350. // }
  351. }
  352. //配置不允许拖出边界。
  353. // if(this.dragGrpahId === nowgap.tmid
  354. // && movex+nowgap.shape.w<this.canvaConfig.width
  355. // && movey+nowgap.shape.h<this.canvaConfig.height
  356. // && x>=0&&y>=0&&movex>=0&&movey>=0
  357. // ){
  358. // }
  359. // this.$emit('shape:touchmove',{x:x,y:y,shape:nowgap})
  360. }
  361. },
  362. touchstart(event) {
  363. let t = this;
  364. let evx = 0;
  365. let evy = 0;
  366. let isPc = false
  367. //触摸
  368. if (event.type.indexOf('mouse') == -1 && event.changedTouches.length == 1) {
  369. evx = event.changedTouches[0].x
  370. evy = event.changedTouches[0].y
  371. isPc = false
  372. //电脑端。
  373. } else {
  374. evx = event.pageX - this.canvaConfig.left
  375. evy = event.pageY - this.canvaConfig.top
  376. isPc = true;
  377. }
  378. let x = evx
  379. let y = evy
  380. let gps = render.graphs;
  381. //点中了哪些图片,第一个是最顶层的,依次类推。
  382. let isClickGrpahs = gps.filter((el, index) => {
  383. // 要判断谁的层级高就是先托动谁。
  384. return el.hoverCheck([x, y], el) || el.hoverCheckProcessor([x, y], el);
  385. });
  386. if (isClickGrpahs.length > 0) {
  387. var indexOfMax = 0;
  388. var max = isClickGrpahs.reduce( (a,c,i) => c.index > a ? (indexOfMax = i,c.index) : a, 0)
  389. let nowgap = isClickGrpahs[indexOfMax];
  390. if (nowgap.drag === true) {
  391. this.dragGrpahId = nowgap.tmid;
  392. let gapPos = [];
  393. if (nowgap.name == "circle" || nowgap.name == "ellipse" ||
  394. nowgap.name == "ring" || nowgap.name == "arc" || nowgap.name == "regPolygon"
  395. ) {
  396. gapPos = [nowgap.shape.rx, nowgap.shape.ry]
  397. } else if (nowgap.name == "rect" ||nowgap.name == 'rectRound'|| nowgap.name == "path"|| nowgap.name == "image"|| nowgap.name == "star"|| nowgap.name =='arrow') {
  398. gapPos = [nowgap.shape.x, nowgap.shape.y]
  399. } else if (nowgap.name == "text") {
  400. gapPos = nowgap.shape.position
  401. }
  402. if (isPc) {
  403. this.old_x = evx - gapPos[0]
  404. this.old_y = evy - gapPos[1];
  405. } else {
  406. this.old_x = x - gapPos[0];
  407. this.old_y = y - gapPos[1];
  408. }
  409. this.isDrag = true
  410. }
  411. // 执行元素上绑定的事件。
  412. if (nowgap[event.type]) nowgap[event.type].call(nowgap, {
  413. x: x,
  414. y: y
  415. });
  416. } else {
  417. this.dragGrpahId = ""
  418. }
  419. this.$emit('touchstart', {
  420. x: x,
  421. y: y
  422. })
  423. },
  424. },
  425. }
  426. </script>
  427. <script module="CRender" lang="renderjs">
  428. var cdr = require('@/tm-vuetify/tool/function/crender/crender.min.js')
  429. const CRender = window.CRender.CRender
  430. var render_app;
  431. export default {
  432. mounted() {
  433. // #ifdef APP-PLUS
  434. this.$nextTick(function(){
  435. this.initsAppH5();
  436. })
  437. // #endif
  438. },
  439. methods: {
  440. initsAppH5(e) {
  441. let t = this;
  442. let canvas = document.querySelector('#exid').querySelector('canvas')
  443. let canvasPrent = document.querySelector('.tm-render')
  444. let w = canvasPrent.offsetWidth;
  445. let h = canvasPrent.offsetHeight;
  446. canvas.style.width = w+'px';
  447. canvas.style.height = h+'px';
  448. render_app = new CRender(canvas)
  449. this.$ownerInstance.$vm.$set(this.$ownerInstance.$vm.app_opts,'render_app',render_app)
  450. setTimeout(function() {
  451. t.$ownerInstance.callMethod('renderCavans', render_app)
  452. }, 10);
  453. },
  454. update_app_opts(newValue, oldValue, ownerInstance, instance) {
  455. if(newValue.graph){
  456. let graph = render_app.add(newValue.graph)
  457. this.$ownerInstance.$vm.app_opts.graph=null;
  458. }
  459. if(newValue.fun){
  460. if(typeof(newValue.fun)=="object" && Array.isArray(newValue.fun)){
  461. if(newValue.fun.length>0){
  462. if(newValue.fun.length==1){
  463. render_app[newValue.fun[0]]();
  464. }else if(newValue.fun.length==2){
  465. render_app[newValue.fun[0]](newValue.fun[1])
  466. }
  467. }
  468. }
  469. }
  470. },
  471. wait(time) {
  472. return new Promise(resolve => setTimeout(resolve, time))
  473. },
  474. getTextWidthAndPos(shape) {
  475. // #ifdef APP-PLUS
  476. return [0,0,0,0];
  477. // #endif
  478. if (!render) return [0, 0, 0, 0];
  479. let {
  480. content,
  481. position,
  482. maxWidth,
  483. rowGap
  484. } = shape.shape
  485. const {
  486. textBaseline,
  487. fontSize,
  488. textAlign
  489. } = shape.style
  490. let [x, y] = position
  491. content = content.split('\n')
  492. const rowNum = content.length
  493. const lineHeight = fontSize + rowGap
  494. const allHeight = rowNum * lineHeight - rowGap
  495. const twidth = render.ctx.measureText(content + "").width;
  496. if (textBaseline === 'middle') {
  497. y -= allHeight * rowNum + fontSize / 2
  498. }
  499. if (textBaseline === 'bottom') {
  500. y += fontSize
  501. }
  502. if (textAlign === 'center') {
  503. x -= twidth / 2
  504. y += fontSize
  505. }
  506. return [x, y, twidth, allHeight]
  507. // measureText
  508. },
  509. touchend_app(event) {
  510. let t = this;
  511. let evx = 0;
  512. let evy = 0;
  513. //触摸
  514. if (event.type.indexOf('mouse') == -1 && event.changedTouches.length == 1) {
  515. evx = event.changedTouches[0].x
  516. evy = event.changedTouches[0].y
  517. //电脑端。
  518. } else {
  519. evx = event.pageX - this.app_opts.canvaConfig.left
  520. evy = event.pageY - this.app_opts.canvaConfig.top;
  521. }
  522. let x = evx;
  523. let y = evy;
  524. this.dragGrpahId = "";
  525. this.isDrag = false
  526. //触发画板的事件。
  527. this.$emit('touchend', {
  528. x: x,
  529. y: y
  530. })
  531. //在那个元素上离开的。
  532. let gps = render_app.graphs;
  533. let isClickGrpahs = gps.filter((el, index) => {
  534. if (el.name == 'text') {
  535. let rect = t.getTextWidthAndPos(el);
  536. el.hoverRect = rect
  537. }
  538. return el.hoverCheck([x, y], el) || el.hoverCheckProcessor([x, y], el);
  539. });
  540. if (isClickGrpahs.length > 0) {
  541. let nowgap = isClickGrpahs[0];
  542. // 执行元素上绑定的事件。
  543. if (nowgap[event.type]) nowgap[event.type].call(nowgap, {
  544. x: x,
  545. y: y
  546. });
  547. }
  548. },
  549. touchmove_app(event) {
  550. let t = this;
  551. let evx = 0;
  552. let evy = 0;
  553. let isPc = false
  554. //触摸
  555. if (event.type.indexOf('mouse') == -1 && event.changedTouches.length == 1) {
  556. evx = event.changedTouches[0].x
  557. evy = event.changedTouches[0].y
  558. isPc = false
  559. //电脑端。
  560. } else {
  561. evx = event.pageX - this.app_opts.canvaConfig.left
  562. evy = event.pageY - this.app_opts.canvaConfig.top;
  563. isPc = true;
  564. }
  565. let movex = evx - this.old_x;
  566. let movey = evy - this.old_y;
  567. let x = evx;
  568. let y = evy;
  569. // 触发发画板的事件
  570. this.$emit('touchmove', {
  571. x: x,
  572. y: y
  573. })
  574. if(this.isDrag==false) return;
  575. //在哪个元素移动的。
  576. let gps = render_app.graphs;
  577. let isClickGrpahs = gps.filter((el, index) => {
  578. return (el.hoverCheck([x, y], el) || el.hoverCheckProcessor([x, y], el))&&el.tmid==t.dragGrpahId;
  579. });
  580. if (isClickGrpahs.length > 0) {
  581. let nowgap = isClickGrpahs[0];
  582. if (isPc) {
  583. movex = evx - this.old_x;
  584. movey = evy - this.old_y;
  585. }
  586. if ((nowgap.drag === true && this.isDrag == true) || (nowgap.drag === true && isPc == false)) {
  587. if (nowgap.name == "circle" || nowgap.name == "ellipse" ||
  588. nowgap.name == "ring" || nowgap.name == "arc" || nowgap.name == "regPolygon") {
  589. nowgap.attr('shape', {
  590. rx: movex,
  591. ry: movey
  592. })
  593. } else if (nowgap.name == "rect" ||nowgap.name == 'rectRound'|| nowgap.name == "path"|| nowgap.name == "image"|| nowgap.name == "star" || nowgap.name =='arrow') {
  594. nowgap.attr('shape', {
  595. x: movex,
  596. y: movey
  597. })
  598. } else if (nowgap.name == "text") {
  599. nowgap.attr('shape', {
  600. position: [movex, movey]
  601. })
  602. }
  603. // 执行元素上绑定的事件。
  604. if (nowgap[event.type]) nowgap[event.type].call(nowgap, {
  605. x: movex,
  606. y: movey
  607. });
  608. }
  609. }
  610. },
  611. touchstart_app(event) {
  612. let t = this;
  613. let evx = 0;
  614. let evy = 0;
  615. let isPc = false
  616. //触摸
  617. if (event.type.indexOf('mouse') == -1 && event.changedTouches.length == 1) {
  618. evx = event.changedTouches[0].x
  619. evy = event.changedTouches[0].y
  620. isPc = false
  621. //电脑端。
  622. } else {
  623. evx = event.pageX - this.app_opts.canvaConfig.left
  624. evy = event.pageY - this.app_opts.canvaConfig.top
  625. isPc = true;
  626. }
  627. let x = evx
  628. let y = evy
  629. let gps = render_app.graphs;
  630. //点中了哪些图片,第一个是最顶层的,依次类推。
  631. let isClickGrpahs = gps.filter((el, index) => {
  632. return el.hoverCheck([x, y], el) || el.hoverCheckProcessor([x, y], el);
  633. });
  634. if (isClickGrpahs.length > 0) {
  635. var indexOfMax = 0;
  636. var max = isClickGrpahs.reduce( (a,c,i) => c.index > a ? (indexOfMax = i,c.index) : a, 0)
  637. let nowgap = isClickGrpahs[indexOfMax];
  638. if (nowgap.drag === true) {
  639. this.dragGrpahId = nowgap.tmid;
  640. let gapPos = [];
  641. if (nowgap.name == "circle" || nowgap.name == "ellipse" ||
  642. nowgap.name == "ring" || nowgap.name == "arc" || nowgap.name == "regPolygon"
  643. ) {
  644. gapPos = [nowgap.shape.rx, nowgap.shape.ry]
  645. } else if (nowgap.name == "rect" ||nowgap.name == 'rectRound'|| nowgap.name == "path"|| nowgap.name == "image"|| nowgap.name == "star"|| nowgap.name =='arrow') {
  646. gapPos = [nowgap.shape.x, nowgap.shape.y]
  647. } else if (nowgap.name == "text") {
  648. gapPos = nowgap.shape.position
  649. }
  650. if (isPc) {
  651. this.old_x = evx - gapPos[0]
  652. this.old_y = evy - gapPos[1];
  653. } else {
  654. this.old_x = x - gapPos[0];
  655. this.old_y = y - gapPos[1];
  656. }
  657. this.isDrag = true
  658. }
  659. // 执行元素上绑定的事件。
  660. if (nowgap[event.type]) nowgap[event.type].call(nowgap, {
  661. x: x,
  662. y: y
  663. });
  664. } else {
  665. this.dragGrpahId = ""
  666. }
  667. this.$emit('touchstart', {
  668. x: x,
  669. y: y
  670. })
  671. },
  672. }
  673. }
  674. </script>
  675. <style lang="scss">
  676. body {}
  677. </style>