Browse Source

调整下载逻辑

lex-xin 9 months ago
parent
commit
a36ac4c85e
2 changed files with 86 additions and 96 deletions
  1. 13 60
      src/views/cloudPractice/cloudPractice.tsx
  2. 73 36
      src/views/cloudPractice/formatSvgToImg.ts

+ 13 - 60
src/views/cloudPractice/cloudPractice.tsx

@@ -5,7 +5,6 @@ import { ElEmpty, ElMessage, ElScrollbar } from "element-plus"
 import Dictionary from "@/components/dictionary"
 import MyInput from "@/components/myInput"
 import { NImage, NPopselect, NSpin, NTooltip } from "naive-ui"
-// import PlayLoading from "./component/play-loading"
 import PlayItem from "./component/play-item"
 import icon_default from "../../img/cloudPractice/icon_default.png"
 import iconBtnPause from "../../img/cloudPractice/icon-btn-pause.png"
@@ -26,8 +25,6 @@ import {
    queryTree_klx,
    selectCondition_klx
 } from "@/api/cloudPractice.api"
-// import { getToken } from "@/libs/auth"
-// import { URL_TEACH_GYM } from "@/config"
 import axios from "axios"
 import { getInstrumentName } from "@/libs/instruments"
 import { formatXML, getCustomInfo, onlyVisible } from "./instrument"
@@ -37,7 +34,7 @@ import PlayLoading from "./component/play-loading"
 import PracticeForm from "@/businessComponents/practiceForm"
 import { saveAs } from "file-saver"
 import JSZip from "jszip"
-import { svgtopng } from "./formatSvgToImg"
+import { svgtoblob } from "./formatSvgToImg"
 
 export default defineComponent({
    name: "cloudPractice",
@@ -859,76 +856,33 @@ export default defineComponent({
          }
       }
 
-      // // 获取文件blob格式
-      const imgToCanvas = async (url: string) => {
-         const img = document.createElement("img")
-         img.setAttribute("crossOrigin", "anonymous")
-         // 为了处理base64 和 连接加载不同的
-         if (url && typeof url == "string" && url.includes("data:image")) {
-            img.src = url
-         } else {
-            img.src = url + `?t=${+new Date()}`
-         }
-
-         // 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
-         await new Promise(resolve => (img.onload = resolve))
-         // 创建canvas DOM元素,并设置其宽高和图片一样
-         const canvas = document.createElement("canvas")
-         canvas.width = img.width
-         canvas.height = img.height
-         // 坐标(0,0) 表示从此处开始绘制,相当于偏移。
-         const ctx = canvas.getContext("2d") as CanvasRenderingContext2D
-
-         ctx.fillStyle = "rgb(255, 255, 255)"
-         ctx.fillStyle = "#fff"
-         ctx.fillRect(0, 0, img.width, img.height)
-         ctx.drawImage(img, 0, 0)
-         return canvas
-      }
-
-      const getFileBlob = async (url: string, type = "image/png") => {
-         const canvas: any = await imgToCanvas(url)
-         return new Promise((resolve, reject) => {
-            canvas.toBlob((blob: Blob) => {
-               if (blob) {
-                  resolve(blob)
-               } else {
-                  reject(new Error("转换失败"))
-               }
-            }, type)
-         })
-      }
-
       // // 多个文件下载
       const downLoadMultiFile = (files: any, filesName: string) => {
          const zip = new JSZip()
          const result = []
+         console.log(files)
          for (const i in files) {
-            const promise = getFileBlob(files[i].url).then((res: any) => {
-               zip.file(files[i].name, res, { binary: true })
-            })
-            result.push(promise)
+            zip.file(files[i].name, files[i].url, { binary: true })
          }
-         Promise.all(result)
-            .then(() => {
-               zip.generateAsync({ type: "blob" }).then(res => {
-                  saveAs(res, filesName ? filesName + ".zip" : `文件夹${Date.now()}.zip`)
-               })
-            })
-            .catch(() => {
-               ElMessage.error("下载失败")
-            })
-
+         zip.generateAsync({ type: "blob" }).then(res => {
+            saveAs(res, filesName ? filesName + ".zip" : `文件夹${Date.now()}.zip`)
+         })
          downloadStatus.value = false
       }
 
       const showLoading = async (e: any) => {
          if (e.data?.api === "musicStaffRender") {
+            const musicName =
+               activeItem.value.name +
+               ((activeItem.value.musicSheetType === "CONCERT" && state.selectedPartName) || state.selectedTrack
+                  ? `(${state.selectedPartName || state.selectedTrack})`
+                  : "")
+            console.log(musicName, "musicName")
             try {
                const osmdImg = e.data.osmdImg
                const imgs = []
                for (let i = 0; i < osmdImg.length; i++) {
-                  const img = await svgtopng(osmdImg[i].img, osmdImg[i].width, osmdImg[i].height)
+                  const img = await svgtoblob(osmdImg[i].img, osmdImg[i].width, osmdImg[i].height, musicName)
                   imgs.push({
                      url: img,
                      name: i + 1 + ".png"
@@ -944,7 +898,6 @@ export default defineComponent({
       }
 
       const searchContent = async () => {
-         // const status = state.musicPdfUrl ? true : false
          await toDetail()
          if (activeItem.value?.id) {
             if (state.musicPdfUrl) {

+ 73 - 36
src/views/cloudPractice/formatSvgToImg.ts

@@ -29,7 +29,7 @@ if (!window.OffscreenCanvas) {
 }
 
 const preset: any = presets.offscreen()
-const blobToBase64 = (blob: any) => {
+export const blobToBase64 = (blob: any) => {
    return new Promise(resolve => {
       const reader = new FileReader()
       reader.onloadend = () => resolve(reader.result)
@@ -37,32 +37,24 @@ const blobToBase64 = (blob: any) => {
    })
 }
 
-// export const svgtopng = async (svg: any, width: any, height: any) => {
-//    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
-//    // @ts-ignore
-//    const canvas = new OffscreenCanvas(width, height)
-//    const ctx = canvas.getContext("2d")!
-//    const v = await Canvg.fromString(ctx!, svg, preset)
-
-//    /**
-//     * Resize SVG to fit in given size.
-//     * @param width
-//     * @param height
-//     * @param preserveAspectRatio
-//     */
-//    v.resize(width * 2, height * 2, "xMidYMid meet")
-
-//    // Render only first frame, ignoring animations and mouse.
-//    await v.start()
-//    const blob = await canvas.convertToBlob()
-//    const base64 = await blobToBase64(blob)
-//    return base64
-// }
+export const addMusicTitle = (canvas: any, title: any) => {
+   canvas.getContext("2d")
+   const water = document.createElement("canvas")
+
+   // 小水印画布大小
+   water.width = canvas.width
+   water.height = canvas.height + 120
+   const waterCtx = water.getContext("2d") as CanvasRenderingContext2D
+   waterCtx.font = `66pt Calibri`
+   waterCtx.fillStyle = "#000"
+   waterCtx.textAlign = "center"
+   waterCtx.drawImage(canvas, 0, 40)
+   waterCtx.fillText(title, canvas.width / 2, 160)
+   return water
+}
 
 let canvas = null as any
-export const svgtopng = async (svg: any, width: any, height: any) => {
-   // console.log(canvas, +new Date() + '-----')
-
+export const svgtoblob = async (svg: any, width: any, height: any, name: string) => {
    if (!canvas) {
       // eslint-disable-next-line @typescript-eslint/ban-ts-comment
       // @ts-ignore
@@ -84,39 +76,84 @@ export const svgtopng = async (svg: any, width: any, height: any) => {
    await v.start()
    // const blob = await canvas.convertToBlob()
    // const base64 = await blobToBase64(blob)
-   const base64 = await canvasAddPadding(canvas)
+   const base64 = await canvasAddPadding(canvas, name)
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    await v.stop()
    v = null
    return base64
 }
 
-const convertToBlob = (canvas: any) => {
-   return new Promise(resolve => {
-      canvas.toBlob(resolve)
+const convertToBlob = (canvas: any, type = "image/png") => {
+   return new Promise((resolve, reject) => {
+      canvas.toBlob((blob: Blob) => {
+         if (blob) {
+            resolve(blob)
+         } else {
+            reject(new Error("转换失败"))
+         }
+      }, type)
    })
 }
 
-const canvasAddPadding = async (sourceCanvas: any) => {
+const canvasAddPadding = async (sourceCanvas: any, name: string) => {
    const targetCanvas = document.createElement("canvas")
    targetCanvas.width = sourceCanvas.width + 400
-   targetCanvas.height = sourceCanvas.height + 100
+   targetCanvas.height = sourceCanvas.height + 200
+
    // 坐标(0,0) 表示从此处开始绘制,相当于偏移。
    const targetContext = targetCanvas.getContext("2d") as CanvasRenderingContext2D
 
-   const sourceContext = sourceCanvas.getContext("2d") as CanvasRenderingContext2D
+   // const sourceContext = sourceCanvas.getContext("2d") as CanvasRenderingContext2D
 
    // 从源canvas中获取图像数据
-   const imageData = sourceContext.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height)
+   // const imageData = sourceContext.getImageData(0, 0, sourceCanvas.width, sourceCanvas.height)
 
    // 清空目标canvas
    targetContext.clearRect(0, 0, targetCanvas.width, targetCanvas.height)
 
    // 将图像数据绘制到目标canvas上,并添加边距
-   targetContext.putImageData(imageData, 200, 50)
+   // targetContext.putImageData(imageData, 200, 100)
+   targetContext.fillStyle = "#fff"
+   targetContext.fillRect(0, 0, targetCanvas.width, targetCanvas.height)
+   // targetCanvas = await addMusicTitle(targetCanvas, name)
+
+   // 小水印画布大小
+   // const waterCtx = water.getContext("2d") as CanvasRenderingContext2D
+   targetContext.font = `66pt Calibri`
+   targetContext.fillStyle = "#000"
+   targetContext.textAlign = "center"
+   targetContext.drawImage(canvas, 200, 240)
+   targetContext.fillText(name, canvas.width / 2, 200)
 
    const blob = await convertToBlob(targetCanvas)
-   const base64 = await blobToBase64(blob)
+   // const base64 = await blobToBase64(blob)
    targetContext.clearRect(0, 0, targetCanvas.width, targetCanvas.height)
-   return base64
+   return blob
+}
+
+// // 获取文件blob格式
+export const imgToCanvas = async (url: string) => {
+   const img = document.createElement("img")
+   img.setAttribute("crossOrigin", "anonymous")
+   // 为了处理base64 和 连接加载不同的
+   if (url && typeof url == "string" && url.includes("data:image")) {
+      img.src = url
+   } else {
+      img.src = url + `?t=${+new Date()}`
+   }
+
+   // 防止跨域引起的 Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.
+   await new Promise(resolve => (img.onload = resolve))
+   // 创建canvas DOM元素,并设置其宽高和图片一样
+   const canvas = document.createElement("canvas")
+   canvas.width = img.width
+   canvas.height = img.height
+   // 坐标(0,0) 表示从此处开始绘制,相当于偏移。
+   const ctx = canvas.getContext("2d") as CanvasRenderingContext2D
+
+   ctx.fillStyle = "rgb(255, 255, 255)"
+   ctx.fillStyle = "#fff"
+   ctx.fillRect(0, 0, img.width, img.height)
+   ctx.drawImage(img, 0, 0)
+   return canvas
 }