最近开发的小程序都有分享需求,功能大体为点击分享按钮,或主动生成海报后,用户操作保存对应海报为图片实现分享。以下是具体实现。
此处主要是生成工具库来生成普通二维码,如果要生成小程序码,只能通过后台接口调用开放API实现,且需要小程序已上线发布才能通过微信扫一扫进入小程序(废话不多说了。。。。)
template
<template>
<view class="page">
<canvas
id="canvas"
style="width: 160rpx; height: 160rpx"
canvas-id="canvas"
>canvas>
view>
template>
script
// 调用很简单
const drawQrcode = require("@/lib/weapp.qrcode.min.js)
export default {
data(){return {}};
onLoad(){
this.drawCode();
}
methods:{
drawCode(){
drawQrcode({
text: `二维码内容`,
canvasId: "canvas",
width: 80,
height: 80
})
console.log("二维码生成")
}
}
}
生成海报分为两步
一是海报预览弹窗(这个是小程序内页弹窗所以直接代码编写就好)
二是通过painter将元素生成为图片保存到本地。以下代码只描述重点部分,全部代码请查看源码文件。
这里用到了painter这个组件库,这是一个通过配置json就直接生成图片的工具库,开源地址
这里引用了painter组件来生成(懒人不想造轮子- _ -)。因为是微信原生编写,所以放在根目录下的wxcomponents中
目录如下:
|__ wxcomponents
|__ painter
|__ painter.wxml
|__ painter.wxss
|__painter.json
|__painter.js
|__ ...
page.json中引入微信组件
{
"globalStyle":{
"usingComponents": {
"painter": "/wxcomponents/painter/painter"
}
}
}
这里新建了两个文件,一个share.vue用于在小程序中直接展示海报的样式,一个share.js是配置painter海报的数据源
<template>
<view class="share" v-if="visible">
<view class="share-content">
<view class="share-chart-wrap">
<image
class="share-chart"
@longpress="saveImgNow"
src="http://qiniu.kingdou.fun/kingdou1.jpeg"
mode="widthFix"
/>
<view class="share-title">这是每报标题view>
view>
<view class="share-card">
<view class="content-block">
<view class="content-row">
<view class="content-label">海报时间view>
<view class="content-value">{{ data.time }}view>
view>
<view class="content-row">
<view class="content-label">描述view>
<view class="content-value">{{ data.introduce }}view>
view>
<view class="content-row">
<view class="content-label">比赛说明view>
<view class="content-value">限定时间内根据动作次数记分view>
view>
view>
<view class="qr-block">
<view class="qr-tips">
<view class="tips-title">长按图片进行保存或者转发view>
<view class="tips-content"
>扫描二维码即可参赛~<br />快去分享吧~
view>
view>
<slot name="qrcode" @longpress="init">slot>
view>
view>
view>
<uni-icons
class="close-btn"
size="50"
type="close"
color="#fff"
@click="close"
/>
<painter
v-show="isSave"
style="position: absolute; top: 79rpx; left: 60rpx"
:palette="template"
@imgOK="onImgOK"
@imgErr="onImgErr"
/>
view>
template>
<script>
import Card from "./share";
export default {
props: {
visible: {
type: Boolean,
default: false,
},
data: {
type: Object,
default: () => {
return {
time: "",
introduce: "",
};
},
},
},
data() {
return {
imagePath: "",
template: "",
};
},
methods: {
saveImgNow() {
let data = { ...this.data};
this.template = new Card().palette(data);
},
saveImage() {
if (this.imagePath && typeof this.imagePath === "string") {
// 图片保存到本地
wx.saveImageToPhotosAlbum({
filePath: this.imagePath,
});
// 关闭分享弹窗
setTimeout(() => {
this.$emit("update:visible", false)
}, 500)
}
},
close() {
this.$emit("close");
},
onImgOK(e) {
this.imagePath = e.detail.path;
this.saveImage(this.imagePath);
},
onImgErr() {
console.log("保存图片失败");
},
},
};
script>
<style lang="scss" scoped>
样式内容省略,详见源码。。。
style>
export default class LastMayday {
palette(data) { // 传入动态数据源
return {
width: "320px",
height: "430px",
background: "#f1f1f1",
views: [
{
type: "text",
text: "海报时间",
css: {
color: "#373737",
background: "rgba(0,0,0,0)",
width: "60px",
height: "15.819999999999999px",
top: "202px",
left: "40px",
// 。。。。省略
},
},
{
type: "text",
text: data.time, //这里是动态数据
css: {
color: "#0061D4",
background: "rgba(0,0,0,0)",
width: "181px",
height: "15.819999999999999px",
top: "202px",
// 。。。。省略
},
},
// 。。。。。
}
这里即是对上面的share.js来历进行说明。要生成图片,得有生成图片的规则,也就是painter的绘制数据源。这里也是通过第三方网站来可视化生成的,通过在这个网站中先绘制好海报的样式后,再一键生成json文件,最后放进代码中。
- painter海报json在线绘制生成工具\
- 最终生成内容如上述share.js
import Card from './share.js'
export default {
// 。。。。省略。。。
methods: {
// 这里假设用户长按图片,触发此方法。即上面share.vue中, @longpress="saveImgNow"
saveImgNow() {
let data = { ...this.data};
this.template = new Card().palette(data);
},
// 生成图片事件监听(在调用new Card()后会自动触发
// 图片生成成功时
onImgOK(e) {
this.imagePath = e.detail.path;
this.saveImage(this.imagePath);
},
// 图片生成失败时
onImgErr() {
console.log("保存图片失败");
},
}
<painter style="position: absolute; top: -799999rpx; left: -999960rpx" :palette="template" @imgOK="onImgOK"
@imgErr="onImgErr" />
地址参见:https://gitee.com/sophie-code-box/share-poster