uniapp canvas小程序app生成海报图(附带生成中Loading)

效果图:

飞书20230721-082529

 话不多说直接上代码:

html部分:

<template>
    <!--自定义的头部部分-->
	<nav-tap navColor="#333" title="推广二维码" isBack isHei></nav-tap>
	<view class="container">
		<canvas canvas-id="myCanvas" style="width: 600rpx;height:890rpx;position: fixed;top:-200%;left:-200%;opacity: 0;"></canvas>
		<image :src="data.path" style="width: 100%;height: 100%;"></image>
	</view>
	<view class="bottomBtn">
		<view class="leftBtn" @click.stop="saveImage">
			<image style="width: 44rpx;height: 44rpx;margin-right: 16rpx;" src="http://wisdomhallsup.oss-cn-beijing.aliyuncs.com/uploads/20230720/973dbaf930b3988948393e1c03dc77b5.png"></image>
			<text>保存图片</text>
		</view>
		<view class="rightBtn">
			<image style="width: 44rpx;height: 44rpx;margin-right: 16rpx;" src="http://wisdomhallsup.oss-cn-beijing.aliyuncs.com/uploads/20230720/d787c0dd9f4f0e8c056d83247be77923.png"></image>
			<text>分享好友</text>
		</view>
	</view>
	<view v-if="data.show" style="display: flex;align-items: center;justify-content: center;position: fixed;width: 100vw;height: 100vh;top:0;left: 0;background-color: rgba(0,0,0,0.5);">
		<view style="height: 220rpx;width:220rpx;background-color: #fff;border-radius: 20rpx;">
			<view style="height: 140rpx;display: flex;align-items: center;justify-content: center;">
				<view class="loading">
				  <view class="item"></view>
				  <view class="item"></view>
				  <view class="item"></view>
				</view>
			</view>
			<view class="step" style="height: 34rpx;width: 100%;text-align: center;color: #999;font-size: 28rpx;margin-top:20rpx;">
				<text style="--i:1">海</text>
				<text style="--i:2">报</text>
				<text style="--i:3">绘</text>
				<text style="--i:4">制</text>
				<text style="--i:5">中</text>
				<text style="--i:6">.</text>
				<text style="--i:7">.</text>
				<text style="--i:8">.</text>
			</view>
		</view>
	</view>
</template>

js部分:

<script setup>
	import { onShow,onReady,onLoad} from '@dcloudio/uni-app'
	import { inject,reactive,ref} from "vue"
	import navTap from '@/components/navTap.vue'
	const $request = inject('$request')
	const $api = inject('$api')
	const topheight = ref(0)
	const painter = ref(null)
	const data = reactive({
		path:'',
		show:false,
	})
	const saveImage = () => {
		uni.saveImageToPhotosAlbum({  //保存到相册
			filePath: data.path,
			success: function () {
				console.log('save success');
			}
		});
	}
	const drawDone = (flag = false,ctx) => {
		return new Promise((resolve,reject)=>{
			ctx.draw(flag,()=>setTimeout(()=>resolve(),100))
		})
	}
	onLoad(()=>{
		data.show = true
		setTimeout(async ()=>{  //延时为了模拟请求数据
			const ctx = uni.createCanvasContext('myCanvas')
			const image = 'https://m.360buyimg.com/babel/jfs/t1/196317/32/13733/288158/60f4ea39E6fb378ed/d69205b1a8ed3c97.jpg'
			const image2 = 'http://wisdomhallsup.oss-cn-beijing.aliyuncs.com/uploads/20230720/43123dbf0df41745dd2071481c288354.png'
			ctx.drawImage(image,0,0,600,890)
			await drawDone(false,ctx)
			ctx.drawImage(image2,50,150,200,200)
			await drawDone(true,ctx)
			uni.canvasToTempFilePath({ 
				canvasId: 'myCanvas',
				destWidth: '600',
				destHeight: '890',
				fileType: 'jpg',
				quality: 0.4,
				success: function(res1) {
					data.show = false
					data.path = res1.tempFilePath	            
				},
				fail: function(res) {
					console.log(res.errMsg)
				}
			})
		},2000)
	})
</script>

css部分:

<style lang="scss">
	.container{
		width: 600rpx;
		height:890rpx;
		background:#d9d9d9;
		margin:40rpx auto;
	}
	.bottomBtn{
		height:80rpx;
		width: 100%;
		padding:0 40rpx;
		box-sizing: border-box;
		margin-top:180rpx;
		display: flex;
		align-items: center;
		justify-content: space-between;
		.leftBtn,.rightBtn{
			height: 100%;
			width: 290rpx;
			display: flex;
			align-items: center;
			justify-content: center;
			background: linear-gradient(90deg, #1791FF 0%, rgba(23, 145, 255, 0.69) 100%);
			border-radius: 80rpx;
			font-size: 32rpx;
			color: #fff;
			font-weight: bold;
		}
	}
	
	.loading{
		width: 100rpx;
		height: 100rpx;
		border-radius: 50%;
		position: relative;
		.item {
			width: 100%;
			height: 100%;
			border-radius: 50%;
			position: absolute;
		}
		.item:nth-child(1) {
			border-bottom: 14rpx solid #1890ff;
			transform: rotateX(15deg) rotateY(-45deg);
			animation: rotate_one 1s linear infinite -0.8s;
		}
		.item:nth-child(2) {
			border-bottom: 14rpx solid #f40968;
			transform: rotateX(50deg) rotateY(10deg);
			animation: rotate_two 1s linear infinite -0.4s;
		}
		.item:nth-child(3) {
			border-bottom: 14rpx solid #77d970;
			transform: rotateX(35deg) rotateY(55deg);
			animation: rotate_three 1s linear infinite;
		}
		@keyframes rotate_one {
		  to {
		    transform: rotateX(15deg) rotateY(-45deg) rotateZ(360deg);
		  }
		}
		
		@keyframes rotate_two {
		  to {
		    transform: rotateX(50deg) rotateY(10deg) rotateZ(360deg);
		  }
		}
		
		@keyframes rotate_three {
		  to {
		    transform: rotateX(35deg) rotateY(55deg) rotateZ(360deg);
		  }
		}
		.step {
			position: relative;
			-webkit-box-reflect: below -12px linear-gradient(transparent, rgba(0, 0, 0, 0.2))
		}
	}
	.step text {
		position: relative;
		display: inline-block;
		animation: animate 1.2s ease-in-out infinite;
		animation-delay: calc(.1s*var(--i))
	}
	@keyframes animate {
		0% {
			transform: translateY(0)
		}
	
		20% {
			transform: translateY(-18rpx)
		}
	
		40%,
		100% {
			transform: translateY(0)
		}
	}
</style>

猜你喜欢

转载自blog.csdn.net/Lsir1998/article/details/131843862