uni-app 微信小程序 图文生成图片 wxml-to-canvas

在做的小程序要增加一个将文字与图片生成图片不可修改的功能,第一次做,在网上找了不少资料。参考了wxml-to-canvas | 微信开放文档  ,又看了一些相关事例,尝试写了一下。
 

需要准备的文件及配置项:

1、先把代码片段下载到本地

2、创建wxcomponents目录,把代码片段中的文件拷到此目录下,并将下图的目录改成真实目录。

3、修改配置文件pages.json,找到要写此功能的路径,加上

"style": {
                "app-plus": {
                    "titleNView": false //禁用原生导航栏
                },
                "navigationBarTitleText": "",
                "enablePullDownRefresh": false,
                "navigationStyle": "custom",
                "usingComponents":{
                    "wxml-to-canvas": "/wxcomponents/wxml-to-canvas/index"
                }
            }

 

 4、开始写组件。注意this.widget = this.selectComponent('.widget');一定要放在onLoad页面生命周期中,不然不生效

 <view :style="{width: canvasWidth + 'px', height: canvasHeight + 'px' }">
        <wxml-to-canvas class="widget" :width="canvasWidth" :height="canvasHeight"></wxml-to-canvas>
    </view>

const {
        wxml,
        style
    } = require('./notification.js')
    export default {
        data() {
            return {
                imgSrc: '/static/img/3.png',
                //最后生成的图片信息
                imageData: null,
                canvasWidth: 320, // 默认canvas宽高
                canvasHeight: 480,
                screenWidth: null, // 设备宽度
                screenHeight: null, // 设备宽度
                userInfo: {},
                isRegister: '',
                controlContent: undefined,
                statusCode: undefined,
                //上个页面用到的图片地址
                tempFile:undefined
            }
        },
        onLoad(option) {
            this.userInfo = uni.getStorageSync('weixin-userInfo') ? JSON.parse(uni.getStorageSync('weixin-userInfo')) :{};
            // 获取设备信息
            wx.getSystemInfo({
                success: (res) => {
                    this.screenWidth = res.screenWidth
                    this.screenHeight = 800 //高度建议计算得出或写死。如使用res.screenHeight,文字过长时无法生成(安卓手机,最新鸿蒙系统高度不能超过1000)
                    this.canvasWidth = this.screenWidth
                    this.canvasHeight = this.screenHeight
                    setTimeout(() => {
                        this.widget = this.selectComponent('.widget');
                        this.controlContent = option.controlContent;
                        this.tempFile = option.tempFile
                        this.download();
                    }, 1000)
                }
            });
        },
        methods: {
            //生成图片
            download() {
                // 数字容器宽度 动态设置 
                setTimeout(() => {
                    uni.showLoading({
                        title: '图片生成中...'
                    })
                    this.renderToCanvas()
                }, 1000)
            },
            renderToCanvas() {
                const _wxml = wxml('test', this.tempFile, this.controlContent) //调用wxml
                const _style = style(this.screenWidth, this.canvasWidth, this.canvasHeight)
                setTimeout(() => {
                    const p1 = this.widget.renderToCanvas({
                        wxml: _wxml,
                        style: _style
                    })
                    p1.then((res) => {
                        uni.hideLoading()
                        this.saveImageToPhotosAlbum();
                    }).catch((err) => {
                        console.log('生成失败')
                    })
                }, 100)

            },
           //保存图片到本地
			saveImageToPhotosAlbum() {
				uni.showLoading({
					title: '正在保存中...'
				})
				const p2 = this.widget.canvasToTempFilePath()
				let that = this
				p2.then(result => {
					let path = result.tempFilePath
					uni.uploadFile({
						url: '上传服务地址',
						filePath: path,
						name: 'file',
						formData: {
							'user': 'test'
						},
						success: (res) => {
							let data = JSON.parse(res.data)
							if (data.code == 200) {
								uni.saveImageToPhotosAlbum({
									filePath: path,
									success: () => {
										uni.hideLoading()
										uni.showToast({
											title: '保存成功,可去手机相册查看',
											duration: 2000,
											icon: 'none'
										});
										/* uni.redirectTo({
										    url: '../communityControl/notification?tempFile='+ this.tempFile    
										});     */
										uni.navigateBack();
									}
								});
							}

						}
					});
				})
			}
        }
    }

 5、写notification.js文件,必须要按照wxml-to-canvas写生成模板,不然不生效

const wxml = (name, pic, content) => `
<view class="container">
    <text class="content">` + content + `</text>
     <image src="` + pic + `"  class="pic"/>
</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',
			padding: '30rpx 20rpx',
        },
        "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.84,
            marginLeft: canvasWidth * 0.08,
			marginTop: canvasWidth * 0.08,
        },
        "pic": {
            width: canvasWidth * 0.4,
            height: screenWidth * 0.2,
            marginTop: canvasWidth * 0.1,
            marginLeft: canvasWidth * 0.35,
            marginBottom: canvasWidth * 0.05,
            borderRadius: screenWidth * 0.14,
            overflow: 'hidden',
        },
    }
}

module.exports = {
    wxml,
    style
}

本文档适用于vue2,并正式运用到项目中,但本人未在vue3的环境下使用,有友友提醒说不能用在vue3中,特在此说明,也欢迎使用的友友们提出宝贵意见。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 11
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值