Canvas 製做海報

  • HTML
<template>
    <view class="content">
        <view class="flex_row_c_c modalView" :class="qrShow?'show':''" @tap="hideQr()">
            <view class="flex_column">
                <view class="backgroundColor-white border_radius_10px padding1vh">
                    <image :src="poster.finalPath" mode="widthFix" class="posterImage"></image>
                </view>
                <view class="flex_row marginTop2vh">
                    <button type="primary" size="mini" @tap.prevent.stop="saveImage()">保存圖片</button>
                    <button type="primary" size="mini" @tap.prevent.stop="share()">分享圖片</button>
                </view>
            </view>
        </view>
        
        <button type="primary" @tap="shareFc()">生成海報</button>
        <view class="hideCanvasView">
            <canvas class="hideCanvas" canvas-id="default_PosterCanvasId" :style="{width: (poster.width||0) + 'px', height: (poster.height||0) + 'px'}"></canvas>
        </view>
    </view>
</template>

  • JS
<script>
    import _app from '@/util/QS-SharePoster/app.js';
    import getSharePoster from '@/util/QS-SharePoster/QS-SharePoster.js';
    export default {
        data() {
            return {
                poster: {},
                qrShow: false,
                canvasId: 'default_PosterCanvasId'
            }
        },
        methods: {
            
            async shareFc() {
                try {
                    if (!this.poster.finalPath) {
                        const d = await getSharePoster({
                            type: 'testShareType',
                            posterCanvasId: this.canvasId,
                            qrCodeArray: ({bgObj, type, bgScale}) => {
                                return [{
                                    text: 'xiazhenjie',
                                    size: bgObj.width*0.25,
                                    dx: bgObj.width*0.05,
                                    dy: bgObj.height - bgObj.width*0.25 - 50
                                }]
                            },
                            imagesArray: ({bgObj, type, bgScale}) => { //接收的第一個參數爲背景圖片的信息, 第二個參數是自定義標識(感受這裏用不到), 圖片爲示例圖片
                                const dx = bgObj.width*0.3; 
                                return [
                                    {
                                        url: '/static/good_image.jpg',
                                        dx:0,
                                        dy: 80,
                                        infoCallBack(imageInfo) {
                                            let scale = bgObj.width*0.2 / imageInfo.height;
                                            return {
                                                dWidth: bgObj.width,
                                                dHeight: bgObj.height*0.4,
                                            }
                                        }
                                    },
                                    {
                                        url: '/static/2.jpg',
                                        dx,
                                        dy: bgObj.height - bgObj.width*0.25 - 50,
                                        infoCallBack(imageInfo) {
                                            let scale = bgObj.width*0.2 / imageInfo.height;
                                            return {
                                                circleSet: {
                                                    x: imageInfo.width * scale/2,
                                                    y: bgObj.width*0.2/2,
                                                    r: bgObj.width*0.2/2
                                                },  // 圓形圖片 , 若circleSet與roundRectSet一同設置 優先circleSet設置
                                                dWidth: imageInfo.width * scale,    // 由於設置了圓形圖片 因此要乘以2
                                                dHeight: bgObj.width*0.2,
                                                roundRectSet: { // 圓角矩形
                                                    r: imageInfo.width*0.1
                                                }
                                            }
                                        }
                                    },
                                ]
                            },
                            textArray: ({bgObj, type, bgScale}) => {
                                const fontSize = bgObj.width*0.045;
                                const lineHeight = bgObj.height*0.04;
                                return [
                                    {
                                        // fontStyle: 'bold',
                                        text: '【新品】大牌來襲,香港直郵教育是護膚品2件套金和爽膚露',
                                        size: 15,
                                        color: '#333333',
                                        alpha: .5,
                                        textAlign: 'left',
                                        textBaseline: 'middle',
                                        infoCallBack(textLength) {
                                            _app.log('index頁面的text的infocallback ,textlength:' + textLength);
                                            return {
                                                dx: 2,
                                                dy: 10
                                            }
                                        }
                                    },
                                    {
                                        text: '200ml溫和清潔乳200ml撒嬌好多話莪個月 惡客額度金額的',
                                        size: 15,
                                        color: '#333333',
                                        alpha: .5,
                                        textAlign: 'left',
                                        textBaseline: 'middle',
                                        infoCallBack(textLength) {
                                            return {
                                                dx: 2,
                                                dy: 32
                                            }
                                        }
                                    },
                                    {
                                        text: '話後過來的.',
                                        size: 15,
                                        color: '#333333',
                                        alpha: .5,
                                        textAlign: 'left',
                                        textBaseline: 'middle',
                                        infoCallBack(textLength) {
                                            return {
                                                dx: 2,
                                                dy: 54
                                            }
                                        }
                                    },
                                    {
                                        text: '限時特賣 19日21:00開搶',
                                        size: 15,
                                        color: '#333333',
                                        alpha: .5,
                                        textAlign: 'left',
                                        textBaseline: 'middle',
                                        infoCallBack(textLength) {
                                            return {
                                                dx: 120,
                                                dy: 345
                                            }
                                        }
                                    },
                                    {
                                        text: '美美的夏末的店鋪',
                                        size: 15,
                                        color: '#333333',
                                        alpha: .5,
                                        textAlign: 'left',
                                        textBaseline: 'middle',
                                        infoCallBack(textLength) {
                                            return {
                                                dx: bgObj.width - 160,
                                                dy: bgObj.height - 130
                                            }
                                        }
                                    },
                                    {
                                        text: '美利',
                                        size: 12,
                                        color: '#333333',
                                        alpha: .5,
                                        textAlign: 'left',
                                        textBaseline: 'middle',
                                        infoCallBack(textLength) {
                                            return {
                                                dx: bgObj.width - 160,
                                                dy: bgObj.height - 110
                                            }
                                        }
                                    },
                                    {
                                        text: '¥219.00',
                                        size: 15,
                                        color: '#333333',
                                        alpha: .5,
                                        textAlign: 'left',
                                        textBaseline: 'middle',
                                        infoCallBack(textLength) {
                                            return {
                                                dx: bgObj.width - 260,
                                                dy: bgObj.height - 50
                                            }
                                        }
                                    },
                                    {
                                        text: '長按圖片識別 二維碼查看商品詳情',
                                        size: 12,
                                        color: '#333333',
                                        alpha: .5,
                                        textAlign: 'left',
                                        textBaseline: 'middle',
                                        infoCallBack(textLength) {
                                            return {
                                                dx: bgObj.width - 260,
                                                dy: bgObj.height - 30
                                            }
                                        }
                                    },
                                ]
                            },
                            setCanvasWH: ({bgObj, type, bgScale}) => { // 爲動態設置畫布寬高的方法,
                                this.poster = bgObj;
                                this.poster.height = 600;
                            },
                            setDraw: ({Context, bgObj, type, bgScale}) => {
                                Context.setFillStyle('#F5F4F9');
                                Context.setGlobalAlpha(0.6);
                                Context.fillRect(0, bgObj.height - bgObj.height*0.2 - 40, bgObj.width, bgObj.height*0.2 + 30);
                            }
                        });
                        console.log('海報生成成功, 臨時路徑: ' + d.poster.tempFilePath)
                        this.poster.finalPath = d.poster.tempFilePath;
                    }
                    this.qrShow = true;
                } catch (e) {
                    _app.hideLoading();
                    _app.showToast(JSON.stringify(e));
                    console.log(JSON.stringify(e));
                }
            },
            
            saveImage() {
                // #ifndef H5
                uni.saveImageToPhotosAlbum({
                    filePath: this.poster.finalPath,
                    success(res) {
                        _app.showToast('保存成功');
                    }
                })
                // #endif
                // #ifdef H5
                _app.showToast('保存了');
                // #endif
            },
            
            share() {
                // #ifdef APP-PLUS
                _app.getShare(false, false, 2, '', '', '', this.poster.finalPath, false, false);
                // #endif

                // #ifndef APP-PLUS
                _app.showToast('分享了');
                // #endif
            },
            
            hideQr() {
                this.qrShow = false;
            }
            
        }
    }
</script>

  • CSS
.hideCanvasView {
        position: relative;
    }

    .hideCanvas {
        position: fixed;
        top: -99999upx;
        left: -99999upx;
        z-index: -99999;
    }

    .flex_row_c_c {
        display: flex;
        flex-direction: row;
        justify-content: center;
        align-items: center;
    }

    .modalView {
        width: 100%;
        height: 100%;
        position: fixed;
        top: 0;
        left: 0;
        right: 0;
        bottom: 0;
        opacity: 0;
        outline: 0;
        transform: scale(3);
        perspective: 2500upx;
        background: rgba(0, 0, 0, 0.6);
        transition: all .3s ease-in-out;
        pointer-events: none;
        backface-visibility: hidden;
        z-index: 999;
    }

    .modalView.show {
        opacity: 1;
        transform: scale(1);
        pointer-events: auto;
    }

    .flex_column {
        display: flex;
        flex-direction: column;
    }

    .backgroundColor-white {
        background-color: white;
    }

    .border_radius_10px {
        border-radius: 10px;
    }

    .padding1vh {
        /* padding: 1vh; */
        padding-top: 20px;
    }
    .padding1vh2{
        padding-top: 20px;
        padding-bottom: 20px;
    }

    .posterImage {
        width: 80vw;
        height: 40vw;
    }

    .flex_row {
        display: flex;
        flex-direction: row;
    }

    .marginTop2vh {
        margin-top: 2vh;
    }

參考:https://ext.dcloud.net.cn/plugin?id=471git

項目地址 :https://dev.tencent.com/u/Coding-Neo/p/CanvasPoster/gitcanvas

相關文章
相關標籤/搜索