<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>
<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>
.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