182 lines
5.6 KiB
JavaScript
182 lines
5.6 KiB
JavaScript
/**
|
||
* HTML转图片工具
|
||
* 支持将HTML元素转换为PNG、JPEG格式的图片
|
||
* 使用html2canvas库实现
|
||
*/
|
||
|
||
class HTMLToImage {
|
||
constructor(options = {}) {
|
||
this.options = {
|
||
scale: 2, // 缩放比例,提高图片清晰度
|
||
useCORS: true, // 启用跨域图片支持
|
||
allowTaint: false, // 不允许污染画布
|
||
backgroundColor: '#ffffff', // 背景颜色
|
||
width: null, // 自定义宽度
|
||
height: null, // 自定义高度
|
||
...options
|
||
};
|
||
|
||
// 检查是否已加载html2canvas
|
||
if (typeof html2canvas === 'undefined') {
|
||
console.warn('html2canvas未加载,将动态加载...');
|
||
this.loadHtml2Canvas();
|
||
}
|
||
}
|
||
|
||
|
||
/**
|
||
* 将HTML元素转换为图片
|
||
* @param {HTMLElement} element - 要转换的HTML元素
|
||
* @param {Object} options - 转换选项
|
||
* @returns {Promise<string>} - 返回图片的DataURL
|
||
*/
|
||
async toImage(element, options = {}) {
|
||
try {
|
||
// 确保html2canvas已加载
|
||
if (typeof html2canvas === 'undefined') {
|
||
await this.loadHtml2Canvas();
|
||
}
|
||
|
||
const mergedOptions = { ...this.options, ...options };
|
||
|
||
const canvas = await html2canvas(element, mergedOptions);
|
||
return canvas.toDataURL('image/png');
|
||
} catch (error) {
|
||
console.error('HTML转图片失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 将HTML元素转换为JPEG图片
|
||
* @param {HTMLElement} element - 要转换的HTML元素
|
||
* @param {number} quality - JPEG质量 (0-1)
|
||
* @param {Object} options - 转换选项
|
||
* @returns {Promise<string>} - 返回图片的DataURL
|
||
*/
|
||
async toJPEG(element, quality = 0.92, options = {}) {
|
||
try {
|
||
if (typeof html2canvas === 'undefined') {
|
||
await this.loadHtml2Canvas();
|
||
}
|
||
|
||
const mergedOptions = { ...this.options, ...options };
|
||
|
||
const canvas = await html2canvas(element, mergedOptions);
|
||
return canvas.toDataURL('image/jpeg', quality);
|
||
} catch (error) {
|
||
console.error('HTML转JPEG失败:', error);
|
||
throw error;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 下载图片
|
||
* @param {string} dataURL - 图片的DataURL
|
||
* @param {string} filename - 文件名
|
||
*/
|
||
downloadImage(dataURL, filename = 'image.png') {
|
||
const link = document.createElement('a');
|
||
link.download = filename;
|
||
link.href = dataURL;
|
||
link.click();
|
||
}
|
||
|
||
/**
|
||
* 将图片DataURL转换为Blob对象
|
||
* @param {string} dataURL - 图片的DataURL
|
||
* @returns {Promise<Blob>}
|
||
*/
|
||
dataURLToBlob(dataURL) {
|
||
return new Promise((resolve) => {
|
||
const byteString = atob(dataURL.split(',')[1]);
|
||
const mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0];
|
||
const ab = new ArrayBuffer(byteString.length);
|
||
const ia = new Uint8Array(ab);
|
||
|
||
for (let i = 0; i < byteString.length; i++) {
|
||
ia[i] = byteString.charCodeAt(i);
|
||
}
|
||
|
||
resolve(new Blob([ab], { type: mimeString }));
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 获取图片的尺寸信息
|
||
* @param {string} dataURL - 图片的DataURL
|
||
* @returns {Promise<{width: number, height: number}>}
|
||
*/
|
||
getImageDimensions(dataURL) {
|
||
return new Promise((resolve) => {
|
||
const img = new Image();
|
||
img.onload = () => {
|
||
resolve({
|
||
width: img.width,
|
||
height: img.height
|
||
});
|
||
};
|
||
img.src = dataURL;
|
||
});
|
||
}
|
||
|
||
/**
|
||
* 批量转换多个元素
|
||
* @param {HTMLElement[]} elements - 要转换的元素数组
|
||
* @param {Object} options - 转换选项
|
||
* @returns {Promise<string[]>} - 返回图片DataURL数组
|
||
*/
|
||
async batchConvert(elements, options = {}) {
|
||
const results = [];
|
||
|
||
for (let i = 0; i < elements.length; i++) {
|
||
try {
|
||
const dataURL = await this.toImage(elements[i], options);
|
||
results.push(dataURL);
|
||
console.log(`第 ${i + 1} 个元素转换完成`);
|
||
} catch (error) {
|
||
console.error(`第 ${i + 1} 个元素转换失败:`, error);
|
||
results.push(null);
|
||
}
|
||
}
|
||
|
||
return results;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 便捷函数:快速转换并下载
|
||
* @param {HTMLElement} element - 要转换的HTML元素
|
||
* @param {string} filename - 文件名
|
||
* @param {Object} options - 转换选项
|
||
*/
|
||
async function convertAndDownload(element, filename = 'screenshot.png', options = {}) {
|
||
const converter = new HTMLToImage(options);
|
||
try {
|
||
const dataURL = await converter.toImage(element, options);
|
||
converter.downloadImage(dataURL, filename);
|
||
console.log('图片下载成功');
|
||
return Promise.resolve(); // 返回成功的Promise
|
||
} catch (error) {
|
||
console.error('转换下载失败:', error);
|
||
return Promise.reject(error); // 返回失败的Promise
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 便捷函数:获取图片DataURL
|
||
* @param {HTMLElement} element - 要转换的HTML元素
|
||
* @param {Object} options - 转换选项
|
||
* @returns {Promise<string>}
|
||
*/
|
||
async function getImageDataURL(element, options = {}) {
|
||
const converter = new HTMLToImage(options);
|
||
return await converter.toImage(element, options);
|
||
}
|
||
|
||
// 导出到全局作用域
|
||
if (typeof window !== 'undefined') {
|
||
window.HTMLToImage = HTMLToImage;
|
||
window.convertAndDownload = convertAndDownload;
|
||
window.getImageDataURL = getImageDataURL;
|
||
} |