index.ts 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. import padStart from 'lodash/padStart'
  2. import Clipboard from 'clipboard'
  3. import CryptoJS from 'crypto-js'
  4. const CRYPTO_KEY = 'zxc_ppt_online_editor'
  5. // 生成随机数
  6. export const createRandomNumber = (min: number, max: number) => {
  7. return Math.floor(min + Math.random() * (max - min))
  8. }
  9. // 生成随机码
  10. export const createRandomCode = (len = 6) => {
  11. const charset = `_0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz`
  12. const maxLen = charset.length
  13. let ret = ''
  14. for(let i = 0; i < len; i++) {
  15. const randomIndex = Math.floor(Math.random() * maxLen)
  16. ret += charset[randomIndex]
  17. }
  18. return ret
  19. }
  20. // 生成uuid
  21. export const createUUID = () => {
  22. const url = URL.createObjectURL(new Blob())
  23. const uuid = url.toString()
  24. URL.revokeObjectURL(url)
  25. return uuid.substr(uuid.lastIndexOf('/') + 1)
  26. }
  27. // 获取当前日期字符串
  28. export const getDateTime = (format = 'yyyy-MM-dd hh:mm:ss') => {
  29. const date = new Date()
  30. const formatMap = {
  31. 'y+': date.getFullYear(),
  32. 'M+': date.getMonth() + 1,
  33. 'd+': date.getDate(),
  34. 'h+': date.getHours(),
  35. 'm+': date.getMinutes(),
  36. 's+': date.getSeconds(),
  37. }
  38. for(const item of Object.keys(formatMap)) {
  39. if(new RegExp('(' + item + ')').test(format)) {
  40. const formated = (formatMap[item] + '').length < RegExp.$1.length ? padStart('' + formatMap[item], RegExp.$1.length, '0') : formatMap[item]
  41. format = format.replace(RegExp.$1, formated)
  42. }
  43. }
  44. return format
  45. }
  46. // 数字转中文,如1049 -> 一千零四十九
  47. export const digitalToChinese = (n: number) => {
  48. const str = n + ''
  49. const len = str.length - 1
  50. const idxs = ['', '十', '百', '千']
  51. const num = ['零', '一', '二', '三', '四', '五', '六', '七', '八', '九']
  52. return str.replace(/([1-9]|0+)/g, ($, $1, idx) => {
  53. const pos = len - idx
  54. if($1 !== 0) {
  55. if(idx === 0 && $1 === 1 && idxs[pos] === '十') return idxs[pos]
  56. return num[$1] + idxs[pos]
  57. }
  58. if(idx + $1.length >= str.length) return ''
  59. return '零'
  60. })
  61. }
  62. // 数字补足位数,例如将6补足3位 -> 003
  63. export const fillDigit = (digit: number, len: number) => {
  64. return padStart('' + digit, len, '0')
  65. }
  66. // 进入全屏
  67. export const enterFullscreen = () => {
  68. const docElm = document.documentElement
  69. docElm.requestFullscreen()
  70. }
  71. // 退出全屏
  72. export const exitFullscreen = document.exitFullscreen
  73. // 判断是否全屏
  74. export const isFullscreen = () => document.fullscreenEnabled
  75. // 判断用户的操作系统是否安装了某字体
  76. export const isSupportFontFamily = (fontFamily: string) => {
  77. if(typeof fontFamily !== 'string') return false
  78. const arial = 'Arial'
  79. if(fontFamily.toLowerCase() === arial.toLowerCase()) return true
  80. const a = 'a'
  81. const size = 100
  82. const width = 100
  83. const height = 100
  84. const canvas = document.createElement('canvas')
  85. const ctx = canvas.getContext('2d')
  86. if(!ctx) return false
  87. canvas.width = width
  88. canvas.height = height
  89. ctx.textAlign = 'center'
  90. ctx.fillStyle = 'black'
  91. ctx.textBaseline = 'middle'
  92. const getDotArray = (_fontFamily: string) => {
  93. ctx.clearRect(0, 0, width, height)
  94. ctx.font = `${size}px ${_fontFamily}, ${arial}`
  95. ctx.fillText(a, width / 2, height / 2)
  96. const imageData = ctx.getImageData(0, 0, width, height).data
  97. return [].slice.call(imageData).filter(item => item !== 0)
  98. }
  99. return getDotArray(arial).join('') !== getDotArray(fontFamily).join('')
  100. }
  101. // 获取图片的原始宽高
  102. export const getImageSize = (imgUrl: string) => {
  103. return new Promise((resolve, reject) => {
  104. const img = document.createElement('img')
  105. img.src = imgUrl
  106. img.style.opacity = '0'
  107. document.body.appendChild(img)
  108. img.onload = () => {
  109. const imgWidth = img.clientWidth
  110. const imgHeight = img.clientHeight
  111. img.onload = null
  112. img.onerror = null
  113. document.body.removeChild(img)
  114. resolve({ imgWidth, imgHeight })
  115. }
  116. img.onerror = () => {
  117. img.onload = null
  118. img.onerror = null
  119. reject('图片加载失败')
  120. }
  121. })
  122. }
  123. // 复制文本到剪贴板
  124. export const copyText = (text: string) => {
  125. return new Promise((resolve, reject) => {
  126. const fakeElement = document.createElement('button')
  127. const clipboard = new Clipboard(fakeElement, {
  128. text: () => text,
  129. action: () => 'copy',
  130. container: document.body,
  131. })
  132. clipboard.on('success', e => {
  133. clipboard.destroy()
  134. resolve(e)
  135. })
  136. clipboard.on('error', e => {
  137. clipboard.destroy()
  138. reject(e)
  139. })
  140. document.body.appendChild(fakeElement)
  141. fakeElement.click()
  142. document.body.removeChild(fakeElement)
  143. })
  144. }
  145. // 读取剪贴板
  146. export const readClipboard = () => {
  147. if(navigator.clipboard) {
  148. navigator.clipboard.readText().then(text => {
  149. if(!text) return { err: '剪贴板为空或者不包含文本' }
  150. return { text }
  151. })
  152. }
  153. return { err: '浏览器不支持或禁止访问剪贴板' }
  154. }
  155. // 加密函数
  156. export const encrypt = (msg: string) => {
  157. return CryptoJS.AES.encrypt(msg, CRYPTO_KEY).toString()
  158. }
  159. // 解密函数
  160. export const decrypt = (ciphertext: string) => {
  161. const bytes = CryptoJS.AES.decrypt(ciphertext, CRYPTO_KEY)
  162. return bytes.toString(CryptoJS.enc.Utf8)
  163. }
  164. // 获取DOM节点样式
  165. export const getStyle = (el: HTMLElement, style: string) => {
  166. if(!el) return null
  167. return window.getComputedStyle(el, null).getPropertyValue(style)
  168. }
  169. // 检查元素是否处在可视区域内
  170. export const checkElementInViewport = (el: HTMLElement) => {
  171. const rect = el.getBoundingClientRect()
  172. return (
  173. rect.top >= 0 &&
  174. rect.left >= 0 &&
  175. rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) &&
  176. rect.right <= (window.innerWidth || document.documentElement.clientWidth)
  177. )
  178. }