微信小程序通过保存图片分享到朋友圈

说明

首先说明一点,小程序内是不能直接分享到朋友圈的。所以只能通过生成图片,携带小程序二维码,保存到手机相册,让用户自己选择发到朋友圈。然后可以通过在小程序中识别二维码来进入小程序的指定页面。参考市面上支持分享的应用,基本都是这种实现方式。

准备阶段

  1. 通过服务器获取小程序码

这里可以参考下微信的官方文档,给后台指定的参数和路径等信息,让后台生成指定的小程序码。然后调用wx.getImageInfo将后台生成的小程序码保存起来。

注意一定要仔细看下微信的文档,如果生成小程序码的路径正式服务器不存在,将会生成失败。这点也很蛋疼,很不方便调试。

wx.getImageInfo({                       
    src:'https://xxx.jpg',//服务器返回的带参数的小程序码地址
    success: function (res) {
        //res.path是网络图片的本地地址
        qrCodePath = res.path;
    },
    fail: function (res) {
        //失败回调
    }
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  1. 通过canvas绘制所需信息

准备好所有的图片之后就可以通过canvas绘制了,然后再将canvas导出为图片。关于绘制这块,可以参考微信的canvas api,下面的基本都是查着api的方法走的。

其中需要注意的有几点。

  1. 是不知道绘出来的文字长度,所以不知道文字到底什么时候该换行,所以针对商品标题,可能多行的数据固定了一行18个字符。
  2. 是关于绘制图片的导出,按照官方api的说法应该在draw()完成的回调中执行,但是通过 
    canvasCtx.draw(false,function(res){

    }); 
    这种方式,一直不回调完成。不知道哪里出问题了。所以最后只好加了一个延时去保存图片。

    /**
     * 绘制分享的图片
     * @param goodsPicPath 商品图片的本地链接
     * @param qrCodePath 二维码的本地链接
     */
    drawSharePic: function (goodsPicPath, qrCodePath) {
        wx.showLoading({
            title: '正在生成图片...',
            mask: true,
        });
        //y方向的偏移量,因为是从上往下绘制的,所以y一直向下偏移,不断增大。
        let yOffset = 20;
        const goodsTitle = this.data.orderDetail.paltProduct.name1;
        let goodsTitleArray = [];
        //为了防止标题过长,分割字符串,每行18个
        for (let i = 0; i < goodsTitle.length / 18; i++) {
            if (i > 2) {
                break;
            }
            goodsTitleArray.push(goodsTitle.substr(i * 18, 18));
        }
        const price = this.data.orderDetail.price;
        const marketPrice = this.data.orderDetail.marketPrice;
        const title1 = '您的好友邀请您一起分享精品好货';
        const title2 = '立即打开看看吧';
        const codeText = '长按识别小程序码查看详情';
        const imgWidth = 780;
        const imgHeight = 1600;
    
        const canvasCtx = wx.createCanvasContext('shareCanvas');
        //绘制背景
        canvasCtx.setFillStyle('white');
        canvasCtx.fillRect(0, 0, 390, 800);
        //绘制分享的标题文字
        canvasCtx.setFontSize(24);
        canvasCtx.setFillStyle('#333333');
        canvasCtx.setTextAlign('center');
        canvasCtx.fillText(title1, 195, 40);
        //绘制分享的第二行标题文字
        canvasCtx.fillText(title2, 195, 70);
        //绘制商品图片
        canvasCtx.drawImage(goodPicPath, 0, 90, 390, 390);
        //绘制商品标题
        yOffset = 490;
        goodsTitleArray.forEach(function (value) {
            canvasCtx.setFontSize(20);
            canvasCtx.setFillStyle('#333333');
            canvasCtx.setTextAlign('left');
            canvasCtx.fillText(value, 20, yOffset);
            yOffset += 25;
        });
        //绘制价格
        yOffset += 8;
        canvasCtx.setFontSize(20);
        canvasCtx.setFillStyle('#f9555c');
        canvasCtx.setTextAlign('left');
        canvasCtx.fillText('¥', 20, yOffset);
        canvasCtx.setFontSize(30);
        canvasCtx.setFillStyle('#f9555c');
        canvasCtx.setTextAlign('left');
        canvasCtx.fillText(price, 40, yOffset);
        //绘制原价
        const xOffset = (price.length / 2 + 1) * 24 + 50;
        canvasCtx.setFontSize(20);
        canvasCtx.setFillStyle('#999999');
        canvasCtx.setTextAlign('left');
        canvasCtx.fillText('原价:¥' + marketPrice, xOffset, yOffset);
        //绘制原价的删除线
        canvasCtx.setLineWidth(1);
        canvasCtx.moveTo(xOffset, yOffset - 6);
        canvasCtx.lineTo(xOffset + (3 + marketPrice.toString().length / 2) * 20, yOffset - 6);
        canvasCtx.setStrokeStyle('#999999');
        canvasCtx.stroke();
        //绘制最底部文字
        canvasCtx.setFontSize(18);
        canvasCtx.setFillStyle('#333333');
        canvasCtx.setTextAlign('center');
        canvasCtx.fillText(codeText, 195, 780);
        //绘制二维码
        canvasCtx.drawImage(qrCodePath, 95, 550, 200, 200);
        canvasCtx.draw();
        //绘制之后加一个延时去生成图片,如果直接生成可能没有绘制完成,导出图片会有问题。
        setTimeout(function () {
            wx.canvasToTempFilePath({
                x: 0,
                y: 0,
                width: 390,
                height: 800,
                destWidth: 390,
                destHeight: 800,
                canvasId: 'shareCanvas',
                success: function (res) {
                    that.setData({
                        shareImage: res.tempFilePath,
                        showSharePic: true
                    })
                    wx.hideLoading();
                },
                fail: function (res) {
                    console.log(res)
                    wx.hideLoading();
                }
            })
        }, 2000);
    },
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92
    • 93
    • 94
    • 95
    • 96
    • 97
    • 98
    • 99
    • 100
    • 101
    • 102
    • 103
    • 104
    • 105
    • 106

最后看下绘制出来的效果图。 
这里写图片描述

生成图片之后就可以提示用户去保存分享了。

原文链接:加载失败,请重新获取