useCanvasAPI.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. import { miniprogramThis } from '../internals/global'
  2. import { getSystemInfoSync } from './useNativeAPI'
  3. import { useRef } from './useDOM'
  4. export function getCanvasRef(canvasId, vm) {
  5. return useRef(`#${canvasId}`, vm)
  6. .then((res) => {
  7. if (!res) {
  8. return Promise.reject({
  9. errMsg: 'Canvas is not supported in the current environment.',
  10. })
  11. }
  12. return res.node
  13. })
  14. }
  15. export function createImage({ imageWidth, imageHeight, imageUrl }, canvas) {
  16. return new Promise((resolve, reject) => {
  17. if (typeof canvas.createImage === 'function') {
  18. const ratio = getSystemInfoSync(['window']).pixelRatio
  19. const ctx = canvas.getContext('2d')
  20. const img = canvas.createImage()
  21. img.onload = () => {
  22. ctx.drawImage(
  23. img,
  24. (-imageWidth * ratio) / 2,
  25. (-imageHeight * ratio) / 2,
  26. imageWidth * ratio,
  27. imageHeight * ratio
  28. )
  29. resolve(imageUrl)
  30. }
  31. img.onerror = () => {
  32. reject({
  33. errMsg: 'Image creation failed in canvas.createImage.',
  34. })
  35. }
  36. img.src = imageUrl
  37. } else {
  38. reject({
  39. errMsg: 'Canvas.createImage is not a function.',
  40. })
  41. }
  42. })
  43. }
  44. /**
  45. * 把当前画布指定区域的内容导出生成指定大小的图片
  46. *
  47. * @export
  48. * @param {number} width 指定的画布区域的宽度
  49. * @param {number} height 指定的画布区域的高度
  50. * @param {string} type 目标文件的类型,可选值为 png, jpg, jpeg, webp
  51. * @param {number} quality 图片的质量,目前仅对 jpg 有效。取值范围为 (0, 1],不在范围内时当作 1.0 处理。
  52. * @param {object} canvas 画布标识,传入 canvas 组件实例 (canvas type="2d" 时使用该属性)。
  53. * @return {string}
  54. */
  55. export function toDataURL({
  56. width,
  57. height,
  58. type ='png',
  59. quality = 1,
  60. }, canvas) {
  61. return new Promise((resolve) => {
  62. if (typeof canvas.toDataURL === 'function') {
  63. // 基础库 2.11.0 开始支持
  64. // @see https://developers.weixin.qq.com/miniprogram/dev/api/canvas/Canvas.toDataURL.html
  65. const fileType = type === 'jpg' || type === 'jpeg' ? 'jpeg' : type
  66. resolve(canvas.toDataURL(`image/${fileType}`, quality))
  67. } else if (typeof miniprogramThis.canvasToTempFilePath === 'function') {
  68. // 基础库 1.9.6 开始支持
  69. // @see https://developers.weixin.qq.com/miniprogram/dev/api/canvas/wx.canvasToTempFilePath.html
  70. const ratio = getSystemInfoSync(['window']).pixelRatio
  71. const fileType = type === 'jpg' || type === 'jpeg' ? 'jpg' : 'png'
  72. miniprogramThis.canvasToTempFilePath({
  73. destWidth: width * ratio,
  74. destHeight: height * ratio,
  75. canvas,
  76. fileType,
  77. quality,
  78. success: (res) => resolve(res.tempFilePath),
  79. fail: () => resolve(''),
  80. })
  81. } else {
  82. resolve('')
  83. }
  84. })
  85. }
  86. export function downloadImage(imageUrl) {
  87. return new Promise((resolve, reject) => {
  88. if (
  89. /^http/.test(imageUrl) &&
  90. // @ts-ignore
  91. !/^http:\/\/tmp/.test(imageUrl)
  92. ) {
  93. miniprogramThis.downloadFile({
  94. url: imageUrl,
  95. success: (res) => {
  96. if (res.statusCode === 200) {
  97. resolve(res.tempFilePath)
  98. } else {
  99. reject({ errMsg: res.errMsg })
  100. }
  101. },
  102. fail(err) {
  103. reject(err)
  104. },
  105. })
  106. } else {
  107. // 支持本地地址
  108. resolve(imageUrl)
  109. }
  110. })
  111. }