context.js 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. const uniPlatform = uni.getSystemInfoSync().uniPlatform
  2. export const uniContext = (canvasId, context) => {
  3. let ctx = uni.createCanvasContext(canvasId, context)
  4. if (!ctx.uniDrawImage) {
  5. ctx.uniDrawImage = ctx.drawImage
  6. ctx.drawImage = (image, ...agrs) => {
  7. ctx.uniDrawImage(image.src, ...agrs)
  8. }
  9. }
  10. if (!ctx.getImageData) {
  11. ctx.getImageData = (x, y, width, height) => {
  12. return new Promise((resolve, reject) => {
  13. // #ifdef MP || VUE2
  14. if (context.proxy) context = context.proxy
  15. // #endif
  16. uni.canvasGetImageData({
  17. canvasId,
  18. x,
  19. y,
  20. width:parseInt(width),
  21. height:parseInt(height),
  22. success(res) {
  23. resolve(res)
  24. },
  25. fail(error) {
  26. reject(error)
  27. }
  28. }, context)
  29. })
  30. }
  31. } else {
  32. ctx._getImageData = ctx.getImageData
  33. ctx.getImageData = (x, y, width, height) => {
  34. return new Promise((resolve, reject) => {
  35. ctx._getImageData({
  36. x,
  37. y,
  38. width: parseInt(width) ,
  39. height:parseInt(height),
  40. success(res) {
  41. resolve(res)
  42. },
  43. fail(error) {
  44. reject(error)
  45. }
  46. })
  47. })
  48. }
  49. }
  50. return ctx
  51. }
  52. class Image {
  53. constructor() {
  54. this.currentSrc = null
  55. this.naturalHeight = 0
  56. this.naturalWidth = 0
  57. this.width = 0
  58. this.height = 0
  59. this.tagName = 'IMG'
  60. }
  61. onerror() {}
  62. onload() {}
  63. set src(src) {
  64. this.currentSrc = src
  65. uni.getImageInfo({
  66. src,
  67. success: (res) => {
  68. this.naturalWidth = this.width = res.width
  69. this.naturalHeight = this.height = res.height
  70. this.onload()
  71. },
  72. fail: () => {
  73. this.onerror()
  74. }
  75. })
  76. }
  77. get src() {
  78. return this.currentSrc
  79. }
  80. }
  81. export const createImage = () => {
  82. return new Image()
  83. }
  84. export function useCurrentPage() {
  85. const pages = getCurrentPages();
  86. return pages[pages.length - 1];
  87. }
  88. export const toDataURL = (canvasId, context, options = {}) => {
  89. // #ifdef MP-QQ
  90. // context = context.$scope
  91. // #endif
  92. // #ifdef MP-ALIPAY
  93. context = ''
  94. // #endif
  95. return new Promise((resolve, reject) => {
  96. let {
  97. canvas,
  98. width,
  99. height,
  100. destWidth = 0,
  101. destHeight = 0,
  102. x = 0,
  103. y = 0,
  104. preferToDataURL
  105. } = options
  106. const {
  107. pixelRatio
  108. } = uni.getSystemInfoSync()
  109. // #ifdef MP-ALIPAY
  110. const isDD = typeof dd != 'undefined'
  111. if (!isDD && (!destWidth || !destHeight)) {
  112. destWidth = width * pixelRatio;
  113. destHeight = height * pixelRatio;
  114. width = destWidth;
  115. height = destHeight;
  116. x = x * pixelRatio
  117. y = y * pixelRatio
  118. }
  119. // #endif
  120. const params = {
  121. ...options,
  122. canvasId,
  123. id: canvasId,
  124. // #ifdef MP-ALIPAY
  125. x,
  126. y,
  127. width,
  128. height,
  129. destWidth,
  130. destHeight,
  131. // #endif
  132. canvas,
  133. success: (res) => {
  134. resolve(res.tempFilePath)
  135. },
  136. fail: (err) => {
  137. reject(err)
  138. }
  139. }
  140. // 抖音小程序canvas 2d不支持canvasToTempFilePath
  141. if (canvas && canvas.toDataURL && preferToDataURL) {
  142. let next = true
  143. const devtools = uni.getSystemInfoSync().platform == 'devtools'
  144. // #ifdef MP-TOUTIAO
  145. next = uni.getSystemInfoSync().platform != 'devtools'
  146. if (!next) {
  147. console.warn('[lime-signature] 抖音开发工具不支持bbox')
  148. }
  149. // #endif
  150. if ((x || y) && next) {
  151. const offCanvas = uni.createOffscreenCanvas({
  152. type: '2d'
  153. });
  154. const ctx = offCanvas.getContext("2d");
  155. const destWidth = Math.floor(width * pixelRatio)
  156. const destHeight = Math.floor(height * pixelRatio)
  157. offCanvas.width = destWidth // canvas.width;
  158. offCanvas.height = destHeight // canvas.height;
  159. // ctx.scale(pixelRatio, pixelRatio)
  160. // ctx.drawImage(canvas, Math.floor(x*pixelRatio), Math.floor(y*pixelRatio), destWidth, destHeight, 0,0, destWidth, destHeight);
  161. // 抖音不能在drawImage使用canvas
  162. const image = canvas.createImage()
  163. image.onload = () => {
  164. ctx.drawImage(image, Math.floor(x * pixelRatio), Math.floor(y * pixelRatio),
  165. destWidth, destHeight, 0, 0, destWidth, destHeight)
  166. const tempFilePath = offCanvas.toDataURL();
  167. resolve(tempFilePath)
  168. if (params.success) {
  169. params.success({
  170. tempFilePath
  171. })
  172. }
  173. }
  174. image.src = canvas.toDataURL()
  175. } else {
  176. const tempFilePath = canvas.toDataURL()
  177. resolve(tempFilePath)
  178. if (params.success) {
  179. params.success({
  180. tempFilePath
  181. })
  182. }
  183. }
  184. } else if (canvas && canvas.toTempFilePath) {
  185. canvas.toTempFilePath(params)
  186. } else {
  187. uni.canvasToTempFilePath(params, context)
  188. }
  189. })
  190. }