utils.js 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. export const networkReg = /^(http|\/\/)/;
  2. export const isBase64 = (path) => /^data:image\/(\w+);base64/.test(path);
  3. export function sleep(delay) {
  4. return new Promise(resolve => setTimeout(resolve, delay))
  5. }
  6. let {platform, SDKVersion} = uni.getSystemInfoSync()
  7. export const isPC = /windows|mac/.test(platform)
  8. // 缓存图片
  9. let cache = {}
  10. export function isNumber(value) {
  11. return /^-?\d+(\.\d+)?$/.test(value);
  12. }
  13. export function toPx(value, baseSize, isDecimal = false) {
  14. // 如果是数字
  15. if (typeof value === 'number') {
  16. return value
  17. }
  18. // 如果是字符串数字
  19. if (isNumber(value)) {
  20. return value * 1
  21. }
  22. // 如果有单位
  23. if (typeof value === 'string') {
  24. const reg = /^-?([0-9]+)?([.]{1}[0-9]+){0,1}(em|rpx|px|%)$/g
  25. const results = reg.exec(value);
  26. if (!value || !results) {
  27. return 0;
  28. }
  29. const unit = results[3];
  30. value = parseFloat(value);
  31. let res = 0;
  32. if (unit === 'rpx') {
  33. res = uni.upx2px(value);
  34. } else if (unit === 'px') {
  35. res = value * 1;
  36. } else if (unit === '%') {
  37. res = value * toPx(baseSize) / 100;
  38. } else if (unit === 'em') {
  39. res = value * toPx(baseSize || 14);
  40. }
  41. return isDecimal ? res.toFixed(2) * 1 : Math.round(res);
  42. }
  43. return 0
  44. }
  45. // 计算版本
  46. export function compareVersion(v1, v2) {
  47. v1 = v1.split('.')
  48. v2 = v2.split('.')
  49. const len = Math.max(v1.length, v2.length)
  50. while (v1.length < len) {
  51. v1.push('0')
  52. }
  53. while (v2.length < len) {
  54. v2.push('0')
  55. }
  56. for (let i = 0; i < len; i++) {
  57. const num1 = parseInt(v1[i], 10)
  58. const num2 = parseInt(v2[i], 10)
  59. if (num1 > num2) {
  60. return 1
  61. } else if (num1 < num2) {
  62. return -1
  63. }
  64. }
  65. return 0
  66. }
  67. function gte(version) {
  68. // #ifdef MP-ALIPAY
  69. SDKVersion = my.SDKVersion
  70. // #endif
  71. return compareVersion(SDKVersion, version) >= 0;
  72. }
  73. export function canIUseCanvas2d() {
  74. // #ifdef MP-WEIXIN
  75. return gte('2.9.2');
  76. // #endif
  77. // #ifdef MP-ALIPAY
  78. return gte('2.7.15');
  79. // #endif
  80. // #ifdef MP-TOUTIAO
  81. return gte('1.78.0');
  82. // #endif
  83. return false
  84. }
  85. // #ifdef MP
  86. export const prefix = () => {
  87. // #ifdef MP-TOUTIAO
  88. return tt
  89. // #endif
  90. // #ifdef MP-WEIXIN
  91. return wx
  92. // #endif
  93. // #ifdef MP-BAIDU
  94. return swan
  95. // #endif
  96. // #ifdef MP-ALIPAY
  97. return my
  98. // #endif
  99. // #ifdef MP-QQ
  100. return qq
  101. // #endif
  102. // #ifdef MP-360
  103. return qh
  104. // #endif
  105. }
  106. // #endif
  107. /**
  108. * base64转路径
  109. * @param {Object} base64
  110. */
  111. export function base64ToPath(base64) {
  112. const [, format] = /^data:image\/(\w+);base64,/.exec(base64) || [];
  113. return new Promise((resolve, reject) => {
  114. // #ifdef MP
  115. const fs = uni.getFileSystemManager()
  116. //自定义文件名
  117. if (!format) {
  118. reject(new Error('ERROR_BASE64SRC_PARSE'))
  119. }
  120. const time = new Date().getTime();
  121. let pre = prefix()
  122. const filePath = `${pre.env.USER_DATA_PATH}/${time}.${format}`
  123. fs.writeFile({
  124. filePath,
  125. data: base64.split(',')[1],
  126. encoding: 'base64',
  127. success() {
  128. resolve(filePath)
  129. },
  130. fail(err) {
  131. console.error(err)
  132. reject(err)
  133. }
  134. })
  135. // #endif
  136. // #ifdef H5
  137. // mime类型
  138. let mimeString = base64.split(',')[0].split(':')[1].split(';')[0];
  139. //base64 解码
  140. let byteString = atob(base64.split(',')[1]);
  141. //创建缓冲数组
  142. let arrayBuffer = new ArrayBuffer(byteString.length);
  143. //创建视图
  144. let intArray = new Uint8Array(arrayBuffer);
  145. for (let i = 0; i < byteString.length; i++) {
  146. intArray[i] = byteString.charCodeAt(i);
  147. }
  148. resolve(URL.createObjectURL(new Blob([intArray], {
  149. type: mimeString
  150. })))
  151. // #endif
  152. // #ifdef APP-PLUS
  153. const bitmap = new plus.nativeObj.Bitmap('bitmap' + Date.now())
  154. bitmap.loadBase64Data(base64, () => {
  155. if (!format) {
  156. reject(new Error('ERROR_BASE64SRC_PARSE'))
  157. }
  158. const time = new Date().getTime();
  159. const filePath = `_doc/uniapp_temp/${time}.${format}`
  160. bitmap.save(filePath, {},
  161. () => {
  162. bitmap.clear()
  163. resolve(filePath)
  164. },
  165. (error) => {
  166. bitmap.clear()
  167. reject(error)
  168. })
  169. }, (error) => {
  170. bitmap.clear()
  171. reject(error)
  172. })
  173. // #endif
  174. })
  175. }
  176. /**
  177. * 路径转base64
  178. * @param {Object} string
  179. */
  180. export function pathToBase64(path) {
  181. if (/^data:/.test(path)) return path
  182. return new Promise((resolve, reject) => {
  183. // #ifdef H5
  184. let image = new Image();
  185. image.setAttribute("crossOrigin", 'Anonymous');
  186. image.onload = function() {
  187. let canvas = document.createElement('canvas');
  188. canvas.width = this.naturalWidth;
  189. canvas.height = this.naturalHeight;
  190. canvas.getContext('2d').drawImage(image, 0, 0);
  191. let result = canvas.toDataURL('image/png')
  192. resolve(result);
  193. canvas.height = canvas.width = 0
  194. }
  195. image.src = path + '?v=' + Math.random()
  196. image.onerror = (error) => {
  197. reject(error);
  198. };
  199. // #endif
  200. // #ifdef MP
  201. if (uni.canIUse('getFileSystemManager')) {
  202. uni.getFileSystemManager().readFile({
  203. filePath: path,
  204. encoding: 'base64',
  205. success: (res) => {
  206. resolve('data:image/png;base64,' + res.data)
  207. },
  208. fail: (error) => {
  209. console.error({error, path})
  210. reject(error)
  211. }
  212. })
  213. }
  214. // #endif
  215. // #ifdef APP-PLUS
  216. plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), (entry) => {
  217. entry.file((file) => {
  218. const fileReader = new plus.io.FileReader()
  219. fileReader.onload = (data) => {
  220. resolve(data.target.result)
  221. }
  222. fileReader.onerror = (error) => {
  223. reject(error)
  224. }
  225. fileReader.readAsDataURL(file)
  226. }, reject)
  227. }, reject)
  228. // #endif
  229. })
  230. }
  231. export function getImageInfo(path, useCORS) {
  232. const isCanvas2D = this && this.canvas && this.canvas.createImage
  233. return new Promise(async (resolve, reject) => {
  234. // let time = +new Date()
  235. let src = path.replace(/^@\//,'/')
  236. if (cache[path] && cache[path].errMsg) {
  237. resolve(cache[path])
  238. } else {
  239. try {
  240. // #ifdef MP || APP-PLUS
  241. if (isBase64(path) && (isCanvas2D ? isPC : true)) {
  242. src = await base64ToPath(path)
  243. }
  244. // #endif
  245. // #ifdef H5
  246. if(useCORS) {
  247. src = await pathToBase64(path)
  248. }
  249. // #endif
  250. } catch (error) {
  251. reject({
  252. ...error,
  253. src
  254. })
  255. }
  256. // #ifndef APP-NVUE
  257. if(isCanvas2D && !isPC) {
  258. const img = this.canvas.createImage()
  259. img.onload = function() {
  260. const image = {
  261. path: img,
  262. width: img.width,
  263. height: img.height
  264. }
  265. cache[path] = image
  266. resolve(cache[path])
  267. }
  268. img.onerror = function(err) {
  269. reject({err,path})
  270. }
  271. img.src = src
  272. return
  273. }
  274. // #endif
  275. uni.getImageInfo({
  276. src,
  277. success: (image) => {
  278. const localReg = /^\.|^\/(?=[^\/])/;
  279. // #ifdef MP-WEIXIN || MP-BAIDU || MP-QQ || MP-TOUTIAO
  280. image.path = localReg.test(src) ? `/${image.path}` : image.path;
  281. // #endif
  282. if(isCanvas2D) {
  283. const img = this.canvas.createImage()
  284. img.onload = function() {
  285. image.path = img
  286. cache[path] = image
  287. resolve(cache[path])
  288. }
  289. img.onerror = function(err) {
  290. reject({err,path})
  291. }
  292. img.src = src
  293. return
  294. }
  295. // #ifdef APP-PLUS
  296. // console.log('getImageInfo', +new Date() - time)
  297. // ios 比较严格 可能需要设置跨域
  298. if(uni.getSystemInfoSync().osName == 'ios' && useCORS) {
  299. pathToBase64(image.path).then(base64 => {
  300. image.path = base64
  301. cache[path] = image
  302. resolve(cache[path])
  303. }).catch(err => {
  304. console.error({err, path})
  305. reject({err,path})
  306. })
  307. return
  308. }
  309. // #endif
  310. cache[path] = image
  311. resolve(cache[path])
  312. },
  313. fail(err) {
  314. console.error({err, path})
  315. reject({err,path})
  316. }
  317. })
  318. }
  319. })
  320. }
  321. // #ifdef APP-PLUS
  322. const getLocalFilePath = (path) => {
  323. if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path
  324. .indexOf('_downloads') === 0) {
  325. return path
  326. }
  327. if (path.indexOf('file://') === 0) {
  328. return path
  329. }
  330. if (path.indexOf('/storage/emulated/0/') === 0) {
  331. return path
  332. }
  333. if (path.indexOf('/') === 0) {
  334. const localFilePath = plus.io.convertAbsoluteFileSystem(path)
  335. if (localFilePath !== path) {
  336. return localFilePath
  337. } else {
  338. path = path.substr(1)
  339. }
  340. }
  341. return '_www/' + path
  342. }
  343. // #endif