<template>
<view class="p-20">
<view class="flex flex-wrap">
<view v-for="(item,index) in 50" :key="index" class="w-1/2 relative p-10">
<view class="rounded-20 overflow-hidden">
<uv-image height="550rpx" src="https://cdn.uviewui.com/uview/album/1.jpg"
width="100%"></uv-image>
</view>
<view class="flex absolute bottom-40 left-1/2 items-center pt-20" style="transform: translateX(-50%)">
<view class="w-120">
<xxz-button size="mini" text="分享" @ok="handleShare"></xxz-button>
</view>
</view>
</view>
</view>
<uv-popup ref="popup" bgColor="none" mode="center" @change="change">
<view class="rounded-20 overflow-hidden" style="height: 80vh;width: 80vw">
<view class="w-full" style="height: 80%">
<uv-image height="100%" src="https://cdn.uviewui.com/uview/album/1.jpg"
width="100%"></uv-image>
</view>
<view class="bg-white p-30">
<view class="flex justify-between">
<view class="relative">
<view>王德发</view>
<view>151******888</view>
<view class="w-100 absolute bottom-20">
<xxz-button size="mini" text="保存相册" @ok="saveImg"/>
</view>
</view>
<view>
<uv-image height="180rpx" src="https://cdn.uviewui.com/uview/album/1.jpg"
width="180rpx"></uv-image>
</view>
</view>
</view>
</view>
</uv-popup>
<view class="relative" style="width: 100vw;overflow: hidden">
<!-- 画布 -->
<canvas canvas-id="myCanvas"
style="width: 750rpx;height: 1300rpx;position: absolute;opacity: 0;left:100%"></canvas>
</view>
</view>
</template>
<script lang="ts" setup>
import {onMounted, ref} from "vue";
/**
* 画布
*/
const ctx: any = ref('')
const img1Path = ref('https://cdn.uviewui.com/uview/album/1.jpg') // 图片背景路径
const img2Path = ref('https://cdn.uviewui.com/uview/album/1.jpg') // 图片二维码路径
const powerW: any = ref('')
// 点击-保存海报
const saveImg = async () => {
// 调用合并图片的方法。
mergeImages();
}
// 合并图片的方法
const mergeImages = async () => {
// 加载第一张图片到canvas上
const image1 = await loadImage(img1Path.value);
// 背景色
ctx.value.setFillStyle('#ffffff')
ctx.value.fillRect(0, 0, 999, 999)
// 在(0,0)位置绘制图片1,图一宽高分别为345px和334px
ctx.value.drawImage(image1, 0, 0, 375 * powerW.value, 500 * powerW.value);
// 加载第二张图片到canvas上,并设置位置和大小(根据需要调整)
const image2 = await loadImage(img2Path.value);
// 在(10,209)位置绘制图片2,图片二宽高75px,可以根据需要调整位置和大小
ctx.value.drawImage(image2, 270 * powerW.value, 520 * powerW.value, 90 * powerW.value, 90 * powerW.value);
// 设置字体样式
// this.ctx.font = '8px Arial';
ctx.value.font = `bold ${(18 * powerW.value).toFixed(0)}px Arial`;
ctx.value.fillStyle = '#000000'; // 设置填充颜色
// 在 Canvas 上绘制文字
// 第二个和第三个参数是文字的 x 和 y 坐标
ctx.value.fillText('王德发', 20 * powerW.value, 540 * powerW.value);
ctx.value.font = `${(16 * powerW.value).toFixed(0)}px Arial`;
ctx.value.fillStyle = '#000000'; // 设置填充颜色
ctx.value.fillText('15245822325', 20 * powerW.value, 565 * powerW.value);
ctx.value.font = `${(14 * powerW.value).toFixed(0)}px Arial`;
ctx.value.fillStyle = '#000000'; // 设置填充颜色
ctx.value.fillText('【扫一扫识别二维码】', 15 * powerW.value, 600 * powerW.value);
// 完成绘制并导出为图片(可选)
ctx.value.draw(true, () => {
// 这里可以处理合并后的图片,比如保存到相册或上传到服务器等操作。
// 如果需要导出为文件或上传等操作,可以使用uni.canvasToTempFilePath等方法。
uni.canvasToTempFilePath({// res.tempFilePath临时路径
canvasId: 'myCanvas',
success: (res) => {
console.log(res, '临时路径');
uni.saveImageToPhotosAlbum({ // 保存本地
filePath: res.tempFilePath,
success: (response) => {
uni.showToast({
title: '保存成功',
icon: 'success'
})
console.log(response, 'success');
},
fail: (response) => {
console.log(response, 'error');
uni.openSetting({ //打开权限
success: (response) => {
if (!response.authSetting['scope.writePhotosAlbum']) {
uni.showToast({
title: '获取权限成功, 再次点击即可保存',
icon: 'none'
})
} else {
uni.showToast({
title: '获取权限失败, 无法保存',
icon: 'none'
})
}
}
})
}
})
}
})
});
}
// 注:canvas绘图在开发者工具上支持base64图片,在真机上是不可以的,
// 需让后台返回图片网络链接通过getimageinfo方法获取临时路径再进行操作
const loadImage = (src) => {
return new Promise((resolve, reject) => {
uni.getImageInfo({
src: src, // 图片的URL或临时文件路径
success: (res) => {
console.log(res, 1.5);
// 获取图片的本地路径或临时文件路径,用于在canvas上绘制。
resolve(res.path);
},
fail: reject, // 处理加载失败的情况。
});
});
}
const popup = ref()
const handleShare = () => {
popup.value.open();
}
const change = (e) => {
console.log('弹窗状态改变:', e);
}
onMounted(() => {
powerW.value = uni.getSystemInfoSync().windowWidth / 375;
// console.log(this.powerW, '宽度比率');
// 创建画布 初始化canvas上下文
ctx.value = uni.createCanvasContext('myCanvas');
})
</script>
<style lang="scss" scoped>
</style>