vue项目中如何实现网页的截图功能 (html2canvas)

 更新时间:2023年02月18日 15:57:05   作者:俺是老王  
这篇文章主要介绍了vue项目中如何实现网页的截图功能 (html2canvas),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

vue实现网页的截图功能 (html2canvas)

最近做地图的项目,有个需求就是前端需要将网页的内容生成一张图片,这个功能如果让后端做的话,前端需要把大量的代码传给后端,然后后端去解析生成图片,再返回给前端,幸运的是,html2canvas.js让这件事情变得简单起来,下面是我在vue项目中实现截图功能的代码:

先安装html2canvas

npm install html2canvas --save

或者

yarn add html2canvas

引入html2canvas

import html2canvas from 'html2canvas'

主要实现代码

1、HTML中:

<template>
    <!--超级地图-->
    <div id="superMap"/>
    
    <!--点击button即可实现页面的截图-->
    <div id="test">
      <el-button @click="getImg">截图</el-button>
    </div>
</template>

2、JavaScript中:

methods:{

//截图方法
 getImg(){
   html2canvas(
     document.getElementById('superMap'),
     {
       backgroundColor:null,//画出来的图片有白色的边框,不要可设置背景为透明色(null)
       useCORS: true,//支持图片跨域
       scale:1,//设置放大的倍数
     }
   ).then(canvas => {
     //截图用img元素承装,显示在页面的上
     let img = new Image();
     img.src = canvas.toDataURL('image/jpeg');// toDataURL :图片格式转成 base64
     document.getElementById('test').appendChild(img);
 
     //如果你需要下载截图,可以使用a标签进行下载
     let a = document.createElement('a');
     a.href = canvas.toDataURL('image/jpeg');
     a.download = 'test';
     a.click();
   })
 }
 
}

在使用html2canvas时

估计大家可能会遇到下面的问题

1、图片跨域:如果需要截图的地方包含其他域名的图片,那么会出现跨域问题

解决:

  • 1)设置useCORS:true,
  • 2)把后端的图片转成base64
  • 3)将图片都放在同一个域名下

2、画出来的图片有白色的边框

解决:

  • 1)设置 backgroundColor: null

当然本文只是关于html2canvas一小部分的配置的使用,具体可见官网:http://html2canvas.hertzen.com/documentation

vue拖动截图功能实现

拖动鼠标进行页面截图(也可指定区域拖动截图)

安装html2canvas、vue-cropper

npm i html2canvas --save          //用于将指定区域转为图片
npm i vue-cropper -S             //将图片进行裁剪

在main.js注册vue-cropper组件

import VueCropper from 'vue-cropper'
Vue.use(VueCropper)

页面中引入html2canvas

  import html2canvas from "html2canvas"
  export default{
  }

代码分解

1、将指定区域转为图片

this.$nextTick(()=>{
   html2canvas(document.body,{}).then(canvas => {    
     let dataURL = canvas.toDataURL("image/png");
     this.uploadImg = dataURL
     this.loading = true
   });
 })

这里是将body整个页面转为图片,得到base64格式数据,其他区域直接获取class或者id

2、将生成的图片进行拖动截图

<template>
    <div class="pop_alert" v-if="show">
       <vueCropper
          @mouseenter.native="enter"
          @mouseleave.native="leave"
          ref="cropper"
          :img="uploadImg"
          :outputSize="option.size"
          :outputType="option.outputType"
          :info="true"
          :full="option.full"
          :canMove="option.canMove"
          :canMoveBox="option.canMoveBox"
          :original="option.original"
          :autoCrop="option.autoCrop"
          :fixed="option.fixed"
          :fixedNumber="option.fixedNumber"
          :centerBox="option.centerBox"
          :infoTrue="option.infoTrue"
          :fixedBox="option.fixedBox"
          style="background-image:none"
        ></vueCropper>
        <div class="btn_box">
            <div @click="save">确认截图</div>
               <div @click="close">取消</div>
        </div>
     </div>
 </template>
<script>
 export default{
   data(){
       option: {
          info: true, // 裁剪框的大小信息
          outputSize: 0.8, // 裁剪生成图片的质量
          outputType: "jpeg", // 裁剪生成图片的格式
          canScale: false, // 图片是否允许滚轮缩放
          autoCrop: false, // 是否默认生成截图框
          fixedBox: false, // 固定截图框大小 不允许改变
          fixed: false, // 是否开启截图框宽高固定比例
          fixedNumber: [7, 5], // 截图框的宽高比例
          full: true, // 是否输出原图比例的截图
          canMove: false, //时候可以移动原图
          canMoveBox: true, // 截图框能否拖动
          original: false, // 上传图片按照原始比例渲染
          centerBox: false, // 截图框是否被限制在图片里面
          infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
        },
        uploadImg:"",
        show: false
   },
   methods:{
     enter() {
       if (this.uploadImg == "") {
         return;
       }
       this.$refs.cropper.startCrop(); //开始裁剪
     },
     leave() {
       this.$refs.cropper.stopCrop();//停止裁剪
     },
     save() {        //确认截图
        this.$refs.cropper.getCropData((data) => {      //获取截图的base64格式数据
          console.log(data)
          this.show = false
        })
        // this.$refs.cropper.getCropBlob(data => { //获取截图的Blob格式数据
        //   this.cutImg = data;
        // });
      },
      close(){        //取消
        this.show = false
      }
   }
 }
 </script>

全部代码

<template>
   <div>
     <div @click="tailoring">裁剪</div>
    <!--继续写页面的其他内容 pop_alert可封装成组件使用-->
    
     <div class="pop_alert" v-if="show">
       <vueCropper
          @mouseenter.native="enter"
          @mouseleave.native="leave"
          ref="cropper"
          :img="uploadImg"
          :outputSize="option.size"
          :outputType="option.outputType"
          :info="true"
          :full="option.full"
          :canMove="option.canMove"
          :canMoveBox="option.canMoveBox"
          :original="option.original"
          :autoCrop="option.autoCrop"
          :fixed="option.fixed"
          :fixedNumber="option.fixedNumber"
          :centerBox="option.centerBox"
          :infoTrue="option.infoTrue"
          :fixedBox="option.fixedBox"
          style="background-image:none"
        ></vueCropper>
        <div class="btn_box">
            <div @click="save">确认截图</div>
               <div @click="close">取消</div>
        </div>
     </div>
   </div>
</template>
<script>
import html2canvas from "html2canvas"
 export default{
  data(){
   return{
     option: {
          info: true, // 裁剪框的大小信息
          outputSize: 0.8, // 裁剪生成图片的质量
          outputType: "jpeg", // 裁剪生成图片的格式
          canScale: false, // 图片是否允许滚轮缩放
          autoCrop: false, // 是否默认生成截图框
          fixedBox: false, // 固定截图框大小 不允许改变
          fixed: false, // 是否开启截图框宽高固定比例
          fixedNumber: [7, 5], // 截图框的宽高比例
          full: true, // 是否输出原图比例的截图
          canMove: false, //时候可以移动原图
          canMoveBox: true, // 截图框能否拖动
          original: false, // 上传图片按照原始比例渲染
          centerBox: false, // 截图框是否被限制在图片里面
          infoTrue: true // true 为展示真实输出图片宽高 false 展示看到的截图框宽高
        },
        uploadImg:"",
        show: false
   }
  },
  methods:{
    tailoring(){            //裁剪
      this.$nextTick(()=>{
           html2canvas(document.body,{}).then(canvas => {
             let dataURL = canvas.toDataURL("image/png");
             this.uploadImg = dataURL
             this.show = true
           });
       })
    },
    enter() {
       if (this.uploadImg == "") {
         return;
       }
       this.$refs.cropper.startCrop(); //开始裁剪
     },
     leave() {
       this.$refs.cropper.stopCrop();//停止裁剪
     },
     save() {        //确认截图
        this.$refs.cropper.getCropData((data) => {      //获取截图的base64格式数据
          console.log(data)
          this.show = false
        })
        // this.$refs.cropper.getCropBlob(data => { //获取截图的Blob格式数据
        //   this.cutImg = data;
        // });
      },
      close(){        //取消
        this.show = false
      }
   }
 }
</script>
<style>
    .pop_alert{
      width: 100%;
      height: 100%;
      position: absolute;
      top: 0;
      left: 0;
      border: 1px dashed red;
      background-color: #000000;
    }
    .btn_box{
        position: absolute;
        top: 0;
        color: red;
        right: 0;
        font-size: 30px;
        display: flex;
        align-items: center;
        z-index: 6666;
    }
</style>

效果图

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • vue中el-input绑定键盘按键(按键修饰符)

    vue中el-input绑定键盘按键(按键修饰符)

    这篇文章主要介绍了vue中el-input绑定键盘按键(按键修饰符),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • vue单向以及双向数据绑定方式(v-bind和v-model的使用)

    vue单向以及双向数据绑定方式(v-bind和v-model的使用)

    这篇文章主要介绍了vue单向以及双向数据绑定方式(v-bind和v-model的使用),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-04-04
  • el-table渲染慢卡顿问题最优解决方案

    el-table渲染慢卡顿问题最优解决方案

    本文主要介绍了el-table渲染慢卡顿问题最优解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • vue tab切换,解决echartst图表宽度只有100px的问题

    vue tab切换,解决echartst图表宽度只有100px的问题

    这篇文章主要介绍了vue tab切换,解决echartst图表宽度只有100px的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-07-07
  • vue根据权限动态渲染按钮、组件等的函数式组件实现

    vue根据权限动态渲染按钮、组件等的函数式组件实现

    这篇文章主要介绍了vue根据权限动态渲染按钮、组件等的函数式组件实现方式,具有很好的参考价值,希望杜大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-11-11
  • Element UI中v-infinite-scroll无限滚动组件使用详解

    Element UI中v-infinite-scroll无限滚动组件使用详解

    在移动端数据的更新中许多方法孕育而生,无限滚轮也是解决的方案一种,Element-ui为vue开发了一个事件(v-infinite-scroll),下面这篇文章主要给大家介绍了关于Element UI中v-infinite-scroll无限滚动组件使用的相关资料,需要的朋友可以参考下
    2023-02-02
  • VUE3+Element-plus中el-form的使用示例代码

    VUE3+Element-plus中el-form的使用示例代码

    这篇文章主要介绍了VUE3+Element-plus中el-form的使用示例代码,本文通过图文示例代码相结合给大家介绍的非常详细,需要的朋友可以参考下
    2024-07-07
  • VUE html5-qrcode实现H5扫一扫功能实例

    VUE html5-qrcode实现H5扫一扫功能实例

    这篇文章主要给大家介绍了关于VUE html5-qrcode实现H5扫一扫功能的相关资料,html5-qrcode是轻量级和跨平台的QR码和条形码扫码的JS库,集成二维码、条形码和其他一些类型的代码扫描功能,需要的朋友可以参考下
    2023-08-08
  • Vue.js设计与实现无限递归学习总结

    Vue.js设计与实现无限递归学习总结

    这篇文章主要为大家介绍了Vue.js设计与实现无限递归学习总结,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-05-05
  • vue-cli项目中img如何使用require动态获取图片

    vue-cli项目中img如何使用require动态获取图片

    这篇文章主要介绍了vue-cli项目中img如何使用require动态获取图片,具有很好的参考价值,希望对大家有所帮助。
    2022-09-09

最新评论