H5 图片压缩处理

功能:基本压缩,水印操作,单个批量图片的压缩
实例调用

  1. const fileDom = document.querySelector('#fileUpload')
  2. const afterImg = document.querySelector('#afterImg')
  3. fileDom.onchange = (e) => {
  4. let file = e.target.files[0]
  5. const watermark = [
  6. {
  7. text: '水印一',
  8. color: 'black',
  9. size: 34
  10. },
  11. {
  12. text: '水印二',
  13. color: 'red',
  14. size: 12
  15. }
  16. ]
  17. compressImg(file, 0.2, watermark).then((res) => {
  18. console.log(res, '压缩后文件d0-00--')
  19. afterImg.src = res.afterSrc
  20. })
  21. console.log(file, '原文件--d0-00--')
  22. }
  1. const compressImg = (file, quality, watermark = []) => {
  2. const blobToDataURL = (blob, cb) => {
  3. let reader = new FileReader()
  4. reader.onload = (evt) => {
  5. let base64 = evt.target.result
  6. cb(base64)
  7. }
  8. reader.readAsDataURL(blob)
  9. }
  10. function fileToBase64(file) {
  11. return new Promise((resolve, reject) => {
  12. const reader = new FileReader()
  13. reader.readAsDataURL(file)
  14. reader.onload = () => {
  15. resolve(reader.result)
  16. }
  17. reader.onerror = (error) => {
  18. reject(error)
  19. }
  20. })
  21. }
  22. /**
  23. * canvas添加水印
  24. * @param {canvas对象} canvas
  25. * @param {水印文字} text
  26. */
  27. function addWatermark({
  28. canvas,
  29. width,
  30. height,
  31. color = 'red',
  32. text,
  33. layout = 'topLeft',
  34. level = 20,
  35. size = 18
  36. }) {
  37. const ctx = canvas.getContext('2d')
  38. ctx.fillStyle = color
  39. ctx.textBaseline = 'middle'
  40. const layoutWH = {
  41. topLeft: { w: 0, h: 0 },
  42. topRight: { w: width - level, h: 0 },
  43. bottomLeft: { w: 20, h: height - level },
  44. bottomRight: { w: width - 20, h: height - level },
  45. center: { w: width / 2, h: height / 2 - level }
  46. }
  47. const layerWH = layoutWH[layout]
  48. ctx.fillText(text, layerWH.w, layerWH.h)
  49. ctx.font = `${size}px Arial`
  50. return canvas
  51. }
  52. const fileTypes = [
  53. 'image/jpeg',
  54. 'image/png',
  55. 'image/gif',
  56. 'image/x-icon'
  57. ]
  58. if (Array.isArray(file)) {
  59. return Promise.all(
  60. Array.from(file).map((item) => compressImg(item, quality))
  61. )
  62. return false
  63. }
  64. return new Promise((resolve, reject) => {
  65. if (!fileTypes.includes(file.type)) {
  66. fileToBase64(file).then((src) => {
  67. resolve({
  68. file: file,
  69. origin: false,
  70. beforeSrc: src,
  71. afterSrc: src,
  72. beforeKB: Number((file.size / 1024).toFixed(2)),
  73. afterKB: Number((file.size / 1024).toFixed(2))
  74. })
  75. })
  76. return false
  77. }
  78. const fileReader = new FileReader()
  79. fileReader.onload = ({ target: { result: src } }) => {
  80. const image = new Image()
  81. image.onload = async () => {
  82. const canvas = document.createElement('canvas')
  83. canvas.width = image.width
  84. canvas.height = image.height
  85. const ctx = canvas.getContext('2d')
  86. ctx.fillStyle = '#fff'
  87. ctx.fillRect(0, 0, canvas.width, canvas.height)
  88. ctx.drawImage(image, 0, 0, image.width, image.height)
  89. // 5. 添加水印
  90. if (watermark && watermark.length > 0) {
  91. watermark.forEach((item, index) => {
  92. addWatermark({
  93. canvas,
  94. width: canvas.width,
  95. height: canvas.height - 50,
  96. color: item.color || '#fff',
  97. text: item.text,
  98. sie: item.size || '16',
  99. layout: item.layout || 'bottomLeft',
  100. level: index * 20
  101. })
  102. })
  103. }
  104. const canvasURL = canvas.toDataURL('image/jpeg', quality)
  105. const buffer = atob(canvasURL.split(',')[1])
  106. let length = buffer.length
  107. const bufferArray = new Uint8Array(new ArrayBuffer(length))
  108. while (length--) {
  109. bufferArray[length] = buffer.charCodeAt(length)
  110. }
  111. const miniFile = new File([bufferArray], file.name, {
  112. type: 'image/jpeg'
  113. })
  114. resolve({
  115. file: miniFile,
  116. origin: false,
  117. beforeSrc: src,
  118. afterSrc: canvasURL,
  119. beforeKB: Number((file.size / 1024).toFixed(2)),
  120. afterKB: Number((miniFile.size / 1024).toFixed(2))
  121. })
  122. }
  123. image.src = src
  124. }
  125. fileReader.readAsDataURL(file)
  126. })
  127. }

大数据渲染-切片处理

💡 Tips: window.requestAnimationFrame

范例

 'use strict'
      let list = document.querySelector('.list')
      let total = 100000
      let size = 20
      let index = 0
      const render = (total, index) => {
        if (total <= 0) {
          return
        }
        let curPage = Math.min(total, size)
        window.requestAnimationFrame(() => {
          let fragment = document.createDocumentFragment()
          for (let i = 0; i < curPage; ++i) {
            let item = document.createElement('li')
            item.innerText = `我是${index + i}`
            fragment.appendChild(item)
          }
          list.appendChild(fragment)
          render(total - curPage, index + curPage)
        })
      }
      render(total, index)

代码块

💡 Tips:输入/代码块或点击上方工具栏点击上方工具栏image.png,选择「代码块」、插入代码卡片。

代码块同时支持多种颜色主题:

export default class QuickSort extends Sort {
  sort(originalArray) {
    const array = [...originalArray];

    if (array.length <= 1) {
      return array;
    }

    // Init left and right arrays.
    const leftArray = [];
    const rightArray = [];

    // Take the first element of array as a pivot.
    const pivotElement = array.shift();
    const centerArray = [pivotElement];

    // Split all array elements between left, center and right arrays.
    while (array.length) {
      const currentElement = array.shift();

      // Call visiting callback.
      this.callbacks.visitingCallback(currentElement);

      if (this.comparator.equal(currentElement, pivotElement)) {
        centerArray.push(currentElement);
      } else if (this.comparator.lessThan(currentElement, pivotElement)) {
        leftArray.push(currentElement);
      } else {
        rightArray.push(currentElement);
      }
    }
    // Sort left and right arrays.
    const leftArraySorted = this.sort(leftArray);
    const rightArraySorted = this.sort(rightArray);

    return leftArraySorted.concat(centerArray, rightArraySorted);
  }
}
export default class QuickSort extends Sort {
  sort(originalArray) {
    const array = [...originalArray];

    if (array.length <= 1) {
      return array;
    }

    // Init left and right arrays.
    const leftArray = [];
    const rightArray = [];

    // Take the first element of array as a pivot.
    const pivotElement = array.shift();
    const centerArray = [pivotElement];

    // Split all array elements between left, center and right arrays.
    while (array.length) {
      const currentElement = array.shift();

      // Call visiting callback.
      this.callbacks.visitingCallback(currentElement);

      if (this.comparator.equal(currentElement, pivotElement)) {
        centerArray.push(currentElement);
      } else if (this.comparator.lessThan(currentElement, pivotElement)) {
        leftArray.push(currentElement);
      } else {
        rightArray.push(currentElement);
      }
    }
    // Sort left and right arrays.
    const leftArraySorted = this.sort(leftArray);
    const rightArraySorted = this.sort(rightArray);

    return leftArraySorted.concat(centerArray, rightArraySorted);
  }
}
export default class QuickSort extends Sort {
  sort(originalArray) {
    const array = [...originalArray];

    if (array.length <= 1) {
      return array;
    }

    // Init left and right arrays.
    const leftArray = [];
    const rightArray = [];

    // Take the first element of array as a pivot.
    const pivotElement = array.shift();
    const centerArray = [pivotElement];

    // Split all array elements between left, center and right arrays.
    while (array.length) {
      const currentElement = array.shift();

      // Call visiting callback.
      this.callbacks.visitingCallback(currentElement);

      if (this.comparator.equal(currentElement, pivotElement)) {
        centerArray.push(currentElement);
      } else if (this.comparator.lessThan(currentElement, pivotElement)) {
        leftArray.push(currentElement);
      } else {
        rightArray.push(currentElement);
      }
    }
    // Sort left and right arrays.
    const leftArraySorted = this.sort(leftArray);
    const rightArraySorted = this.sort(rightArray);

    return leftArraySorted.concat(centerArray, rightArraySorted);
  }
}

数学公式

💡 Tips:输入 /公式或点击上方工具栏点击上方工具栏image.png,选择「公式」、插入公式卡片。

公式支持行内嵌套:前端优化处理 - 图3,也支持块级嵌入。
前端优化处理 - 图4

画板

💡 Tips:输入/画板或点击上方工具栏image.png,选择「画板」、绘制流程图、架构图等各种图形。

前端优化处理 - 图6
前端优化处理 - 图7

前端优化处理 - 图8

文本绘图

💡 Tips:输入/文本绘图点击上方工具栏image.png,选择「文本绘图」、插入文本绘图卡片。
支持 plantumlmermaid 等多种格式,点击预览可看到图形。具体代码样式见说明文档

前端优化处理 - 图10前端优化处理 - 图11