国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

uniapp實(shí)現(xiàn)微信小程序端動(dòng)態(tài)生成海報(bào)

這篇具有很好參考價(jià)值的文章主要介紹了uniapp實(shí)現(xiàn)微信小程序端動(dòng)態(tài)生成海報(bào)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

  1. 背景:

基于uniapp實(shí)現(xiàn)微信小程序中商品詳情的海報(bào)生成與保存

  1. 效果圖:

uniapp 生成海報(bào),微信小程序,小程序,Powered by 金山文檔
  1. 思路:

  1. 首先把海報(bào)上需要的內(nèi)容準(zhǔn)備好,比如用戶頭像,商品信息,二維碼等。需要注意的是,因?yàn)槎S碼是動(dòng)態(tài)生成的,所以需要后端傳給我們,前端需要把路徑和參數(shù)傳給后端,后端請(qǐng)求微信服務(wù)接口,通過配置對(duì)應(yīng)的參數(shù)就可以生成一個(gè)二維碼啦,再將二維碼發(fā)送給前端。

  1. 圖片不能是網(wǎng)絡(luò)圖片,我們需要的是本地圖片,如非本地圖片,那我們需要對(duì)圖片進(jìn)行處理。uniapp可以通過uni.getImageInfo獲取圖片本地路徑(uni.chooseImage(OBJECT) | uni-app官網(wǎng) (dcloud.net.cn))

  1. 如果通過臨時(shí)路徑來保存圖片,canvas一倍會(huì)比較模糊,我們可以加到2或3倍,太大安卓機(jī)容易出問題,我們可以采用設(shè)備的像素作為倍率,uni.getSystemInfo獲取設(shè)備信息

  1. 創(chuàng)建canvas繪制上下文,在繪制canvas的時(shí)候,把兩個(gè)圖片都切割成圓形的圖片,然后中間就出現(xiàn)了一條線,在之后對(duì)原價(jià)進(jìn)行劃線刪除狀態(tài)的時(shí)候設(shè)置劃線的顏色,會(huì)影響圓形的邊線顏色。然后才知道,canvas繪圖是在JS中完成,只能通過JS代碼來控制,JS提供了beginPath()和closePath()兩個(gè)函數(shù)來控制canvas中模塊的開始和結(jié)束,這樣就可以避免屬性覆蓋。

  1. 補(bǔ)充:和后端交互生成二維碼,需要傳參數(shù),要注意頁面路徑不能再根目錄前不增加/,攜帶的參數(shù)最大為32個(gè)可見字符,且字符有要求限制,如果不符合規(guī)范就會(huì)生成二維碼失敗

  1. 在頁面的onLoad生命周期參數(shù)options判斷options.scene是否存在,存在就是掃描二維碼進(jìn)入,需要對(duì)二維碼返回的參數(shù)進(jìn)行處理,先根據(jù)官方文檔來進(jìn)行解碼,decodeURIComponent會(huì)將%3D解碼成=,我傳參的時(shí)候是通過&符號(hào)將參數(shù)之間隔開的,所以我這里使用split('&'),將解碼后的字符串通過&符號(hào)分割成數(shù)組,循環(huán)數(shù)組得到鍵名和鍵值,代碼如下(掃普通鏈接二維碼打開小程序 | 微信開放文檔 (qq.com))

  1. 生成、獲取二維碼代碼

onLoad: function(options) {
? ? if (options.scene) { //二維碼進(jìn)入
                const scene1 = decodeURIComponent(options.scene);
                let a = scene1.toString().split('&');
                let obj = {}
                for (let i = 0; i < a.length; i++) {
                    // 獲取=前
                    let index = a[i].indexOf("=")
                    let name = a[i].substring(0, index);//鍵名
                    // 獲取=后
                    let index1 = a[i].indexOf("=")
                    let value = a[i].substring(index1 + 1, a[i].length);
                    obj[name] = value //鍵值
                }
                this.goodsId = obj.id //獲取商品id
                this.getType = obj.type; //獲取進(jìn)入頁面的方式
       } else{//非二維碼進(jìn)入

? ? ? ?}
}
//生成二維碼向后端傳遞的參數(shù)
let data = {
      page: 'page_my/pages/chengbei-goods-details/index',//路徑
     scene: `id=${that.goodsId}&code=${that.userCode}&type=${that.getType}`, //參數(shù)
}
  1. HTML代碼如下

<!-- 海報(bào) -->
        <canvas :style="{height: pupopHeight + 'px',width: pupopWidth + 'px'}" canvas-id="myCanvas"></canvas>
        <uni-popup ref="popup" type="center">
            <view class="popup-wrap" :style="'width:' + width + 'px'">
                <!-- <view class="popup-head">
                    生成海報(bào)
                    <view @click="close_popup()" class="close_icon"></view>
                </view> -->
                <image :src="posterImg" mode="widthFix" style="width: 100%;"></image>
                <view class="popup-footer">
                    <view class="buttons margin_l30 marTop20" @click="saveToLocal()">保存到相冊(cè)</view>
                    <view class="buttonNo margin_l30 marTop20" @click="closeToLocal()">取消</view>
                    <!-- <view class="tips">保存圖片到相冊(cè),你就可以分享啦!</view> -->
                </view>
            </view>
        </uni-popup>
        <!-- 海報(bào)end -->
  1. JS代碼如下文章來源地址http://www.zghlxwxcb.cn/news/detail-532625.html

data(){
? ? return{
? ? ? ? ? ? ? ? // 海報(bào)
                pupopWidth: 590,
                pupopHeight: 900,
                pixelRatio: 3, //屏幕像數(shù)密度
                inviteQR: '', //動(dòng)態(tài)二維碼
                posterImg: '', //最后生成的海報(bào)
                width: 100, //當(dāng)前手機(jī)寬度
                // 海報(bào)end ? 
? ? }
},
onLoad(){
? ? ? ? ? ? let that = this
            uni.getSystemInfo({
                success: function(res) {
                    that.width = res.windowWidth * 0.8 //獲取海報(bào)彈出層的寬度
                    that.pixelRatio = res.pixelRatio //獲取像素比
                }
            })
            this.pupopWidth = this.pupopWidth * this.pixelRatio
            this.pupopHeight = this.pupopHeight * this.pixelRatio
            console.log("屏幕像素密度", this.pixelRatio, this.pupopWidth, this.pupopHeight)
},
methods:{
? ? ? ? ? ? // 生成海報(bào)
            shareing() {
                this.isHideSharePopor()
                uni.showLoading({
                    title: "海報(bào)生成中...",
                    mask: true
                })

                //#ifdef MP-WEIXIN
                //這里參數(shù)是前端和后端商議好,生成二維碼需要前端傳那些對(duì)應(yīng)的值,這里我傳了當(dāng)前頁面的路徑和邀請(qǐng)碼及當(dāng)前頁面的參數(shù)
                
                this.inviteQR = this.ewmImgUrl //這里是獲取后端傳來的二維碼,先給寫死了
                this.createPoster();
                //#endif

            },
            //生成海報(bào)--微信端
            createPoster() {
                let _this = this
                _this.headImg = uni.getStorageSync('avatarUrl') //去本地緩存獲取頭像
                uni.getImageInfo({
                    src: _this.headImg,
                    success(image) {
                        const canvasId = "myCanvas"
                        let ctx = uni.createCanvasContext(canvasId, _this) // 自定義組件中 一定要傳this 
                        // 填充背景
                        ctx.setFillStyle('#FAFAFA')
                        ctx.fillRect(0, 0, _this.pupopWidth, _this.pupopHeight);
                        ctx.save()

                        // 頭像和二維碼大小都需要在規(guī)定大小的基礎(chǔ)上放大像素比的比例后面都會(huì)*this.pixelRatio
                        let headerW = 102 * _this.pixelRatio
                        let headerX = 40 * _this.pixelRatio
                        let headerY = 40 * _this.pixelRatio
                        // 控制頭像為圓形
                        ctx.beginPath()
                        ctx.setStrokeStyle('rgba(0,0,0,.2)') //設(shè)置線條顏色,如果不設(shè)置默認(rèn)是黑色,頭像四周會(huì)出現(xiàn)黑邊框
                        ctx.arc(headerX + headerW / 2, headerY + headerW / 2, headerW / 2, 0, 2 * Math.PI)
                        ctx.stroke() //畫出當(dāng)前路徑的邊框
                        ctx.clip()//畫完之后執(zhí)行clip()方法,否則不會(huì)出現(xiàn)圓形效果
                        ctx.drawImage(image.path, headerX, headerY, headerW, headerW)// 將頭像畫到畫布上
                        ctx.restore()
                        ctx.strokeStyle = '#EEEEEE';
                        ctx.save()
                        ctx.closePath()
                        //繪制小程序名字
                        const uniqueCode = "木之本櫻";
                        let invateCode = `${uniqueCode}`
                        let invateCodeX = headerX + headerW + 14 * _this.pixelRatio
                        let invateCodeY = headerY + (40 * _this.pixelRatio)
                        ctx.setFontSize(26 * _this.pixelRatio);
                        ctx.setFillStyle('#333333');
                        ctx.fillText(invateCode, invateCodeX, invateCodeY);
                        ctx.stroke();
                        //繪制廣告語
                        let invateCode1 = "廣告語"
                        let invateCodeX1 = headerX + headerW + 14 * _this.pixelRatio
                        let invateCodeY1 = headerY + (84 * _this.pixelRatio)
                        ctx.setFontSize(26 * _this.pixelRatio);
                        ctx.setFillStyle('#333333');
                        ctx.fillText(invateCode1, invateCodeX1, invateCodeY1);
                        ctx.stroke();
                        //生成banner圖
                        uni.getImageInfo({
                            src: _this.goodsThumbnailUrl, //這里的banner是展示的商品圖 
                            success(image) {
                                let bannerW = 510 * _this.pixelRatio
                                let bannerH = 510 * _this.pixelRatio
                                let bannerX = 40 * _this.pixelRatio
                                let bannerY = 40 * _this.pixelRatio + headerW + 24 * _this.pixelRatio
                                // 控制商品圖片為圓形
                                ctx.beginPath()
                                ctx.setStrokeStyle('rgba(0,0,0,.2)') //設(shè)置線條顏色,如果不設(shè)置默認(rèn)是黑色,頭像四周會(huì)出現(xiàn)黑邊框
                                ctx.arc(bannerX + bannerW / 2, bannerY + bannerW / 2, bannerW / 2, 0, 2 * Math.PI)
                                // ctx.strokeStyle = 'red'; //設(shè)置線的顏色狀態(tài)
                                ctx.stroke()
                                //畫完之后執(zhí)行clip()方法,否則不會(huì)出現(xiàn)圓形效果
                                ctx.clip()
                                // 將商品主圖畫到畫布上
                                ctx.drawImage(image.path, bannerX, bannerY, bannerW, bannerH)
                                ctx.restore()
                                ctx.save()
                                ctx.closePath()
                                //現(xiàn)價(jià)
                                let bannerTextX = 40 * _this.pixelRatio
                                let bannerTextY = bannerY + bannerH + 20 * _this.pixelRatio + 50 * _this.pixelRatio //這里的y軸起始值是頂上的距離還要特意加上文字的行高
                                let chr = `¥${_this.oldPrice}`; //這個(gè)方法是將一個(gè)字符串分割成字符串?dāng)?shù)組
                                ctx.setFontSize(50 * _this.pixelRatio);
                                ctx.setFillStyle('#EA5506');
                                ctx.fillText(chr, bannerTextX, bannerTextY);
                                ctx.stroke();
                                // 測試當(dāng)前現(xiàn)價(jià)的寬度 
                                let metrics = ctx.measureText(`¥${_this.oldPrice}`)
                                // 劃線價(jià)
                                let bannerTextX1 = 40 * _this.pixelRatio + metrics.width + 20 * _this
                                    .pixelRatio
                                let bannerTextY1 = bannerY + bannerH + 20 * _this.pixelRatio + 50 * _this
                                    .pixelRatio //這里的y軸起始值是頂上的距離還要特意加上文字的行高
                                let chr1 = `¥${_this.newPrice}`; //這個(gè)方法是將一個(gè)字符串分割成字符串?dāng)?shù)組
                                ctx.setFontSize(26 * _this.pixelRatio);
                                ctx.setFillStyle('#999999');
                                ctx.fillText(chr1, bannerTextX1, bannerTextY1);
                                ctx.stroke();
                                // 測試原價(jià)的寬度
                                let metrics1 = ctx.measureText(`¥${_this.newPrice}`)
                                //畫字體刪除線
                                ctx.beginPath()
                                ctx.moveTo(bannerTextX1, bannerTextY1 - 10 * _this.pixelRatio); //移動(dòng)到指定位置 X Y
                                //設(shè)置起點(diǎn)狀態(tài)
                                ctx.lineTo(bannerTextX1 + metrics1.width, bannerTextY1 - 10 * _this
                                    .pixelRatio);
                                //設(shè)置末端狀態(tài)
                                ctx.lineWidth = 1 * _this.pixelRatio; //設(shè)置線寬狀態(tài)
                                ctx.strokeStyle = '#999999'; //設(shè)置線的顏色狀態(tài)
                                // ctx.setStrokeStyle('#999999')
                                ctx.stroke();
                                ctx.closePath()
                                //二維碼
                                uni.getImageInfo({
                                    src: _this.inviteQR,
                                    success(res) {
                                        // 畫當(dāng)前頁面的二維碼 _this.pupopWidth

                                        const img_w = 160 * _this.pixelRatio
                                        const img_x = _this.pupopWidth - 40 * _this.pixelRatio -
                                            img_w
                                        const img_y = bannerY + bannerH + 20 * _this.pixelRatio
                                        ctx.drawImage(res.path, img_x, img_y, img_w, img_w)
                                        // 商品名字 goodsName
                                        //這里會(huì)處理多行顯示文字,超出顯示省略號(hào)的效果 
                                        let bannerTextX = 40 * _this.pixelRatio
                                        let bannerTextY = bannerY + bannerH + 20 * _this.pixelRatio + 150 * _this.pixelRatio //這里的y軸起始值是頂上的距離還要特意加上文字的行高
                                        let chr = _this.goodsName.split(""); //這個(gè)方法是將一個(gè)字符串分割成字符串?dāng)?shù)組
                                        let temp = "";
                                        let row = [];
                                        ctx.setFontSize(30 * _this.pixelRatio)
                                        ctx.setFillStyle("#333333")
                                        for (var a = 0; a < chr.length; a++) {
                                            if (ctx.measureText(temp).width < 300 * _this.pixelRatio) {
                                                temp += chr[a];
                                            } else {
                                                a--; //這里添加了a-- 是為了防止字符丟失,效果圖中有對(duì)比
                                                row.push(temp);
                                                temp = "";
                                            }
                                        }
                                        row.push(temp);
                                        if (row.length > 2) {
                                            let rowCut = row.slice(0, 1);
                                            let rowPart = rowCut[0];
                                            let test = "";
                                            let empty = [];
                                            for (var a = 0; a < rowPart.length; a++) {
                                                if (ctx.measureText(test).width < 300 * _this.pixelRatio) {
                                                    test += rowPart[a];
                                                } else {
                                                    break;
                                                }
                                            }
                                            empty.push(test);
                                            var group = empty[0] + "..." //這里只顯示1行,超出的用...表示
                                            rowCut.splice(0, 1, group);
                                            row = rowCut;
                                        }
                                        for (var b = 0; b < row.length; b++) {
                                            ctx.fillText(row[b], bannerTextX, bannerTextY + b *50 * _this.pixelRatio, 510 * _this.pixelRatio);
                                        }
                                        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轉(zhuǎn)換為圖片
                                                    _this.$refs.popup.open();
                                                    uni.hideLoading()

                                                },
                                                fail(error) {
                                                    console.log('4', error)
                                                    // appEv.arrTips("生成海報(bào)失敗,請(qǐng)稍后重試!")
                                                    setTimeout(() => {
                                                        uni.hideLoading()
                                                    }, 2000)
                                                }
                                            }, _this)
                                        })
                                    },
                                    fail(error) {
                                        console.log('獲取二維碼失敗', error)
                                        // appEv.arrTips("生成海報(bào)失敗,獲取二維碼失敗")
                                        setTimeout(() => {
                                            uni.hideLoading()
                                        }, 2000)
                                    }
                                })
                            },
                            fail(error) {
                                console.log('生成商品圖失敗', error)
                                // appEv.arrTips("生成海報(bào)失敗,獲取商品圖失敗")
                                setTimeout(() => {
                                    uni.hideLoading()
                                }, 2000)


                            }
                        });

                    },
                    fail(error) {
                        console.log('生成頭像失敗', error)
                        // appEv.arrTips("生成海報(bào)失敗,獲取頭像失敗")
                        setTimeout(() => {
                            uni.hideLoading()
                        }, 2000)

                    }
                })
            },
            // 取消保存
            closeToLocal() {
                this.$refs.popup.close()
            },
            //將圖片保存到本地相冊(cè)
            saveToLocal() {
                //#ifdef MP-WEIXIN
                uni.saveImageToPhotosAlbum({
                    filePath: this.posterImg,
                    success: () => {
                        console.log('保存到相冊(cè)成功')
                        // appEv.arrTips("保存到相冊(cè)成功")
                        this.$refs.popup.close()
                    },
                    fail: (err) => {
                        console.log("保存到相冊(cè)失敗", err)
                    }
                });
                //#endif 
            },
},

到了這里,關(guān)于uniapp實(shí)現(xiàn)微信小程序端動(dòng)態(tài)生成海報(bào)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包