前端uniapp生成海报并保存相册

uiapp插件

目录

    • 图片
    • qrcode.vue源码完整版
    • 封装源码qrcodeSwiper.vue
    • 最后

图片

请添加图片描述

qrcode.vue源码完整版

<template><view class="qrcode"><div class="qrcode_swiper SourceHanSansSC-Normal"><!-- <cc-scroolCard :dataInfo="datas" :swiperIndex="swiperIndex" @change="swiperChangeClick"></cc-scroolCard> --><!-- // 下面全是引入swiper数据 start!!!!!!! --><view class="swiper-wrap" v-if="imgList.length"><!-- previous-margin="111rpx" next-margin="111rpx" 控制左右间距 --><swiper class="image-container" previous-margin="111rpx" next-margin="111rpx" circular@change="swiperChange"><!-- currentIndex索引默认0	data --><swiper-item :class="currentIndex == index ? 'swiper-item' : 'swiper-item-side'"v-for="(item, index) in imgList" :key="index"><view class="item-content" :class="currentIndex == index ? 'item-img' : 'item-img-side'"><image :src="item.file_path" lazy-load :style="dontFirstAnimation ? 'animation: none;' : ''"mode="aspectFill"></image><!-- 保存图片背景颜色是canvas绘画上去的,而不是css样式,但是css也必须设置颜色,因为要显示 --><image :src="bgwhite" class="bgwhiteImg"><view class="bottom-box flex-center"><!-- 二维码图片 --><image :src="qrcode" class="code"></image><view class="right-inner"><view class="invite-top">我的邀请码</view><view class="invite-center">{{inviteCode}}</view><view class="font-color-46 invite-bottom">长按识别二维码加入中闽天品</view></view></view></image></view></swiper-item></swiper></view><!-- 画布 --><view style="width: 100%;z-index: 500;position: fixed;left: 0;top: -1000vh;"><view style="width: 100%;height: 1624upx;position: relative;background-color: #FFFFFF;"><canvas style="width: 400rpx;height: 710rpx;" canvas-id="myCanvas" ref="myBox"></canvas></view></view><!-- // 上面全是引入swiper数据 end!!!!!!! --></div><!-- 我的邀请码 --><view class="myinvitationcode"><view class="myinvitationcode_lft"><view class="myinvitationcode_lft_top">我的邀请码</view><view class="myinvitationcode_lft_btm">{{invite_code}}</view></view><view class="myinvitationcode_rgt" @tap="copy(invite_code)"><text class="myinvitationcode_rgt_txt">复制</text></view><!-- 			<view style="width: 100rpx; height: 100rpx; border: 1rpx solid red;" @tap="getSwiper">跳转</view> --></view><!-- 邀请步骤 --><view class="invitationsteps"><view class="invitationsteps_lft"><text class="invitationsteps_lft_one">邀请步骤</text><text class="invitationsteps_lft_two">1.分享邀请海报给好友</text><text class="invitationsteps_lft_two">2.好友通过海报下载APP</text><text class="invitationsteps_lft_two">3.好友注册APP时填写您的邀请码</text></view><view class="invitationsteps_rgt"><image :src="qrcode_url" mode="aspectFill" class="poster_image"></image></view></view><!-- 保存按钮 --><view class="btns-wrap"><!-- 下面这个要 --><!-- <button class="btn-red" type="default" @click="savePosterImg">保存图片</button>--><!-- #ifdef MP || APP-PLUS --><!-- <button class="btn-red" type="default" @click="downLoad">保存图片</button> --><!-- <button type="default" @click="downLoad"><image src="../../../static/poster/posterDownload.png" mode="aspectFill"></image><text>保存图片</text></button> --><view class="wrapBtn" type="default" @click="downLoad"><image src="../../../static/poster/posterDownload.png" mode="aspectFill"></image><text>保存图片到相册</text></view><!-- #endif  --><!-- <button class="btn-red" type="default" @click="savePosterImg">保存图片</button> --><!-- H5	不加保存了 下面这个不要 --><!-- #ifdef H5 --><!-- <view class="f34 tc ww100" type="default">长按保存图片</view> --><!-- #endif --></view></view>
</template><script>// import bwSwiper from '@/wxcomponents/bw-swiper/bw-swiper.vue';export default {components: {// bwSwiper},data() {return {qrcode_url: '',// user_id: '',invite_code: '',// 下面全是引入swiper数据 start!!!!!!!// 接口获取swiper图片数组imgList: [],// 本地测试假数据// imgList: [// 	{// 		currentIndex: 0,// 		file_path: 'https://testshop.yunjingwl.com/uploads/20230919/940337925d4f0a897d8447dd9b72d918.jpg',// 	},// 	{// 		currentIndex: 1,// 		file_path: 'https://testshop.yunjingwl.com/uploads/20230919/7686286376d8ab9627c892776384cf20.png',// 	},// 	{// 		currentIndex: 2,// 		file_path: 'https://testshop.yunjingwl.com/uploads/20230919/940337925d4f0a897d8447dd9b72d918.jpg',// 	},// 	{// 		currentIndex: 3,// 		file_path: 'https://testshop.yunjingwl.com/uploads/20230919/7686286376d8ab9627c892776384cf20.png',// 	},// ],// 轮播图索引index默认选中0,第一个currentIndex: 0,dontFirstAnimation: true,codeTwo: '',inviteCode: '', //邀请码// canvas绘制的图片路径picture: uni.getStorageSync('tempFilePath'),// 接口获取二维码图片qrcode: '', // view上面也要绑定image 绑定src路径bgwhite: '', // swiper底部白色背景图,要绑定image 绑定src路径// 上面全是引入swiper数据 end !!!!!!!}},onShow() {// 下面全是引入swiper数据 start!!!this.getCavasSwiperImgData();// 上面全是引入swiper数据 end!!!},mounted() {/*获取数据1*/this.getData();// this.user_id = uni.getStorageSync('user_id');// 获取我的邀请码this.getMycodeData();},methods: {/*获取数据*/getData() {let self = this;uni.showLoading({title: '加载中',});let source = self.getPlatform();self._get('plus.agent.qrcode/poster', {source: source}, function(data) {uni.hideLoading();self.qrcode_url = data.data.qrcode;});},// 复制按钮https://blog.csdn.net/Zhuangvi/article/details/113089000copy(value) {uni.setClipboardData({data: value + '', //	接受字符串类型 value转化为字符串success: () => {uni.showToast({title: '复制成功',duration: 2000,icon: 'success'});}});},// 获取我的邀请码getMycodeData() {let self = this;uni.showLoading({title: '加载中'});self._post('user.index/detail', {source: self.getPlatform()}, function(res) {//#ifdef MP-WEIXINif (res.data.getPhone) {//#ifdef MP-WEIXINself.gotoPage('/pages/login/bindmobile');//#endif//#ifndef MP-WEIXINself.bindMobile();//#endifreturn;}//#endif// self.detail = res.data.userInfo;// swiper 数据 end !!!!// swiper里面的		邀请码self.inviteCode = res.data.userInfo.invite_code;// swiper 数据 end !!!!// 图片下面的	我的邀请码self.invite_code = res.data.userInfo.invite_code// console.log(res, 'resssself.invite_code');uni.hideLoading();});},// 跳转自己封装的海报swiper组件// getSwiper() {// 	console.log(111);// 	uni.navigateTo({// 		url: '/pages/agent/qrcode/qrcodeSwiper/qrcodeSwiper',// 	})// },// 下面全是引入swiper数据 start!!!!!// 获取背景图 二维码后	执行  =>		cavas画布绘画// 必须先获取图片后在		执行  =>		cavas画布绘画 	=> 否则空白图片async getCavasSwiperImgData() {let self = this;// uni.showLoading({// 	title: '加载中',// });let source = self.getPlatform();self._get('plus.agent.qrcode/poster', {source: source},res => {// 必须是es6语法否则报错,如何这个不行就缓存普通函数funtion,报错显示this.setcanvas();未找到uni.hideLoading();if (res.data) {// console.log(res,'111获取swiper数组路径&&&222二维码路径');self.imgList = res.data.poster;self.qrcode = res.data.qrcode;self.bgwhite = res.data.back;// let qrcode_Path = uni.setStorageSync('qrcodePath',res.data.qrcode);// qrcode	二维码路径 放到本地存储防止	data取值为空uni.setStorageSync('qrcodePath', res.data.qrcode);//	获取底部白色背景图uni.setStorageSync('bgwhitePath', res.data.back);// 必须先获取图片二维码文字完后执行   =>	后 canvas绘画 this.setcanvas() 这个方法this.setcanvas();}});},// 这里面应该获取数字和二维码 这个是原始案例没用到注释即可 里面有需要兼容编译// async userFission() {// 	let source = ''// 	// #ifdef APP-PLUS// 	source = 'app'// 	// #endif// 	// // #ifdef MP-WEIXIN// 	// source = 'wx'// 	// // #endif// 	// #ifdef H5// 	source = 'h5'// 	// #endif// 	this._post('user.user/getMyInvitationInfo', {// 		category_id: 5,// 		source: source// 	}, res => {// 		if (res.data) {// 			const {// 				rtn// 			} = res.data;// 			this.codeTwo = rtn.invitation_code_img;// 			this.inviteCode = rtn.invitation_code;// 			this.imgList = rtn.supplier_bg;// 			// 必须先获取图片二维码文字完后执行   =>	后 canvas绘画 this.setcanvas() 这个方法// 			this.setcanvas();// 		}// 	});// },/**该方法用来绘制一个有填充色的圆角矩形*@param cxt:canvas的上下文环境 *@param x:左上角x轴坐标 *@param y:左上角y轴坐标 *@param width:矩形的宽度 *@param height:矩形的高度 *@param radius:圆的半径 *@param fillColor:填充颜色 **/fillRoundRect(cxt, x, y, width, height, radius, /*optional*/ fillColor) {//圆的直径必然要小于矩形的宽高          if (2 * radius > width || 2 * radius > height) {return false;}cxt.save();cxt.translate(x, y);//绘制圆角矩形的各个边  this.drawRoundRectPath(cxt, width, height, radius);cxt.fillStyle = fillColor || "#fff"; //若是给定了值就用给定的值否则给予默认值  cxt.fill();cxt.restore();},drawRoundRectPath(cxt, width, height, radius) {cxt.beginPath(0);//从右下角顺时针绘制,弧度从0到1/2PI  cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);//矩形下边线  cxt.lineTo(radius, height);//左下角圆弧,弧度从1/2PI到PI  cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);//矩形左边线  cxt.lineTo(0, radius);//左上角圆弧,弧度从PI到3/2PI  cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);//上边线  cxt.lineTo(width - radius, 0);//右上角圆弧  cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);//右边线  cxt.lineTo(width, height - radius);cxt.closePath();},// 1.获取图片下载下来 通过异步[return new Promise]返回到		绘制返回到下面 //  => setcanvas() 里面 =>ctx.drawImage(await this.downloadFiles 的await是等待的意思 return new Promise返回图片绘制downloadFiles(url, that) {// console.log(url.file_path, '图片地址未取到llllll');// console.log(that, '全局Vue this');return new Promise(function(resolve, reject) {uni.downloadFile({url: url.file_path,success: function(res) {// console.log(url.file_path,'resIIIIIIIIIIIIIIIIIIIIII');if (res.statusCode == 200) {resolve(res.tempFilePath)} else {console.log('出错了')}},fail: function() {console.log('服务未返回')}})})},// 获取二维码downloadQrcode(url, that) {// console.log(url.file_path, '图片地址未取到llllll');// console.log(that, '全局Vue this');// console.log(url, '获取二维码图片路径');return new Promise(function(resolve, reject) {uni.downloadFile({url: url,success: function(res) {// console.log(url.file_path,'resIIIIIIIIIIIIIIIIIIIIII');if (res.statusCode == 200) {resolve(res.tempFilePath)} else {console.log('出错了')}},fail: function() {console.log('服务未返回')}})})},// 这里是绘制async setcanvas() {let bg_img = this.imgList[this.currentIndex];// console.log(bg_img, '滑动的每一个对象');// 	获取整个canvas上面viewlet ctx = uni.createCanvasContext('myCanvas');// var ctx = uni.createCanvasContext('myCanvas', this);// 上面报错就用这个// 这个是背景图swiper !!!	获取每个swiper下面item滑动选中的哪一个ctx.drawImage(await this.downloadFiles(bg_img, this), 0, 0, uni.upx2px(400), uni.upx2px(710)); //绘制图 uni.upx2px(750) *// ctx.drawImage(this.codeTwo, uni.upx2px(28), uni.upx2px(590), uni.upx2px(82), uni.upx2px(82));// 注释1// ctx.drawImage(await this.downloadFiles(this.codeTwo, this), uni.upx2px(28), uni.upx2px(590), uni// 	.upx2px(82), uni.upx2px(82));// ctx.drawImage(await this.downloadFiles(this.qrcode, this), uni.upx2px(28), uni.upx2px(590), uni// 	.upx2px(82), uni.upx2px(82));// ctx.drawImage(this.qrcode, uni.upx2px(28), uni.upx2px(590), uni// 	.upx2px(82), uni.upx2px(82));// ctx.drawImage(await this.downloadFiles(this.qrcode, this), uni.upx2px(28), uni.upx2px(590), uni.upx2px(82), uni.upx2px(82));// 底部白色背景图1// ctx.drawImage(await this.downloadQrcode(this.bgwhite, this), uni.upx2px(26), uni.upx2px(590), uni// 	.upx2px(350), uni// 	.upx2px(100));ctx.drawImage(await this.downloadQrcode(this.bgwhite, this), uni.upx2px(26), uni.upx2px(590), uni.upx2px(350), uni.upx2px(100));// qrcode	二维码路径 放到本地存储防止	data取值为空let qrcode_Path = uni.getStorageSync('qrcodePath');// 可以二维码// ctx.drawImage(await this.downloadQrcode(qrcode_Path, this), uni.upx2px(28), uni.upx2px(590), uni// 	.upx2px(82), uni.upx2px(82));ctx.drawImage(await this.downloadQrcode(qrcode_Path, this), uni.upx2px(35), uni.upx2px(600), uni.upx2px(82), uni.upx2px(82));ctx.font = 'normal 8px sans-serif';ctx.fillStyle = "#848484";// ctx.fillText('我的邀请码', uni.upx2px(130), uni.upx2px(606));ctx.fillText('我的邀请码', uni.upx2px(135), uni.upx2px(620));ctx.font = 'normal 10px sans-serif';ctx.fillStyle = "#FF2741";// ctx.fillText(this.inviteCode, uni.upx2px(130), uni.upx2px(640));ctx.fillText(this.inviteCode, uni.upx2px(135), uni.upx2px(648));ctx.font = 'normal 8px sans-serif';ctx.fillStyle = "#282828";// ctx.fillText('长按识别二维码加入中闽天品', uni.upx2px(130), uni.upx2px(670));ctx.fillText('长按识别二维码加入中闽天品', uni.upx2px(135), uni.upx2px(675));ctx.draw(false, () => {// console.log('绘制完成')// 注释2// console.error(bg_img)this.getFail();})// // 注释2// console.log(bg_img, 'bg_imgbg_img');},//点击画布宽高设置	图片 getFail(type) {let self = this;uni.canvasToTempFilePath({ // 把画布转化成临时文件1x: 0,y: 0,width: uni.upx2px(400), // 截取的画布的宽height: uni.upx2px(710), // 截取的画布的高destWidth: uni.upx2px(360) * 3, // 保存成的画布宽度destHeight: uni.upx2px(680) * 3, // 保存成的画布高度fileType: 'png', // 保存成的文件类型quality: 1, // 图片质量canvasId: 'myCanvas', // 画布ID success(res) {// 绘画图片路径self.picture = res.tempFilePath;//  绘制最后路径// console.log(res, '绘制完成图片路径');uni.setStorageSync('tempFilePath', res.tempFilePath);self.picture = uni.setStorageSync('tempFilePath', res.tempFilePath);},fail(fail) {uni.showToast({title: '保存失败,稍后再试', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();}})},// 点击下载保存相册按钮downLoad() {// console.log(this.imgList[this.currentIndex],'this.imgList[this.currentIndex]');console.log(uni.getStorageSync('tempFilePath'), 'getStorageSync下载按钮未取到路径啊啊');let self = this;// 2-保存图片至相册uni.saveImageToPhotosAlbum({ // 存成图片至手机1// filePath: this.picture,// filePath: pathw,// filePath:'data:image/png;base64,base64'+ uni.getStorageSync('tempFilePath'),filePath: uni.getStorageSync('tempFilePath'), // 未取到路径myPromisesuccess(res2) {uni.hideLoading();uni.showToast({title: '保存成功', //'保存成功'duration: 500})},fail(res3) {console.log(res3, 'res3AAAAAA');if (res3.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {uni.showToast({title: '保存失败,稍后再试1', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();} else {uni.showToast({title: '保存失败,稍后再试2', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();}}})},copyCode() {uni.setClipboardData({data: this.inviteCode,success: () => {uni.showToast({title: '复制成功'})}});},swiperChange(e) {this.dontFirstAnimation = falsethis.currentIndex = e.detail.currentthis.setcanvas()// 切换调用图片二维码数据this.getCavasSwiperImgData();},// 上面全是引入swiper数据 end !!!!!}}
</script><style lang="scss" scoped>page {background: #F8F8F8;}.qrcode {width: 100%;// height: 100vh !important;}// 下面全是引入swiper数据 start!!!!!!.qrcode_swiper {margin-top: 71rpx;// height: 500rpx;// border:1rpx solid red;.swiper-wrap {padding-top: 20rpx;}.image-container {width: 750rpx;// height: 939rpx;height: 756rpx;}.item-img {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 14rpx;animation: to-big .3s;}// 中间选中.swiper-item {// width: 528rpx;width: 540rpx;// height: 939rpx;height: 756rpx;display: flex;justify-content: center;align-items: center;}.item-img-side {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 14rpx;animation: to-mini .3s;// transform: scale(0.85);transform: scale(0.85);// @keyframes to-mini 也要改 在最下面scale(0.85)// 两侧底部有白边超出父元素隐藏overflow: hidden;}// 两边.swiper-item-side {width: 528rpx;// height: 939rpx;height: 756rpx;display: flex;justify-content: center;align-items: center;// transform: scale(0.85);transform: scale(0.85);}.item-content {position: relative;image {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 20rpx;}.bgwhiteImg {margin-left: 20rpx;// border-radius: 20rpx;}.bottom-box {position: absolute;left: 50%;transform: translateX(-50%);bottom: 31rpx;padding: 16rpx 19rpx;background-color: #FFFFFF;width: 492rpx;border-radius: 10rpx;// height: 140rpx;display: flex;box-sizing: border-box;.code {width: 111rpx;height: 108rpx;margin-right: 12rpx;flex-shrink: 0;}.right-inner {height: 80rpx;display: flex;flex-direction: column;justify-content: space-between;.invite-top {font-size: 25rpx;font-family: Microsoft YaHei;font-weight: 400;color: #848484;// line-height: 22rpx;}.invite-center {font-size: 28rpx;font-family: Microsoft YaHei;font-weight: bold;color: #FF2741;// line-height: 1.5;}.invite-bottom {font-size: 25rpx;font-family: Microsoft YaHei;font-weight: bold;color: #282828;// line-height: 1.5;// 强制不换行white-space: nowrap;}}}}@keyframes to-mini {from {transform: scale(1);}to {// transform: scale(0.85);transform: scale(0.85);}}@keyframes to-big {from {// transform: scale(0.85);transform: scale(0.85);}to {transform: scale(1);}}}// 上面全是引入swiper数据 end !!!!!// 我的邀请码.myinvitationcode {// margin-top: 56rpx;width: 700rpx;height: 178rpx;background: #FFFFFF;border-radius: 10rpx;margin: 56rpx auto;display: flex;align-items: center;justify-content: space-between;.myinvitationcode_lft {margin-left: 49rpx;display: flex;flex-direction: column;.myinvitationcode_lft_top {font-size: 26rpx;font-family: Microsoft YaHei;font-weight: 400;color: #727272;line-height: 38rpx;}.myinvitationcode_lft_btm {font-size: 45rpx;font-family: Microsoft YaHei;font-weight: bold;color: #000000;line-height: 1.2;}}.myinvitationcode_rgt {margin-right: 49rpx;width: 168rpx;height: 70rpx;// background: #FF2741;// background: rgb(223, 216, 239);background: #000;// opacity: 0.1;border-radius: 35rpx;display: flex;justify-content: center;align-items: center;.myinvitationcode_rgt_txt {font-size: 32rpx;font-family: Microsoft YaHei;font-weight: 400;// color: FF2741;// color: rgb(223, 51, 93);color: #fff;// line-height: 24rpx;}}}// 邀请步骤.invitationsteps {display: flex;justify-content: space-between;flex-direction: row;align-items: center;.invitationsteps_lft {margin-left: 31rpx;display: flex;flex-direction: column;.invitationsteps_lft_one {font-size: 28rpx;font-family: Microsoft YaHei;font-weight: bold;color: #9F9F9F;line-height: 38rpx;}.invitationsteps_lft_two {font-size: 28rpx;font-family: Microsoft YaHei;font-weight: 400;color: #AFAEAE;line-height: 38rpx;}}.invitationsteps_rgt {margin-right: 53rpx;width: 185rpx;height: 185rpx;}}// .poster_img {// 	width: 100%;// 	height: 100vh !important;// 	position: absolute;// }// .poster_image {// 	width: 100%;// 	height: 100vh !important;// }// uni-image {// 	width: 100%;// 	height: 100vh !important;// 	position: absolute;// }// .qrcode_img_box {// 	width: 100%;// 	display: flex;// 	justify-content: center;// 	.qrcode_img {// 		width: 80%;// 		position: relative;// 		border-radius: 15rpx;// 		position: fixed;// 		bottom: 150rpx;// 		z-index: 999;// 		background-color: #fff;// 		// width: 100rpx !important;// 		// height: 100rpx !important;// 		display: flex;// 		padding: 20rpx;// 		// margin: 20rpx;// 		.qrcode_img_left {// 			width: 150rpx;// 			height: 150rpx;// 		}// 		.qrcode_img_right {// 			display: flex;// 			flex-direction: column;// 			justify-content: space-around;// 			margin-left: 20rpx;// 			.qrcode_img_right_top {// 				color: #ccc;// 				font-size: 30rpx// 			}// 			.qrcode_img_right_center {// 				color: rgb(223, 70, 109);// 				font-size: 30rpx;// 				font-weight: 800;// 			}// 			.qrcode_img_right_tbtm {// 				color: #000;// 				font-size: 30rpx;// 			}// 		}// 	}// }.btns-wrap {position: fixed;height: 88rpx;right: 0;bottom: 35rpx;left: 0;display: flex;z-index: 10;}// button样式// .btns-wrap button {// 	width: 700rpx;// 	height: 94rpx;// 	background: linear-gradient(90deg, #FF2C43, #FC5B5A);// 	border-radius: 10rpx;// 	margin: 0 auto;// 	display: flex;// 	justify-content: center;// 	align-items: center;// }// .btns-wrap button image{// 	width: 33rpx;// 	height: 33rpx;// }// .btns-wrap button text {// 	font-size: 28rpx;// 	font-family: Microsoft YaHei;// 	font-weight: 400;// 	color: #FFFFFF;// 	line-height: 88rpx;// }.wrapBtn {width: 700rpx;height: 94rpx;background: linear-gradient(90deg, #FF2C43, #FC5B5A);border-radius: 10rpx;margin: 0 auto;display: flex;justify-content: center;align-items: center;}.wrapBtn image {width: 35rpx;height: 35rpx;}.wrapBtn text {font-size: 35rpx;font-family: Microsoft YaHei;font-weight: 400;color: #FFFFFF;line-height: 27rpx;// margin-left: 13rpx;margin-left: 10rpx;}.btns-wrap .btn-red {width: 100%;height: 88rpx;line-height: 88rpx;border-radius: 0;}
</style>

封装源码qrcodeSwiper.vue

<template><view class="page-view SourceHanSansSC-Normal"><!-- <base-head title="邀请好友"></base-head><bg-img :combg="true"></bg-img> --><view class="swiper-wrap" v-if="imgList.length"><!-- previous-margin="111rpx" next-margin="111rpx" 控制左右间距 --><swiper class="image-container" previous-margin="111rpx" next-margin="111rpx" circular@change="swiperChange"><!-- currentIndex索引默认0	data --><swiper-item :class="currentIndex == index ? 'swiper-item' : 'swiper-item-side'"v-for="(item, index) in imgList" :key="index"><view class="item-content" :class="currentIndex == index ? 'item-img' : 'item-img-side'"><image :src="item.file_path" lazy-load :style="dontFirstAnimation ? 'animation: none;' : ''"mode="aspectFill"></image><!-- 保存图片背景颜色是canvas绘画上去的,而不是css样式,但是css也必须设置颜色,因为要显示 --><image :src="bgwhite" class="bgwhiteImg"><view class="bottom-box flex-center"><!-- 二维码图片 --><image :src="qrcode" class="code"></image><view class="right-inner"><view class="invite-top">我的邀请码</view><view class="invite-center">{{inviteCode}}</view><view class="font-color-46 invite-bottom">长按识别二维码加入中闽天品</view></view></view></image></view></swiper-item></swiper></view><view class="section-wrap"><view class="group-three-wrap flex-item-center" v-if="imgList.length"><view class="flex-item-center btn" @tap="downLoad"><!-- <image src="https://app.moai.pro/static/moai/xiazai.png"></image> --><text class="font-color-fff">保存到手机</text></view></view></view><!-- 画布 --><view style="width: 100%;z-index: 500;position: fixed;left: 0;top: -1000vh;"><view style="width: 100%;height: 1624upx;position: relative;background-color: #FFFFFF;"><canvas style="width: 400rpx;height: 710rpx;" canvas-id="myCanvas" ref="myBox"></canvas></view></view></view>
</template><script>export default {data() {return {// 接口获取swiper图片数组imgList: [],// 本地测试假数据// imgList: [// 	{// 		currentIndex: 0,// 		file_path: 'https://testshop.yunjingwl.com/uploads/20230919/940337925d4f0a897d8447dd9b72d918.jpg',// 	},// 	{// 		currentIndex: 1,// 		file_path: 'https://testshop.yunjingwl.com/uploads/20230919/7686286376d8ab9627c892776384cf20.png',// 	},// 	{// 		currentIndex: 2,// 		file_path: 'https://testshop.yunjingwl.com/uploads/20230919/940337925d4f0a897d8447dd9b72d918.jpg',// 	},// 	{// 		currentIndex: 3,// 		file_path: 'https://testshop.yunjingwl.com/uploads/20230919/7686286376d8ab9627c892776384cf20.png',// 	},// ],// 轮播图索引index默认选中0,第一个currentIndex: 0,dontFirstAnimation: true,codeTwo: '',inviteCode: '', //邀请码// canvas绘制的图片路径picture: uni.getStorageSync('tempFilePath'),// 接口获取二维码图片qrcode: '', // view上面也要绑定image 绑定src路径bgwhite: '', // swiper底部白色背景图,要绑定image 绑定src路径}},onShow() {this.getCavasSwiperImgData();// this.userFission();// 之前是注释状态},onLoad() {// console.log(this.imgList,'swiper路径');// console.log(this.qrcode,'二维码路径');this.getMycodeData();},methods: {// 获取背景图 二维码后	执行  =>		cavas画布绘画 // 必须先获取图片后在		执行  =>		cavas画布绘画 	=> 否则空白图片async getCavasSwiperImgData() {let self = this;uni.showLoading({title: '加载中',});let source = self.getPlatform();self._get('plus.agent.qrcode/poster', {source: source},res => {// 必须是es6语法否则报错,如何这个不行就缓存普通函数funtion,报错显示this.setcanvas();未找到uni.hideLoading();if (res.data) {// console.log(res,'111获取swiper数组路径&&&222二维码路径');self.imgList = res.data.poster;self.qrcode = res.data.qrcode;self.bgwhite = res.data.back;// let qrcode_Path = uni.setStorageSync('qrcodePath',res.data.qrcode);// qrcode	二维码路径 放到本地存储防止	data取值为空uni.setStorageSync('qrcodePath', res.data.qrcode);//	获取底部白色背景图uni.setStorageSync('bgwhitePath', res.data.back);// 必须先获取图片二维码文字完后执行   =>	后 canvas绘画 this.setcanvas() 这个方法this.setcanvas();}});},// 这里面应该获取数字和二维码 这个是原始案例没用到注释即可// async userFission() {// 	let source = ''// 	// #ifdef APP-PLUS// 	source = 'app'// 	// #endif// 	// // #ifdef MP-WEIXIN// 	// source = 'wx'// 	// // #endif// 	// #ifdef H5// 	source = 'h5'// 	// #endif// 	this._post('user.user/getMyInvitationInfo', {// 		category_id: 5,// 		source: source// 	}, res => {// 		if (res.data) {// 			const {// 				rtn// 			} = res.data;// 			this.codeTwo = rtn.invitation_code_img;// 			this.inviteCode = rtn.invitation_code;// 			this.imgList = rtn.supplier_bg;// 			// 必须先获取图片二维码文字完后执行   =>	后 canvas绘画 this.setcanvas() 这个方法// 			this.setcanvas();// 		}// 	});// },/**该方法用来绘制一个有填充色的圆角矩形*@param cxt:canvas的上下文环境 *@param x:左上角x轴坐标 *@param y:左上角y轴坐标 *@param width:矩形的宽度 *@param height:矩形的高度 *@param radius:圆的半径 *@param fillColor:填充颜色 **/fillRoundRect(cxt, x, y, width, height, radius, /*optional*/ fillColor) {//圆的直径必然要小于矩形的宽高          if (2 * radius > width || 2 * radius > height) {return false;}cxt.save();cxt.translate(x, y);//绘制圆角矩形的各个边  this.drawRoundRectPath(cxt, width, height, radius);cxt.fillStyle = fillColor || "#fff"; //若是给定了值就用给定的值否则给予默认值  cxt.fill();cxt.restore();},drawRoundRectPath(cxt, width, height, radius) {cxt.beginPath(0);//从右下角顺时针绘制,弧度从0到1/2PI  cxt.arc(width - radius, height - radius, radius, 0, Math.PI / 2);//矩形下边线  cxt.lineTo(radius, height);//左下角圆弧,弧度从1/2PI到PI  cxt.arc(radius, height - radius, radius, Math.PI / 2, Math.PI);//矩形左边线  cxt.lineTo(0, radius);//左上角圆弧,弧度从PI到3/2PI  cxt.arc(radius, radius, radius, Math.PI, Math.PI * 3 / 2);//上边线  cxt.lineTo(width - radius, 0);//右上角圆弧  cxt.arc(width - radius, radius, radius, Math.PI * 3 / 2, Math.PI * 2);//右边线  cxt.lineTo(width, height - radius);cxt.closePath();},// 1.获取图片下载下来 通过异步[return new Promise]返回到		绘制返回到下面 //  => setcanvas() 里面 =>ctx.drawImage(await this.downloadFiles 的await是等待的意思 return new Promise返回图片绘制downloadFiles(url, that) {// console.log(url.file_path, '图片地址未取到llllll');// console.log(that, '全局Vue this');return new Promise(function(resolve, reject) {uni.downloadFile({url: url.file_path,success: function(res) {// console.log(url.file_path,'resIIIIIIIIIIIIIIIIIIIIII');if (res.statusCode == 200) {resolve(res.tempFilePath)} else {console.log('出错了')}},fail: function() {console.log('服务未返回')}})})},// 获取二维码downloadQrcode(url, that) {// console.log(url.file_path, '图片地址未取到llllll');// console.log(that, '全局Vue this');console.log(url, '获取二维码图片路径');return new Promise(function(resolve, reject) {uni.downloadFile({url: url,success: function(res) {// console.log(url.file_path,'resIIIIIIIIIIIIIIIIIIIIII');if (res.statusCode == 200) {resolve(res.tempFilePath)} else {console.log('出错了')}},fail: function() {console.log('服务未返回')}})})},// 这里是绘制async setcanvas() {let bg_img = this.imgList[this.currentIndex];// console.log(bg_img, '滑动的每一个对象');// 	获取整个canvas上面viewlet ctx = uni.createCanvasContext('myCanvas');// var ctx = uni.createCanvasContext('myCanvas', this);// 上面报错就用这个// 这个是背景图swiper !!!	获取每个swiper下面item滑动选中的哪一个ctx.drawImage(await this.downloadFiles(bg_img, this), 0, 0, uni.upx2px(400), uni.upx2px(710)); //绘制图 uni.upx2px(750) *// ctx.drawImage(this.codeTwo, uni.upx2px(28), uni.upx2px(590), uni.upx2px(82), uni.upx2px(82));// 注释1// ctx.drawImage(await this.downloadFiles(this.codeTwo, this), uni.upx2px(28), uni.upx2px(590), uni// 	.upx2px(82), uni.upx2px(82));// ctx.drawImage(await this.downloadFiles(this.qrcode, this), uni.upx2px(28), uni.upx2px(590), uni// 	.upx2px(82), uni.upx2px(82));// ctx.drawImage(this.qrcode, uni.upx2px(28), uni.upx2px(590), uni// 	.upx2px(82), uni.upx2px(82));// ctx.drawImage(await this.downloadFiles(this.qrcode, this), uni.upx2px(28), uni.upx2px(590), uni.upx2px(82), uni.upx2px(82));// 底部白色背景图1// ctx.drawImage(await this.downloadQrcode(this.bgwhite, this), uni.upx2px(26), uni.upx2px(590), uni// 	.upx2px(350), uni// 	.upx2px(100));ctx.drawImage(await this.downloadQrcode(this.bgwhite, this), uni.upx2px(26), uni.upx2px(590), uni.upx2px(350), uni.upx2px(100));// qrcode	二维码路径 放到本地存储防止	data取值为空let qrcode_Path = uni.getStorageSync('qrcodePath');// 可以二维码// ctx.drawImage(await this.downloadQrcode(qrcode_Path, this), uni.upx2px(28), uni.upx2px(590), uni// 	.upx2px(82), uni.upx2px(82));ctx.drawImage(await this.downloadQrcode(qrcode_Path, this), uni.upx2px(35), uni.upx2px(600), uni.upx2px(82), uni.upx2px(82));ctx.font = 'normal 8px sans-serif';ctx.fillStyle = "#848484";// ctx.fillText('我的邀请码', uni.upx2px(130), uni.upx2px(606));ctx.fillText('我的邀请码', uni.upx2px(135), uni.upx2px(620));ctx.font = 'normal 10px sans-serif';ctx.fillStyle = "#FF2741";// ctx.fillText(this.inviteCode, uni.upx2px(130), uni.upx2px(640));ctx.fillText(this.inviteCode, uni.upx2px(135), uni.upx2px(648));ctx.font = 'normal 8px sans-serif';ctx.fillStyle = "#282828";// ctx.fillText('长按识别二维码加入中闽天品', uni.upx2px(130), uni.upx2px(670));ctx.fillText('长按识别二维码加入中闽天品', uni.upx2px(135), uni.upx2px(675));ctx.draw(false, () => {console.log('绘制完成')// 注释2// console.error(bg_img)this.getFail();})// // 注释2// console.log(bg_img, 'bg_imgbg_img');},//点击画布宽高设置	图片 getFail(type) {let self = this;uni.canvasToTempFilePath({ // 把画布转化成临时文件1x: 0,y: 0,width: uni.upx2px(400), // 截取的画布的宽height: uni.upx2px(710), // 截取的画布的高destWidth: uni.upx2px(400) * 3, // 保存成的画布宽度destHeight: uni.upx2px(710) * 3, // 保存成的画布高度fileType: 'jpg', // 保存成的文件类型quality: 1, // 图片质量canvasId: 'myCanvas', // 画布ID success(res) {// 绘画图片路径self.picture = res.tempFilePath;//  绘制最后路径console.log(res, '绘制完成图片路径');uni.setStorageSync('tempFilePath', res.tempFilePath);self.picture = uni.setStorageSync('tempFilePath', res.tempFilePath);},fail(fail) {uni.showToast({title: '保存失败,稍后再试', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();}})},// 点击下载保存相册按钮downLoad() {// console.log(this.imgList[this.currentIndex],'this.imgList[this.currentIndex]');console.log(uni.getStorageSync('tempFilePath'), 'getStorageSync下载按钮未取到路径啊啊');let self = this;// 2-保存图片至相册uni.saveImageToPhotosAlbum({ // 存成图片至手机1// filePath: this.picture,// filePath: pathw,// filePath:'data:image/png;base64,base64'+ uni.getStorageSync('tempFilePath'),filePath: uni.getStorageSync('tempFilePath'), // 未取到路径myPromisesuccess(res2) {uni.hideLoading();uni.showToast({title: '保存成功', //'保存成功'duration: 2000})},fail(res3) {console.log(res3, 'res3AAAAAA');if (res3.errMsg === 'saveImageToPhotosAlbum:fail auth deny') {uni.showToast({title: '保存失败,稍后再试1', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();} else {uni.showToast({title: '保存失败,稍后再试2', //'保存失败,稍后再试'duration: 2000,icon: 'none'})uni.hideLoading();}}})},copyCode() {uni.setClipboardData({data: this.inviteCode,success: () => {uni.showToast({title: '复制成功'})}});},swiperChange(e) {this.dontFirstAnimation = falsethis.currentIndex = e.detail.currentthis.setcanvas()// 切换调用图片二维码数据this.getCavasSwiperImgData();},// 获取我的邀请码getMycodeData() {let self = this;uni.showLoading({title: '加载中'});self._post('user.index/detail', {source: self.getPlatform()}, function(res) {//#ifdef MP-WEIXINif (res.data.getPhone) {//#ifdef MP-WEIXINself.gotoPage('/pages/login/bindmobile');//#endif//#ifndef MP-WEIXINself.bindMobile();//#endifreturn;}//#endif// self.detail = res.data.userInfo;// invite_codeself.inviteCode = res.data.userInfo.invite_code// console.log(self.detail, 'detail');console.log(res, 'resss');uni.hideLoading();});},}}
</script><style lang="scss">page {background: #FFFFFF;}.page-view {}.section-wrap {padding: 111rpx 25rpx 44rpx;.group-three-wrap {display: flex;justify-content: center;.btn {width: 600rpx;height: 88rpx;background: #FFA615;border-radius: 44rpx;display: flex;align-items: center;justify-content: center;color: #FFFFFF;font-size: 28rpx;image {width: 26rpx;height: 26rpx;margin-right: 12rpx;}}}}.swiper-wrap {padding-top: 20rpx;}.image-container {width: 750rpx;// height: 939rpx;height: 756rpx;}.item-img {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 14rpx;animation: to-big .3s;}// 中间选中.swiper-item {// width: 528rpx;width: 540rpx;// height: 939rpx;height: 756rpx;display: flex;justify-content: center;align-items: center;}.item-img-side {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 14rpx;animation: to-mini .3s;// transform: scale(0.85);transform: scale(0.85);// @keyframes to-mini 也要改 在最下面scale(0.85)// swiper图两侧底部有白边超出父元素隐藏overflow:hidden;}// 两边.swiper-item-side {width: 528rpx;// height: 939rpx;height: 756rpx;display: flex;justify-content: center;align-items: center;// transform: scale(0.85);transform: scale(0.85);}.item-content {position: relative;image {width: 528rpx;// height: 939rpx;height: 756rpx;border-radius: 20rpx;}.bgwhiteImg {margin-left: 20rpx;// border-radius: 20rpx;}.bottom-box {position: absolute;left: 50%;transform: translateX(-50%);bottom: 31rpx;padding: 16rpx 19rpx;background-color: #FFFFFF;width: 492rpx;border-radius: 10rpx;// height: 140rpx;display: flex;box-sizing: border-box;.code {width: 111rpx;height: 108rpx;margin-right: 12rpx;flex-shrink: 0;}.right-inner {height: 80rpx;display: flex;flex-direction: column;justify-content: space-between;.invite-top {font-size: 15rpx;font-family: Microsoft YaHei;font-weight: 400;color: #848484;line-height: 22rpx;}.invite-center {font-size: 21rpx;font-family: Microsoft YaHei;font-weight: bold;color: #FF2741;// line-height: 32rpx;line-height: 2.5;}.invite-bottom {font-size: 16rpx;font-family: Microsoft YaHei;font-weight: bold;color: #282828;// line-height: 22rpx;line-height: 1.5;// 强制不换行white-space: nowrap;}}}}@keyframes to-mini {from {transform: scale(1);}to {// transform: scale(0.85);transform: scale(0.85);}}@keyframes to-big {from {// transform: scale(0.85);transform: scale(0.85);}to {transform: scale(1);}}
</style>

最后

感觉文章好的话记得点个心心和关注和收藏,有错的地方麻烦指正一下,如果需要转载,请标明出处,多谢!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/128643.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

入侵防御系统(IPS)网络安全设备介绍

入侵防御系统&#xff08;IPS&#xff09;网络安全设备介绍 1. IPS设备基础 IPS定义 IPS&#xff08;Intrusion Prevention System&#xff09;是一种网络安全设备或系统&#xff0c;用于监视、检测和阻止网络上的入侵尝试和恶意活动。它是网络安全架构中的重要组成部分&…

什么是智能档案柜?如何使用智能档案柜?

智能档案柜是一种具有智能化功能的文件存储设备&#xff0c;它通过应用现代科技&#xff0c;集成了电子锁、自动化控制、智能管理系统技术&#xff0c;具有自动识别、高效存储、安全可靠等特点&#xff0c;提高档案管理的效率和安全性。适用于企业单位、图书馆等需要储存文件资…

ssm173基于SSM的养老院老人健康监护平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用Vue技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

CVE-2021-4034 polkit提权漏洞复现

CVE-2021-4034 polkit提权漏洞复现 1.前期准备2.复现 1.前期准备 Github地址&#xff1a; https://github.com/berdav/CVE-2021-4034polkit是一个授权管理器&#xff0c;其系统架构由授权和身份验证代理组成&#xff0c;pkexec是其中polkit的其中一个工具&#xff0c;他的作用…

动画圆圈文字标志效果

效果展示 CSS 知识点 实现圆圈文字animation 属性回顾 实现思路 从效果的实现思路很简单&#xff0c;其实就是两个圆圈就可以实现。外层大圆&#xff08;灰色&#xff09;用于圆圈文字的展示&#xff0c;而内圆&#xff08;藏青色&#xff09;主要用于存放 Logo 图片。布局采…

【Qt】顶层窗口和普通窗口区别以及用法

区别 在Qt项目开发中&#xff0c;经常会用到窗体控件用于显示及数据操作和其他交互等。 但&#xff0c;窗体分为顶层窗口&#xff08;Top-level Window&#xff09;和普通窗口&#xff08;Regular Window&#xff09;。 他们之间是有区别的&#xff0c;包括在项目实际中的用法…

asp.net高校留学生信息管理系统VS开发sqlserver数据库web结构c#编程Microsoft Visual Studio

一、源码特点 asp.net 高校留学生信息管理系统 是一套完善的web设计管理系统&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为vs2010&#xff0c;数据库为sqlserver2008&#xff0c;使 用c#语言开发 asp.net留学生信息管理系…

FPGA设计时序约束三、设置时钟组set_clock_groups

目录 一、背景 二、时钟间关系 2.1 时钟关系分类 2.2 时钟关系查看 三、异步时钟组 3.1 优先级 3.2 使用格式 3.3 asynchronous和exclusive 3.4 结果示例 四、参考资料 一、背景 Vivado中时序分析工具默认会分析设计中所有时钟相关的时序路径&#xff0c;除非时序约束…

NoSQL之Redis 主从复制配置详解及哨兵模式

目录 1 Redis 主从复制 1.1 主从复制的作用 1.2 主从复制流程 2 搭建Redis 主从复制 2.1 安装 Redis 2.2 修改 Redis 配置文件&#xff08;Master节点操作&#xff09; 2.3 修改 Redis 配置文件&#xff08;Slave节点操作&#xff09; 2.4 验证主从效果 3 Redis 哨兵模…

【办公-excel】两个时间相减 (二) - 带毫秒的时间进行相减操作

一、使用内部函数 1.1 效果展示 TEXT(((RIGHT(TEXT(B2,"yyyy-mm-dd hh:mm:ss.000"),LEN(TEXT(B2,"yyyy-mm-dd hh:mm:ss.000"))-FIND(".",TEXT(B2,"yyyy-mm-dd hh:mm:ss.000")))-RIGHT(TEXT(A2,"yyyy-mm-dd hh:mm:ss.000"),…

Go 团队发布组织 / 构建 Go module 的官方指南

导读Go 团队发布了一份官方指南&#xff0c;帮助开发者更规范地组织 / 构建 Go module。 刚接触 Go 的开发者常见问题之一是&#xff0c;“就文件和文件夹的组织布局而言&#xff0c;如何组织我的 Go 项目&#xff1f;”。这份指南就是提供建议来帮助回答这个问题。其中包括针对…

ADuM1250 ADuM1251 模块 I2C IIC总线2500V电磁隔离 接口保护

功能说明&#xff1a; 1&#xff0c;2500V电磁隔离&#xff0c;2通道双向I2C&#xff1b; 2&#xff0c;支持电压在3到5.5V&#xff0c;最大时钟频率可达1000KHz&#xff1b; 3&#xff0c;将该隔离模块接入总线&#xff0c;可以保护主MCU引脚&#xff0c;降低I2C总线上的干…