• 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="{ (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 {
    		 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 {
    		 80vw;
    		height: 40vw;
    	}
    
    	.flex_row {
    		display: flex;
    		flex-direction: row;
    	}
    
    	.marginTop2vh {
    		margin-top: 2vh;
    	}
    
    

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

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

  • 相关阅读:
    【科技】扩展Lucas随想
    【NOI 2018】屠龙勇士(扩欧)
    【NOI 2018】冒泡排序(组合数学)
    【NOI 2018】归程(Kruskal重构树)
    【APIO 2018】铁人两项(圆方树)
    【科技】KD-tree随想
    UOJ#207. 共价大爷游长沙 LCT
    UOJ#23. 【UR #1】跳蚤国王下江南 仙人掌 Tarjan 点双 圆方树 点分治 多项式 FFT
    UOJ#33. 【UR #2】树上GCD 点分治 莫比乌斯反演
    UOJ#191. 【集训队互测2016】Unknown 点分治 分治 整体二分 凸包 计算几何
  • 原文地址:https://www.cnblogs.com/neo-java/p/11454060.html
Copyright © 2020-2023  润新知