评论

小程序将小程序码与图片结合生成海报分享朋友圈

通过canvas 将小程序码绘制到多张海报图上,客户选择喜欢的海报保存至本地,并分享到朋友圈

样例参考(瑞幸咖啡小程序)

需求分析

  1. 服务器端会返回不确认的图片资源到前端
  2. 前端将返回的每张图片都要贴上小程序码
  3. 将贴上小程序码的图片使用 swiper 组件轮播
  4. 用户点击保存时,将图片保存至相册。
  5. 至于点击保存如何保存至相册(wx.saveImageToPhotosAlbuml 了解一下,注意一下授权问题即可)

碰到的问题

  1. canvas为原生组件, 而原生组件的层级是最高的,所以页面中的其他组件无论设置 z-index 为多少,都无法盖在原生组件上。
采用方法: 通过定位,将其移除到不在可视范围,如iphone6  
.canvas {
    position: relative;
    left: -375px;
}
  1. 绘制多张图片时, 一个canvas 标签只能对应画一张图片 (目前我测试的是这样,如有其它方法,欢迎评论交流)
采用方法: 
1. html端循环要生成的图片张数,对应循环出多个 canvas 组件,分别设置不同的 canvasId 区分
2. 封装一个绘制海报的函数,返回一个Promise对象,用于后面绘制完所有的图片,统一赋值渲染,避免多次触发数据更新
3. js端 循环执行一次 绘制海豹函数,存于一个数组列表
4.  使用 Promise.all 函数,统一绘制完毕将生产图片路径赋值

html:
<canvas 
    v-for="u in m.urlList" :key="u"
    :canvas-id="'poster'+index"
    class="canvas"
    style="width:100%; height:100%;">
</canvas>

<swiper
    :indicator-dots="true"
    :circular="true"
    :autoplay="true"
    indicator-color="rgba(255,255,255,.2)"
    indicator-active-color="#fff"
    class="swiper">
    <swiper-item v-for="f in m.filePaths" :key="index">
        <image :src="f">
    </swiper-item>
</swiper>

js: 
// 数据 (mpvue 开发)
function data(){
    return {
        m : {
            urlLIst: [            // 图片资源
                '/static/poster0.jpg',
                '/static/poster1.jpg'
             ],
             filePaths: [],     // 生成图片(贴上小程序码)
         }
     }
}

try {
    let res = wx.getSystemInfoSync();  // 同步获取系统信息
    let w   = res.windowWidth;            // 手机可用区域宽度
    let h   = res.windowHeight;           // 手机可用区域高度
    
    let codeUrl  = '/static/code.jpg';   // 小程序码
    let drawList = [];                            // 用于保存绘制海报图Promise对象
    m.urlList.forEach( (u, i)=> {
        // 传入canvas组件ID,图片路径(测试使用的是本地路径)
        drawList.push(drawPoster('poster'+i,  u, codeUrl));
    })
    
    // 统一更新数据
    Promise.all(drawList).then((valuse)=>{
        m.filePaths = valuse;
    });
    
    // 封装绘制图片函数
    function drawPoster(canvasId, bgUrl, codeUrl){
        return new Promise( (resolve, reject) => {
            // 创建画布实例
            let ctx = wx.createCanvasContext(canvasId);
                // 绘制背景图: 图片路径,x坐标,y坐标,宽,高
                ctx.drawImage(bgUrl, 0, 0, w, h);
                // 绘制小程序码
                ctx.drawImage(codeUrl, w-120, h-120, 100, 100);
                // 绘制
                ctx.draw(false, ()=>{
                    // 该通过函数将canvas绘制导出为图片           
                    wx.canvasToTempFilePath({
                    	x: 0,
                        y: 0,
                        width: w,
                        height: h,
                        canvasId: canvasId,
                        success(res){
                            resolve(res.tempFilePath);
                        }
                });
        });
    }
}catch(e){
	// 自己封装了一成
	wx.$toast(e);
}

最终demo效果图

在社区中暂未看到多张海报实现的方案,如果有更好的实现方案,欢迎交流

最后一次编辑于  07-30  
点赞 10
收藏
评论

7 个评论

  • 名仁华
    名仁华
    11-27

    膜拜大佬

    11-27
    赞同
    回复
  • 徐大治
    徐大治
    11-09

    mark备用

    11-09
    赞同
    回复
  • 我
    09-22

    canvas无法解析标签

    09-22
    赞同
    回复
  • 40哥哥。
    40哥哥。
    08-30

    mark收藏下。后面说不定就用到了

    08-30
    赞同
    回复
  • 仙森ღ₅₂₀¹³¹⁴
    仙森ღ₅₂₀¹³¹⁴
    08-13

    有代码片段么

    08-13
    赞同
    回复
  • 仙森ღ₅₂₀¹³¹⁴
    仙森ღ₅₂₀¹³¹⁴
    07-31

    交流下,使用JSON配置绘制位置:

    https://developers.weixin.qq.com/community/develop/doc/000048447844f80b9107d64ab51006

    07-31
    赞同
    回复 8
    •  
       
      07-31
      感谢提供的方法,不过得等这周五上完线再试试你的方法。
      07-31
      回复
    • 仙森ღ₅₂₀¹³¹⁴
      仙森ღ₅₂₀¹³¹⁴
      07-31回复 
      这是写的生成文章:https://developers.weixin.qq.com/community/develop/article/doc/000ac686c5c5506f18b87ee825b013
      07-31
      回复
    • Beck
      Beck
      08-02回复仙森ღ₅₂₀¹³¹⁴
      好的,谢谢提供
      08-02
      回复
    • Beck
      Beck
      08-12回复仙森ღ₅₂₀¹³¹⁴
      我这边用的 mpvue, 按照另外一篇 mpvue文章引入,在使用组件的时候,更新palette的值,发现出了初始化的时候有侦听到,后面更改,就没有变化了
      08-12
      回复
    • 我
      09-22
      canvas无法解析标签,怎么解决
      09-22
      回复
    查看更多(3)
  •  
     
    07-31

    我这边做的功能和你的类似,不知道你那边有没有在iPhone6s上面测试过,图片会稍微变形。其他机型暂时没有问题,目前还没有找到解决的方法,😂。

    07-31
    赞同
    回复 5
    • Beck
      Beck
      07-31
      我这边用的是6s测试的,跟原图比较感觉是有那么稍微变形,还有一个问题就是,保存到系统相册的时候,图片又被放大了,我最后截图的小程序码距离边有点位置,保存到手机上这个距离被裁减掉了,还在找解决的方法
      07-31
      回复
    •  
       
      07-31回复Beck
      一样,如果还有其他可以解决的方法麻烦告知再帖子下面。
      07-31
      回复
    • 仙森ღ₅₂₀¹³¹⁴
      仙森ღ₅₂₀¹³¹⁴
      07-31
      https://developers.weixin.qq.com/community/develop/article/doc/000ac686c5c5506f18b87ee825b013
      07-31
      回复
    • 林
      07-31回复Beck
      用苹果6做模型,然后进首页的时候获取当前手机的宽高,对比750宽度做个参数。苹果6PS就是750的1.1倍左右,画图的时候宽高还有边距都加上这个1.1倍就可以了
      07-31
      回复
    • Beck
      Beck
      08-02回复 
      哈哈哈,同样同样,如果你找到原因,还望告知
      08-02
      回复