网页转图片的方法(超出可视范围的也可以)dom-to-image

        在工作中偶尔会遇到要将整个网页或者网页的局部转为图片保存下来,最开始使用html2canvas,发现只能转可视窗口里面的元素,并且会存在css样式乱码、饿了么组件变形等问题,最后发现使用dom-to-image可以实现自己的需求

一、安装dom-to-image

npm install dom-to-image

二、演示页面

先做一个简单的demo页面,做了预览功能和下载功能。

<template>
  <div class="content">
    <div class="left">
      <el-button type="primary" @click="preview">预览</el-button>
      <el-button type="primary" @click="download">下载</el-button>
      <el-image
          style="width: 200px; height: auto;margin-top: 100px"
          :src="imgUrl"
          :zoom-rate="1.2"
          :max-scale="7"
          :min-scale="0.2"
          :preview-src-list="[imgUrl]"
          :initial-index="1"
          fit="cover"
      />
    </div>
    <div class="right" ref="rightRef">
      <div class="item red"></div>
      <div class="item green"></div>
      <div class="item blue"></div>
      <div class="item gray"></div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.content {
  width: 100vw;
  height: 100vh;
  display: flex;

  .left {
    width: 300px;
  }

  .right {
    flex: 1;
    overflow: auto;
  }

  .item {
    width: 100%;
    height: 33%;
    margin-bottom: 20px;
  }

  .red {
    background-color: rgba(255, 0, 0, .5);
  }

  .green {
    background-color: rgba(0, 255, 28, .5);
  }

  .blue {
    background-color: rgba(55, 2, 255, .5);
  }

  .gray {
    background-color: rgba(179, 179, 179, .5);
  }
}

</style>

三、dom-to-image的使用

import domtoimage from 'dom-to-image';

const rightRef = ref() //要进行转化为图片的元素对象
const imgUrl = ref() //用于存储图片地址

//预览图片
function preview() {
  domtoimage.toPng(rightRef.value)
      .then(function (base64Image:any) {
        imgUrl.value = base64Image  //转化出来后的数据是base64的类型
      })
}

点击预览后,当前窗口中的元素就已经被转为图片格式了

四、当前页面超出滚动条部分的处理

根据dom-to-image官网:https://github.com/tsayen/dom-to-image?tab=readme-ov-file的提示,可以设置图片的宽高和样式

于是可以在生成图片的时候,将图片的宽高设置为所需元素的宽高

//预览图片
function preview() {
  // 临时移除高度限制(如果需要)
  const originalHeight = rightRef.value.style.height;

  rightRef.value.style.height = 'auto'; //先把高度放开

  // 定义图片的变量
  const option = { 
    width: rightRef.value.scrollWidth,  // 确保宽度包含所有内容
    height: rightRef.value.scrollHeight, // 确保高度包含所有内容
    style: {
      overflow: 'visible',      // 确保内容不会被裁剪
    },
  }
  domtoimage.toPng(rightRef.value,option)
      .then(function (base64Image:any) {
        rightRef.value.style.height = originalHeight; // 再将盒子恢复成原样
        imgUrl.value = base64Image
      })
}

这个时候,点击预览出现的图片,就会是完整的元素图片

再添加一个下载功能

function download() {
  // 下载日报图片
  const a = document.createElement('a');
  a.href = imgUrl.value;
  a.download = '网址转图片.png';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}

五、完整demo代码

<script setup lang="ts">
import {ref} from 'vue'
import domtoimage from 'dom-to-image';

const rightRef = ref() //需要进行网页转图片的实例
const imgUrl = ref() //用于存放base64

//预览图片
function preview() {
  // 临时移除高度限制(如果需要)
  const originalHeight = rightRef.value.style.height;

  rightRef.value.style.height = 'auto'; //先把高度放开

  // 定义图片的变量
  const option = {
    width: rightRef.value.scrollWidth,  // 确保宽度包含所有内容
    height: rightRef.value.scrollHeight, // 确保高度包含所有内容
    style: {
      overflow: 'visible',      // 确保内容不会被裁剪
    },
  }
  domtoimage.toPng(rightRef.value,option)
      .then(function (base64Image:any) {
        rightRef.value.style.height = originalHeight; // 再将盒子恢复成原样
        imgUrl.value = base64Image
      })
}

function download() {
  // 下载日报图片
  const a = document.createElement('a');
  a.href = imgUrl.value;
  a.download = '网址转图片.png';
  document.body.appendChild(a);
  a.click();
  document.body.removeChild(a);
}


</script>

<template>
  <div class="content">
    <div class="left">
      <el-button type="primary" @click="preview">预览</el-button>
      <el-button type="primary" @click="download">下载</el-button>
      <el-image
          style="width: 200px; height: auto;margin-top: 100px"
          :src="imgUrl"
          :zoom-rate="1.2"
          :max-scale="7"
          :min-scale="0.2"
          :preview-src-list="[imgUrl]"
          :initial-index="1"
          fit="cover"
      />
    </div>
    <div class="right" ref="rightRef">
      <div class="item red"></div>
      <div class="item green"></div>
      <div class="item blue"></div>
      <div class="item gray"></div>
    </div>
  </div>
</template>

<style scoped lang="scss">
.content {
  width: 100vw;
  height: 100vh;
  display: flex;

  .left {
    width: 300px;
  }

  .right {
    flex: 1;
    overflow: auto;
  }

  .item {
    width: 100%;
    height: 33%;
    margin-bottom: 20px;
  }

  .red {
    background-color: rgba(255, 0, 0, .5);
  }

  .green {
    background-color: rgba(0, 255, 28, .5);
  }

  .blue {
    background-color: rgba(55, 2, 255, .5);
  }

  .gray {
    background-color: rgba(179, 179, 179, .5);
  }
}

</style>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值