tm-signBoard.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <template>
  2. <view class="tm-signBoard" >
  3. <!-- @touchmove.stop.prevent="stopEvent" -->
  4. <!-- #ifdef H5 || APP-VUE || APP-PLUS -->
  5. <canvas
  6. :style="{
  7. width: ctx_w + 'px',
  8. height: ctx_h + 'px'
  9. }"
  10. :disable-scroll="true"
  11. @touchstart="touchstart"
  12. @touchmove.stop.prevent="touchsmove"
  13. @touchend="touchsend"
  14. @mousedown="touchstart"
  15. @mousemove.stop.prevent="touchsmove"
  16. @mouseup="touchsend"
  17. :canvas-id="uid"
  18. :id="uid"
  19. ></canvas>
  20. <!-- #endif -->
  21. <!-- #ifdef MP -->
  22. <canvas
  23. :style="{
  24. width: ctx_w + 'px',
  25. height: ctx_h + 'px'
  26. }"
  27. :disable-scroll="true"
  28. @touchstart="touchstart"
  29. @touchmove="touchsmove"
  30. @touchend="touchsend"
  31. @mousedown="touchstart"
  32. @mousemove.stop.prevent="touchsmove"
  33. @mouseup="touchsend"
  34. canvas-id="tm-signBoard-id"
  35. id="tm-signBoard-id"
  36. ></canvas>
  37. <!-- #endif -->
  38. </view>
  39. </template>
  40. <script>
  41. /**
  42. * 手写签名板
  43. * @description 手写签名板,笔峰效果,通过ref执行clear和save功能。
  44. * @property {Number} line-width = [] 默认:6,线宽度。
  45. * @property {String} line-color = [] 默认:'#000000',线颜色
  46. * @property {Number} width = [] 默认:0, 画布宽,默认使用父组件的宽高。单位upx
  47. * @property {Number} height = [] 默认:400, 画布高,单位upx
  48. * @example <tm-signBoard></tm-signBoard>
  49. */
  50. export default {
  51. name: 'tm-signBoard',
  52. props: {
  53. lineWidth: {
  54. type: Number,
  55. default: 6
  56. },
  57. lineColor: {
  58. type: String,
  59. default: '#000000'
  60. },
  61. // 默认使用父组件的宽高。单位upx
  62. width: {
  63. type: Number,
  64. default: 0
  65. },
  66. // 单位upx
  67. height: {
  68. type: Number,
  69. default: 400
  70. }
  71. },
  72. data() {
  73. return {
  74. ctx: null,
  75. uid:"f",
  76. ctx_w: 0,
  77. ctx_h: 0
  78. };
  79. },
  80. created() {
  81. // #ifdef H5 || APP-VUE || APP-PLUS
  82. this.uid = this.$tm.guid();
  83. // #endif
  84. },
  85. async mounted() {
  86. let qins = await this.$Querey('.tm-signBoard',this,50).catch(e => {});
  87. this.ctx_w = uni.upx2px(this.width) || qins[0].width;
  88. this.ctx_h = uni.upx2px(this.height) || qins[0].height;
  89. this.$nextTick(function() {
  90. // #ifdef H5 || APP-VUE || APP-PLUS
  91. this.ctx = uni.createCanvasContext(this.uid, this);
  92. // #endif
  93. // #ifdef MP
  94. this.ctx = uni.createCanvasContext('tm-signBoard-id', this);
  95. // #endif
  96. this.handwriting = new uni.$tm.HandwritingSelf(this.ctx,this.ctx_w,this.ctx_h,this.lineWidth,this.lineColor)
  97. });
  98. },
  99. methods: {
  100. touchstart(event) {
  101. event.preventDefault()
  102. event.stopPropagation()
  103. if (event.type.indexOf('mouse')==-1&&event.changedTouches.length==1) {
  104. var touch = event.changedTouches[0];
  105. this.handwriting.down(touch.x,touch.y);
  106. }else{
  107. this.handwriting.down(event.pageX-event.currentTarget.offsetLeft,event.pageY-event.currentTarget.offsetTop);
  108. }
  109. },
  110. touchsmove(event) {
  111. event.preventDefault()
  112. event.stopPropagation()
  113. if (event.type.indexOf('mouse')==-1&&event.changedTouches.length == 1) {
  114. var touch = event.changedTouches[0];
  115. this.handwriting.move(touch.x,touch.y);
  116. }else{
  117. this.handwriting.move(event.pageX-event.currentTarget.offsetLeft,event.pageY-event.currentTarget.offsetTop);
  118. }
  119. },
  120. touchsend(event) {
  121. event.preventDefault()
  122. event.stopPropagation()
  123. if (event.type.indexOf('mouse')==-1&&event.changedTouches.length == 1) {
  124. var touch = event.changedTouches[0];
  125. this.handwriting.up(touch.x,touch.y);
  126. }else{
  127. this.handwriting.up(event.pageX-event.currentTarget.offsetLeft,event.pageY-event.currentTarget.offsetTop);
  128. }
  129. },
  130. clear() {
  131. if (!this.ctx) return;
  132. this.ctx.clearRect(0, 0, this.ctx_w, this.ctx_h);
  133. this.ctx.draw(false);
  134. this.$nextTick(function() {
  135. // #ifdef H5
  136. this.ctx = uni.createCanvasContext(this.uid, this);
  137. // #endif
  138. // #ifndef H5
  139. this.ctx = uni.createCanvasContext('tm-signBoard-id', this);
  140. // #endif
  141. this.handwriting = new uni.$tm.HandwritingSelf(this.ctx,this.ctx_w,this.ctx_h,this.lineWidth,this.lineColor)
  142. });
  143. },
  144. save() {
  145. let t = this;
  146. return new Promise((su, fa) => {
  147. if (!this.ctx) {
  148. fa('ctx未初始化');
  149. return;
  150. }
  151. let uid =this.uid;
  152. // #ifndef H5
  153. uid='tm-signBoard-id'
  154. // #endif
  155. uni.canvasToTempFilePath(
  156. {
  157. x: 0,
  158. y: 0,
  159. width: t.ctx_w,
  160. height: t.ctx_h,
  161. canvasId: uid,
  162. success: function(res) {
  163. // 在H5平台下,tempFilePath 为 base64
  164. su(res.tempFilePath);
  165. },
  166. fail: res => {
  167. fa(res);
  168. }
  169. },
  170. );
  171. });
  172. },
  173. stopEvent(event) {
  174. event.preventDefault()
  175. event.stopPropagation()
  176. }
  177. }
  178. };
  179. </script>
  180. <style lang="scss"></style>