前端生成海报图片(html2canvas偏移坑)

2 篇文章 0 订阅

好久没写博客了,今天必须立刻马上现在写一个,记录一下悲惨的两天进坑旅程!

业务需求:

大佬要求前端生成一个海报图片,用户在微信内长按图片可以进行分享,并且海报内要有分享二维码。

嗯?前端生成海报?图片?什么操作?没玩过啊,咋整?后端能生成吗?不知道啊,反正大佬说前端来,那来吧....爬坑开始。

1:html2canvas

官网地址:http://html2canvas.hertzen.com/

干啥的?

根据html2canvas官方文档的介绍,html2canvas库的工作原理并不是真正的“截图”,而是读取网页上的目标DOM节点的信息来绘制canvas,所以它并不支持所有的css属性(详情参考这里),而且期望使用的图片跟当前域名同源,不过官方也提供了一些方法来解决跨域图片的加载问题。

1.1:安装(下载html2canvas)

由于我使用的是vue,所以:

npm install html2canvas

1.2:引入

import html2canvas from 'html2canvas';
//components内:VueQr是另一个插件,后面会用到
components: {
	html2canvas,
	VueQr
},

1.3:html部分

首先将要转换的dom元素上设置ref='imageWrapper',后面会用到。

这个dom应该包裹着所有要生成图片的元素,他是父元素盒子。

其次应该再设置一个dom,这个dom用来显示生成后的海报图片。

<div class="p2_box2_con3" v-show="this.canvasDom==true" ref="imageWrapper">
    //内容....
</div>
//下面是显示海报图片的dom
<div class="canvasDom" v-show="this.canvasDom==false">
	<img :src="this.imgUrl" />
</div>

1.4:js开始使用html2canvas生成海报

去官网查看参数说明,反正十来个每个只有一句话解释,也没看见什么详细的示例,非常简洁,如下所示。好吧,我自己度娘搜搜,一搜还挺多需求都是和我一样的要生成什么海报图...有点开心,好啊,这些坑原来前辈们都踩过了那问题应该不大吧,窃喜....

//官网示例,真简单!
html2canvas(document.body).then(function(canvas) {
    document.body.appendChild(canvas);
});

照着大佬们的博客啊日志啊试了试,一天就这么完了...问题出现了一大堆,比如:点击生成按钮后,生成出来的是白色空白图片,黑市空白图片...尝试了好久好了终于能生成了,原因是参数没设置,其中主要的两个参数x,y,这两参数干啥的?Crop canvas x-coordinate意思是裁剪画布X,Y坐标。奇怪的是看大佬们的博客里都没有设置这两个参数....实际上不是没有设置,而是x,y参数有默认值,默认值为x-offset/y-offset。好,设置一下,x设置为0,y设置成pageYOffset,pageYOffset 属性返回文档在窗口左上角水平和垂直方向滚动的像素。应该可以了吧?刷新测试,问题又来了,图片生成了,但是出现了严重的问题,图片偏移了,没有剪切全,左边以及上边出现了很多空白,问题很大有点慌...偏移了?再看看官方文档,发现两个参数:scrollX,scrollY控制偏移的,全部设置为0!这很重要。再试试,还是不行,那x,y调整一下呗x来个30?y来个pageYOffset+多少?试了试咦可行哎,解决了?手机上测试测试,换了七八个浏览器+微信,有意思的是每个偏移都不一样,那再调整调整吧,试了半天这个可以了那个又不行...好吧,很蠢,很明显这样有很大的问题,解决不了问题。

慌了慌了,再度娘度娘....嗯,度娘无敌!搜了搜很多道友也遇到了偏移问题,照着他们说的又试了好久,各种不行...好吧,是不是这插件本身不行吗?换个试试,再搜一搜还有没有别的生成图片的插件,搜了好久没有...只有这个...此时钉钉响了...大佬催我了,怎么还没弄出来...这很尴尬!非常尴尬!能说不行吗...大佬提议我们自己canvas,自己canvas?那试试呗...好两小时又没了...结果是生成的不敢叫海报,太丑了太丑了,说实话对canvas不熟没怎么用过,菜鸡一枚...绝望,还是回来再研究研究一下html2canvas吧,我将页面其他元素都删除,只保留了我要生成的dom,试一试,将x,y都设置为0。惊奇的发现所有浏览器这下全部保持一致了,看来设置scrollX,scrollY后还出现偏移就与x,y参数有关了,y是什么?裁剪画布y坐标,y坐标?高度?好像明白了点什么,之前设置过pageYOffset出现了偏移,那么自己精确计算一下要生成的dom之上的所有dom的高度不就行了,好,获取dom的高度,设置,经过测试终于可以了...终于可以了...在所有浏览器上都能保持一致,不再存在偏移空白。

最终代码如下:

let upDom = this.$refs.p_text;//要生成的dom元素之上所有元素包裹盒子
let upDomHeight = upDom .offsetHeight;//包裹盒子高度
let elHeight = dom.offsetHeight;//要生成海报的dom的原始高度
let elWidth = dom.offsetWidth;//要生成海报的dom的原始宽度
// 第一个参数是需要生成截图的元素,第二个是自己需要配置的参数,宽高等
html2canvas(this.$refs.imageWrapper,{
	logging: false, //日志开关,便于查看html2canvas的内部执行流程
	width:dom.clientWidth,//生成后的宽度
	height:dom.clientHeight,//生成后的高度
	// x:0,
	y:upDomHeight,//要生成的dom元素之上所有dom的高度
	scrollY: 0, 
	scrollX: 0,
	useCORS: true,//允许跨域
	backgroundColor: null //避免图片有白色边框
}).then((canvas) => {
	let dataURL = canvas.toDataURL("image/png");
	this.imgUrl = dataURL;
	this.canvasDom=false;
})

经过上面的步骤实际上就完成了,可以正常生成了。

2:生成二维码

前端怎么动态生成二维码?一般使用插件qrcodejs2。

2.1:安装

npm install  qrcodejs2

2.2:引入

import QRcode from 'qrcodejs2';

2.3:html内设置显示二维码的dom

<div id="qrcode" ref="qrcode"></div>

2.4:使用

crateQrcode () {
    let qrcode = new QRCode('qrcode', {
	width: 80,//生成二维码宽度
	height: 80,//生成二维码高度
	text: url, // 二维码地址或文本,如果是网址扫码后会跳转网址
	colorDark : "#000",
	colorLight : "#fff"
    })
}

合适的地方合适的时间调用该方法就能生成二维码。使用还是很简单的,也没有坑。

此时大佬又提要求了,这二维码不好看啊,中间加个咱公司logo!

加logo?好吧,大佬说加咱就加,看了半天没发现qrcodejs2可以让二维码中间有图片。此时发现了另一个插件,使用也很简单,中间可以生成logo。

3:vue-qr

3.1:安装

//安装
npm install vue-qr 
//引入
import VueQr from 'vue-qr'

3.2:引入组件

components: {
	VueQr
},

3.3:html使用组件

<vue-qr id="qrcode" :logoSrc="logo" :text="codeValue" logoScale="100"></vue-qr>

logoSrc是logo的图片,vue require加载一下即可

text二维码内容,可以是文本,网址,如果是网址扫码后会自动跳转

其他参数:

如何让二维码在海报内被生成?很简单,将VueQr组件放置在海报dom内即可。

好了,经过上面步骤就能成功生成带二维码的海报了。 继续下一个坑...微信内分享...

  • 1
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值