u-canvas.vue 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. <template>
  2. <canvas
  3. :id="canvasId"
  4. :canvas-id="canvasId"
  5. :type="type"
  6. :disable-scroll="disableScroll"
  7. :hidpi="hidpi"
  8. @touchstart="e => $emit('onTouchstart', e)"
  9. @touchmove="e => $emit('onTouchmove', e)"
  10. @touchend="e => $emit('onTouchend', e)"
  11. @touchcancel="e => $emit('onTouchcancel', e)"
  12. @longtap="e => $emit('onLongtap', e)"
  13. @error="e => $emit('onError', e)"
  14. :style="[{
  15. width: $u.addUnit(width),
  16. height: $u.addUnit(height)
  17. },$u.addStyle(customStyle)]"
  18. />
  19. </template>
  20. <script>
  21. import WxCanvas from './wx-canvas.js';
  22. import props from './props.js';
  23. import mixin from '../../libs/mixin/mixin'
  24. import mpMixin from '../../libs/mixin/mpMixin';
  25. /**
  26. * Canvas 画布
  27. * @description 画布,支持2d和webgl,统一用法
  28. * @tutorial https://uview.d3u.cn/components/canvas.html
  29. *
  30. * @property {String} width 画布宽度
  31. * @property {String} height 画布高度
  32. * @property {String} type 画布类型
  33. * @example <u-canvas :type="type" width="100" height="100"></u-canvas>
  34. */
  35. let canvasNode = {};
  36. export default {
  37. name: 'u-canvas',
  38. mixins: [mpMixin, mixin, props],
  39. data() {
  40. return {
  41. canvasId: 'canvas' + uni.$u.guid(),
  42. }
  43. },
  44. methods: {
  45. queryCanvas() {
  46. return new Promise((resolve, reject) => {
  47. const query = uni.createSelectorQuery().in(this);
  48. query.select(`#${this.canvasId}`).fields({
  49. node: true,
  50. size: true
  51. }).exec((res) => {
  52. if (res[0]) {
  53. resolve(res[0])
  54. } else {
  55. reject(res)
  56. }
  57. });
  58. })
  59. },
  60. getCanvasContext() {
  61. return new Promise((resolve) => {
  62. let ctx;
  63. const query = uni.createSelectorQuery().in(this).select(`#${this.canvasId}`);
  64. if(this.type == '2d') {
  65. const { pixelRatio } = uni.$u.window();
  66. query.fields({node: true,size: true,}).exec((res) => {
  67. let width = parseInt(res[0].width);
  68. let height = parseInt(res[0].height);
  69. let canvas = res[0].node;
  70. canvasNode[this.canvasId] = canvas;
  71. ctx = canvas.getContext('2d');
  72. const wxCanvas = new WxCanvas(this.type, ctx, this.canvasId, true, canvas);
  73. wxCanvas.width = width * pixelRatio;
  74. wxCanvas.height = height * pixelRatio;
  75. wxCanvas.scale(pixelRatio, pixelRatio);
  76. resolve({ canvas: wxCanvas, width, height, canvasId: this.canvasId, use2D: true });
  77. });
  78. } else {
  79. canvasNode[this.canvasId] = null;
  80. // #ifdef MP-ALIPAY
  81. ctx = uni.createCanvasContext(this.canvasId);
  82. // #endif
  83. // #ifndef MP-ALIPAY
  84. ctx = uni.createCanvasContext(this.canvasId, this);
  85. // #endif
  86. const wxCanvas = new WxCanvas(this.type, ctx, this.canvasId, true);
  87. query.boundingClientRect((data) => {
  88. let width = parseInt(data.width);
  89. let height = parseInt(data.height);
  90. resolve({ canvas: wxCanvas, width, height, canvasId: this.canvasId, use2D: false });
  91. }).exec();
  92. }
  93. });
  94. },
  95. canvasToTempFilePath(options) {
  96. return new Promise((resolve, reject) => {
  97. let params = {
  98. canvas: canvasNode[this.canvasId],
  99. canvasId: this.canvasId,
  100. ...options,
  101. success: (res) => {
  102. resolve(res.tempFilePath);
  103. },
  104. fail: (error) => {
  105. reject(error);
  106. }
  107. }
  108. // #ifdef MP-ALIPAY
  109. uni.canvasToTempFilePath(params);
  110. // #endif
  111. // #ifndef MP-ALIPAY
  112. uni.canvasToTempFilePath(params, this);
  113. // #endif
  114. });
  115. }
  116. },
  117. // #ifdef VUE2
  118. beforeDestroy() {
  119. delete canvasNode[this.canvasId];
  120. },
  121. // #endif
  122. // #ifdef VUE3
  123. beforeUnmount() {
  124. delete canvasNode[this.canvasId];
  125. }
  126. // #endif
  127. }
  128. </script>