当前位置: 首页 > article >正文

《微信小程序实战(3) · 推广海报制作》

📢 大家好,我是 【战神刘玉栋】,有10多年的研发经验,致力于前后端技术栈的知识沉淀和传播。 💗

🌻 CSDN入驻不久,希望大家多多支持,后续会继续提升文章质量,绝不滥竽充数,欢迎多多交流。👍

文章目录

    • 写在前面的话
    • 海报生成
      • 需求简介
      • 功能分析
      • 小程序码生成
      • 绘制canvas海报
      • 小程序页面接收
    • 总结陈词

写在前面的话

本篇文章是微信小程序系列的第三篇,本着介绍实用功能块的原则,这边将分享一下实战中十分常见的推广海报生成功能,让我们开始。

相关文章
《微信小程序实战(1)· 开篇示例 》
《微信小程序实战(2) · 组件封装》


海报生成

需求简介

通常微信小程序开发完毕后,进入运营阶段,主要就是不断推广分享,积累用户。

单纯依靠基础的onShareAppMessage,只能实现微信聊天中的分享,效果较为一般。

通常会选择生成带小程序码的推广海报,这样可以用于朋友圈、地推等多种运营手段。

具体如下所示,那具体要怎么实现呢?

功能分析

要实现的海报效果,涉及若干知识点,也可以拆解为若干步骤。

1、第一步要做的就是生成带有个人或详情信息的小程序码。

2、接着就是要用到小程序的canvas画布技术,拼接信息生成海报;

3、实现图片分享效果,这里的方式多种;

接下来进一步将功能实现。


小程序码生成

小程序的海报之所以具备分享功能,主要还是依靠小程序码,小程序码除了用于定位具体页面,通常还包含特殊的业务属性。

官网提供了多种小程序码的生成API,参考:微信小程序官方文档 - 小程序码

海报制作场景,我们通常采用获取不限制的小程序码方式,如何调用API参考上方教程即可。

这边给出部分示例代码:
1、前端调用

ace.sendGet是封装的http工具方法,具体封装参考《微信小程序实战(1)· 开篇示例 》。

调用成功就继续下一步的绘制海报。

ace.sendGet('wxmin/user/' + app.globalData.appId + '/getPoster?page=mark&scene=' + that.data.markId, function (data) {
    if (data) {
        that.eventDraw(data)
    } else {
        ace.msg('生成小程序码失败~');
    }
});

2、后端逻辑

这里使用的是开源的微信小程序后端API封装依赖weixin-java-miniapp,感兴趣的可以搜索一下。

值得注意的是,小程序码的场景值只允许传递一个32位的字符,通常会传递详情页的ID或推荐人ID,如果两个信息都要怎么办?那就是先组装信息,生成一个UUID,然后以K-V的结构存储在Redis中,最终以Key作为场景值。具体扫码进入的页面,根据这个key再解析出对应信息即可。

@GetMapping("/getPoster")
public ResultModel getPoster(@PathVariable String appId, String scene, String page) {
    final WxMaService wxService = WxMaConfiguration.getMaService(appId);
    try {
        //省略页面的处理
        
        //省略场景值的处理

        //生成小程序码
        File tempFile = wxService.getQrcodeService()
        .createWxaCodeUnlimit(scene, page);
        return ResultModel.success(AliOSSUtil.upload(tempFile));
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

绘制canvas海报

微信小程序的Canvas技术是一种在微信小程序中绘制图形和动画的API,它允许开发者使用JavaScript和Canvas 2D API在页面上创建丰富的图形和动画效果。

首先,我们先看一下官网,微信小程序官方文档 - canvas,能了解到部分信息。

其实,海报生成功能,主要是这点比较有难度,对于后端程序猿而言,样式本来就不擅长,还要用到canvas,对于前端程序猿而言,大部分接触到canvas的比较少,属于知识盲区。没办法,这个是小程序必备功能,绕不过了,迎难而上吧。

好在我们虽然不擅长,但懂得找,于是找到了一款不错的海报组件,用这套模板可以减少我们不少工作量。

下面贴出关键代码,模板参考:链接

Step1、引入插件

"usingComponents": {
  "canvasdrawer": "/components/canvasdrawer/canvasdrawer"
}

Step2、页面添加组件

<!-- 海报制作 -->
<view class='poste_box' wx:if="{{showCanvas}}" id='canvas-container'>
  <canvasdrawer painting="{{painting}}" class="canvasdrawer" bind:getImage="eventGet"/>
</view>

Step3、编写核心逻辑

   /**
     * 海报绘制
     */
    eventDraw(img) {
        let that = this;
        let markInfo = that.data.markInfo
        wx.showLoading({
            title: '绘制分享图片中', mask: true
        })
        this.setData({
            painting: {
                width: 375, height: 555, clear: true, views: [{
                    type: 'image',
                    url: '~~~',
                    top: 0,
                    left: 0,
                    width: 375,
                    height: 555
                }, //外框图片

                    {
                        type: 'image', url: markInfo.imgUrl1, top: 26, left: 30.5, width: 320, height: 415
                    }, //主图片

                    {
                        type: 'image', url: img, top: 460, left: 285, width: 65, height: 65
                    }, //小程序码

                    {
                        type: 'text',
                        content: markInfo.markName,
                        fontSize: 16,
                        lineHeight: 21,
                        color: '#383549',
                        textAlign: 'left',
                        top: 460,
                        left: 34,
                        width: 287,
                        MaxLineNumber: 2,
                        breakWord: true,
                        bolder: true
                    }, //标记名称

                    {
                        type: 'text',
                        content: '分享人:' + markInfo.userName,
                        fontSize: 13,
                        color: '#7E7E8B',
                        textAlign: 'left',
                        top: 490,
                        left: 34, // textDecoration: 'line-through'
                    }, //分享人

                    {
                        type: 'text',
                        content: '二维码长期有效',
                        fontSize: 13,
                        color: '#7E7E8B',
                        textAlign: 'left',
                        top: 515,
                        left: 34, // textDecoration: 'line-through'
                    } //文字提示
                ]
            }
        })
    },

    /**
     * 展示图片
     */
    eventGetImage(event) {
        let that = this
        const {tempFilePath, errMsg} = event.detail
        wx.hideLoading()
        if (errMsg === 'canvasdrawer:ok') {
            setTimeout(function () {
                wx.previewImage({
                    current: tempFilePath, // 当前显示图片的http链接
                    urls: [tempFilePath] // 需要预览的图片http链接列表
                });
                that.setData({
                    showCanvas: false, shareImage: tempFilePath
                });
            }, 1000)
        }
    }

最终点击页面按钮,可以生成如下效果。

值得一提的是:

1、绘制完canvas后,这边是选择wx.previewImage预览功能,实现图片的分享和保存,也可以添加保存到本地的功能,这些都是可选的;

2、绘制过程中,尽量先用静态的图片和文字,不断尝试调整效果,最后满意了,再替换为动态信息,这样可以节省很多时间;


小程序页面接收

这边就是描述,小程序码识别后进入具体页面,如何处理,下方是一段示例代码。

onLoad: function (options) {
    let that = this;
    let markId = options.id || '24889222fb8a4f2db26d6c7487280cc1'
  
    //场景值
    if (options.scene) {
        markId = decodeURIComponent(options.scene);
    }
  
    if (!markId) {
        ace.msg('页面缺失标记ID');
        return;
    }
  
    //获取用户信息
    ace.getUserInfo(function (data) {
        that.setData({
            userObj: data, markId, payNo: data.payNo,
        }, function () {
            //初始化页面逻辑
            that.initHandle();
        })
    });
},

总结陈词

此篇文章是《微信小程序实战》系列的第三篇,后续会继续分享小程序实战技能,希望可以帮助到大家。

💗 后续会逐步分享企业实际开发中的实战经验,有需要交流的可以联系博主。


http://www.kler.cn/news/316855.html

相关文章:

  • 文件系统(软硬链接 动静态库 动态库加载的过程)
  • C++学习笔记(32)
  • 在C#中使用NPOI将表格中的数据导入excel中
  • 工业交换机如何保证数据的访问安全
  • SkyWalking 简介
  • 深入理解Go语言中的并发封闭与for-select循环模式
  • 使用脚本自动化管理外部Git仓库依赖
  • 如何基于Flink CDC与OceanBase构建实时数仓,实现简化链路,高效排查
  • MySQL面试题——第一篇
  • 人工智能不是人工“制”能
  • FreeSWITCH 简单图形化界面29 - 使用mod_xml_curl 动态获取配置、用户、网关数据
  • 寻呼机爆炸,炸醒通讯安全警惕心
  • 【操作系统强化】王道强化一轮笔记
  • k8s1.27.7部署higress,代理非k8s集群业务
  • 如何借助ChatGPT提升论文质量:实战指南
  • 真正能抵抗裁员的,从不是专业能力,早知道这些都财务自由了
  • JAVA_17
  • pSort
  • < 微积分Calculus >
  • 【自学笔记】支持向量机(3)——软间隔
  • MySQL--导入SQL文件(命令行导入)
  • 马尔科夫蒙特卡洛_吉布斯抽样算法(Markov Chain Monte Carlo(MCMC)_Gibbs Sampling)
  • 小程序服务零工市场
  • 基于51单片机的矿井安全检测系统
  • SpringBoot 整合 apache fileupload 轻松实现文件上传与下载(通用版)
  • LeetCode 260. 只出现一次的数字 III
  • 用Python提取PowerPoint演示文稿中的音频和视频
  • CVE-2024-46101
  • 0.初始化项目(Vue2升级到Vue3)
  • 物联网新闻2024.09.16-2024.09.22