• 效果
    类似骨朵的一键长图骨朵剧集排行榜 通过点击按钮实现长截图,并可以滚动,长按保存或者转发。
  • java微信小程序截长图 微信小程序如何截长图_html

  • 思路
  1. 参考骨朵数据,使用的是html2canvas,骨朵的小程序是个空壳,所有的页面都是H5写的,是一整个H5项目通过<web-view src="{{realUrl}}"></web-view>嵌入到小程序中,一键长图通过用html2canvas插件生成长图。
  2. 原生小程序是无法使用html2canvas插件的。
  3. 微信小程序提供了webview组件以承载web页面。有了这个组件就可以借助web页面做很多事情了。该方案的实现正是基于这一个组件。
    该方案的实现思路:小程序页面通过webview组件加载H5页面,然后在H5页面中引入html2canvas,利用html2canvas实现HTML到canvas的转换,再把canvas转换为图片进行上。
  4. 在github上拉取了一个通过html2canvas实现长截图的项目,进行简单修改在浏览器上运行后可以实现一键长图并保存到本地
  5. 根据修改的demo在具体的实际场景中应用:由于我们只是针对个别页面进行一键长图,整体功能还是用小程序去实现,需要截图的使用html2canvas实现,那么需要截图的页面就需要是H5页面,此时,需要在小程序页面通过点击跳转到<web-view src="{{realUrl}}"></web-view>该url,在该url展示的页面去进去一键长图。
首先,记录一下git上拉下的例子

java微信小程序截长图 微信小程序如何截长图_H5_02


java微信小程序截长图 微信小程序如何截长图_java微信小程序截长图_03


java微信小程序截长图 微信小程序如何截长图_H5_04


java微信小程序截长图 微信小程序如何截长图_java微信小程序截长图_05

// views/html2canvas/html2canvas
<template>
  <div class="html2canvas-wrap">
        <div ref="area" id="aaa">
          <p>1234</p>
          <p>123</p>
          <p>123</p>

          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>123</p>
          <p>1234</p>
          <p>1234</p>
          <img src="../../../img/1.jpeg" alt="" style="width:400px; height:300px;">
        </div>
        <van-button style="position:fixed; right: 0; top: 0; z-index: 9" type="primary" @click="generateImage">生成图片</van-button>
  </div>
</template>

<script>
export default {
  name: 'html2canvas',
  components: {},
  filters: {},
  mixins: [],
  props: {},
  data () {
    return {
      imgUrl: ''
    }
  },
  computed: {},
  watch: {},
  created () {
  },
  mounted () {
  },
  methods: {
    generateImage () {
      const rect = this.$refs.area.getBoundingClientRect() // 关键代码
      console.log('3333', rect)
      this.$html2canvas(this.$refs.area, {
        scrollY: rect.top, // 关键代码
        height: rect.height + 50 // 加高度,避免截取不全
      }).then(canvas => {
        canvas.toBlob(blob => {
          this.imgUrl = URL.createObjectURL(blob)
          const aImg = document.createElement('a')
          aImg.href = this.imgUrl
          // 使用该行,点击生成的图片没有.png后缀
          // aImg.download = this.imgUrl
          // 修改后点击生成的图片有.png后缀,可以预览
          aImg.download = Date.now() + '.png'
          document.body.appendChild(aImg)
          aImg.click()
          document.body.removeChild(aImg)
        }, 'image/png')
      })
    }
  }
}
</script>
<style lang="scss" scoped>
</style>



  • 在微信小程序跳转到H5实现一键长图
    一、小程序页面
  1. 微信小程序只需要实现点击事件及需要跳转的路径即可
    具体的插件截图方法及保存方法在H5页面去实现。
    pages/index/index.wxml
<view bindtap="gogo">一键长图</view>

pages/index/index.js

Page({
	data: {},
	gogo: function(e) {
	    wx.navigateTo({
	      url: '/pages/gogo/gogo'
	    })
	}
})
  1. 提供承载H5页面的组件
    pages/gogo/gogo.wxml
<web-view src="{{realUrl}}"></web-view>

pages/gogo/gogo.js

Page({
	data: {
		// 需要一键截图页面的路径
		realUrl: 'http://193.178.1.7:8080/#/login',
	}
})

二、H5页面

  1. 先安装html2canvas
    npm install --save html2canvas
  2. 在main.js中引入依赖插件
import html2canvas from 'html2canvas'
Vue.prototype.$html2canvas = html2canvas
  1. 在home.vue中配置各方法
<template>
	<div>
		<div ref="area">
			<div>具体页面内容</div>
		</div>
		<div class="imgBox" style="display: none">
	      <div class="imgMain">
	        <p style="font-size: 14px; font-weight: bold; color: rgb(88, 88, 88);">长按下图保存或分享</p>
	        <div class="canvasImg">
	          <img src="" alt="" id="canvasPic">
	        </div>
	      </div>
	    </div>
	    <button style="position:fixed; right: 0; top: 0; z-index: 9; background: blue" type="primary" @click="generateImage">生成图片</button>
	</div>
</template>

<script>
import { mapState } from 'vuex'

export default {
  name: 'home',
  components: {},
  data() {},
  methods: {
	generateImage () {
      const rect = this.$refs.area.getBoundingClientRect() // 关键代码
      console.log(rect)
      document.body.scrollTop = 0
      document.documentElement.scrollTop = 0
      this.$html2canvas(this.$refs.area, {
        scrollY: rect.top, // 关键代码
        height: rect.height + 50 // 加高度,避免截取不全
      }).then(canvas => {
        canvas.toBlob(blob => {
          var imgBoxEle = document.getElementsByClassName('imgBox')[0]
          imgBoxEle.style.display = "block"

          this.imgUrl = canvas.toDataURL('image/jpeg')
          const aImg = document.getElementById('canvasPic')
          aImg.style = 'width: 100%;height: auto;-webkit-touch-callout: none;margin-left: 20'
          aImg.src = this.imgUrl
        }, 'image/png')
      })
    }
  }
}
</script>
<style lang="less" scoped>
@rem: 40rem;

.imgBox {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: #eee;
  color: #607d8b;
  text-align: center;
  z-index: 10000;
  .imgMain {
    position: relative;
    margin: 0;
    padding: 0 0 15px 0;
    width: 100%;
    max-width: 750px;
    min-width: 300px;
    height: auto;
    top: 0;
    left: 50%;
    transform: translate(-50%, 0);
    p {
      padding: 10px 0px;
    }
    .canvasImg {
      max-height: 547px;
      position: relative;
      margin-left: 15px;
      margin-right: 15px;
      overflow-x: hidden;
      overflow-y: auto;
      img {
        width: 100%;
        height: auto;
        background: #525252;
      }
    }
  }
}
</style>

遇到的问题

  • 小程序无法截图
    首先需要把<web-view src="{{realUrl}}"></web-view>中的路径换成ip地址,不能使用localhost,连接相同的wifi。
    在浏览器上localhost截图没有问题,
    用ip访问,会存在生成的文件没有后缀名

    发现生成的文件没有后缀名,需要自己加上,加上.png才能打开。
<template>
  <div class="html2canvas-wrap">
        <div ref="area" id="aaa">
          <p>1234</p>
          <p>123</p>
          <img src="../../../img/1.jpeg" alt="" style="width:400px; height:300px;">
        </div>
        <van-button style="position:fixed; right: 0; top: 0; z-index: 9" type="primary" @click="generateImage">生成图片</van-button>
  </div>

</template>

methods: {
    generateImage () {
      const rect = this.$refs.area.getBoundingClientRect() // 关键代码
      this.$html2canvas(this.$refs.area, {
        scrollY: rect.top, // 关键代码
        height: rect.height + 50 // 加高度,避免截取不全
      }).then(canvas => {
        canvas.toBlob(blob => {
          this.imgUrl = URL.createObjectURL(blob)
          const aImg = document.createElement('a')
          aImg.href = this.imgUrl

          // 使用该行,点击生成的图片没有.png后缀
          // aImg.download = this.imgUrl
          // 修改后点击生成的图片有.png后缀,可以预览
          aImg.download = Date.now() + '.png'
          
          document.body.appendChild(aImg)
          aImg.click()
          document.body.removeChild(aImg)
        }, 'image/png')
      })
    }
  }
  • 该代码直接放到引入小程序中的H5页面中并不可用,方法修改历程如下:
    截取不全、页面滚动后截取不全、截取的图片展示样式
generateImage () {
      const rect = this.$refs.area.getBoundingClientRect() // 关键代码
      // 4、解决页面滚动一部分后,点击截图出现截取不全的问题,需要页面滚动到顶部
      document.body.scrollTop = 0
      document.documentElement.scrollTop = 0
      this.$html2canvas(this.$refs.area, {
        scrollY: rect.top, // 关键代码
        height: rect.height + 50 // 加高度,避免截取不全
      }).then(canvas => {
        canvas.toBlob(blob => {
          var imgBoxEle = document.getElementsByClassName('imgBox')[0]
          imgBoxEle.style.display = "block"
          // 1、这段是pc浏览器上截图实现的方式
          // this.imgUrl = URL.createObjectURL(blob)
          // const aImg = document.createElement('a')
          // aImg.href = this.imgUrl
          // aImg.download = Date.now() + '.png'
          // document.body.appendChild(aImg)
          // aImg.click()
          // document.body.removeChild(aImg)

          // 2、将上面的全部注释改成这5行,可以截图,但出现截取不全
          // this.imgUrl = URL.createObjectURL(blob)
          // const aImg = document.createElement('img')
          // aImg.style = 'border:1px solid #000;width: 300px;height: auto;position:fixed;top:0;left:0;'
          // aImg.src = this.imgUrl
          // document.body.appendChild(aImg)

          // 3、解决截图不全的问题,注释掉的是最初截图生成的图片直接显示在最下面了,需要的样式是覆盖当前页面并可以滚动
          this.imgUrl = canvas.toDataURL('image/jpeg')
          // const aImg = document.createElement('img')
          const aImg = document.getElementById('canvasPic')
          // aImg.style = 'border:1px solid #000;width: 90%;height: auto;-webkit-touch-callout: none;vertical-align: top;position: fixed;top: 30;margin-left: 20'
          aImg.style = 'width: 100%;height: auto;-webkit-touch-callout: none;margin-left: 20'
          aImg.src = this.imgUrl
          // document.body.appendChild(aImg)
        }, 'image/png')
      })
    }
  • 参考文章
    主要参考前三篇,上文例子使用第三个链接
    微信小程序超长页面生成截图的一种解决方案html2canvas截长图html2canvas截长图 GitHub项目html2canvas - 实现网页截图(+下载截图) 功能html2canvas - 微信中长按存图 - 将h5活动结果保存到本地GitHub项目 gy134340/wxml2canvas小程序中如何将页面生成图片?Painter 一款轻量级的小程序海报生成组件如何实现快速生成朋友圈海报分享图