1、定义canvas
<canvas class="myCanvas" canvas-id="myCanvas" :style="{width:canvasW*2+'rpx',height:canvasH*2+'rpx'}"></canvas>
2、设立背景图和根据点击位置确认图片位置
<view class="test-box" v-if="canvasShow" :style="{height:pageH+'px'}">
<view class="test-warpper">
<image id="testMain" :style="{height:pageH+'px'}" @click="clickAddIcon($event)" class="test-bg" :src="img" mode="widthFix"></image>
<template>
<image class="img-icon"
v-if="logos"
v-for="(item,idx) in logos"
:key="idx"
:style="{top:item.topY+'px',left:item.leftX+'px',width:item.width+'px',height:item.height+'px'}"
:src="item.src" mode="widthFix">
</image>
</template>
</view>
</view>
3、翻页与确认
<view class="test-btn-box">
<view class="btn-flex">
<view class="pre-btn">
上一页
</view>
<view class="pre-btn">
下一页
</view>
<view class="pre-btn" @click="moreShowFun">
更多
</view>
</view>
<view class="more-box" v-if="moreShow">
<view class="more-warpper">
<view class="more-btn" @click="previewImage(img,0)">
预览
</view>
<view class="more-btn">
操作
</view>
<view class="more-btn">
退出
</view>
<view class="more-btn" @click="canvasImage">
确定
</view>
</view>
</view>
</view>
4、js方法处理
<script>
export default {
data() {
return {
canvasShow: true,//显示隐藏操作页
moreShow:false,
img:require('../../../static/travel_3.png'),//本地图片
logo:require('../../../static/logo.png'),//本地图片
logos:[],//选择的需要合成的图片合图片的位置
topY:'',//点击的纵坐标
leftX:'',//点击的很坐标
canvasW:'',//canvas宽度
canvasH:"",//canvas高度
systemInfo:{
}, // 设备信息
offsetLeft:'',//原图左偏移量
offsetTop:'',//原图上偏移量
pageH:'',//页面高度
}
},
onLoad() {
uni.getSystemInfo({
success(res) {
console.log(res)
if(res.windowHeight > res.windowWidth){
this.pageH = res.windowHeight;
}else{
this.pageH = res.windowWidth;
}
}
})
},
methods: {
getElSize(id) {
//得到元素的size
return new Promise((res, rej) => {
uni.createSelectorQuery().select('#' + id).fields({
size: true,
scrollOffset: true
}, (data) => {
res(data);
}).exec();
});
},
//确定合成图片
canvasImage:function(){
let that = this;
let testCanvas = uni.createCanvasContext('myCanvas',that);
try{
testCanvas.drawImage(that.img,that.offsetLeft,that.offsetTop,that.canvasW,that.canvasH);
}catch(e){
//TODO handle the exception
console.log(e)
}
//多张图片的循环处理
that.logos.forEach((item,idx)=>{
testCanvas.drawImage(item.src,item.leftX,item.topY,item.width,item.height);
});
testCanvas.draw(true,()=>{
uni.canvasToTempFilePath({
canvasId:'myCanvas',
success: (res) => {
uni.getImageInfo({
src:res.tempFilePath,
success(re) {
// console.log(re)
that.canvasShow = false;
}
})
}
})
})
},
//点击添加图标
clickAddIcon:function(ev){
let that = this;
that.getElSize('testMain').then(res=>{
that.canvasW = res.width;
that.canvasH = res.height;
});
that.topY = ev.target.y;
that.leftX = ev.target.x
that.offsetLeft = ev.target.offsetLeft;
that.offsetTop = ev.target.offsetTop;
let obj = {
};
obj.src = that.logo;
obj.width = 40;
obj.height = 40;
obj.leftX = that.leftX-20;
obj.topY = that.topY-20;
that.logos.push(obj);
},
//更多
moreShowFun:function(){
let that = this;
that.moreShow = !that.moreShow;
},
//预览图片
previewImage:function(imgs, idx){
if (typeof imgs === 'string') {
imgs = Array(imgs);
}
uni.previewImage({
urls: imgs,
current: idx
});
},
}
}
</script>
5、css样式
<style>
.myCanvas{
position: absolute;
z-index: -1;
/* background-color: #4CD964; */
}
.img-icon{
position: absolute;
z-index: 111;
}
.test-box{
position: fixed;
top: 0;
left: 0;
width: 100vw;
/* height: 100vh; */
z-index: 1;
background-color: #007AFF;
}
.test-warpper{
width: 100vw;
height: 100vh;
/* display: flex;
flex-flow: column;
justify-content: center;
align-items: center; */
}
.test-bg{
width: 100%;
height: 100%;
min-height: 100vh;
}
.test-btn-box{
position: fixed;
bottom: 0;
left: 0;
width: 100vw;
height: 120rpx;
z-index: 100;
}
.btn-flex{
width: calc(100vw - 48rpx);
height: 120rpx;
padding: 0 24rpx;
display: flex;
flex-flow: row;
justify-content: space-between;
align-items: center;
}
.pre-btn{
margin: 10rpx 24rpx;
width: 140rpx;
height: 80rpx;
line-height: 80rpx;
border-radius: 20rpx;
text-align: center;
background-color: #40d2d9;
font-size: 32rpx;
color: #FFFFFF;
}
.more-box{
position: absolute;
right: 24rpx;
bottom: 140rpx;
width: 120rpx;
/* height: 600rpx; */
z-index: 110;
/* background-color: #40D2D9; */
transition: all .3s;
}
.more-warpper{
display: flex;
flex-flow: column;
justify-content: center;
align-items: center;
}
.more-btn{
width: 100rpx;
height: 90rpx;
line-height: 90rpx;
border-radius: 40rpx;
margin-bottom: 20px;
text-align: center;
background-color: #40D2D9;
font-size: 32rpx;
color: #FFFFFF;
}
</style>