• uniapp canvas 生成海报并保存到本地


    最终生成的样式

    注释已经打好,详情看代码

    <template>
        <view class="canvas-box">
            <!-- 导航栏 -->
            <view class="nav-box">
                <view class="title-top" :style="'padding-top:' + statusBarHeight + 'rpx'">
                    <u-icon class="title-icon" name="arrow-left" color="#ffffff" size="36" @click="getBack"></u-icon>
                    <text>海报分享</text>
                </view>
            </view>
            
            <!-- 开发完成之前,取消 fixed;opacity: 0;-->
            <canvas style=" 346px;height: 500px;position: fixed;opacity: 0;" class="canvas" canvas-id="canvasID"></canvas>
            <!-- 完成海报制作后,需要把canvas移到看不见的地方,或者隐藏,把image显示出来 -->
            <image :src="imgUrl" mode=""></image>
    
            <view class="footer">
                <view class="download" @click="saveImage">
                    <!-- 小于符号图标 -->
                    <u-icon name="download" color="#ffffff" size="34"></u-icon>
                    <text>保存到相册</text>
                </view>
            </view>
        </view>
    </template>
    
    <script>
        export default {
            data() {
                return {
                    imgUrl: '',
                    statusBarHeight: 0,
                    avatar: '../../../../static/images/default-chat-avatar.png', //头像地址
                    hello: '../../../../static/images/share/weixin-hi.png', // hello图标
                    mony: '../../../../static/images/share/mony.png' //圆的钱图标
                }
            },
            created() {
                this.$tool.getSystemInfo().then(res => {
                    this.statusBarHeight = res
                })
            },
            mounted() {
                let ctx = uni.createCanvasContext('canvasID', this);
                // ctx.setFillStyle("transparent"); //设置canvas背景颜色
                // ctx.fillRect(0, 0, 346, 500) //设置canvas画布大小
                this.fillRoundRect(ctx, 0, 0, 346, 500, 15); //绘制一个圆角矩形
                this.fillRoundRect(ctx, 0, 0, 346, 182, 15, '#333231'); //绘制一个圆角矩形
                this.drawCircular(ctx, this.avatar, 36, 32, 50, 50) //绘制圆形头像
    
                ctx.setFontSize(18)
                ctx.setFillStyle("#ffffff")
                ctx.fillText('明天依然是晴天', 98, 65)
                ctx.drawImage(this.hello, 240, 10, 86, 86) //二维码
                ctx.font = '20px normal'
                ctx.setFillStyle("#09CFB1")
                ctx.fillText('我为“贤马”带盐', 30, 122)
                ctx.font = '16px normal'
                ctx.setFillStyle("#ffffff")
                ctx.fillText('“闲么?上贤马做兼职”', 20, 152)
    
                // 绘制职位标题,多余文字自动换行
                ctx.setFontSize(28)
                ctx.setFillStyle("#333333")
    
                let str = '店铺实习生ZAra重庆龙湖时代'
                // 字符串总长度
                let _strLength = str.length
                // 总结截取次数
                let _strNum = Math.ceil(_strLength / 9)
    
                // 每次开始截取字符串的索引
                let _strHeight = 0
                // 绘制的字体 x,y的初始位置
                let _strX = 27,
                    _strY = 223
                let strIndex = 223
                // 开始截取
                for (let i = 0; i < _strNum; i++) {
                    strIndex = _strY + i * 40
                    ctx.fillText(str.substr(_strHeight + i * 9, 9), _strX, _strY + i * 40)
                }
                strIndex += 30
                ctx.setFontSize(14)
                ctx.setFillStyle("#1BB99A")
                let strtitle = '环境好/结算快/时间短'
                ctx.fillText(strtitle, _strX, strIndex)
    
                ctx.setFontSize(20)
                ctx.setFillStyle("#333231")
                ctx.fillText('16元/小时', _strX, 418)
    
                this.drawCircular(ctx, this.mony, _strX, 429, 14, 14) //绘制圆形头像
                ctx.setFontSize(12)
                ctx.setFillStyle("#F7BA65")
                ctx.fillText('已预付', _strX + 20, 440)
    
                // 绘制微信二维码
                ctx.drawImage(this.hello, 208, 370, 120, 120) //二维码
    
                ctx.draw(false, () => {
                    // 返回canvas图片信息
                    uni.canvasToTempFilePath({
                        canvasId: 'canvasID',
                        success: (res) => {
                            this.imgUrl = res.tempFilePath
                            // console.log(res.tempFilePath)
                        },
                        fail: function(err) {
                            console.log(err)
                        }
                    })
                })
            },
            methods: {
                getBack() {
                    uni.navigateBack({
                        delta: 1
                    });
                },
                saveImage() { //点击保存
                    var _this = this;
                    uni.saveImageToPhotosAlbum({
                        filePath: _this.imgUrl,
                        success() {
                            uni.showModal({
                                title: "保存成功",
                                content: "图片已成功保存到相册,快去分享到您的圈子吧",
                                showCancel: false
                            })
                        }
                    })
                },
                // 将网络图片转为临时图片地址
                async getImageInfo({imgSrc}) {
                    return new Promise((resolve, errs) => {
                        uni.downloadFile({
                            src: imgSrc,
                            success: function(image) {
                                resolve(image);
                            },
                            fail(err) {
                                errs(err);
                            }
                        });
                    });
                },
                // 绘制圆形头像
                drawCircular(ctx, url, x, y, width, height) {
                    //画圆形头像
                    var avatarurl_width = width;
                    var avatarurl_heigth = height;
                    var avatarurl_x = x;
                    var avatarurl_y = y;
                    ctx.save(); //先保存状态,已便于画完园再用
                    ctx.beginPath(); //开始绘制
                    ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math
                        .PI * 2, false);
                    ctx.setFillStyle("#FFFFFF")
                    ctx.fill() //保证图片无bug填充
                    ctx.clip(); //剪切
                    ctx.drawImage(url, avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); //推进去图片
                    ctx.restore();
                },
                // 绘制带圆角的矩形方法
                fillRoundRect(cxt, x, y, width, height, radius,  fillColor) {
                    //圆的直径必然要小于矩形的宽高
                    if (2 * radius > width || 2 * radius > height) {
                        return false;
                    }
    
                    cxt.save();
                    cxt.translate(x, y);
                    //绘制圆角矩形的各个边
                    this.drawRoundRectPath(cxt, width, height, radius);
                    cxt.fillStyle = fillColor || '#fff'; //若是给定了值就用给定的值否则给予默认值
                    cxt.fill();
                    cxt.restore();
                },
                drawRoundRectPath(cxt, width, height, radius) {
                    cxt.beginPath(0);
                    //从右下角顺时针绘制,弧度从0到1/2PI
                    cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);
    
                    //矩形下边线
                    cxt.lineTo(radius, height);
    
                    //左下角圆弧,弧度从1/2PI到PI
                    cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);
    
                    //矩形左边线
                    cxt.lineTo(0, radius);
    
                    //左上角圆弧,弧度从PI到3/2PI
                    cxt.arc(radius, radius, radius, Math.PI, (Math.PI * 3) / 2);
    
                    //上边线
                    cxt.lineTo(width - radius, 0);
    
                    //右上角圆弧
                    cxt.arc(width - radius, radius, radius, (Math.PI * 3) / 2, Math.PI * 2);
    
                    //右边线
                    cxt.lineTo(width, height - radius);
                    cxt.closePath();
                }
            }
        }
    </script>
    
    <style lang="scss" scoped>
        .canvas-box {
            height: 100vh;
            display: flex;
            align-items: center;
            justify-content: center;
            background-color: #1ABC9C;
    
            /deep/.nav-box {
                 100%;
                padding: 0 20rpx;
                position: absolute;
                z-index: 9999;
                top: 0;
                left: 0;
    
                .title-top {
                    font-size: 36rpx;
                    font-weight: 550;
                    color: #FFFFFF;
                    display: flex;
                    justify-content: center;
                    align-items: center;
                    position: relative;
                    margin-bottom: 30rpx;
    
                    .title-icon {
                        position: absolute;
                        left: 0;
                    }
                }
            }
    
            image {
                 335px;
                height: 500px;
            }
    
            .footer {
                display: flex;
                align-items: center;
                justify-content: space-between;
                position: absolute;
                justify-content: center;
                padding: 0 40rpx;
                 100%;
                left: 0;
                bottom: 10%;
    
                .download {
                    border: 1rpx solid #ffffff;
                    color: #ffffff;
                    display: flex;
                    align-items: center;
                }
    
                view {
                    padding: 0 20rpx;
                    height: 78rpx;
                    text-align: center;
                    line-height: 78rpx;
                    font-size: 30rpx;
                    border-radius: 36rpx;
                }
            }
        }
    </style>

      

  • 相关阅读:
    YARN的设计
    在(MRv1)中JobTracker工作方式
    经典 MapReduce框架(MRv1)
    进程与线程的简单解释
    Java序列化的机制和原理
    ibatis源码学习4_参数和结果的映射原理
    ibatis源码学习3_源码包结构
    ibatis源码学习2_初始化和配置文件解析
    ibatis源码学习1_整体设计和核心流程
    spring中的设计模式
  • 原文地址:https://www.cnblogs.com/tlfe/p/15223727.html
Copyright © 2020-2023  润新知