HTML页面DOM内容整体生成图片——html2canvas依赖

目录

第一步:需要引入html2canvas这个插件

项目控制台中输入:npm install --save html2canvas 

第二步:在你需要使用的页面中将插件引入import html2canvas from "html2canvas"

第三步:将指定DOM元素转成图片

示例组件代码

效果展示


前言

html2canvas 是一个用于将 HTML 页面或页面中的某一部分转换为 canvas 图像的 JavaScript 库。它允许开发者在客户端浏览器中生成网页或网页元素的截图,这在需要分享、打印或保存网页内容为图像格式时非常有用。

以下是 html2canvas 的一些主要特点:

  1. 跨浏览器兼容性:html2canvas 支持多种现代浏览器,包括 Chrome、Firefox、Safari 和 Edge。

  2. 易于使用:通过简单的 API,你可以轻松地调用 html2canvas 来捕获指定元素或整个页面的截图。

  3. 异步渲染:html2canvas 提供了异步渲染能力,这意味着它不会阻塞主线程,从而避免造成页面卡顿。

  4. 可定制性:它允许你自定义输出的图片质量、分辨率等参数。

  5. 支持CSS样式:html2canvas 能够处理复杂的 CSS 样式和布局,虽然一些复杂的CSS特性可能无法完美支持。

  6. 支持跨域图片:html2canvas 可以处理跨域图片资源,但可能需要服务器端设置 CORS(跨源资源共享)策略。

  7. 支持事件处理:它提供了对用户交互的支持,如滚动事件、窗口调整等。

  8. 插件系统:html2canvas 提供了插件接口,使得你可以根据需求扩展其功能。

  9. 开源:html2canvas 是开源的,可以在 GitHub 上找到其源代码,并拥有活跃的社区支持。

要注意的是,由于 html2canvas 是基于浏览器渲染引擎的,它不可能完美地支持所有的 HTML 和 CSS 特性。例如,一些基于 WebGL 的图形或者使用了某些特定 CSS 属性的元素可能无法被正确渲染。因此,在使用 html2canvas 时,最好对目标内容进行适当的测试,以确保它能满足你的项目需求。


第一步:需要引入html2canvas这个插件

项目控制台中输入:npm install --save html2canvas 


第二步:在你需要使用的页面中将插件引入
import html2canvas from "html2canvas"


第三步:将指定DOM元素转成图片

要让html2canvas获取到你想要转换的节点内容,需要添加ref标记 或者 使用 id之类的方式

<div class="getMe" ref="getMEDom" id="getMeId"></div>

转换DOM内容为图片:

    /**
     * 将页面指定节点内容转为图片
     * 1.拿到想要转换为图片的内容节点DOM;
     * 2.转换,拿到转换后的canvas
     * 3.转换为图片
     */
    clickGeneratePicture() {
      html2canvas(this.$refs.getMeDom).then(canvas => {
        // 转成图片,生成图片地址
        //将canvas通过toDataURL转成图片url
        const imgUrl = canvas.toDataURL("image/png");
      });
    }

当然,也可以用官网的示例:

html2canvas(document.querySelector("#capture")).then(canvas => {
    document.body.appendChild(canvas)
});

 转换得到的就是一个生成好的canvas元素


示例组件代码

<template>
  <div>
    <div
      class="myBiaoZhu"
      id="myBiaoZhuDiv"
      ref="imageDom"
    >
      <img
        id="myBiaoZhu"
        :src="parseImgUrl"
        alt="平面图"
      />
    </div>
    <!-- 预览标注后的图片 -->
    <div style="width:100%">
      <img
        :src="imgUrl"
        alt=""
        style="width:100%"
      >
    </div>
    <div>
      <el-button
        type="primary"
        size="mini"
        @click="clickGeneratePicture"
      >保存标注</el-button>
    </div>

  </div>

</template>
<script>
// !可将指定dom转码为base64的插件:https://blog.youkuaiyun.com/zhongguohaoshaonian/article/details/88891021
import html2canvas from 'html2canvas'
export default {
  name: 'FlatIcon',
  components: {},
  created () {
    //   获取平面图数据
    // this.getFlatIcon()
  },
  data () {
    return {
      // require 是必须的,否则直接使用字符串,图片没法加载出来
      parseImgUrl: require('@/assets/logo.png'),
      //   图钉标注图片
      pointImg: require('@/assets/Thumbtack.svg'),
      //   标注图片的div大小
      pointSize: 50, // 标注的大小
      //   用于判断当前的标注数量,以达到点击后取消标记
      banMa: [],
      //   标出图钉后,转码成base64的图片数据
      imgUrl: ''
    }
  },
  methods: {
    //   打开页面,获取平面图数据
    getFlatIcon () {
      this.$axios.get('url').then((res) => {
        // ! 注意,axios中的then()必须用ES6语法==>(res)=>{},  否则会出现this指向错乱
        // ! function (err){} 这个就是ES5的,会造成this指向错乱
        this.parseImgUrl = res.data
      })
    },
    /**
         * 将页面指定节点内容转为图片
         * 1.拿到想要转换为图片的内容节点DOM;
         * 2.转换,拿到转换后的canvas
         * 3.转换为图片
     */
    clickGeneratePicture () {
      html2canvas(this.$refs.imageDom).then(canvas => {
        // 转成图片,生成图片地址
        this.imgUrl = canvas.toDataURL('image/png')
        console.log('带有图钉标注的图片base64数据')
        console.log(this.imgUrl)
        this.$axios.post('url', { id: 1, imgUrl: this.imgUrl }).then((res) => {
          this.$message({
            // 是否显示msg的关闭按钮
            showClose: true,
            message: '保存成功',
            type: 'success'
          })
        })
      })
    },

    // 画点
    createMarker (x, y) {
      var div = document.createElement('div')
      div.className = 'marker'
      div.id = 'marker' + this.banMa.length
      y = y + document.getElementById('myBiaoZhu').offsetTop - this.pointSize / 2
      x = x + document.getElementById('myBiaoZhu').offsetLeft - this.pointSize / 2
      div.style.width = this.pointSize + 'px'
      div.style.height = this.pointSize + 'px'
      // div.style.backgroundColor = this.pointColor;
      //   设置图钉背景图的大小,居中
      div.style.background = 'url(' + this.pointImg + ') no-repeat'
      div.style.backgroundSize = '100% 100%'
      div.style.backgroundPosition = 'bottom 0px center'
      div.style.position = 'absolute'
      div.style.left = x + 'px'
      //   向下偏移一点,看着更精确,不然div内背景图会居中,底部有一定的悬空
      div.style.top = (y - (this.pointSize / 2) + 10) + 'px'
      div.onmousedown = e => {
        // 再次点击时删除该图钉
        document.getElementById('myBiaoZhuDiv').removeChild(div)
        this.banMa = []
        this.banMa.push({ regionId: this.regionId })
        if (e && e.preventDefault) {
          // 阻止默认浏览器动作(W3C)
          e.preventDefault()
        } else {
          // IE中阻止函数器默认动作的方式
          window.event.returnValue = false
        }
        return false
      }
      //   将图钉div插入到页面中去
      document.getElementById('myBiaoZhuDiv').appendChild(div)
    }
  },
  mounted () {
    //   oncontextmenu  ===> 鼠标右击
    document.getElementById('myBiaoZhu').oncontextmenu = e => {
      if (e && e.preventDefault) {
        // 阻止默认浏览器动作(W3C)
        e.preventDefault()
      } else {
        // IE中阻止函数器默认动作的方式
        window.event.returnValue = false
      }
      return false
    } // 阻止冒泡行为和默认右键菜单事件

    document.getElementById('myBiaoZhu').onmousedown = e => {
      e = e || window.event
      if (e.button !== 2) {
        // 判断是否右击
        /*
      event.screenX是屏幕左上角到鼠标当前位置的x轴距离;
      event.clientX是浏览器左上角到鼠标当前位置的x轴距离;
      event.setoffX是鼠标当前点击控件左上角到鼠标当前位置的x轴距离;
      */
        var x = e.offsetX || e.layerX
        var y = e.offsetY || e.layerY
        console.log(x, y)
        this.banMa.push({
          // id: this.banMa.length + 1,
          positionLat: x,
          positionLng: y

        })
        this.createMarker(x, y)
      }
    }
  }
}
</script>

<style lang="less" scoped>
#myBiaoZhuDiv {
  position: relative;
  overflow: hidden;
  width: 100%;
  height: 100%;
  img {
    display: inline-block;
    z-index: 1;
    width: 100%;
    height: 100%;
  }
  .marker {
    position: absolute;
    border-radius: 50%;
    background-position: center center;
    background-size: 100%;
    z-index: 999;
  }
}
</style>

效果展示

当我在页面中点击几处后,dom中插入了【图钉图片】,看着就像在底图上钉着一样

然后,将整个dom元素转换成图片,这样哪些【图钉图片】就和底图形成了一个完成图片了

这串base64数据就是整个dom元素的图片内容

参考博客:vue页面内容生成图片并保存本地方案_小圣贤君的博客-优快云博客_vue生成图片icon-default.png?t=N7T8https://blog.youkuaiyun.com/zhongguohaoshaonian/article/details/88891021 


 博主 [DTcode7] 带您 溺亖在知识的海洋里,嘿嘿嘿.~
🐒 个人主页—— DTcode7 的博客🐒

《微信小程序相关博客》
《Vue相关博客》
《前端开发习惯与小技巧相关博客》
《AIGC相关博客》

《photoshop相关博客》
😚 吾辈才疏学浅,摹写之作,恐有瑕疵。望诸君海涵赐教。望轻喷,嘤嘤嘤 🙈
🕍 愿斯文对汝有所裨益,纵其简陋未及渊博,亦足以略尽绵薄之力。倘若尚存阙漏,敬请不吝斧正,俾便精进!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DTcode7

客官,赏个铜板吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值