首页 > 编程语言 >uniapp小程序使用wxml-to-canvas生成图片

uniapp小程序使用wxml-to-canvas生成图片

时间:2022-09-22 15:56:38浏览次数:92  
标签:uniapp canvas wxml widget canvasWidth c1 screenWidth

开发框架:uniapp

场景:小程序保存页面为图片并上传

尝试方案:使用html-to-canvas,问题:小程序不允许操作dom,也无法获取dom标签,只能通过wx.createSelectorQuery()获取dom信息。

微信小程序官方解决方案:wxml-to-canvas。问题:只支持wxml的原生小程序canvas图片生成,相关配置也是原生小程序的配置。

解决方案:

1、打开微信小程序官方代码片段代码片段

2、在程序根目录下新建wxcomponents文件夹,将代码片段中的miniprogram_npm下的widget-ui和wxml-to-canvas两个文件夹复制进去

3、将/wxcomponents/wxml-to-canvas/index.js中的

module.exports = require("widget-ui");
//改为
module.exports = require("../widget-ui/index.js")

4、配置pages.json(这样uni-app才会打包wxcomponents)

"pages": [
    {
        "path": "pages/share",
        "style": {
            "usingComponents": {
              "wxml-to-canvas": "/wxcomponents/wxml-to-canvas/index"
            }
        }
    },
...
]

5、主页面 pages/share.vue

<template>
    <view class="share-page">
        <view class="share-page-box" id="box" v-if="show"
            :style="{width: canvasWidth + 'px', height: canvasHeight + 'px' }">
            <wxml-to-canvas class="widget" :width="canvasWidth" :height="canvasHeight"></wxml-to-canvas>
        </view>
        <view class="share-page-btn" @tap="extraImage">
            <button class="btn-big" :style="getBtnStyle">保存图片</button>
        </view>
    </view>
</template>
<script>
    const {
        wxml,
        style
    } = require('./domData.js')
    export default {
        name: '',
        data() {
            return {
                show: false, // 是否显示canvas
                canvasWidth: 320, // 默认canvas宽高
                canvasHeight: 480,
                screenWidth: null, // 设备宽度
                screenHeight: null, // 设备宽度
                name: '',
                pic: '',
                chapter: '',
                widget: null,
            }
        },
        onl oad(options) {
            console.log('options', options);
            this.name = 'wxml生成canvas(liangtao)'
            this.pic = 'https://pic1.zhimg.com/80/v2-58fe538a59f870407b1435bfd45893ed_720w.jpeg'
            this.chapter = ['第一段对话','第二段对话','第三段对话','第四段对话','第五段对话','第六段对话','第七段对话','第八段对话','第九段对话','第十段对话','第十一段对话','第十二段对话','第十三段对话']
            // 获取设备信息
            wx.getSystemInfo({
                success: (res) => {
                    console.log("设备信息",res);
                    this.screenWidth = res.screenWidth
                    this.screenHeight = 1000//高度建议计算得出或写死。如使用res.screenHeight,文字过长时无法生成
                    this.canvasWidth = this.screenWidth 
                    this.canvasHeight = this.screenHeight
                    this.show = true
                    // 数字容器宽度 动态设置 
                    setTimeout(() => {
                        wx.showLoading({
                            title: '图片生成中...'
                        })
                        this.widget = this.selectComponent('.widget')
                        this.renderToCanvas()
                    }, 1000)
                }
            });
        },
        methods: {
            // wxml 转 canvas
            renderToCanvas() {
                console.log('this.widget', this.widget)
                const _wxml = wxml(this.name, this.pic, this.chapter)//调用wxml
                const _style = style(this.screenWidth, this.canvasWidth, this.canvasHeight)
                const p1 = this.widget.renderToCanvas({
                    wxml: _wxml,
                    style: _style
                })
                p1.then((res) => {
                    console.log('生成成功');
                    wx.hideLoading()
                }).catch((err) => {
                    console.log('生成失败')
                })
            },
            // 保持图片
            extraImage() {
                const p2 = this.widget.canvasToTempFilePath()
                let that = this
                p2.then(result => {
                    let path = result.tempFilePath
                    console.log(path);
                })
            },
        }
    }
</script>

 

6、配置wxml页面 /pages/domData.js

const wxml = (name, pic, c1) => `
<view class="container">
    <image src="` + pic + `"  class="pic"/>
    <text class="name">` + name + `</text>
    <text class="content">` + c1[0] + `</text>
    <text class="content">` + c1[1] + `</text>
    <text class="content">` + c1[2] + `</text>
    <text class="content">` + c1[3] + `</text>
    <text class="content">` + c1[4] + `</text>
    <text class="content">` + c1[5] + `</text>
    <text class="content">` + c1[6] + `</text>
    <text class="content">` + c1[7] + `</text>
    <text class="content">` + c1[8] + `</text>
    <text class="content">` + c1[9] + `</text>
    <text class="content">` + c1[10] + `</text>
    <text class="content">` + c1[11] + `</text>
    <text class="content">` + c1[12] + `</text>
</view>
`

/**
 * @param {*} screenWidth 屏幕宽度
 * @param {*} canvasWidth  画布宽度
 * @param {*} canvasHeight  画布高度
 * @param {*} numberWidth  数字宽度,动态设置
 * @return {*} 
 */
const style = (screenWidth, canvasWidth, canvasHeight) => {
    return {
        "container": {
            width: canvasWidth,
            height: canvasHeight,
            position: 'relative',
            overflow: 'hidden',
            backgroundColor: '#ffffff',
        },
        "name": {
            fontSize: 20,
            color: '#333',
            marginLeft: canvasWidth * 0.08,
            width: canvasWidth * 0.84,
            height: screenWidth * 0.18,
            textAlign: 'center',
        },
        "content": {
            fontSize: 14,
            color: '#333',
            width: canvasWidth * 0.84,
            height: screenWidth * 0.15,
            marginLeft: canvasWidth * 0.08,
        },
        "pic": {
            width: canvasWidth * 0.3,
            height: screenWidth * 0.28,
            marginTop: canvasWidth * 0.1,
            marginLeft: canvasWidth * 0.35,
            marginBottom: canvasWidth * 0.05,
            borderRadius: screenWidth * 0.14,
            overflow: 'hidden',
        },
    }
}

module.exports = {
    wxml,
    style
}

 7、最终效果

 

wxml-to-canvas要注意的一些问题

1、只能画view,text,img
2、每个元素必须要设置宽高
3、默认是flex布局,可以通过flexDirection: "column"来改变排列方式

 

标签:uniapp,canvas,wxml,widget,canvasWidth,c1,screenWidth
From: https://www.cnblogs.com/liangtao999/p/16719534.html

相关文章

  • 在线直播系统源码,canvas 生成图片模糊
    在线直播系统源码,canvas生成图片模糊关于canvas的一些基础知识 canvas绘制的是位图canvas的width和height属性 canvas的width和height属性与style的width,height......
  • AttributeError: module 'backend_interagg' has no attribute 'FigureCanvas'. Did y
     plt报错像是下面这样子File"C:\Users\abc\AppData\Local\Programs\Python\Python310\lib\site-packages\matplotlib\pyplot.py",line191,in_get_required_inter......
  • 02 uniapp/微信小程序 项目day02
    一.分类1.1页面布局首先创建cate的分支定义基本结构,因为是两个需要滚动的区域,所以这里要用到组件scroll这个组件如果是yscroll那就要固定高度,xscroll那就要固定......
  • uniapp H5与原生安卓的数据互通和方法调用
    1、准备我这里是uniapp与原生安卓之间的相互调用,也就是原生安卓内嵌H5页面,下面先来准备一下安卓端的代码。(1)、初始化的MainActivity类定义一个WebViewprivateWebView......
  • uniapp未添加本地push模块
    1.引入push模块所需的jar/aar文件本地push模块需要这个文件:aps-release.aar,在SDK/libs目录下找到这个文件后复制到android\simpleDemo\libs目录下获取途径:下载androidsd......
  • 在UniApp的H5项目中,生成二维码和扫描二维码的操作处理
    在我们基于UniApp的H5项目中,需要生成一些二维码进行展示,另外也需要让用户可以扫码进行一定的快捷操作,本篇随笔介绍一下二维码的生成处理和基于H5的扫码进行操作。二维码的......
  • 01 uniapp/微信小程序 项目day01
    一.起步1.1配置uni-app开发环境什么是uni-app,就是基于vue的一个开发框架,可以将我们写的一套代码,同时发布到ios、安卓、小程序等多个平台官方推荐使用Hbuilderx来写uni......
  • 基于HBuilderX+UniApp+ThorUI的手机端前端的页面组件化开发经验
    现在的很多程序应用,基本上都是需要多端覆盖,因此基于一个WebAPI的后端接口,来构建多端应用,如微信、H5、APP、WInForm、BS的Web管理端等都是常见的应用。本篇随笔继续分析总......
  • 如何利用OpenHarmony ArkUI的Canvas组件实现涂鸦功能?
     简介ArkUI是一套UI开发框架,提供了开发者进行应用UI开发时所需具备的能力。随着OpenAtomOpenHarmony(以下简称“OpenHarmony”)不断更新迭代,ArkUI也提供了很多新的组件......
  • uniapp生成二维码
    uniapp—H5生成二维码操作<template> <viewclass='pages'> <!--二维码--> <viewclass="qr-box"> <canvascanvas-id="qrcode"v-show="qrShow"/> </vi......