108 lines
3.0 KiB
JavaScript
108 lines
3.0 KiB
JavaScript
/**
|
||
* HTML转图片工具
|
||
* 基于 html-to-image 将DOM元素转换为图片
|
||
*/
|
||
|
||
import { toCanvas } from 'html-to-image'
|
||
|
||
/**
|
||
* 将DOM元素转换为图片
|
||
* @param {string|HTMLElement} selector - DOM选择器或元素
|
||
* @param {Object} options - 配置选项
|
||
* @param {number} [options.width] - 自定义宽度(会应用到元素上)
|
||
* @param {number} [options.height] - 自定义高度(会应用到元素上)
|
||
* @param {number} [options.canvasWidth] - 输出画布宽度
|
||
* @param {number} [options.canvasHeight] - 输出画布高度
|
||
* @param {number} [options.pixelRatio] - 像素比例,默认2
|
||
* @param {boolean} [options.useCORS] - 是否允许跨域,默认true
|
||
* @param {string} [options.format] - 图片格式,'png'或'jpeg',默认'png'
|
||
* @param {number} [options.quality] - 图片质量,0-1,仅jpeg有效,默认1.0
|
||
* @returns {Promise<string>} - 返回base64图片数据URL
|
||
*/
|
||
export async function toDataURL(selector, options = {}) {
|
||
const {
|
||
width,
|
||
height,
|
||
canvasWidth,
|
||
canvasHeight,
|
||
pixelRatio = 2,
|
||
useCORS = true,
|
||
format = 'png',
|
||
quality = 1.0
|
||
} = options
|
||
|
||
const element = typeof selector === 'string' ? document.querySelector(selector) : selector
|
||
if (!element) {
|
||
throw new Error('Element not found')
|
||
}
|
||
|
||
const canvasEl = await toCanvas(element, {
|
||
width,
|
||
height,
|
||
canvasWidth,
|
||
canvasHeight,
|
||
pixelRatio,
|
||
cors: useCORS,
|
||
backgroundColor: '#ffffff',
|
||
fetchLikeCORS: true
|
||
})
|
||
|
||
const mimeType = format === 'jpeg' ? 'image/jpeg' : 'image/png'
|
||
return canvasEl.toDataURL(mimeType, quality)
|
||
}
|
||
|
||
/**
|
||
* 将DOM元素转换为图片并下载
|
||
* @param {string|HTMLElement} selector - DOM选择器或元素
|
||
* @param {string} [filename] - 下载文件名,不含扩展名
|
||
* @param {Object} options - 配置选项,同toDataURL
|
||
*/
|
||
export async function toImageDownload(selector, filename = 'download', options = {}) {
|
||
const dataUrl = await toDataURL(selector, options)
|
||
|
||
const link = document.createElement('a')
|
||
link.download = filename + '.png'
|
||
link.href = dataUrl
|
||
document.body.appendChild(link)
|
||
link.click()
|
||
document.body.removeChild(link)
|
||
}
|
||
|
||
/**
|
||
* 将DOM元素转换为Blob
|
||
* @param {string|HTMLElement} selector - DOM选择器或元素
|
||
* @param {Object} options - 配置选项,同toDataURL
|
||
* @returns {Promise<Blob>}
|
||
*/
|
||
export async function toBlob(selector, options = {}) {
|
||
const dataUrl = await toDataURL(selector, options)
|
||
|
||
const arr = dataUrl.split(',')
|
||
const mime = arr[0].match(/:(.*?);/)[1]
|
||
const bstr = atob(arr[1])
|
||
let n = bstr.length
|
||
const u8arr = new Uint8Array(n)
|
||
while (n--) {
|
||
u8arr[n] = bstr.charCodeAt(n)
|
||
}
|
||
return new Blob([u8arr], { type: mime })
|
||
}
|
||
|
||
/**
|
||
* 通过 dataURL 直接下载图片
|
||
*/
|
||
export function downloadByDataURL(dataUrl, filename = 'download') {
|
||
const link = document.createElement('a')
|
||
link.download = filename + '.png'
|
||
link.href = dataUrl
|
||
document.body.appendChild(link)
|
||
link.click()
|
||
document.body.removeChild(link)
|
||
}
|
||
|
||
export default {
|
||
toDataURL,
|
||
toImageDownload,
|
||
toBlob,
|
||
downloadByDataURL
|
||
} |