js实现一键任意html元素生成截图功能

最近在搞一个项目,用户需要截图datatable表格,表格出现滚动条时,用户需要滚动表格并截图多次,截图大小不一,比较麻烦,于是我实现一键生成html任意元素截图的功能,对于出现滚动条看不见的元素也能生成图片,示例代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/html2canvas/1.3.3/html2canvas.min.js"></script>
    <title>Canvas to Image</title>
</head>
<body>

<div id="mydiv" style="background-color:yellow">1</div>
<div id="mydiv2" style="background-color:red">2</div>
<div id="mydiv3" style="background-color:black">3</div>
<div id="mydiv4" style="background-color:purple">4</div>

<button id="pic_btn">Convert to Image</button>

<script>

$("#pic_btn").click(function(){
    convert_elements_to_image_and_download(["#mydiv", "#mydiv2", "#mydiv3", "#mydiv4"]);
})

async function convert_elements_to_image_and_download(array_ele_selectors, is_vertical=true) {
    // 元素img data保存列表
    let array_ele_img_datas = new Array();
    // 元素img 宽度保存列表
    let array_ele_img_widths = new Array();
    // 元素img 高度保存列表
    let array_ele_img_heights = new Array();
    for(let i=0; i < array_ele_selectors.length; i++){
        let selector = document.querySelector(array_ele_selectors[i]);
        array_ele_img_datas.push(await generate_img_data(selector));
        array_ele_img_widths.push(get_ele_width(selector));
        array_ele_img_heights.push(get_ele_height(selector));
    }

    let img_data = null;
    if(is_vertical){
        //垂直排列合并元素图片
        img_data = await vertical_merge_elements_pic(
            array_ele_img_datas,
            array_ele_img_widths,
            array_ele_img_heights);
    }else{
       console.log("Not support yet!");
       return false;
    }

    download_picture(img_data);
}

async function vertical_merge_elements_pic(array_ele_img_datas,
                                     array_ele_img_widths,
                                     array_ele_img_heights){
    // 垂直方向合并各个元素图片

    let total_height = 0;
    let max_width = 0;
    for(let i=0; i < array_ele_img_datas.length; i++){
        total_height += array_ele_img_heights[i];
        if(max_width < array_ele_img_widths[i]){
            max_width = array_ele_img_widths[i];
        }
    }

    // 创建canvas元素
    var canvas = document.createElement('canvas');
    // 设置canvas的宽高
    canvas.width = max_width;
    canvas.height = total_height;
    // 获取canvas的2D绘图上下文
    var ctx = canvas.getContext('2d');

    //在canvas上绘制图片
    let already_have_height = 0;
    for(var j=0;j<array_ele_img_datas.length;j++){
        await new Promise((resolve, reject) => {
            let tmp_img = new Image();
            tmp_img.onload = () => {
              ctx.drawImage(tmp_img, 0, already_have_height);
              resolve();
            };
            tmp_img.onerror = reject;
            tmp_img.src = array_ele_img_datas[j];
        });
        already_have_height += array_ele_img_heights[j];
    }

    // 返回合并后的图片
    return canvas.toDataURL();
}

function get_ele_width(element){
    //获取元素宽度
    return element.clientWidth;
}

function get_ele_height(element){
    //获取元素高度
    return element.clientHeight;
}


async function generate_img_data(element) {
  //返回的是图片base64编码
  try {
    // html2canvas是异步执行的
    // 使用await关键字等待html2canvas的Promise完成
    const canvas = await html2canvas(element);
    console.log("Canvas generated:", canvas);
    return canvas.toDataURL();
  } catch (error) {
    console.error('Error generating canvas:', error);
  }
}

function download_picture(data_url){
    // 创建一个a标签用于下载
    const a = document.createElement('a');
    a.href = data_url;
    // 设置下载的文件名
    a.download = 'screenshot.png';
    // 触发点击事件
    a.click();
}

</script>

</body>
</html>

相关推荐

  1. js实现任意html元素生成功能

    2024-07-13 14:00:02       20 阅读
  2. html2canvas生产海报图片

    2024-07-13 14:00:02       58 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-13 14:00:02       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-13 14:00:02       72 阅读
  3. 在Django里面运行非项目文件

    2024-07-13 14:00:02       58 阅读
  4. Python语言-面向对象

    2024-07-13 14:00:02       69 阅读

热门阅读

  1. 一、字符串/数组

    2024-07-13 14:00:02       20 阅读
  2. 2024年城市客运安全员考试题库及答案

    2024-07-13 14:00:02       17 阅读
  3. SwiftBrush算法与代码解读

    2024-07-13 14:00:02       20 阅读
  4. 005-基于Sklearn的机器学习入门:逻辑回归

    2024-07-13 14:00:02       28 阅读
  5. opencv—常用函数学习_“干货“_总

    2024-07-13 14:00:02       22 阅读
  6. Web组成架构

    2024-07-13 14:00:02       23 阅读
  7. Artificial intelligence machine learning DATA4800

    2024-07-13 14:00:02       24 阅读
  8. 自用的C++20协程学习资料

    2024-07-13 14:00:02       21 阅读
  9. 如何在uniapp中使用websocket?

    2024-07-13 14:00:02       16 阅读
  10. 【linux】预防rm误删文件的3种方法

    2024-07-13 14:00:02       23 阅读