h5移动端生成海报图,可长按图片保存或发送给朋友,或长按识别二维码。两种场景:第一种是生成项目分享海报图,通过背景图和地址生成的二维码合成一张海报图;第二种是通过页面生成商品海报图,页面有产品介绍信息,商户名称logo和商品详情页生成的二维码,把含有二维码的页面生成海报图。
示例:这里使用jquey实现的。
在script中引入jquery、qrcode.js生成二维码的插件。
长按海报转发,邀请好友助力点亮
#myCanvas {
width: 300px;
height: 532px;
}
// 根据海报背景图和地址合成一张海报图
function createPoster(){
// 二维码访问的地址拼接
let thref = location.protocol + "//"+location.hostname+"/flowerLantern/help.html?id="+voteId+"&orgId="+orgId+"&itemId="+itemIds;
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var devicePixelRatio = window.devicePixelRatio || 1,
backingStoreRatio = ctx.webkitBackingStorePixelRatio || ctx.mozBackingStorePixelRatio || ctx.msBackingStorePixelRatio || ctx.oBackingStorePixelRatio || ctx.backingStorePixelRatio || 1,
ratio = devicePixelRatio / backingStoreRatio;
var qrcode = new QRCode("qrcode",{
render: "canvas", //渲染方式指定canvas方式
width: 72*ratio, //宽度
height: 72*ratio, //高度
typeNumber: -1, //计算模式
text: thref, //任意内容
colorDark: "#000000",
colorLight: "#ffffff",
correctLevel: QRCode.CorrectLevel.H
});
var mycanvas1=document.getElementsByTagName('canvas')[0]; //获取网页中的canvas对象,这里是通过qrcode生成的二维码的canvas
//将转换后的二维码img标签插入到html中
var imgewm=convertCanvasToImage(mycanvas1); // 将二维码canvas生成图片
$('#qrcode').html("");//移除已生成的避免重复生成
$('#qrcode img').hide();
var width = document.getElementById("myCanvas").clientWidth; //宽度
var height = document.getElementById("myCanvas").clientHeight; // 高度
canvas.width = width*ratio;
canvas.height = height*ratio;
//首先画上背景图
var img = new Image();
img.src = './img/post.jpg'; // 背景图路径
img.width = width;
img.height = height;
img.crossOrigin="*";
img.onload = function() { //必须等待图片加载完成
ctx.scale(ratio, ratio);
ctx.drawImage(img, 0, 0, width, height); //绘制背景图像进行拉伸
console.log(" ~ file: index.html ~ line 410 ~ createPoster ~ img", img)
ctx.drawImage(imgewm,114,370,72,72); //绘制二维码
//在ios上无法在画完之后取到整个画布内容,加了个settimeout
setTimeout(function(){
var srcImg = new Image();
srcImg.src = canvas.toDataURL('images/png'); // 将合成的canvas转换成图片
$('#h').html("");//移除已生成的避免重复生成
$('#h').append(srcImg);// 将合成的图片渲染在页面上
$('#h img').attr("width",'100%');
$('#h img').attr("height",'100%');
$('#qrcode').hide();
},0)
}
}
示例:这里使用vue实现的,通过npm安装相应的插件
cnpm install qrcodejs2 --save
cnpm install html2canvas --save
import QRCode from 'qrcodejs2';
import html2canvas from 'html2canvas'
<div class="poster-top">
<!-- 海报图生成的页面模块 -->
<div id="posterHtml" v-show="true">
<div class="postProduct">
<!-- 商品图 -->
<img :src="dataInfo.coverImg"/>
</div>
<!-- 内容 -->
<div class="post-merch">
<!-- 商户logo -->
<img :src="merchantLogoUrl"/>
<span>{{ realname}} 为您推荐团兽兽好物</span>
</div>
<div class="post-content">
<div class="post-content-left">
<div class="post-product">{{ dataInfo.title.split('#')[0] }}</div>
<div class="post-price">
<span class="price"><span class="rmb">¥</span>{{ dataInfo.salePrice}} </span>
<!-- <p class="stock"> <span class="stock">库存:{{ dataInfo.stockCount }}</span></p> -->
</div>
</div>
<div class="qrcode-wrapper">
<!-- 二维码 -->
<div id="qrcodeImg" class="qrcode"></div>
<p class="ewm-text">长按识别二维码</p>
</div>
</div>
</div>
<!-- 存放最后生成的海报图 -->
<div id="result"></div>
</div>
js
// 生成二维码
createCode(){
var codeMd5 = this.domain+'/'+this.dataInfo.url;
console.log("md5?",codeMd5);
let qrcode = new QRCode('qrcodeImg', {
width: 70,
height: 70,
// text: "https://www.baidu.com",
text: codeMd5, // 二维码地址
colorDark : "#000",
colorLight : "#fff",
})
},
// 生成海报图
createPoster() {
console.log(" ~ file: poster.vue ~ line 91 ~ createPoster ~ createPoster")
// 生成海报
const vm = this
const domObj = document.getElementById('posterHtml');
var width = domObj.offsetWidth; //获取dom 宽度
var height = domObj.offsetHeight; //获取dom 高度
// var canvas = document.createElement("canvas"); //创建一个canvas节点
// var scale = window.devicePixelRatio; //定义任意放大倍数 支持小数
// // var scale = 2; //定义任意放大倍数 支持小数
// canvas.width = width * scale; //定义canvas 宽度 * 缩放
// canvas.height = height * scale; //定义canvas高度 *缩放
// canvas.style.width = width + "px";
// canvas.style.height = height + "px";
// canvas.getContext("2d").scale(scale,scale); //获取context,设置scale
window.pageYOffset = 0;
document.documentElement.scrollTop = 0
document.body.scrollTop = 0;
const toast1 = this.$toast.loading({
duration: 0, // 持续展示 toast
forbidClick: true, // 禁用背景点击
loadingType: 'spinner',
message: '海报生成中'
});
(window.html2canvas || html2canvas)(domObj, {
// dpi: window.devicePixelRatio * 2,
useCORS: true, //是否尝试使用CORS从服务器加载图像
allowTaint: false, //允许跨域图片.
// logging: false,
// letterRendering: true,
// canvas:canvas, //自定义 canvas
width: domObj.offsetWidth, //为了解决安卓手机截图后出现白边的问题
height: domObj.offsetHeight, //为了解决安卓手机截图后出现白边的问题
// scale: window.devicePixelRatio , // 添加的scale 参数
scale:2,
onclone(doc) {
// let e = doc.querySelector('#posterHtml')
// e.style.display = 'block'
},
onrendered:function(canvas){
console.log(" ~ file: poster.vue ~ line 126 ~ createPoster ~ canvas", canvas)
// vm.posterImg = canvas.toDataURL('image/png',1.0);
// var img = document.createElement("img");
// img.src=vm.posterImg;
// img.style.width = '100%';
}
}).then(function(canvas) {
toast1.clear();
// 在微信里,可长按保存或转发
vm.posterImg = canvas.toDataURL('image/png',1.0)
console.log(" ~ file: view.vue ~ line 166 ~ createPoster ~ vm.posterImg", vm.posterImg)
// var img = document.createElement("img");
// img.src=vm.posterImg;
// img.style.width = '100%';
var img = new Image();
img.src=vm.posterImg;
img.id = 'posterImgBae64';
var result = document.getElementById("result");
result.appendChild(img); // 页面上渲染生成的海报图
img.style.width = '100%';
let e = document.getElementById('posterHtml'); // 原来的页面结构隐藏
e.style.display = 'none';
})
},
if(this.dataInfo.url){
this.createCode(); // 生成二维码
setTimeout( ()=> {
this.createPoster(); //生成海报
},100);
}
两种业务场景生成海报图,都是用canvas生成图片。生成商品海报图时商户logo图模糊,文字模糊,调试像素比,通过scale调整。