TypechoJoeTheme

香草物语

统计
登录
用户名
密码
/
注册
用户名
邮箱
输入密码
确认密码

UniApp开发小程序生成海报

Laughing博主
2024-06-30
/
0 评论
/
302 阅读
/
410 个字
/
百度已收录
06/30
本文最后更新于2024年07月23日,已超过56天没有更新。如果文章内容或图片资源失效,请留言反馈,我会及时处理,谢谢!


具体实现效果就是上面这个图片。里面的元素都是自己根据自己实际情况拼接进去的。

在开发小程序时,我们经常会遇到【分享】这个功能,在实现分享功能时,我们一般会基于当前页面,生成一个海报进行分享。

在实现时,基本上是通过canvas画一个图片,然后生成一个图片,具体的可以看下面的代码。

视图代码

<!-- 报价按钮 -->
        <view :style="{marginTop: '30rpx'}">
            <view class="container-price">
                <view class="container-price-left">
                    <view style="display: flex;flex-direction: column;align-items: center;margin-left: 30rpx;"
                        @click="shareing">
                        <view>
                            <image src="../../static/img/share.svg" style="height: 46rpx;width: 46rpx;"></image>
                        </view>
                        <view style="font-size: 16rpx;height: 30rpx;">分享</view>
                    </view>
                    <view style="display: flex;flex-direction: column;align-items: center;margin-left: 30rpx;"
                        @click="subscribeMsg4Bid">
                        <view>
                            <image src="../../static/img/subscribe.svg" style="height: 46rpx;width: 46rpx;">
                            </image>
                        </view>
                        <view style="font-size: 16rpx;height: 30rpx;">订阅</view>
                    </view>
                </view>
            </view>
        </view>


    <!-- 生成海报 -->
    <canvas v-if="ifGeneratingPosters" :style="{height: pupopHeight + 'px',width: pupopWidth + 'px'}"
        canvas-id="myCanvas"></canvas>
    <uni-popup ref="popupPosters" type="bottom" border-radius="10px 10px 0 0">
        <view class="popup-posters-wrap">
            <image :src="posterImg" mode="aspectFill" :style="{height:'420px',width:'100%'}">
            </image>
            <view class="popup-footer" :style="{marginBottom : (0-safeAreaHeight) + 'px'}">
                <view style="text-align: center;font-size: 20rpx;">立即分享</view>
                <view style="display: flex;flex-direction: row;font-size: 20rpx;margin: 0 20rpx;">
                    <view style="display: flex;flex-direction: column;align-items: center;">
                        <button class="noneButton" data-name="shareBtn" open-type="share">
                            <u-icon size="80" color="#03de6d" name="weixin-circle-fill"></u-icon>
                        </button>
                        <view>微信好友</view>
                    </view>
                    <view style="display: flex;flex-direction: column;align-items: center;margin-left: 20rpx;">
                        <view @click="saveToLocal">
                            <u-icon size="80" color="#18a5f0" name="photo-fill"></u-icon>
                        </view>
                        <view>保存海报</view>
                    </view>
                </view>
                <view
                    :style="{bottom:(safeAreaHeight+5)+'px',left:'50%',position:'fixed',fontSize:'24rpx',transform:'translate(-50%,-50%)',padding:'5rpx 15rpx'}"
                    @click="this.$refs.popupPosters.close()">
                    <view>取消</view>
                </view>
            </view>
        </view>
    </uni-popup>

js代码

//生成海报--微信端
            createPoster() {
                let _this = this
                const canvasId = "myCanvas"
                let ctx = uni.createCanvasContext(canvasId, _this) // 自定义组件中 一定要传this ,这里一开始没加,困惑很久,一定要写一下
                // 填充背景
                ctx.setFillStyle('#FFFFFF')
                ctx.fillRect(0, 0, _this.pupopWidth, _this.pupopHeight);
                ctx.save()
                //生成车辆图册
                uni.getImageInfo({
                    src: _this.imageFileList[0], //这里的banner是展示的商品图
                    success(image) {
                        let bannerW = _this.pupopWidth
                        let bannerH = 400 * _this.pixelRatio
                        let bannerX = 0 * _this.pixelRatio
                        let bannerY = 20 * _this.pixelRatio
                        // 将banner到画布上
                        ctx.drawImage(image.path, bannerX, bannerY, bannerW, bannerH)
                        ctx.restore()
                        ctx.save()

                        //车辆描述
                        ctx.setFontSize(18 * _this.pixelRatio)
                        ctx.setFillStyle("#000")

                        let bannerTextX = 20 * _this.pixelRatio
                        let bannerTextY = bannerY + bannerH + 20 * _this.pixelRatio + 20
                        let title = _this.inquiry.vehicleBrand + _this.inquiry.vehicleSeries +
                            _this.inquiry.vehicleYear + _this.inquiry.vehicleModel
                        if (title.length > 20) {
                            title = title.slice(0, 20) + '...'
                        }
                        ctx.fillText(title, bannerTextX, bannerTextY, _this.pupopWidth);

                        // 第二行文字
                        ctx.setFontSize(14 * _this.pixelRatio)
                        ctx.setFillStyle("#cb171d")
                        //事故类型
                        let titleAccidentType = _this.inquiry.accidentTypeName
                        ctx.fillText(titleAccidentType, bannerTextX, bannerTextY + 30 * _this.pixelRatio, _this
                            .pupopWidth);
                        let accidentTypeWidth = ctx.measureText(titleAccidentType).width

                        //所有人性质
                        let vehicleOwnerNature = _this.inquiry.vehicleOwnerNatureName
                        ctx.fillText(vehicleOwnerNature, bannerTextX + accidentTypeWidth + 5 * _this.pixelRatio,
                            bannerTextY + 30 * _this.pixelRatio, _this
                            .pupopWidth);
                        let vehicleOwnerNatureWidth = ctx.measureText(vehicleOwnerNature).width

                        // 使用性质
                        let vehicleUsageNature = _this.inquiry.vehicleUsageNatureName
                        ctx.fillText(vehicleUsageNature, bannerTextX + accidentTypeWidth + 5 * _this.pixelRatio +
                            vehicleOwnerNatureWidth + 5 * _this.pixelRatio,
                            bannerTextY + 30 * _this.pixelRatio, _this
                            .pupopWidth);
                        let vehicleUsageNatureWidth = ctx.measureText(vehicleUsageNature).width

                        // 初登日期及地方位置
                        ctx.setFontSize(12 * _this.pixelRatio)
                        ctx.setFillStyle("#b3b3b3")
                        let vehicleRegisterDate = '初登日期 ' + _this.inquiry.vehicleRegisterDate
                        let position = '停放地 ' + _this.inquiry.parkingPositionProvinceName + _this.inquiry
                            .parkingPositionCityName
                        let vehicleRegisterDateWithPosition = vehicleRegisterDate + " / " + position
                        ctx.fillText(vehicleRegisterDateWithPosition,
                            bannerTextX,
                            bannerTextY + 30 * _this.pixelRatio + 20 * _this.pixelRatio,
                            _this.pupopWidth);
                        let vehicleRegisterDateWithPositionWidth = ctx.measureText(vehicleRegisterDateWithPosition)
                            .width

                        //画间隔线
                        ctx.moveTo(40 * _this.pixelRatio, bannerTextY + 20 * _this.pixelRatio +
                            20 * _this.pixelRatio +
                            20 * _this.pixelRatio);
                        //设置起点状态
                        ctx.lineTo(_this.pupopWidth - 40 * _this.pixelRatio, bannerTextY + 20 *
                            _this.pixelRatio + 20 * _this.pixelRatio +
                            20 * _this.pixelRatio);
                        //设置末端状态
                        ctx.lineWidth = 1 * _this.pixelRatio; //设置线宽状态
                        ctx.strokeStyle = '#EEEEEE'; //设置线的颜色状态
                        ctx.stroke();

                        //二维码
                        uni.getImageInfo({
                            src: 'https://oss.guochewang.cn/banner/app/wechat_app.jpg',
                            success(res) {
                                // 画当前页面的二维码
                                const img_x = 20 * _this.pixelRatio
                                const img_w = 60 * _this.pixelRatio
                                const img_y = bannerTextY + 20 *
                                    _this.pixelRatio + 20 * _this.pixelRatio +
                                    20 * _this.pixelRatio + 20 * _this.pixelRatio
                                ctx.drawImage(res.path, img_x, img_y, img_w, img_w)

                                //画提示文字
                                const tiptextX = img_x + img_w + 20 * _this.pixelRatio
                                const tiptext1Y = img_y + 20 * _this.pixelRatio
                                const tiptext2Y = img_y + 20 * _this.pixelRatio + 20 * _this
                                    .pixelRatio + 12 * _this.pixelRatio
                                const tiptext1 = '国车网 '
                                const tiptext1_1 = '一个专注事故车的交易平台 '
                                const tiptext2 = '识别二维码查看车辆更多详情'
                                ctx.setFontSize(16 * _this.pixelRatio)
                                ctx.setFillStyle("#cb171d")
                                ctx.fillText(tiptext1, tiptextX, tiptext1Y);
                                ctx.stroke();

                                let tiptext1Width = ctx.measureText(tiptext1).width
                                ctx.setFontSize(12 * _this.pixelRatio)
                                ctx.setFillStyle("#333333")
                                ctx.fillText(tiptext1_1, tiptextX + tiptext1Width, tiptext1Y);
                                ctx.stroke();

                                ctx.setFontSize(12 * _this.pixelRatio)
                                ctx.setFillStyle("#333333")
                                ctx.fillText(tiptext2, tiptextX, tiptext2Y);
                                ctx.stroke();

                                ctx.draw(false, () => {
                                    uni.canvasToTempFilePath({
                                        width: _this.pupopWidth,
                                        height: _this.pupopHeight,
                                        destWidth: _this.pupopWidth,
                                        destHeight: _this.pupopHeight,
                                        canvasId: canvasId,
                                        fileType: 'png',
                                        quality: 1,
                                        success: function(res) {
                                            _this.posterImg = res
                                                .tempFilePath; //最终将canvas转换为图片
                                            _this.$refs.popupPosters
                                                .open();
                                            uni.hideLoading()
                                            _this.ifGeneratingPosters = false

                                        },
                                        fail(error) {
                                            console.log('4', error)
                                            uni.showToast({
                                                title: '生成海报失败,请稍后重试!'
                                            })
                                            setTimeout(() => {
                                                uni.hideLoading()
                                                _this.ifGeneratingPosters = false
                                            }, 2000)
                                        }
                                    }, _this)
                                })
                            },
                            fail(error) {
                                console.log('获取二维码失败', error)
                                uni.showToast({
                                    title: '生成海报失败,获取二维码失败'
                                })
                                setTimeout(() => {
                                    uni.hideLoading()
                                    _this.ifGeneratingPosters = false
                                }, 2000)
                            }
                        })
                    },
                    fail(error) {
                        console.log('生成商品图失败', error)
                        uni.showToast({
                            title: '生成海报失败,获取商品图失败'
                        })
                        setTimeout(() => {
                            uni.hideLoading()
                            _this.ifGeneratingPosters = false
                        }, 2000)
                    }
                });
            },
            //将图片保存到本地相册
            saveToLocal() {
                //#ifdef MP-WEIXIN
                uni.saveImageToPhotosAlbum({
                    filePath: this.posterImg,
                    success: () => {
                        uni.showToast({
                            icon: 'success',
                            title: '保存到相册成功'
                        })
                        this.$refs.popupPosters.close()
                    },
                    fail: (err) => {
                        console.log("保存到相册失败", err)
                    }
                });
                //#endif 
            },
微信小程序小程序UniApp
朗读
赞(0)
赞赏
感谢您的支持,我会继续努力哒!
版权属于:

香草物语

本文链接:

https://www.xiangcaowuyu.net/wechat/uniapp-development-mini-program-generating-posters.html(转载时请注明本文出处及文章链接)

评论 (0)