微日志_免费提供日志记录|作品展示|学习教程|免费日记

小程序之通过配置,自动生成带二维码海报页面

小程序组件 二维码海报 阅读:212

体验地址:暂无地址

在开发小程序的过程中,往往会遇到这样的需求,就是经过一系列操作后,最后会给用户生成一个带二维码的分享海报,这个海报有一个背景和一个二维码,并且这个二维码是动态生成的,带有对应的属性,让我们可以统计一些信息,这样每次都去写,很麻烦,所以在此封装成了一个组件,通过配置,自动去生成这样的海报,包括给用户展示的页面以及实际保存的海报页面,当然实际保存的海报页面是用户看不见的,只有保存下来才可以看见,原因就是因为如果保存直接在小程序内部用户可以看见的图片,那么保存下来之后,会很模糊,所以一般会从新生成一个比用户看见大的多的一个图,本文就分享出来本人封装的一个小程序组件。

先看一下目录结构:

上面标红的就是我们组件存放的位置,组件里面包括四个文件,先打开index.json文件,将标识设置为组件.

{
"component": true
}

然后打开我们的index.wxml,编写普通的样式布局(说明:本组件目前只是适合一张背景图和一个二维码或者单个二维码生成的一个功能),看代码:

<view class="poster_box" style="min-width:{{qrcodeToImageWidth*2}}rpx;min-height:{{qrcodeToImageHeight*2}}rpx">
<!--自动生成二维码以及海报--->
<image src="{{backgroundImageUrl}}" style="width:{{backgroundImageWidth*2}}rpx;display:{{backgroundImageUrl?'block':'none'}}" mode="widthFix"></image>
<view class="p_content" style="left:{{qrcodeToImageLeft * 2}}rpx;top:{{qrcodeToImageTop * 2}}rpx">
<!---展示的二维码--->
<image src="{{qrcodeImageUrl}}" mode="widthFix" style="width:{{qrcodeToImageWidth*2}}rpx;height:{{qrcodeToImageHeight*2}}rpx;"></image>
</view>
<!---canvas宽度和高度和图片的实际宽度高度一致,比如背景,比如二维码--->
<canvas canvas-id='saveQrcode' class="saveQrcode" style="width:{{backgroundImageUrl?actualBgWidth:actualQrcodeWidth}}rpx!important;height:{{backgroundImageUrl?actualBgHeight:actualQrcodeHeight}}rpx!important;"></canvas>
</view>

其次就是添加一些样式,排列好即可,打开index.wxss,如下代码:

.poster_box{
position: relative;
overflow: hidden;
display: inline-block;
}
.p_content{
position: absolute;
top: 0;
left: 0;
z-index: 2;
}

.saveQrcode {
position: fixed;
z-index: 999;
top: 0;
left: 100vw;
}

最后就是重头戏了,看我们的index.js,看代码,代码里面基本有注释:

Component({
  properties: { //组件属性
    backgroundImageUrl: { //海报背景
      type: String,
      value: ''
},
    isCreateSaveCanvas:{ //是否需要生成保存的海报
      type:Boolean,
      value:true
},
    qrcodeToImageWidth: { //二维码显示的大小,显示在小程序内部的大小
      type: Number
},
    qrcodeToImageHeight: {
      type: Number
},
    qrcodeToImageLeft: { //二维码显示的位置,小程序内海报
      type: Number,
      value: 0
},
    qrcodeToImageTop: {
      type: Number,
      value: 0
},
    actualBgWidth: { //背景实际宽度,图片多宽就是多宽,无backgroundImageUrl,无效
      type: Number,
      value: 0
},
    actualBgHeight: {
      type: Number,
      value: 0
},
    backgroundImageWidth: { //图片的宽度,无backgroundImageUrl,无效
      type: Number
},
    actualQrcodeWidth: { //二维码保存的实际大小
      type: Number,
},
    actualQrcodeHeight: {
      type: Number,
},
    qrcodeImageUrl: { //二维码地址
      type: String,
      value: ''
},
    qrcodeIsNeedDownload: { //二维码是否需要下载
      type: Boolean,
      value: true
},
    backgroundIsNeedDownload:{ //背景图片是否需要下载,无backgroundImageUrl,无效
      type:Boolean,
      value:false
},
    created: { //生成完毕的回调,会自动转化为地址,并且返回
      type: Function
},
    isStartCreate:{ //如果依赖外部变量,请手动更改这个值
      type:Boolean,
      value:true,
observer:function(newValue){
newValue && this.data.isCreateSaveCanvas && this.handleCreateSaveCanvas(); //调用生成二维码
}
}
},
  data: { //内部属性

},
ready() {

},
attached() {
//如果开启了开始就创建,证明图片那些已经就位,并且需要生成canvas,那么直接创建
this.data.isStartCreate && this.data.isCreateSaveCanvas && this.handleCreateSaveCanvas(); //调用生成二维码
},
  methods: {
//创建保存的二维码
handleCreateSaveCanvas() {
wx.showLoading({
        title: '生成中...',
        mask:true
})
let self = this,
ctxSave = wx.createCanvasContext('saveQrcode', self),
saveWidth = self.data.backgroundImageUrl?self.data.actualBgWidth : self.data.actualQrcodeWidth,
saveHeight = self.data.backgroundImageUrl?self.data.actualBgHeight : self.data.actualQrcodeHeight;
//注意这里必须加in,否则获取不到,后者在最后进行this的绑定
wx.createSelectorQuery().in(self).selectAll('.saveQrcode').boundingClientRect(function (rect) {
saveWidth = rect[0].width;
saveHeight = rect[0].height;
let scX,
imageScale;
//先绘制一张背景作为底图
if (self.data.backgroundImageUrl) {
scX = saveWidth / self.data.actualBgWidth;
imageScale = self.data.actualBgWidth / self.data.backgroundImageWidth;
} else {
scX = saveWidth / self.data.actualQrcodeWidth;
imageScale = self.data.actualQrcodeWidth / self.data.qrcodeToImageWidth;
}
if(self.data.backgroundImageUrl && self.data.backgroundIsNeedDownload){
self.handleDownload(self.data.backgroundImageUrl).then(url => {
ctxSave.drawImage(url, 0, 0, self.data.actualBgWidth, self.data.actualBgHeight, 0, 0, saveWidth, saveHeight);
createQrcode();
})
}else{
if(self.data.backgroundImageUrl){
ctxSave.drawImage(self.data.backgroundImageUrl, 0, 0, self.data.actualBgWidth, self.data.actualBgHeight, 0, 0, saveWidth, saveHeight);
}
createQrcode();
}
//创建二维码
function createQrcode(){
if (self.data.qrcodeIsNeedDownload) {
self.handleDownload(self.data.qrcodeImageUrl).then(url => {
ctxSave.drawImage(url, 0, 0, self.data.actualQrcodeWidth, self.data.actualQrcodeHeight, self.data.qrcodeToImageLeft * imageScale * scX, self.data.qrcodeToImageTop * imageScale * scX, self.data.qrcodeToImageWidth * imageScale * scX, self.data.qrcodeToImageHeight * imageScale * scX); //保存的真实图片,比展示的图片大
self.handleCreatePath(ctxSave);
})
} else {
ctxSave.drawImage(self.data.qrcodeImageUrl, 0, 0, self.data.actualQrcodeWidth, self.data.actualQrcodeHeight, self.data.qrcodeToImageLeft * imageScale * scX, self.data.qrcodeToImageTop * imageScale * scX, self.data.qrcodeToImageWidth * imageScale * scX, self.data.qrcodeToImageHeight * imageScale * scX); //保存的真实图片,比展示的图片大
self.handleCreatePath(ctxSave);
}
}
}).exec();

},
/***
     * 重新生成
     * ***/
updated(){
this.data.isStartCreate && this.data.isCreateSaveCanvas && this.handleCreateSaveCanvas(); //调用生成二维码
},
/**
     * 生成路径,并且回调回去
     * **/
handleCreatePath(ctx) {
let self = this;
ctx.draw(false, res => {
wx.canvasToTempFilePath({
          canvasId: 'saveQrcode',
          quality: 1,
          fileType: 'png',
success(e) {
wx.hideLoading({});
self.triggerEvent('created',e.tempFilePath);
},
fail(err) {
console.log(err)
}
}, this); //必须绑定this,否则会说 canvas is empty
});
},
/***
     * 二次封装下载
     * **/
handleDownload(url) {
return new Promise((resolve, reject) => {
wx.downloadFile({ //如果是远程地址,记得需要在微信后台进行配置
          url: url,
success(res) {
resolve(res.tempFilePath);
},
fail(res) {
reject(res)
}
})
})
}

}
})

以上就是这个组件的所有代码,复制即可用。最后,我们来看下如何去使用,随便在pages下面去新建一个页面,并且打开xxx.json文件,引入这个组件,如下:

{
"usingComponents": {
"custom_top":"/components/custom_top/index",
"qr_code_poster":"/components/qr_code_poster/index" //引入二维码生成组件
}
}

然后只需要在xxx.wxml中使用即可了,如下代码:

<qr_code_poster backgroundImageUrl="/pages/detail/images/bg.jpg" 
qrcodeImageUrl="https://ss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=2290471833,2845730168&fm=26&gp=0.jpg"
qrcodeToImageWidth="{{70}}" 
qrcodeToImageHeight="{{70}}"
qrcodeToImageTop="{{440}}"
qrcodeToImageLeft="{{40}}"
actualBgHeight="{{1920}}"
actualBgWidth="{{1080}}"
backgroundImageWidth="{{320}}"
actualQrcodeWidth="{{500}}"
actualQrcodeHeight="{{500}}"
bind:created="handleCreated"
isStartCreate="{{true}}"
></qr_code_poster>

如果需要保存,那么把created去实现就好了,打开xxx.js,内部添加方法:(注意此出和上面的bind:created后面的值同名)

handleCreated(e){
console.log(e.detail,'最后保存的路径')
},

最后我们来看下效果:

小程序内部用户可见图片效果:

实际保存后的效果:

大家可以看到,是不是很棒棒耶。