记一次开发一款小程序遇到的需求:根据用户填写的商品信息,生成一张可分享的购买海报。简单的看了一下小程序的canvas组件,是可以满足这个需求的实现。所以就开始规划、组织代码了。
是可以实现的,这里我就不多说了,但是需要注意的是,在生成图片的时候会有坑,生成出来的图片会是空白,找了很多资料都说是需要坐下处理,官方也说 “在 draw
回调里调用该方法才能保证图片导出成功”,试了很多次,也没有生成出来。这个时候才知道小程序的坑,不止一个两个......
这个时候为了实现需求,这个时候我不得不把矛头指向原生标签——canvas。利用html2canvas这个插件去做处理。在这里,我是利用webView这个开放能力去做的,然后生成图片把图片地址返回给小程序,实现这一需求。
简单的代码就是这样:
let b64;
html2canvas(document.getElementById('node'), {
useCORS: true
}).then(function (canvas) {
console.log(canvas)
try {
b64 = canvas.toDataURL("image/png");
getUrl(name, b64);
//console.log(b64);
} catch (err) {
console.log(err)
}
}).catch(function onRejected(error) {
console.log(error)
});
运行之后会发现,微信开发者工具没问题,安卓手机没问题,就IOS搞事情,偏偏对这个 html2canvas 这个插件支持度不够。
这个时候没办法呀,已经浪费这么多时间啦,还是决定用原生 canvas 去实现。就急急忙忙的看了 dom-to-img 这个插件,貌似还不错,看着gitHub觉得这次应该没问题了,信心满满的开始撸代码了
简单代码是这样的:
domtoimage.toPng(document.getElementById('node'))
.then(function (blob) {
console.log(blob);
}).catch(req => {
let b64;
html2canvas(document.getElementById('node'), {
useCORS: true
}).then(function (canvas) {
try {
b64 = canvas.toDataURL("image/png");
getUrl(name, b64);
// console.log(b64);
} catch (err) {
console.log(err)
}
}).catch(function onRejected(error) {
console.log(error)
});
});
运行了一下,开发者工具没问题,IOS没问题,这次安卓就不开心了,给我报错,说白了就是不支持。
这个时候我就开始怀疑是不是小程序的运行环境是不是有什么bug,怎么两个插件不是对安卓支持度不高,就是对IOS支持度有问题。在论坛上也没有提到这样的问题。
为了项目能正常上线,只好硬着头皮做了这样的垃圾处理:
function reHtml() {
if (phoneType === 1) {
domtoimage.toPng(document.getElementById('node'))
.then(function (blob) {
console.log(blob);
}).catch(req => {
let b64;
html2canvas(document.getElementById('node'), {
useCORS: true
}).then(function (canvas) {
try {
b64 = canvas.toDataURL("image/png");
getUrl(name, b64);
// console.log(b64);
} catch (err) {
console.log(err)
}
}).catch(function onRejected(error) {
console.log(error)
});
});
} else if (phoneType === 2) {
let b64;
html2canvas(document.getElementById('node'), {
useCORS: true
}).then(function (canvas) {
console.log(canvas)
try {
b64 = canvas.toDataURL("image/png");
getUrl(name, b64);
// console.log(b64);
} catch (err) {
console.log(err)
}
}).catch(function onRejected(error) {
console.log(error)
});
}
}
function getUrl(name, url) {
$.ajax({
url: ORIGIN_NAME + '/e-goods-api/noauth/miniprogram/good/poster',
method: 'POST',
headers: {
"content-type": "application/json;charset=UTF-8",
},
processData: false,
data: JSON.stringify({
"goodName": name || '好物来',
"data": url
}),
success: function (res2) {
console.log(new Date(), '结束')
wx.miniProgram.redirectTo({
url: `/pages/sell/poster/index?dataUrl=${res2.resultContent}
&scene=${parmas.id}&updateState=${parmas.updateState}`
})
}
});
}
function infoMore() {
var browser = {
versions: function () {
var u = navigator.userAgent,
app = navigator.appVersion;
return { //移动终端浏览器版本信息
weixin: u.match(/MicroMessenger/i) == 'MicroMessenger',
trident: u.indexOf('Trident') > -1, //IE内核
presto: u.indexOf('Presto') > -1, //opera内核
webKit: u.indexOf('AppleWebKit') > -1, //苹果、谷歌内核
gecko: u.indexOf('Gecko') > -1 && u.indexOf('KHTML') == -1, //火狐内核
mobile: !!u.match(/AppleWebKit.*Mobile.*/) || !!u.match(/AppleWebKit/), //是否为移动终端
ios: !!u.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/), //ios终端
android: u.indexOf('Android') > -1 || u.indexOf('Linux') > -1, //android终端或者uc浏览器
iPhone: u.indexOf('iPhone') > -1 || u.indexOf('Mac') > -1, //是否为iPhone或者QQHD浏览器
iPad: u.indexOf('iPad') > -1, //是否iPad
webApp: u.indexOf('Safari') == -1 //是否web应该程序,没有头部与底部
};
}(),
language: (navigator.browserLanguage || navigator.language).toLowerCase()
}
if (browser.versions.android && browser.versions.webKit) {
//安卓
return 1;
}
if (browser.versions.ios || browser.versions.iPhone || browser.versions.iPad) {
//IOS
return 2;
}
if (browser.versions.weixin && browser.versions.android) {
//微信安卓
return 1;
}
if (browser.versions.weixin && browser.versions.ios || browser.versions.iPhone || browser.versions.iPad) {
//微信IOS
return 2;
}
}
这样做了一下,终于清静了许多,项目也正常上线了,但是心里还是愤愤不平的,怎么就出现了这个问题,其他开发者是怎么写的,怎么就能生成图片。
始终觉得还是利用小程序的——canvas 组件去写的,但我这边生成的图片就是空白,总是不能把页面元素提取绘制出来。页面显示没问题,想不懂问题出现在哪,如果您看到这里,有实现的,可以评论告诉我,谢谢!