由于在微信小程序环境下面没法获取dom,很多方法都很难去实现保存html结构的页面,比较有效的#painter 可以不需要操作dom,但是那玩意儿和重新用js写个页面一样,简单的页面还好,复杂的,元素比较多的就很麻烦,所以考虑用webview+html2canvas来完成
先说一下思路,既然在微信小程序环境下行不通,那就考虑换个环境,用webview加载页面,再通过html2canvas来生成相应的canvas,然后转成图片。
首先是webview,不懂的可以去看下官方文档,贴在这里:https://uniapp.dcloud.net.cn/component/web-view.html#web-view。也就是在小程序或者app环境中挂载一个ifram,小程序加载这个页面必须放到服务器上,其他像app的可以放在本地。文章来源:https://www.toymoban.com/news/detail-504659.html
贴代码文章来源地址https://www.toymoban.com/news/detail-504659.html
//小程序端
<web-view :src="webUrl" @message="handleMessage"></web-view>
//webUrl -->页面路径 handleMessage-->页面像服务器通信的方法
<script>
export default{
methods:{
//
saveImageToPhotosAlbum(data) {
let base64 = data.replace(/^data:image\/\w+;base64,/, "");//去掉data:image/png;base64,
//就是这里需要获取微信环境的保存路径,所以最好把转好的base64传到小程序端来下载
let filePath = wx.env.USER_DATA_PATH + '/detail.png';
uni.getFileSystemManager().writeFile({
filePath: filePath, //创建一个临时文件名
data: base64, //写入的文本或二进制数据
encoding: 'base64', //写入当前文件的字符编码
success: res => {
uni.saveImageToPhotosAlbum({
filePath: filePath,
success: function (res2) {
uni.showToast({
title: '保存成功,请从相册选择再分享',
icon: "none",
duration: 5000
})
},
fail: function (err) {
// console.log(err.errMsg);
}
})
},
fail: err => {
//console.log(err)
}
})
},
//接收来自webview的数据,注意,这里detail.data是一个数组!
handleMessage(res) {
this.saveImageToPhotosAlbum(res.detail.data[0].imgData)
},
}
}
</script>
//webview页面端 我用的是html,你也可以用vue,或者其他的什么框架,但是一定要在服务器上。本地的话就开一个nginx服务调试就好。
//这个html是在uniapp webview copy的模板,里面对各种环境都做了处理,所以我们直接在另一个script里面写逻辑就好了。
//引入在线的vue,css,最重要的是这个:https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js ,引入之后允许我们使用uni的部分api。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
<title>保存html</title>
<script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
<script src="https://unpkg.com/http-vue-loader"></script>
<script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
<link rel="stylesheet" href="//at.alicdn.com/t/c/font_3605152_8p2lf6ioizb.css">
<style type="text/css">
</style>
</head>
<body>
<div id="app">
<div class="main-box" :style="{'--uni':uni, 'background': '#FAFAFA url(' + baseUrl + '/img/chuxian_bg.png) no-repeat', 'background-size': '100%' }">
<div class="order-num">
订单编号:{{ dataObj.orderNumber }}
</div>
<div class="order-title">
<h1>车辆出险报告</h1>
<h3>{{ dataObj.model }}</h3>
</div>
<div class="save">
<button @click="savePicture">保存本页</button>
</div>
</div>
<div id="downimg" v-show="false"></div>
</div>
<script type="text/javascript">
var userAgent = navigator.userAgent;
if (userAgent.indexOf('AlipayClient') > -1) {
// 支付宝小程序的 JS-SDK 防止 404 需要动态加载,如果不需要兼容支付宝小程序,则无需引用此 JS 文件。
document.writeln('<script src="https://appx/web-view.min.js"' + '>' + '<' + '/' + 'script>');
} else if (/QQ/i.test(userAgent) && /miniProgram/i.test(userAgent)) {
// QQ 小程序
document.write(
'<script type="text/javascript" src="https://qqq.gtimg.cn/miniprogram/webview_jssdk/qqjssdk-1.0.0.js"><\/script>'
);
} else if (/miniProgram/i.test(userAgent) && /micromessenger/i.test(userAgent)) {
// 微信小程序 JS-SDK 如果不需要兼容微信小程序,则无需引用此 JS 文件。
document.write('<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"><\/script>');
} else if (/toutiaomicroapp/i.test(userAgent)) {
// 头条小程序 JS-SDK 如果不需要兼容头条小程序,则无需引用此 JS 文件。
document.write(
'<script type="text/javascript" src="https://s3.pstatp.com/toutiao/tmajssdk/jssdk-1.0.1.js"><\/script>');
} else if (/swan/i.test(userAgent)) {
// 百度小程序 JS-SDK 如果不需要兼容百度小程序,则无需引用此 JS 文件。
document.write(
'<script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.18.js"><\/script>'
);
} else if (/quickapp/i.test(userAgent)) {
// quickapp
document.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"><\/script>');
}
</script>
<!-- uni 的 SDK -->
<!-- 需要把 uni.webview.1.5.4.js 下载到自己的服务器 -->
<script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>
<script type="text/javascript">
Vue.use(httpVueLoader)
new Vue({
el: '#app',
data: {
dataObj: {},
baseUrl: 'https://xxx:8443',
},
created () {
this.dataObj = JSON.parse(this.getQueryString('data'))
this.dataObj.result = JSON.parse(this.dataObj.result)
console.log(document.documentElement.clientWidth)
this.uni = 750 / document.documentElement.clientWidth
console.log(this.uni)
},
methods: {
getQueryString (name) {
var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
var r = window.location.search.substr(1).match(reg);
if (r != null) return decodeURI(r[2]); return null;
},
plusXing (str, frontLen, endLen, cha) {
let len = str.length - frontLen - endLen;
let xing = "";
for (let i = 0; i < len; i++) {
xing += cha;
}
return (
str.substring(0, frontLen) + xing + str.substring(str.length - endLen)
);
},
//这里是重点,获取想要保存的html结构,然后设置相应的样式,
savePicture () {
let canvas2 = document.createElement('canvas'), // 创建canvas
_canvas = document.querySelector('.main-box'), //此处可换body,或div等 我们一般可以放绘制的元素
w = parseInt(window.getComputedStyle(_canvas).width),
h = parseInt(window.getComputedStyle(_canvas).height);
//将canvas画布放大若干倍,然后盛放在较小的容器内,就显得不模糊了
canvas2.width = w * 2;
canvas2.height = h * 2;
canvas2.style.width = w + 'px';
canvas2.style.height = h + 'px';
let context = canvas2.getContext('2d'),
rect = $('.main-box').get(0).getBoundingClientRect(); //获取元素相对于视察的偏移量
context.scale(2, 2);
context.translate(-rect.left, -rect.top); //设置context位置,值为相对于视窗的偏移量负值,让图片复位
html2canvas(document.querySelector('.main-box'), {
canvas: canvas2,
useCORS: true, // 允许图片跨域
width: 584, // 绘制图片的宽 2倍
dpi: window.devicePixelRatio * 2, // dpi 如果模糊的话 就把dpi和scale缩放的值调大 dpi越高生成的图片越大
height: 1188 // 绘制图片的高 2倍
}).then(function (canvas) {
var url = canvas.toDataURL() //把canvas转成base64
uni.postMessage({
data: {
imgData: base64, // 刚才拿到的base64 数据
},
});
});
}
},
})
</script>
</body>
</html>
到了这里,关于uni-app 微信小程序 保存当前页面为图片的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!