html2canvas 相关问题踩坑
最近公司项目有个需求是:弹窗的时候要把一些信息合成为图片然后再进行分享等操作,其中信息包括微信头像,昵称等。项目是用vue来搭建的,要合成的区域如下:弹窗的主要html如下:<div class="success-wrap" :class="{opacity:successShow}"><div class=&quo
最近公司项目有个需求是:弹窗的时候要把一些信息合成为图片然后再进行分享等操作,其中信息包括微信头像,昵称等。项目是用vue来搭建的,要合成的区域如下:
弹窗的主要html如下:
<div class="success-wrap" :class="{opacity:successShow}">
<div class="shadow"></div>
<div class="success-modal">
<div class="main-box" :class="{active:successShow}" id="succAni">
<i class="close-btn" @click="closeModal"></i>
<div id="success-box">
<div class="success-panel" id="success">
<div class="photo"><img src="../assets/imgs/default_photo.png" /></div>
<p class="user">{{userInfo.wechat_wxname}}</p>
<p class="thanks-text">
您于{{dateArr[0]}}年{{dateArr[1]}}月{{dateArr[2]}}日捐赠 <span>{{donateCount}}</span> 公益金,感谢您热心参与“<span>公益项目</span>”,这些公益金,将带着您的爱让美好的事情发生。
</p>
<div class="clear">
<div class="qcode-left">
<p class="qcode">
<qriously :value="'http://share.xhebao.cn/qcode.php?u_id='+ u_id" :size="88"/>
<i class="kd-icon"></i>
</p>
<p class="qcode-text">扫码为公益助力</p>
</div>
</div>
<p class="droit">本活动最终解释权归所有</p>
</div>
</div>
<div class="btn-box clear">
<span @click="iosSaveImage">保存图片</span>
<span @click="wxShare">分享爱心</span>
</div>
</div>
</div>
</div>
于是自己就用了html2canvas来做,但是却遇到了很多的坑,总结下遇到的几个坑:
1、合成的区域必须是存在于Dom树中的,所以用v-if显示弹窗的话就要先显示再来进行合成。(项目中自己是用opacity和z-index来控制的)
2、涉及到跨域问题的图片无法合成,除非能在图片服务器那边设置允许跨域(所以自己项目中的微信头像问题,就用了本地的一个默认的头像来代替了)
3、由于合成是从浏览器窗口位置开始的,所以如果合成的区域不是在浏览器窗口的开始位置下,就需要先把合成区域放到浏览器窗口开始位置下,合成后再把合成的图片放到自己想要的位置(这个不知道还有没有什么好的办法,比如可以定义绘制起点之类的)
4、本来自己是想给弹窗显示的时候添加一个缩放(从0.2缩放到原来尺寸)的效果,于是就直接在合成区域的外框上添加了缩放的class,但是这样却会影响合成的效果(也被缩小了),因为在合成前,影响到原效果图的动画都会对合成图片造成影响。于是自己就在合成的时候再来添加动画(具体就是:合成成功时给外框添加0.2的缩放,然后显示的时候再让它过度到原来的尺寸)。
5、如果合成区域要多次合成的话,可以先把要合成的区域display:none掉(而不是remove掉),然后把合成图片添加进去,当要再次合成时再把图片remove掉,和成区域显示,然后进行再次合成
主要合成的代码如下:
//合成图片
getCanvasImg(obj){
var doc = window.document;
var width = obj.content.offsetWidth;
var height = obj.content.offsetHeight;
var canvas = document.createElement("canvas");
var context = canvas.getContext("2d");
var scale = 2;
let that = this;
canvas.width = width * scale;
canvas.height = height * scale;
canvas.getContext("2d").scale(scale, scale);
var opts = {
scale: scale,
canvas: canvas,
logging: true,
width: width,
height: height
};
html2canvas(obj.content, opts).then(function (canvas) {
var dataUrl = canvas.toDataURL();
let ani = document.getElementById('succAni');
var newImg = doc.createElement("img");
newImg.src = dataUrl;
newImg.id = "qcImg";
newImg.style.width = canvas.width/2 + 'px';
newImg.style.height = canvas.height/2 + 'px';
newImg.style.borderRadius = '4px';
newImg.style.webkitBorderRadius = '4px';
ani.style.opacity = '0';
ani.style.transform = 'scale(.2)';
ani.style.transition = 'opacity .3s,transform .3s';
ani.style.webkitTransform = 'scale(.2)';
ani.style.webkitTransition = 'opacity .3s,transform .3s';
document.getElementById('success').style.display = "none"
obj.box.appendChild(newImg);
obj.cb&&obj.cb();
that.hasCanvas = true;
});
},
弹窗显示主要代码:(先合成图片再来显示弹窗,因为还要把合成的图片定位到自己想要的位置,不然会有闪现的效果)
//捐赠成功进行图片合成
let obj = {};
obj.box = document.getElementById('success-box');
obj.content = document.getElementById('success');
obj.cb = function(){
$('.success-wrap .main-box').css({"marginTop":"-4.95rem","marginLeft":"-3.16rem","top":"50%","left":"50%"});
setTimeout(function(){
that.successShow = true;
let ani = document.getElementById('succAni');
ani.style.opacity = '1';
ani.style.transform = 'scale(1)';
ani.style.webkitTransform = 'scale(1)';
},200)
}
that.getCanvasImg(obj);
更多推荐
所有评论(0)