微信小程序插件--wxml-to-canvas(生成图片)

2023-10-29

一、需求

        项目中要实现一个将图片分享到朋友圈的功能,将生成的海报转成图片保存到手机。用到了wxml-to-canvas插件。

二、官方示例使用方法

        1.安装wxml-to-canvas

npm install --save wxml-to-canvas

        2.JSON 组件声明

{
  "usingComponents": {
    "wxml-to-canvas": "wxml-to-canvas",
  }
}

         3.wxml 引入组件

<video class="video" src="{{src}}">
  <wxml-to-canvas class="widget"></wxml-to-canvas>
</video>
<image src="{{src}}" style="width: {{width}}px; height: {{height}}px"></image>

        4. js 获取实例

const {wxml, style} = require('./demo.js')
Page({
  data: {
    src: ''
  },
  onLoad() {
    this.widget = this.selectComponent('.widget')
  },
  renderToCanvas() {
    const p1 = this.widget.renderToCanvas({ wxml, style })
    p1.then((res) => {
      this.container = res
      this.extraImage()
    })
  },
  extraImage() {
    const p2 = this.widget.canvasToTempFilePath()
    p2.then(res => {
      this.setData({
        src: res.tempFilePath,
        width: this.container.layoutBox.width,
        height: this.container.layoutBox.height
      })
    })
  }
})

三、实际项目

        安装、json配置、wxml引入都一样。

        1.wxml

    <wxml-to-canvas class="widget" width="325" height="550"></wxml-to-canvas>   

    <view class='save flex-center-center' bindtap='preservation'>
        保存海报
    </view>

        2.js文件

const net = require('../../../common/network.js');
//⚠️海报内容和样式
const { wxml, style } = require('./canvas.js');
//自己封装的微信api
import wxApi from '../../../common/wxApi';

const app = getApp();

Page({
    /**
     * 页面的初始数据
     */
    data: {

    },

    /**
     * 生命周期函数--监听页面加载
     */
    onLoad(options) {
        wx.showLoading({
            title: '海报生成中...',
        });
        //获取页面初始数据
        this.getServerData();
    },

    getServerData() {
        net.posterInfo().then((response) => {
            const { name, title, teacher, qr_code, task_id } = response.data;
            const { real_name, avatarurl, nickname } = app.globalData.userInfo;
            //画海报用到的数据
            this.setData({
                info: response.data,
                avatarurl,
                name,
                title,
                teacher,
                qr_code,
            });

            //注意⚠️:这里是对页面初始渲染
            this.widget = this.selectComponent('.widget');
            const _wxml = wxml(name, avatarurl, title, teacher, qr_code);
            //onload方法里节点没加载完,设置定时器
            setTimeout(() => {
                //渲染到 canvas,传入 wxml 模板 和 style 对象,返回的容器对象包含布局和样式                            
                //信息。
                const p1 = this.widget.renderToCanvas({
                    wxml: _wxml,
                    style,
                });
                p1.then((res) => {
                    this.container = res;
                    wx.hideLoading();
                });
            }, 500);
        });
    },

    preservation() {
        // this.widget = this.selectComponent('.widget')
        const { task_id } = this.data;
        const p2 = this.widget.canvasToTempFilePath();
        p2.then((res) => {
            //保存到本地相册
            wxApi.apiScopeOauth('scope.writePhotosAlbum').then(() => {
                wx.saveImageToPhotosAlbum({
                    filePath: res.tempFilePath,
                    success(res) {
                        util.showToast(
                            '海报已保存,快去朋友圈分享吧!',
                            'none',
                            3000
                        );
                    },
                    fail(res) {
                        wx.showToast({
                            icon: 'error',
                            title: '保存图片失败!',
                        });
                    },
                });
            });
        }).catch((fail) => {
            wx.showToast({
                icon: 'error',
                title: '请稍后再试',
            });
        });
    },
});

        3.canvas.js

                只展示大体框架,具体内容涉及隐私去掉了。

                wxml返回的是页面内容的字符串。

const wxml = ( name, avatarurl,title,teacher,qr_code ) => {
    return `
    <view class="poster-wapper">
        <image class="poster-img" src="https://1.png"/>
        <view class="author">
            <text class="author-text">作者:${name}</text>
        </view>
        <view class="head">
            <view class="head-border">
                <image class="head-img" src="${avatarurl}"></image>
            </view>
        </view>
        
        <view class="poster-info">
            <view class="info">
                <text class="title">挑战内容:《${title}》</text>
                `+ (teacher?`<text class="teacher">老师:${teacher}</text>`:'')
                +` <view class="line"></view>
                    <text class="tip">本次朗读近乎完美!快来听听吧!</text>
            </view>
            <image class="qrcode-img" src="${qr_code}" />
        </view>
    </view>
    `
}

const style = {
    posterWapper:{
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        position: 'relative',
    },
    
    posterImg: {
        width: 325,
        height: 550
    },
    author: {
        width: 119,
        height: 32,
        borderRadius: 12,
        backgroundColor: 'rgba(255,255,255,0.8)',
        position: 'absolute',
        paddingLeft: 18,
        top: 353,
        left: 45,
    },
    authorText: {
        width: 98,
        height: 32,
        paddingLeft: 13.5,
        fontSize: 11,
        fontWeight: 600,
        color: '#333333',
        verticalAlign: 'middle',
    },
    
    head: {
        width: 51,
        height: 51,
        borderRadius: 25.5,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
        position: 'absolute',
        top: 343,
        left: 12,
        backgroundColor: 'rgba(255,255,255,0.8)',
    },
    headBorder: {
        width: 46,
        height: 46,
        backgroundColor: 'rgba(255,255,255)',
        borderRadius: 23,
        display: 'flex',
        alignItems: 'center',
        justifyContent: 'center',
    },
    headImg: {
        width: 43,
        height: 43,
        borderRadius: 20,
    },
    posterInfo:{
        position: 'absolute',
        bottom: -6,
        width: 325,
        height: 143,
        backgroundColor: '#FFFFFF',
        borderRadius: 10,
        display: 'flex',
        flexDirection: 'row'
    },
    
    info: {
        width: 210,
        height: 140,
        display: 'flex',
        flexDirection: 'column',
        justifyContent: 'center',
        paddingTop: 6,
        paddingLeft: 15
    },
    
    title: {
        width: 210,
        height: 24,
        fontSize: 13,
        fontWeight: 600,
        color: '#333333',
        lineHeight: 24
    },
    
    teacher:{
        width: 210,
        height: 24,
        fontSize: 13,
        fontWeight: 400,
        color: '#666666',
        lineHeight: 24,
    },
    line:{
        width: 190,
        height: 1,
        backgroundColor: 'rgba(3,0,0,0.16)'
    },
    tip: {
        height: 24,
        width: 210,
        fontSize: 13,
        fontFamily: 'PingFang SC',
        fontWeight: 600,
        color: '#333333',
        lineHeight: 24,
    },
    
    btn:{
        width: 140,
        height: 33,
        backgroundColor: '#FF6000',
        borderRadius: 19,
        lineHeight: 33,
        textAlign: 'center',
        marginTop: 7.5,
        position: 'relative'
    },
    btnText:{
        width: 140,
        height: 33,
        fontSize: 18,
        fontFamily: 'PingFang SC',
        fontWeight: 600,
        color: '#FFFFFF',
    },
    btnImg:{
        width:37,
        height:18,
        position: 'absolute',
        left: 150,
        top: 9
    },
    
    qrcodeImg:{
        width: 92,
        height: 92,
        marginLeft: 5,
        position: 'absolute',
        bottom: 33,
        right: 12
    }

}

module.exports = {
    wxml,
    style
}
  

注意点⚠️:

        1.wxml支持 viewtextimage 三种标签,通过 class 匹配 style 对象中的样式。

        2.css对象属性值为对应 wxml 标签的 class 驼峰形式。需为每个元素指定 width 和 height 属性,否则会导致布局错误。

        3.存在多个 className 时,位置靠后的优先级更高,子元素会继承父级元素的可继承属性。

元素均为 flex 布局。left/top 等 仅在 absolute 定位下生效。

        4.css不支持背景图片,在wxml中用img代替。

        5.在写text标签时外边必须套一层view标签,否则不显示。(这一点是我遇到的问题,不知道是不是这样规定)

补充:(2022/12/15)

背景图片在开发工具和开发版都可以正常显示,但是在体验版显示不出来;

图片的域名在项目配置里没有,在后台管理-开发设置-服务器域名-request合法域名-配置图片的域名即可正常显示。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

微信小程序插件--wxml-to-canvas(生成图片) 的相关文章

  • vue 点击改变数组中选中的icon颜色(结合拖拽实现)

    1 vue 点击改变数组中选中的icon颜色 在Vue中 可以通过使用v bind指令来动态地修改元素的样式 要根据点击事件来改变数组中选中图标的颜色 首先需要定义一个data属性来存储当前被选中的索引值或者其他相关信息 然后 在模板中使用
  • vue的组件

    在Vue中 组件是可复用的代码块 用于构建用户界面 Vue的组件系统允许您将界面拆分为独立的 可重复使用的部件 提供了更好的代码组织和复用性 以下是在Vue中创建组件的基本步骤 创建一个组件实例 可以使用Vue extend 方法创建一个V
  • Vue + Element-ui组件上传图片报错问题解决方案

    在使用Vue和Element ui组件上传图片时 可能会遇到一些报错问题 以下是一些常见的问题及解决方案 报错 TypeError Cannot read property name of undefined 解决方案 这个错误通常是因为在
  • React安装依赖 node_modules中有下载依赖项但package.json文件中没有依赖

    React安装依赖 node modules中有下载依赖项但package json文件中没有依赖 直接在下载依赖项后 加 S 就可以解决 随机 id 生成器 uuid nanoid npm install nanoid S S save
  • Typecho 最新XC主题 去除域名授权全解密源码

    简介 Typecho 最新XC主题 去除域名授权全解密源码 这是一款多样式主题 首页支持六种主题样式 支持Pjax优化访问速度 多种单页 如友链 说说等 评论支持表情 自定义编辑器 支持其他样式功能 该主题功能性挺高 比较花里胡哨 感觉有一
  • 微信怎么申请小程序商城?一步步教你完成

    随着移动互联网的发展 越来越多的企业和个人开始关注微信小程序 微信小程序是一种不需要下载安装即可使用的应用 它实现了应用 触手可及 的梦想 用户扫一扫或者搜一下就能打开应用 其中 小程序商城因其便捷性和实用性 受到了众多商家的青睐 那么 如
  • 前端必备的 web 安全知识手记

    前言 安全这种东西就是不发生则已 一发生则惊人 作为前端 平时对这方面的知识没啥研究 最近了解了下 特此沉淀 文章内容包括以下几个典型的 web 安全知识点 XSS CSRF 点击劫持 SQL 注入和上传问题等 下文以小王代指攻击者 话不多
  • WEB前端常见受攻击方式及解决办法总结

    一个网址建立后 如果不注意安全问题 就很容易被人攻击 下面讨论一下集中漏洞情况和放置攻击的方法 一 SQL注入 所谓的SQL注入 就是通过把SQL命令插入到web表单提交或输入域名或页面请求的查询字符串 最终达到欺骗服务器执行恶意的SQL命
  • 每天10个前端小知识 <Day 5>

    前端面试基础知识题 1 typeof 与 instanceof 有什么区别 typeof与instanceof都是判断数据类型的方法 区别如下 typeof会返回一个变量的基本类型 instanceof返回的是一个布尔值 instanceo
  • 前端基础:回顾es6相关知识

    Author note 题记 ECMAscript is international standard of javascript ECMA 是 js的国际标准版语言 let and const 为什么之前用var现在需要用let cons
  • 基于java的饮食分享平台系统设计与实现

    基于java的饮食分享平台系统设计与实现 I 引言 A 研究背景和动机 近年来 随着人们生活水平的提高和健康意识的增强 饮食健康已经成为越来越多人的关注焦点 因此 一个方便快捷的饮食分享平台就显得尤为重要 基于Java的饮食分享平台系统设计
  • 基于java的web仓库管理系统设计与实现

    基于java的web仓库管理系统设计与实现 I 引言 A 研究背景和动机 基于Java的Web仓库管理系统是近年来快速发展的领域之一 它提供了丰富的功能 如数据存储 数据检索 数据分析和数据可视化等 本文将重点介绍基于Java的Web仓库管
  • HTML概述、基本语法(表格整理、标签、基本结构)

    一 HTML概述 HTML指的是超文本标记语言 超文本 是指页面内可以包含图片 链接 声音 视频等内容 标记 标签 通过标记符号来告诉浏览器页面该如何显示 我们可以打开浏览器 右击页面 点击 查看网页源代码 来方便了解HTML标签通过浏览器
  • Vue3 和Vue2的区别,以及钩子函数的使用

    Vue js 3 和 Vue js 2 是两个主要版本的流行前端框架 它们之间有很多区别 包括性能优化 新特性和改进的API等 以下是一些Vue 3与Vue 2之间的主要区别 以及一些示例代码来说明这些差异 1 性能优化 响应式系统 Vue
  • 低代码-添加按钮组件设计

    效果图 可拆分为以下细节 按钮列表 删除 两个操作需同步删除 点击外侧删除 点击复选框删除 添加 点击复选框添加 示例代码 技术栈 vue3 arco design ts less tailwindcss
  • 【ES6】解构语句中的冒号(:)

    在解构赋值语法中 冒号 的作用是为提取的字段指定一个新的变量名 让我们以示例 const billCode code version route query 来说明 billCode code version 表示从 route query
  • APP开发毕业设计|ssm爱心小屋公益机构智慧管理APP

    作者主页 编程指南针 作者简介 Java领域优质创作者 CSDN博客专家 CSDN内容合伙人 掘金特邀作者 阿里云博客专家 51CTO特邀作者 多年架构师设计经验 腾讯课堂常驻讲师 主要内容 Java项目 Python项目 前端项目 人工智
  • Web自动化测试 —— cookie复用

    一 cookie简介 cookie是一些数据 存储于用户电脑的文本文件中 当web服务器想浏览器发送web页面时 在链接关闭后 服务端不会记录用户信息 二 为什么要使用Cookie自动化登录 复用浏览器仍然在每次用例开始都需要人为介入 若用
  • 考虑光伏出力利用率的电动汽车充电站能量调度策略研究(Matlab代码实现)

    欢迎来到本博客 博主优势 博客内容尽量做到思维缜密 逻辑清晰 为了方便读者 座右铭 行百里者 半于九十 本文目录如下 目录 1 概述 2 运行结果 3 参考文献 4 Matlab代码 数据
  • 每天10个前端小知识 <Day 14>

    前端面试基础知识题 1 CSSOM树和DOM树是同时解析的吗 浏览器会下载HTML解析页面生成DOM树 遇到CSS标签就开始解析CSS 这个过程不会阻塞 但是如果遇到了JS脚本 此时假如CSSOM还没有构建完 需要等待CSSOM构建完 再去

随机推荐

  • HTML实现简单登录以及界面跳转

  • 经典上中(左右)下三栏布局

    经典上中 左右 下三栏布局 利用绝对定位实现三栏布局 1 html div class container div class top 我是顶部 div div class content div class div div div
  • 构建用户画像-标签体系

    用户画像是目前在技术公司广泛使用的技术 是根据客户人口统计信息 社交关系 偏好习惯和消费行为等信息而抽象出来的标签化画像 常常用在精准营销 圈定人群 发送短信消息 APP弹窗等等 用户画像的准确性往往会直接影响到运营的效果和获客成本 用户画
  • Qt Widgets 之 QDockWidget(停靠窗口)

    目录 什么是停靠窗口 如何添加停靠窗口 QDockWidget setWidget QMainWindow addDockWidget 设置停靠选项 Options AnimatedDocks AllowNestedDocks AllowT
  • Keil在线调试程序乱跑

    最近改了一个别人写的程序 但是在调试器调试过程中出现了一个奇怪的现象 代码部分如下 Sys Run这个函数在main函数中被无限循环调用 初始化时我会将TCENABLE这个标志位置0 通过CAN发送信息来改变他的数值 按道理来说当我运行程序
  • gcc -O0 -O1 -O2 -O3 四级优化选项及每级分别做什么优化

    相关博客http blog chinaunix net uid 24954950 id 2956476 html 相关博客http blog csdn net misiter article details 7514428 相关博客http
  • linux top命令看到的实存(RES)与虚存(VIRT)分析

    近期在公司中解决程序使用的内存高问题 将一部分之前无法回收的内存进行了回收 实现降内存效果 降实存 在统计效果时 QA问是统计RES 实存 还是VIRT 虚存 在网上学习看了一些博客 这里自己总结一下RES和VIRT的区别 1 概念 VIR
  • 绘制同y轴双侧柱状图,且y轴位置在坐标为0的位置,左右x轴均为正值(Python)

    绘制同y轴双侧柱状图 且y轴位置在坐标为0的位置 左右x轴均为正值 Python 在数据可视化中 柱状图是一种常用的图表类型 用于展示不同类别或变量之间的比较 本文将介绍如何使用Python绘制一个同y轴双侧柱状图 且y轴的位置在坐标为0的
  • JQuery之ContextMenu(右键菜单)

    插件下载地址 http www trendskitchens co nz jquery contextmenu jquery contextmenu r2 js 压缩版 http www trendskitchens co nz jquer
  • java_分数

    题目内容 设计一个表示分数的类Fraction 这个类用两个int类型的变量分别表示分子和分母 这个类的构造函数是 Fraction int a int b 构造一个a b的分数 这个类要提供以下的功能 double toDouble 将分
  • BFS(广度优先搜索)简单例题(一)

    bfs想必非常的熟悉了 bfs大多数用来解决什么问题呢 一个最直观经典的例子就是走迷宫 我们从起点开始 找出到终点的最短路程 很多最短路径算法就是基于广度优先的思想成立的 所以这篇博客 主要是利用bfs找迷宫的最短距离 首先看看bfs一般的
  • 【安卓逆向】分析某人直播.apk登录组包

    安卓逆向交流QQ群692903341 1 打开 人人 apk 进入登陆页面 输入用户名和密码 并用fiddler软件抓包 fiddler抓包如下图所示 红框所示为登录时向服务器发达的包 下面我们要分析这里面每个字段的产生 2 打开ddms
  • 记本地Debug测试遇见异步处理操作数据库遇见的问题

    1 打断点本地测试异步处理 在异步处理子线程里操作数据库报数据库连接池已关闭错误 这里使用 SpringBoot 自带的数据库连接池 HikariDataSource 为例 Caused by org springframework jdb
  • 关于python中的+、+=、*、*=

    不废话 直接干货 1 了解一下python的内存机制 a 1 b 1 id a id b 短的字符串 数字python在内存中是一个对象 a b id a id b 字典 数组这样的对象在内存中python会创建两个不同的对象 a new
  • 生成式对抗网络GAN研究进展(五)——Deep Convolutional Generative Adversarial Nerworks,DCGAN

    前言 本文首先介绍生成式模型 然后着重梳理生成式模型 Generative Models 中生成对抗网络 Generative Adversarial Network 的研究与发展 作者按照GAN主干论文 GAN应用性论文 GAN相关论文分
  • Docker Hub的使用以及配置阿里云镜像加速

    Docker Hub是一个由Docker公司负责维护的公共注册中心 它包含了超过15 000个可用来下载和构建容器的镜像 并且还提供认证 工作组结构 工作流工具 比如webhooks 构建触发器以及私有工具 比如私有仓库可用于存储你并不想公
  • [山东科技大学OJ]2297 Problem F: 编写函数:字符串的小写转大写(Append Code)

    Time Limit 1 Sec Memory Limit 16 MB Submit 3392 Solved 1822 Submit Status Description 输入一些字符串 把其中的小写字母转换成大写字母 编写函数str up
  • python 年月日_在Python中将年/月/日转换为年

    I m using the Python datetime module i e gt gt gt import datetime gt gt gt today datetime datetime now gt gt gt print to
  • 架构师成长系列 - 能力认知(3)

    之前写了关于认知的两篇文章 感觉写的还是不够透彻 可能很多人看不明白 我决定还是再次用比较详尽的一个例子 和我给别人one by one中聊到的认知成长部分来再次说明一下这个问题 在我的成长路径中 认知是非常非常重要的 所以我争取把这个问题
  • 微信小程序插件--wxml-to-canvas(生成图片)

    一 需求 项目中要实现一个将图片分享到朋友圈的功能 将生成的海报转成图片保存到手机 用到了wxml to canvas插件 二 官方示例使用方法 1 安装wxml to canvas npm install save wxml to can