vue3做海报生成并复制分享功能

       老板看到别人系统可以生成海报,也想要自己的系统可以生成海报分享,然后我就琢磨了一个。

        首先,介绍一下html2canvas,通俗的说它就是一个网页截屏脚本,你直接在用户浏览器截取页面或部分网页的“屏幕截屏”,屏幕截图是基于 DOM,因此生成的图片并不一定 100% 一致,因为它没有制作实际的屏幕截图,而是根据页面上可用的信息构建屏幕截图。具体可以看官方文档:关于 html2canvas | html2canvas中文文档
        所以,我们的海报其实也就是一个盒子里的html页面的截图,html2canvas可以将这一块区域内的页面截图生成一个canvas画布。这个就是我们需要的海报,先上代码。
        先下载html2canvas

npm install html2canvas

        我顺便把复制海报做了,生成海报你也可以另起一个盒子,通过canvas去展示,我这边直接复制海报,可以在别的地方粘贴看见。复制需要注意一个问题。复制功能需要在localhost或者https下才能使用。 否则报错:Uncaught TypeError: Cannot read properties of undefined (reading 'setData')。另外,海报的背景图片不能是background-image。只能通过 position: absolute;定位在铺满整个盒子,设置z-index比文字内容低一级,让文字内容浮在图片上。同样,如果有二维码的话也是写在文字内容区。文字内容区的元素位置就按正常操作去排版,布局就好了

//html代码
//定义一个div,注意要写id。这个盒子内就是需要生成canvas画布的页面元素
<div id="poster-container">
    //这一块是文字内容
    <div class="placardconten">
      <p class="placardcontentilte">测试生成海报</p>
    </div>
    //这一块是图片,就是你文字的背景图片
    <div class="bg">
        <img src="" alt="" class="bg"/>
    </div>
</div>
<p @click="generatePoster">复制海报</p>

//script代码,我这里使用了setup语法糖
<script setup>
import html2canvas from "html2canvas";

const generatePoster = () => {
  // 获取要生成海报的DOM元素
  const element = document.getElementById("poster-container");
  html2canvas(element).then((canvas) => {
      canvas.toBlob((blob) => {
        if ('clipboard' in navigator) {
          navigator.clipboard.write([
            new ClipboardItem({ 'image/png': blob })
          ]).then(() => {
            console.log('图片已成功复制到剪贴板');
          }).catch((error) => {
            console.error('复制图片到剪贴板失败:', error);
          });
        } else {
          // 在不支持 ClipboardItem 的浏览器中,使用其他方法复制到剪贴板
          const data = [new File([blob], 'poster.png', { type: 'image/png' })];
          const clipboardData = new DataTransfer();
          clipboardData.items.add(data[0]);

          navigator.clipboard.setData('image/png', clipboardData).then(() => {
            console.log('图片已成功复制到剪贴板');
          }).catch((error) => {
            console.error('复制图片到剪贴板失败:', error);
          });
        }
      }, 'image/png');
  });
};
</script>

//样式
<style>
#poster-container {
  width: 220px;
  height: 390px;
  margin: 0 auto;
  // padding: 20px;
  position: relative;
  z-index: 2;
  
}
.bg {
  width: 220px;
  height: 390px;
  position: absolute;
  top: 0;
  left: 0;
  z-index: -1;
}
</style>