新增服务,增加图片裁剪功能
This commit is contained in:
parent
e8e13a4154
commit
ff8b497c04
|
|
@ -50,21 +50,21 @@
|
||||||
<view class="flex-sub">
|
<view class="flex-sub">
|
||||||
<input class="radius-input" @input="inputSpecs($event, index, 'deduct')"
|
<input class="radius-input" @input="inputSpecs($event, index, 'deduct')"
|
||||||
:value="item.deduct" placeholder="追加提成额"></input>
|
:value="item.deduct" placeholder="追加提成额"></input>
|
||||||
</view>
|
|
||||||
<view class="flex-sub margin-left-xs">
|
|
||||||
<input class="radius-input" @input="inputSpecs($event, index, 'groupPrice')"
|
|
||||||
:value="item.groupPrice" placeholder="团购价"></input>
|
|
||||||
</view>
|
</view>
|
||||||
</view>
|
<view class="flex-sub margin-left-xs">
|
||||||
<view class="flex margin-top-xs">
|
<input class="radius-input" @input="inputSpecs($event, index, 'groupPrice')"
|
||||||
<view class="flex-sub">
|
:value="item.groupPrice" placeholder="团购价"></input>
|
||||||
<input class="radius-input" @input="inputSpecs($event, index, 'goodsUnit')"
|
</view>
|
||||||
:value="item.goodsUnit" placeholder="规格单位"></input>
|
</view>
|
||||||
</view>
|
<view class="flex margin-top-xs">
|
||||||
<view class="flex-sub margin-left-xs">
|
<view class="flex-sub">
|
||||||
<input class="radius-input" @input="inputSpecs($event, index, 'goodsNum')"
|
<input class="radius-input" @input="inputSpecs($event, index, 'goodsUnit')"
|
||||||
:value="item.goodsNum" placeholder="库存"></input>
|
:value="item.goodsUnit" placeholder="规格单位"></input>
|
||||||
</view>
|
</view>
|
||||||
|
<view class="flex-sub margin-left-xs">
|
||||||
|
<input class="radius-input" @input="inputSpecs($event, index, 'goodsNum')"
|
||||||
|
:value="item.goodsNum" placeholder="库存"></input>
|
||||||
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</checkbox-group>
|
</checkbox-group>
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="solid-top"> -->
|
<!-- <view class="solid-top"> -->
|
||||||
<!-- <view class="padding-lr flex align-center">
|
<!-- <view class="padding-lr flex align-center">
|
||||||
<view class="flex-twice flex justify-start align-center">
|
<view class="flex-twice flex justify-start align-center">
|
||||||
<view style="width: 20%;">单位</view>
|
<view style="width: 20%;">单位</view>
|
||||||
<my-uni-combox :candidates="productUnits" placeholder="请选择" v-model="formData.productUnit">
|
<my-uni-combox :candidates="productUnits" placeholder="请选择" v-model="formData.productUnit">
|
||||||
|
|
@ -83,32 +83,33 @@
|
||||||
优惠券+
|
优惠券+
|
||||||
</view>
|
</view>
|
||||||
</view> -->
|
</view> -->
|
||||||
<!-- <view class="padding-lr flex align-center padding-tb-xs"> -->
|
<!-- <view class="padding-lr flex align-center padding-tb-xs"> -->
|
||||||
<!-- <view class="cu-form-group"> -->
|
<!-- <view class="cu-form-group"> -->
|
||||||
<!-- <checkbox style="transform:scale(1)" class="main-color margin-right-xs" :value="true"
|
<!-- <checkbox style="transform:scale(1)" class="main-color margin-right-xs" :value="true"
|
||||||
:v-model="formData.isGoldenServ" :checked="formData.isGoldenServ"></checkbox> -->
|
:v-model="formData.isGoldenServ" :checked="formData.isGoldenServ"></checkbox> -->
|
||||||
<!-- <view class="title">金牌服务<text class="margin-left-xs text-red">*</text></view> -->
|
<!-- <view class="title">金牌服务<text class="margin-left-xs text-red">*</text></view> -->
|
||||||
<!-- <my-uni-combox :candidates="servHonorTitle" placeholder="请选择" v-model="formData.servHonorTitle"> -->
|
<!-- <my-uni-combox :candidates="servHonorTitle" placeholder="请选择" v-model="formData.servHonorTitle"> -->
|
||||||
<!-- </my-uni-combox> -->
|
<!-- </my-uni-combox> -->
|
||||||
<!-- </view> -->
|
<!-- </view> -->
|
||||||
<!-- <view class="flex-twice flex justify-start align-center">
|
<!-- <view class="flex-twice flex justify-start align-center">
|
||||||
<view style="width: 25%;">质保期</view>
|
<view style="width: 25%;">质保期</view>
|
||||||
<my-uni-combox :candidates="productProtectTimes" placeholder="请选择"
|
<my-uni-combox :candidates="productProtectTimes" placeholder="请选择"
|
||||||
v-model="formData.productProtectTime"></my-uni-combox>
|
v-model="formData.productProtectTime"></my-uni-combox>
|
||||||
</view> -->
|
</view> -->
|
||||||
<!-- </view> -->
|
|
||||||
<!-- </view> -->
|
<!-- </view> -->
|
||||||
</view>
|
<!-- </view> -->
|
||||||
<view class="cu-form-group solid-top">
|
</view>
|
||||||
<view class="title">商品单位<text class="text-red">*</text></view>
|
<view class="cu-form-group solid-top">
|
||||||
<input name="goodsUnit" v-model="formData.goodsUnit" placeholder="商品单位显示优先级低于规格单位"></input>
|
<view class="title">商品单位<text class="text-red">*</text></view>
|
||||||
</view>
|
<input name="goodsUnit" v-model="formData.goodsUnit" placeholder="商品单位显示优先级低于规格单位"></input>
|
||||||
<view class="cu-form-group justify-start">
|
</view>
|
||||||
<!-- <checkbox style="transform:scale(1)" class="main-color margin-right-xs" :value="true"
|
<view class="cu-form-group justify-start">
|
||||||
:v-model="formData.isGoldenServ" :checked="formData.isGoldenServ"></checkbox> -->
|
<!-- <checkbox style="transform:scale(1)" class="main-color margin-right-xs" :value="true"
|
||||||
<view class="title">附加服务</view>
|
:v-model="formData.isGoldenServ" :checked="formData.isGoldenServ"></checkbox> -->
|
||||||
<my-uni-combox class="form-val-area" :candidates="servHonorTitle" placeholder="请选择" v-model="formData.servHonorTitle">
|
<view class="title">附加服务</view>
|
||||||
</my-uni-combox>
|
<my-uni-combox class="form-val-area" :candidates="servHonorTitle" placeholder="请选择"
|
||||||
|
v-model="formData.servHonorTitle">
|
||||||
|
</my-uni-combox>
|
||||||
</view>
|
</view>
|
||||||
<view class="solid-top">
|
<view class="solid-top">
|
||||||
<view class="cu-form-group">
|
<view class="cu-form-group">
|
||||||
|
|
@ -132,10 +133,10 @@
|
||||||
</view>
|
</view>
|
||||||
<view class="cu-bar bg-white">
|
<view class="cu-bar bg-white">
|
||||||
<view class="action text-black">区域描述</view>
|
<view class="action text-black">区域描述</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="padding-lr-sm padding-bottom-sm bg-white">
|
<view class="padding-lr-sm padding-bottom-sm bg-white">
|
||||||
<textarea name="areaDesc" style="width: 100%; height: 150rpx;" class="solid radius text-left padding-sm" v-model="formData.areaDesc"
|
<textarea name="areaDesc" style="width: 100%; height: 150rpx;" class="solid radius text-left padding-sm"
|
||||||
maxlength="-1" placeholder="如:XX区XX街道未覆盖或XX区仅服务XX街道"></textarea>
|
v-model="formData.areaDesc" maxlength="-1" placeholder="如:XX区XX街道未覆盖或XX区仅服务XX街道"></textarea>
|
||||||
</view>
|
</view>
|
||||||
<!-- <view class="cu-form-group">
|
<!-- <view class="cu-form-group">
|
||||||
<view class="title">上门费</view>
|
<view class="title">上门费</view>
|
||||||
|
|
@ -157,7 +158,7 @@
|
||||||
<text class='cuIcon-close'></text>
|
<text class='cuIcon-close'></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="solids" @tap="chooseImgList($event, 'coverImgList')"
|
<view class="solids" @tap="chooseImgList($event, 'coverImgList', 200, 200)"
|
||||||
v-if="formData.coverImgList.length === 0">
|
v-if="formData.coverImgList.length === 0">
|
||||||
<text class='cuIcon-cameraadd'></text>
|
<text class='cuIcon-cameraadd'></text>
|
||||||
</view>
|
</view>
|
||||||
|
|
@ -202,7 +203,9 @@
|
||||||
<text class='cuIcon-cameraadd'></text>
|
<text class='cuIcon-cameraadd'></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
|
<ksp-cropper mode="fixed" :width="cropWidth" :height="cropHeight" :maxWidth="1024" :maxHeight="1024" :url="url2Crop"
|
||||||
|
@cancel="oncancel" @ok="onok"></ksp-cropper>
|
||||||
<view class="cu-bar bg-white solid-top">
|
<view class="cu-bar bg-white solid-top">
|
||||||
<view class="action text-black">
|
<view class="action text-black">
|
||||||
视频上传
|
视频上传
|
||||||
|
|
@ -218,14 +221,14 @@
|
||||||
<view class="solids" @tap="chooseVideo()">
|
<view class="solids" @tap="chooseVideo()">
|
||||||
<text class='cuIcon-cameraadd'></text>
|
<text class='cuIcon-cameraadd'></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="grid grid-square flex-sub" v-else>
|
<view class="grid grid-square flex-sub" v-else>
|
||||||
<view class="bg-img" v-for="(item,index) in formData.videoList" :key="index" :data-url="item">
|
<view class="bg-img" v-for="(item,index) in formData.videoList" :key="index" :data-url="item">
|
||||||
<video :src="item" controls></video>
|
<video :src="item" controls></video>
|
||||||
<view class="cu-tag bg-red" @tap.stop="delImg($event, formData.videoList)" :data-index="index">
|
<view class="cu-tag bg-red" @tap.stop="delImg($event, formData.videoList)" :data-index="index">
|
||||||
<text class='cuIcon-close'></text>
|
<text class='cuIcon-close'></text>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
</view>
|
</view>
|
||||||
<view class="padding-sm bg-white solid-top">
|
<view class="padding-sm bg-white solid-top">
|
||||||
|
|
@ -236,9 +239,9 @@
|
||||||
<view class="padding-bottom-lg padding-top bg-white text-center">
|
<view class="padding-bottom-lg padding-top bg-white text-center">
|
||||||
<button class="cu-btn bg-main-color shadow-blur long-btn" @click="submit">确定</button>
|
<button class="cu-btn bg-main-color shadow-blur long-btn" @click="submit">确定</button>
|
||||||
</view>
|
</view>
|
||||||
</form>
|
</form>
|
||||||
<!-- 账户及实名弹窗 -->
|
<!-- 账户及实名弹窗 -->
|
||||||
<!-- <vertify-bank-bind ref="vertifyBankBind"></vertify-bank-bind> -->
|
<!-- <vertify-bank-bind ref="vertifyBankBind"></vertify-bank-bind> -->
|
||||||
<vertify-certify ref="vertifyCertify"></vertify-certify>
|
<vertify-certify ref="vertifyCertify"></vertify-certify>
|
||||||
</view>
|
</view>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -268,7 +271,11 @@
|
||||||
descImgList: [],
|
descImgList: [],
|
||||||
coverImgList: [],
|
coverImgList: [],
|
||||||
videoList: []
|
videoList: []
|
||||||
},
|
},
|
||||||
|
url2Crop: '',
|
||||||
|
cropWidth: 200,
|
||||||
|
cropHeight: 300,
|
||||||
|
curImgListField: '',
|
||||||
categoryList: [],
|
categoryList: [],
|
||||||
categoryMultiIndex: [0, 0],
|
categoryMultiIndex: [0, 0],
|
||||||
regionList: [],
|
regionList: [],
|
||||||
|
|
@ -289,13 +296,13 @@
|
||||||
}, {
|
}, {
|
||||||
code: 5,
|
code: 5,
|
||||||
name: '平方'
|
name: '平方'
|
||||||
}],
|
}],
|
||||||
servHonorTitle: [{
|
servHonorTitle: [{
|
||||||
code: -1,
|
code: -1,
|
||||||
name: '无'
|
name: '无'
|
||||||
}, {
|
}, {
|
||||||
code: 1,
|
code: 1,
|
||||||
name: '金牌服务'
|
name: '金牌服务'
|
||||||
}],
|
}],
|
||||||
productProtectTimes: [{
|
productProtectTimes: [{
|
||||||
code: 1,
|
code: 1,
|
||||||
|
|
@ -306,9 +313,9 @@
|
||||||
}, {
|
}, {
|
||||||
code: 3,
|
code: 3,
|
||||||
name: '45天'
|
name: '45天'
|
||||||
}],
|
}],
|
||||||
curUserInfo: {},
|
curUserInfo: {},
|
||||||
bankCard: null,
|
bankCard: null,
|
||||||
certifyInfo: null
|
certifyInfo: null
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -320,46 +327,46 @@
|
||||||
this.loadData(goodId);
|
this.loadData(goodId);
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async loadData(goodId) {
|
async loadData(goodId) {
|
||||||
this.curUserInfo = this.$request.getCurUserInfo();
|
this.curUserInfo = this.$request.getCurUserInfo();
|
||||||
this.checkBankAndCertify();
|
this.checkBankAndCertify();
|
||||||
this.loadCategoryList();
|
this.loadCategoryList();
|
||||||
this.loadRegionList();
|
this.loadRegionList();
|
||||||
// TODO 如果存在goodId说明是修改,需要查询good信息进行回显
|
// TODO 如果存在goodId说明是修改,需要查询good信息进行回显
|
||||||
// this.categoryList = await this.$api.data('categoryList');
|
// this.categoryList = await this.$api.data('categoryList');
|
||||||
// this.regionList = await this.$api.data('regionList');
|
// this.regionList = await this.$api.data('regionList');
|
||||||
},
|
},
|
||||||
async checkBankAndCertify() {
|
async checkBankAndCertify() {
|
||||||
// 查询账户绑定信息
|
// 查询账户绑定信息
|
||||||
// let bankCardRes = await this.$request.getBindBankCardByWorkerId({
|
// let bankCardRes = await this.$request.getBindBankCardByWorkerId({
|
||||||
// workerId: this.curUserInfo.workerId
|
// workerId: this.curUserInfo.workerId
|
||||||
// });
|
// });
|
||||||
// this.bankCard = bankCardRes.data;
|
// this.bankCard = bankCardRes.data;
|
||||||
// 查询实名信息
|
// 查询实名信息
|
||||||
let certifyInfoRes = await this.$request.getWorkerCertify();
|
let certifyInfoRes = await this.$request.getWorkerCertify();
|
||||||
this.certifyInfo = certifyInfoRes.data;
|
this.certifyInfo = certifyInfoRes.data;
|
||||||
// if (!this.bankCard || !this.bankCard.bankNum) {
|
// if (!this.bankCard || !this.bankCard.bankNum) {
|
||||||
// this.$refs.vertifyBankBind.showModal();
|
// this.$refs.vertifyBankBind.showModal();
|
||||||
// return false;
|
// return false;
|
||||||
if (!this.certifyInfo || !this.certifyInfo.workerCertificationId) {
|
if (!this.certifyInfo || !this.certifyInfo.workerCertificationId) {
|
||||||
this.$refs.vertifyCertify.showModal();
|
this.$refs.vertifyCertify.showModal();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
async loadCategoryList(idArr) {
|
async loadCategoryList(idArr) {
|
||||||
let typeList = await this.$request.listByStep({
|
let typeList = await this.$request.listByStep({
|
||||||
type: 1
|
type: 1
|
||||||
});
|
});
|
||||||
typeList = typeList.data;
|
typeList = typeList.data;
|
||||||
let col1Id = idArr ? idArr[0] : typeList[0].goodsCategoryId;
|
let col1Id = idArr ? idArr[0] : typeList[0].goodsCategoryId;
|
||||||
let subTypeList = await this.$request.listByStep({
|
let subTypeList = await this.$request.listByStep({
|
||||||
type: 1,
|
type: 1,
|
||||||
goodsCategoryId: col1Id
|
goodsCategoryId: col1Id
|
||||||
});
|
});
|
||||||
subTypeList = subTypeList.data;
|
subTypeList = subTypeList.data;
|
||||||
let col2Id = idArr ? idArr[1] : subTypeList[0].goodsCategoryId;
|
let col2Id = idArr ? idArr[1] : subTypeList[0].goodsCategoryId;
|
||||||
let subSubTypeList = await this.$request.listByStep({
|
let subSubTypeList = await this.$request.listByStep({
|
||||||
type: 1,
|
type: 1,
|
||||||
goodsCategoryId: col2Id
|
goodsCategoryId: col2Id
|
||||||
});
|
});
|
||||||
|
|
@ -390,7 +397,7 @@
|
||||||
this.formData.category = chosenCategory;
|
this.formData.category = chosenCategory;
|
||||||
|
|
||||||
// 查询最后一级品类
|
// 查询最后一级品类
|
||||||
let res = await this.$request.listByStep({
|
let res = await this.$request.listByStep({
|
||||||
type: 1,
|
type: 1,
|
||||||
goodsCategoryId: chosenCategory[chosenCategory.length - 1].goodsCategoryId
|
goodsCategoryId: chosenCategory[chosenCategory.length - 1].goodsCategoryId
|
||||||
});
|
});
|
||||||
|
|
@ -400,12 +407,12 @@
|
||||||
let colObj = e.detail;
|
let colObj = e.detail;
|
||||||
// if (colObj.column == 0) {
|
// if (colObj.column == 0) {
|
||||||
// // 通过一级查询二级,通过二级查三级
|
// // 通过一级查询二级,通过二级查三级
|
||||||
// let subTypeList = await this.$request.listByStep({
|
// let subTypeList = await this.$request.listByStep({
|
||||||
// type: 1,
|
// type: 1,
|
||||||
// goodsCategoryId: this.categoryList[0][colObj.value].goodsCategoryId
|
// goodsCategoryId: this.categoryList[0][colObj.value].goodsCategoryId
|
||||||
// });
|
// });
|
||||||
// subTypeList = subTypeList.data;
|
// subTypeList = subTypeList.data;
|
||||||
// let subSubTypeList = await this.$request.listByStep({
|
// let subSubTypeList = await this.$request.listByStep({
|
||||||
// type: 1,
|
// type: 1,
|
||||||
// goodsCategoryId: subTypeList[0].goodsCategoryId
|
// goodsCategoryId: subTypeList[0].goodsCategoryId
|
||||||
// });
|
// });
|
||||||
|
|
@ -415,10 +422,10 @@
|
||||||
// this.categoryList.push(subTypeList);
|
// this.categoryList.push(subTypeList);
|
||||||
// this.categoryList.push(subSubTypeList);
|
// this.categoryList.push(subSubTypeList);
|
||||||
// this.categoryMultiIndex = [colObj.value, 0, 0];
|
// this.categoryMultiIndex = [colObj.value, 0, 0];
|
||||||
// } else
|
// } else
|
||||||
if (colObj.column == 0) {
|
if (colObj.column == 0) {
|
||||||
// 通过二级查三级
|
// 通过二级查三级
|
||||||
let subSubTypeList = await this.$request.listByStep({
|
let subSubTypeList = await this.$request.listByStep({
|
||||||
type: 1,
|
type: 1,
|
||||||
goodsCategoryId: this.categoryList[0][colObj.value].goodsCategoryId
|
goodsCategoryId: this.categoryList[0][colObj.value].goodsCategoryId
|
||||||
});
|
});
|
||||||
|
|
@ -481,27 +488,37 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
chooseImgList(e, imgListField) {
|
chooseImgList(e, imgListField, cropWidth, cropHeight) {
|
||||||
|
this.cropWidth = cropWidth && cropWidth > 0 ? cropWidth : 200;
|
||||||
|
this.cropHeight = cropHeight && cropHeight > 0 ? cropHeight : 300;
|
||||||
uni.chooseImage({
|
uni.chooseImage({
|
||||||
count: 9, //默认9
|
count: 1, //默认9
|
||||||
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
sizeType: ['original', 'compressed'], //可以指定是原图还是压缩图,默认二者都有
|
||||||
sourceType: ['album'], //从相册选择
|
sourceType: ['album'], //从相册选择
|
||||||
success: (res) => {
|
success: (res) => {
|
||||||
uni.showLoading({
|
res.tempFilePaths.forEach((tmpUrl, index) => {
|
||||||
title: '上传中',
|
this.url2Crop = tmpUrl;
|
||||||
mask: true
|
this.curImgListField = imgListField;
|
||||||
});
|
|
||||||
res.tempFilePaths.forEach((tmpUrl, index) => {
|
|
||||||
this.$request.uploadFile(tmpUrl).then((url) => {
|
|
||||||
this.formData[imgListField].push(url);
|
|
||||||
if (index === res.tempFilePaths.length - 1) {
|
|
||||||
uni.hideLoading();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
onok(ev) {
|
||||||
|
uni.showLoading({
|
||||||
|
title: '上传中',
|
||||||
|
mask: true
|
||||||
|
});
|
||||||
|
this.$request.uploadFile(ev.path).then((url) => {
|
||||||
|
this.formData[this.curImgListField].push(url);
|
||||||
|
uni.hideLoading();
|
||||||
|
});
|
||||||
|
// url设置为空,隐藏控件
|
||||||
|
this.url2Crop = "";
|
||||||
|
},
|
||||||
|
oncancel() {
|
||||||
|
// url设置为空,隐藏控件
|
||||||
|
this.url2Crop = "";
|
||||||
|
},
|
||||||
viewImage(e, imgList) {
|
viewImage(e, imgList) {
|
||||||
uni.previewImage({
|
uni.previewImage({
|
||||||
urls: imgList,
|
urls: imgList,
|
||||||
|
|
@ -521,18 +538,18 @@
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
chooseVideo() {
|
chooseVideo() {
|
||||||
let _this = this;
|
let _this = this;
|
||||||
uni.chooseVideo({
|
uni.chooseVideo({
|
||||||
sourceType: ['camera', 'album'],
|
sourceType: ['camera', 'album'],
|
||||||
success: function(res) {
|
success: function(res) {
|
||||||
uni.showLoading({
|
uni.showLoading({
|
||||||
title: '上传中',
|
title: '上传中',
|
||||||
mask: true
|
mask: true
|
||||||
});
|
});
|
||||||
_this.$request.uploadFile(res.tempFilePath).then((url) => {
|
_this.$request.uploadFile(res.tempFilePath).then((url) => {
|
||||||
uni.hideLoading();
|
uni.hideLoading();
|
||||||
_this.formData.videoList.push(url);
|
_this.formData.videoList.push(url);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
@ -544,89 +561,89 @@
|
||||||
// });
|
// });
|
||||||
// this.formData.video = await this.$request.uploadFile(e.tempFilePaths[0]);
|
// this.formData.video = await this.$request.uploadFile(e.tempFilePaths[0]);
|
||||||
// uni.hideLoading();
|
// uni.hideLoading();
|
||||||
// },
|
// },
|
||||||
validData(data) {
|
validData(data) {
|
||||||
let errMsg = "";
|
let errMsg = "";
|
||||||
if (!data.servName) {
|
if (!data.servName) {
|
||||||
errMsg = '服务名称不能为空';
|
errMsg = '服务名称不能为空';
|
||||||
} else if (!data.goodsStandardList || !data.goodsStandardList.length) {
|
} else if (!data.goodsStandardList || !data.goodsStandardList.length) {
|
||||||
errMsg = '至少选择一个规格';
|
errMsg = '至少选择一个规格';
|
||||||
} else if (!this.validSpecData(data.goodsStandardList)) {
|
} else if (!this.validSpecData(data.goodsStandardList)) {
|
||||||
return false;
|
return false;
|
||||||
} else if (!data.goodsUnit) {
|
} else if (!data.goodsUnit) {
|
||||||
errMsg = '商品单位不能为空';
|
errMsg = '商品单位不能为空';
|
||||||
} else if (!data.goodsAreaList || !data.goodsAreaList.length) {
|
} else if (!data.goodsAreaList || !data.goodsAreaList.length) {
|
||||||
errMsg = '至少选择一个上架区域';
|
errMsg = '至少选择一个上架区域';
|
||||||
} else if (!data.coverImgList || !data.coverImgList.length) {
|
} else if (!data.coverImgList || !data.coverImgList.length) {
|
||||||
errMsg = '封面图不能为空'
|
errMsg = '封面图不能为空'
|
||||||
} else if (!data.descImgList || !data.descImgList.length) {
|
} else if (!data.descImgList || !data.descImgList.length) {
|
||||||
errMsg = '详情图不能为空'
|
errMsg = '详情图不能为空'
|
||||||
} else if (!data.imgList || !data.imgList.length) {
|
} else if (!data.imgList || !data.imgList.length) {
|
||||||
errMsg = '轮播图不能为空'
|
errMsg = '轮播图不能为空'
|
||||||
}
|
}
|
||||||
if (errMsg) {
|
if (errMsg) {
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
icon: 'none',
|
icon: 'none',
|
||||||
title: errMsg
|
title: errMsg
|
||||||
})
|
})
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
},
|
|
||||||
validSpecData(goodsStandardList) {
|
|
||||||
let errMsg = "";
|
|
||||||
for (let i = 0; i < goodsStandardList.length; i++) {
|
|
||||||
let spec = goodsStandardList[i];
|
|
||||||
if (!spec.goodsStandardName) {
|
|
||||||
errMsg = '勾选规格的自编辑购买标题不能为空';
|
|
||||||
} else if (!spec.goodsPrice) {
|
|
||||||
errMsg = '勾选规格的价格不能为空';
|
|
||||||
} else if (!spec.groupPrice) {
|
|
||||||
errMsg = '勾选规格的团购价不能为空';
|
|
||||||
} else if (!spec.goodsNum) {
|
|
||||||
errMsg = '勾选规格的库存不能为空';
|
|
||||||
}
|
|
||||||
if (errMsg) {
|
|
||||||
uni.showToast({
|
|
||||||
icon: 'none',
|
|
||||||
title: errMsg
|
|
||||||
})
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (errMsg) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
},
|
},
|
||||||
async submit() {
|
validSpecData(goodsStandardList) {
|
||||||
let goodsStandardList = this.formData.specsList.filter((item) => {
|
let errMsg = "";
|
||||||
if (item.checked) {
|
for (let i = 0; i < goodsStandardList.length; i++) {
|
||||||
return {
|
let spec = goodsStandardList[i];
|
||||||
...item
|
if (!spec.goodsStandardName) {
|
||||||
}
|
errMsg = '勾选规格的自编辑购买标题不能为空';
|
||||||
}
|
} else if (!spec.goodsPrice) {
|
||||||
});
|
errMsg = '勾选规格的价格不能为空';
|
||||||
let goodsAreaList = this.formData.districtList.filter((item) => {
|
} else if (!spec.groupPrice) {
|
||||||
if (item.checked) {
|
errMsg = '勾选规格的团购价不能为空';
|
||||||
item.countryAreaId = item.areaId;
|
} else if (!spec.goodsNum) {
|
||||||
return item;
|
errMsg = '勾选规格的库存不能为空';
|
||||||
}
|
}
|
||||||
});
|
if (errMsg) {
|
||||||
let data2Valid = {
|
uni.showToast({
|
||||||
...this.formData,
|
icon: 'none',
|
||||||
goodsStandardList: goodsStandardList,
|
title: errMsg
|
||||||
goodsAreaList: goodsAreaList
|
})
|
||||||
}
|
break;
|
||||||
if (!this.validData(data2Valid)) {
|
}
|
||||||
return;
|
}
|
||||||
}
|
if (errMsg) {
|
||||||
|
return false;
|
||||||
let checkRes = await this.checkBankAndCertify();
|
}
|
||||||
if (!checkRes) {
|
return true;
|
||||||
return;
|
},
|
||||||
}
|
async submit() {
|
||||||
|
let goodsStandardList = this.formData.specsList.filter((item) => {
|
||||||
|
if (item.checked) {
|
||||||
|
return {
|
||||||
|
...item
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let goodsAreaList = this.formData.districtList.filter((item) => {
|
||||||
|
if (item.checked) {
|
||||||
|
item.countryAreaId = item.areaId;
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
let data2Valid = {
|
||||||
|
...this.formData,
|
||||||
|
goodsStandardList: goodsStandardList,
|
||||||
|
goodsAreaList: goodsAreaList
|
||||||
|
}
|
||||||
|
if (!this.validData(data2Valid)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let checkRes = await this.checkBankAndCertify();
|
||||||
|
if (!checkRes) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// 0是轮播图,1是详情图
|
// 0是轮播图,1是详情图
|
||||||
let goodsImgsList = [];
|
let goodsImgsList = [];
|
||||||
this.formData.imgList.forEach((url) => {
|
this.formData.imgList.forEach((url) => {
|
||||||
|
|
@ -640,12 +657,12 @@
|
||||||
imgUrl: url,
|
imgUrl: url,
|
||||||
imgType: 1
|
imgType: 1
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
let goodsVideoUrl = this.formData.videoList.length ? this.formData.videoList[0] : '';
|
let goodsVideoUrl = this.formData.videoList.length ? this.formData.videoList[0] : '';
|
||||||
|
|
||||||
let params = {
|
let params = {
|
||||||
goodsName: this.formData.servName,
|
goodsName: this.formData.servName,
|
||||||
goodsDesc: this.formData.servDesc,
|
goodsDesc: this.formData.servDesc,
|
||||||
goodsUnit: this.formData.goodsUnit,
|
goodsUnit: this.formData.goodsUnit,
|
||||||
deptGoodsCategoryId: this.formData.category[this.formData.category.length - 1].goodsCategoryId,
|
deptGoodsCategoryId: this.formData.category[this.formData.category.length - 1].goodsCategoryId,
|
||||||
goodsStandardList: goodsStandardList,
|
goodsStandardList: goodsStandardList,
|
||||||
|
|
@ -661,8 +678,8 @@
|
||||||
uni.showToast({
|
uni.showToast({
|
||||||
icon: 'success'
|
icon: 'success'
|
||||||
})
|
})
|
||||||
uni.reLaunch({
|
uni.reLaunch({
|
||||||
url: '/pages/index/index?menuCode=supplyChainPage'
|
url: '/pages/index/index?menuCode=supplyChainPage'
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -682,9 +699,9 @@
|
||||||
|
|
||||||
.long-btn {
|
.long-btn {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.form-val-area {
|
.form-val-area {
|
||||||
flex-basis: 75% !important;
|
flex-basis: 75% !important;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
## 1.1.5(2022-06-14)
|
||||||
|
填新版HBuilderX的坑,简单测试是没问题了。
|
||||||
|
## 1.1.4(2022-02-15)
|
||||||
|
修护ios下微信小程序第一次裁剪的bug
|
||||||
|
## 1.1.3(2022-02-10)
|
||||||
|
修护APP点击无效的bug
|
||||||
|
## 1.1.2(2022-01-24)
|
||||||
|
优化一些细节
|
||||||
|
## 1.1.1(2022-01-19)
|
||||||
|
更新示例项目
|
||||||
|
## 1.1.0(2022-01-18)
|
||||||
|
新增旋转功能
|
||||||
|
## 1.0.2(2022-01-13)
|
||||||
|
修护mode="fixed"模式无效的bug
|
||||||
|
## 1.0.1(2021-12-20)
|
||||||
|
修护IOS下,小程序点击没反应的bug
|
||||||
|
## 1.0.0(2021-12-06)
|
||||||
|
图片裁剪工具
|
||||||
|
|
@ -0,0 +1,971 @@
|
||||||
|
<template>
|
||||||
|
<view v-show="url" :mode="modeValue" :change:mode="mwx.changeMode" :rotate="rotate" :change:rotate="mwx.changeRotate">
|
||||||
|
<!-- #ifdef MP-WEIXIN -->
|
||||||
|
<canvas type="2d" class="canvas" :style="{width: target.width + 'px', height: target.height + 'px'}"></canvas>
|
||||||
|
<!-- #endif -->
|
||||||
|
<!-- #ifdef APP-PLUS || H5 -->
|
||||||
|
<canvas :canvas-id="canvasId" :style="{width: target.width + 'px', height: target.height + 'px'}"></canvas>
|
||||||
|
<!-- #endif -->
|
||||||
|
<view class="panel">
|
||||||
|
<view class="body" @touchstart="mwx.touchstart" @touchmove="mwx.touchmove" @touchend="mwx.touchend" @touchcancel="mwx.touchcancel">
|
||||||
|
<view class="image-wrap" :class="{transit: transit}" :change:rect="mwx.changeImage" :rect="image">
|
||||||
|
<image class="image" :class="{transit: transit}" :src="url" @load="imageLoad"/>
|
||||||
|
</view>
|
||||||
|
<view class="mask"></view>
|
||||||
|
<view class="frame" :class="{transit: transit}" :change:rect="mwx.changeFrame" :rect="frame">
|
||||||
|
<view class="rect">
|
||||||
|
<view class="image-rect" :class="{transit: transit}">
|
||||||
|
<image class="image" :class="{transit: transit}" :src="url"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="line-one"></view>
|
||||||
|
<view class="line-two"></view>
|
||||||
|
<view class="line-three"></view>
|
||||||
|
<view class="line-four"></view>
|
||||||
|
<view class="frame-left-top" @touchstart="mwx.touchstart"></view>
|
||||||
|
<view class="frame-left-bottom" @touchstart="mwx.touchstart"></view>
|
||||||
|
<view class="frame-right-top" @touchstart="mwx.touchstart"></view>
|
||||||
|
<view class="frame-right-bottom" @touchstart="mwx.touchstart"></view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<view class="toolbar">
|
||||||
|
<view @tap="oncancle" class="btn-cancel">取消</view>
|
||||||
|
<view @tap="rotateAngle" class="btn-rotate">旋转</view>
|
||||||
|
<view @tap="onok" class="btn-ok">确定</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
/**
|
||||||
|
* @property {String} mode 模式
|
||||||
|
* @value fixed 固定模式,裁剪出固定大小
|
||||||
|
* @value ratio 等比模式,宽高等比缩放
|
||||||
|
* @value free 自由模式,不限制宽高比
|
||||||
|
* @property {String} url 图片路径
|
||||||
|
* @property {Number} width 宽度
|
||||||
|
* @property {Number} height 高度
|
||||||
|
* @property {Number} maxWidth 最大宽带
|
||||||
|
* @property {Number} minHeight 最大高度
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
mode: {
|
||||||
|
type: String,
|
||||||
|
default: "free"
|
||||||
|
},
|
||||||
|
url: {
|
||||||
|
type: String,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
|
width: {
|
||||||
|
type: Number,
|
||||||
|
default: 200
|
||||||
|
},
|
||||||
|
height: {
|
||||||
|
type: Number,
|
||||||
|
default: 200
|
||||||
|
},
|
||||||
|
maxWidth: {
|
||||||
|
type: Number,
|
||||||
|
default: 1024
|
||||||
|
},
|
||||||
|
maxHeight: {
|
||||||
|
type: Number,
|
||||||
|
default: 1024
|
||||||
|
}
|
||||||
|
},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
canvasId: Math.random().toString(36).slice(-6),
|
||||||
|
real: {
|
||||||
|
width: 100,
|
||||||
|
height: 100
|
||||||
|
},
|
||||||
|
target: {
|
||||||
|
width: 100,
|
||||||
|
height: 100
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
width: 100,
|
||||||
|
height: 100
|
||||||
|
},
|
||||||
|
frame: {
|
||||||
|
left: 50,
|
||||||
|
top: 50,
|
||||||
|
width: 200,
|
||||||
|
height: 300
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
left: 20,
|
||||||
|
top: 20,
|
||||||
|
width: 300,
|
||||||
|
height: 400
|
||||||
|
},
|
||||||
|
rotate: 0,
|
||||||
|
transit: false,
|
||||||
|
modeValue: ""
|
||||||
|
};
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
imageLoad(event) {
|
||||||
|
uni.getImageInfo({
|
||||||
|
src: this.url,
|
||||||
|
success: (rst) => {
|
||||||
|
this.real.width = rst.width;
|
||||||
|
this.real.height = rst.height;
|
||||||
|
this.target = {};
|
||||||
|
var query = uni.createSelectorQuery().in(this);
|
||||||
|
query.select(".body").boundingClientRect((data) => {
|
||||||
|
this.body.width = data.width;
|
||||||
|
this.body.height = data.height;
|
||||||
|
this.init();
|
||||||
|
}).exec();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
init() {
|
||||||
|
this.modeValue = this.mode;
|
||||||
|
this.rotate = 0;
|
||||||
|
var rate = this.width / this.height;
|
||||||
|
var width = this.body.width * 0.7;
|
||||||
|
var height = this.body.height * 0.7;
|
||||||
|
if (width / height > rate) {
|
||||||
|
width = height * rate;
|
||||||
|
} else {
|
||||||
|
height = width / rate;
|
||||||
|
}
|
||||||
|
var left = (this.body.width - width) / 2;
|
||||||
|
var top = (this.body.height - height) / 2;
|
||||||
|
this.frame = {
|
||||||
|
left: left,
|
||||||
|
top: top,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
};
|
||||||
|
rate = this.real.width / this.real.height;
|
||||||
|
width = this.frame.width;
|
||||||
|
height = this.frame.height;
|
||||||
|
if (width / height > rate) {
|
||||||
|
height = width / rate;
|
||||||
|
} else {
|
||||||
|
width = height * rate;
|
||||||
|
}
|
||||||
|
left = (this.frame.width - width) / 2 + this.frame.left;
|
||||||
|
top = (this.frame.height - height) / 2 + this.frame.top;
|
||||||
|
this.image = {
|
||||||
|
left: left,
|
||||||
|
top: top,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
};
|
||||||
|
},
|
||||||
|
async updateData(data) {
|
||||||
|
this.frame = data.frame;
|
||||||
|
this.image = data.image;
|
||||||
|
await this.$nextTick();
|
||||||
|
this.trimImage();
|
||||||
|
},
|
||||||
|
trimImage() {
|
||||||
|
var rate = this.frame.width / this.frame.height;
|
||||||
|
var width = this.body.width * 0.7;
|
||||||
|
var height = this.body.height * 0.7;
|
||||||
|
if (width / height > rate) {
|
||||||
|
width = height * rate;
|
||||||
|
} else {
|
||||||
|
height = width / rate;
|
||||||
|
}
|
||||||
|
var left = (this.body.width - width) / 2;
|
||||||
|
var top = (this.body.height - height) / 2;
|
||||||
|
var mul = width / this.frame.width;
|
||||||
|
var ox = this.frame.left - this.image.left;
|
||||||
|
var oy = this.frame.top - this.image.top;
|
||||||
|
this.frame = {
|
||||||
|
left: left,
|
||||||
|
top: top,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
};
|
||||||
|
width = this.image.width * mul;
|
||||||
|
height = this.image.height * mul;
|
||||||
|
left = this.frame.left - ox * mul;
|
||||||
|
top = this.frame.top - oy * mul;
|
||||||
|
this.image = {
|
||||||
|
left: left,
|
||||||
|
top: top,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
};
|
||||||
|
if (mul != 1) {
|
||||||
|
this.transit = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.transit = false;
|
||||||
|
}, 300);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rotateAngle() {
|
||||||
|
this.rotate -= 90;
|
||||||
|
var width = this.image.height;
|
||||||
|
var height = this.image.width;
|
||||||
|
var left = this.image.left;
|
||||||
|
var top = this.image.top;
|
||||||
|
var rate = width / height;
|
||||||
|
if (width < this.frame.width) {
|
||||||
|
width = this.frame.width;
|
||||||
|
height = width / rate;
|
||||||
|
}
|
||||||
|
if (height < this.frame.height) {
|
||||||
|
height = this.frame.height;
|
||||||
|
width = height * rate;
|
||||||
|
}
|
||||||
|
if (left > this.frame.left) {
|
||||||
|
left = this.frame.left;
|
||||||
|
}
|
||||||
|
if (top > this.frame.top) {
|
||||||
|
top = this.frame.top;
|
||||||
|
}
|
||||||
|
if (left + width < this.frame.left + this.frame.width) {
|
||||||
|
left = this.frame.left + this.frame.width - width;
|
||||||
|
}
|
||||||
|
if (top + height < this.frame.top + this.frame.height) {
|
||||||
|
top = this.frame.top + this.frame.height - height;
|
||||||
|
}
|
||||||
|
this.image = {
|
||||||
|
left: left,
|
||||||
|
top: top,
|
||||||
|
width: width,
|
||||||
|
height: height
|
||||||
|
};
|
||||||
|
this.transit = true;
|
||||||
|
setTimeout(() => {
|
||||||
|
this.transit = false;
|
||||||
|
}, 300);
|
||||||
|
},
|
||||||
|
onok() {
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
this.cropWx();
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS || H5
|
||||||
|
this.cropAppH5();
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
oncancle() {
|
||||||
|
this.$emit("cancel");
|
||||||
|
},
|
||||||
|
async cropWx() {
|
||||||
|
var mx = this.computeMatrix();
|
||||||
|
this.target = {
|
||||||
|
width: mx.tw,
|
||||||
|
height: mx.th
|
||||||
|
};
|
||||||
|
var canvas = await new Promise((resolve) => {
|
||||||
|
uni.createSelectorQuery()
|
||||||
|
.in(this)
|
||||||
|
.select(".canvas")
|
||||||
|
.fields({node: true})
|
||||||
|
.exec((rst) => {
|
||||||
|
var node = rst[0].node;
|
||||||
|
resolve(node);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
canvas.width = mx.tw;
|
||||||
|
canvas.height = mx.th;
|
||||||
|
uni.showLoading({
|
||||||
|
title: "处理中"
|
||||||
|
});
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, 200);
|
||||||
|
});
|
||||||
|
var context = canvas.getContext("2d");
|
||||||
|
var image = canvas.createImage();
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
image.onload = resolve;
|
||||||
|
image.onerror = reject;
|
||||||
|
image.src = this.url;
|
||||||
|
});
|
||||||
|
context.save();
|
||||||
|
context.rotate(this.rotate * Math.PI / 180);
|
||||||
|
context.drawImage(image, mx.sx, mx.sy, mx.sw, mx.sh, mx.dx, mx.dy, mx.dw, mx.dh);
|
||||||
|
context.restore();
|
||||||
|
wx.canvasToTempFilePath({
|
||||||
|
canvas: canvas,
|
||||||
|
destWidth: mx.tw,
|
||||||
|
destHeight: mx.th,
|
||||||
|
success: (rst) => {
|
||||||
|
var path = rst.tempFilePath;
|
||||||
|
this.$emit("ok", {
|
||||||
|
path: path
|
||||||
|
});
|
||||||
|
},
|
||||||
|
complete: () => {
|
||||||
|
uni.hideLoading();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
async cropAppH5() {
|
||||||
|
var mx = this.computeMatrix();
|
||||||
|
this.target = {
|
||||||
|
width: mx.tw,
|
||||||
|
height: mx.th
|
||||||
|
};
|
||||||
|
uni.showLoading({
|
||||||
|
title: "处理中"
|
||||||
|
});
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, 200);
|
||||||
|
});
|
||||||
|
var context = uni.createCanvasContext(this.canvasId, this);
|
||||||
|
context.save();
|
||||||
|
context.rotate(this.rotate * Math.PI / 180);
|
||||||
|
context.drawImage(this.url, mx.sx, mx.sy, mx.sw, mx.sh, mx.dx, mx.dy, mx.dw, mx.dh);
|
||||||
|
context.restore();
|
||||||
|
await new Promise((resolve) => {
|
||||||
|
context.draw(false, resolve);
|
||||||
|
});
|
||||||
|
uni.canvasToTempFilePath({
|
||||||
|
canvasId: this.canvasId,
|
||||||
|
destWidth: mx.tw,
|
||||||
|
destHeight: mx.th,
|
||||||
|
success: (rst) => {
|
||||||
|
var path = rst.tempFilePath;
|
||||||
|
// #ifdef H5
|
||||||
|
var base64 = path;
|
||||||
|
path = this.parseBlob(path);
|
||||||
|
this.$emit("ok", {
|
||||||
|
path: path,
|
||||||
|
base64: base64
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
// #ifdef APP-PLUS
|
||||||
|
this.$emit("ok", {
|
||||||
|
path: path
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
},
|
||||||
|
complete: () => {
|
||||||
|
uni.hideLoading();
|
||||||
|
}
|
||||||
|
}, this);
|
||||||
|
},
|
||||||
|
computeMatrix() {
|
||||||
|
var width = this.width;
|
||||||
|
var height = this.height;
|
||||||
|
var mul = this.image.width / this.real.width;
|
||||||
|
if (this.rotate % 180 != 0) {
|
||||||
|
mul = this.image.height / this.real.width;
|
||||||
|
}
|
||||||
|
if (this.mode != "fixed") {
|
||||||
|
width = this.frame.width / mul;
|
||||||
|
height = this.frame.height / mul;
|
||||||
|
}
|
||||||
|
var rate = width / height;
|
||||||
|
if (width > this.maxWidth) {
|
||||||
|
width = this.maxWidth;
|
||||||
|
height = width / rate;
|
||||||
|
}
|
||||||
|
if (height > this.maxHeight) {
|
||||||
|
height = this.maxHeight;
|
||||||
|
width = height * rate;
|
||||||
|
}
|
||||||
|
var sx = (this.frame.left - this.image.left) / mul;
|
||||||
|
var sy = (this.frame.top - this.image.top) / mul;
|
||||||
|
var sw = this.frame.width / mul;
|
||||||
|
var sh = this.frame.height / mul;
|
||||||
|
var ox = sx + sw / 2;
|
||||||
|
var oy = sy + sh / 2;
|
||||||
|
if (this.rotate % 180 != 0) {
|
||||||
|
var temp = sw;
|
||||||
|
sw = sh;
|
||||||
|
sh = temp;
|
||||||
|
}
|
||||||
|
var angle = this.rotate % 360;
|
||||||
|
if (angle < 0) {
|
||||||
|
angle += 360;
|
||||||
|
}
|
||||||
|
if (angle == 270) {
|
||||||
|
var x = this.real.width - oy;
|
||||||
|
var y = ox;
|
||||||
|
ox = x;
|
||||||
|
oy = y;
|
||||||
|
}
|
||||||
|
if (angle == 180) {
|
||||||
|
var x = this.real.width - ox;
|
||||||
|
var y = this.real.height - oy;
|
||||||
|
ox = x;
|
||||||
|
oy = y;
|
||||||
|
}
|
||||||
|
if (angle == 90) {
|
||||||
|
var x = oy;
|
||||||
|
var y = this.real.height - ox;
|
||||||
|
ox = x;
|
||||||
|
oy = y;
|
||||||
|
}
|
||||||
|
sx = ox - sw / 2;
|
||||||
|
sy = oy - sh / 2;
|
||||||
|
var dr = {x: 0, y: 0, w: width, h: height};
|
||||||
|
dr = this.parseRect(dr, -this.rotate);
|
||||||
|
return {
|
||||||
|
tw: width,
|
||||||
|
th: height,
|
||||||
|
sx: sx,
|
||||||
|
sy: sy,
|
||||||
|
sw: sw,
|
||||||
|
sh: sh,
|
||||||
|
dx: dr.x,
|
||||||
|
dy: dr.y,
|
||||||
|
dw: dr.w,
|
||||||
|
dh: dr.h
|
||||||
|
};
|
||||||
|
},
|
||||||
|
parsePoint(point, angle) {
|
||||||
|
var result = {};
|
||||||
|
result.x = point.x * Math.cos(angle * Math.PI / 180) - point.y * Math.sin(angle * Math.PI / 180);
|
||||||
|
result.y = point.y * Math.cos(angle * Math.PI / 180) + point.x * Math.sin(angle * Math.PI / 180);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
parseRect(rect, angle) {
|
||||||
|
var x1 = rect.x;
|
||||||
|
var y1 = rect.y;
|
||||||
|
var x2 = rect.x + rect.w;
|
||||||
|
var y2 = rect.y + rect.h;
|
||||||
|
var p1 = this.parsePoint({x: x1, y: y1}, angle);
|
||||||
|
var p2 = this.parsePoint({x: x2, y: y2}, angle);
|
||||||
|
var result = {};
|
||||||
|
result.x = Math.min(p1.x, p2.x);
|
||||||
|
result.y = Math.min(p1.y, p2.y);
|
||||||
|
result.w = Math.abs(p2.x - p1.x);
|
||||||
|
result.h = Math.abs(p2.y - p1.y);
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
parseBlob(base64) {
|
||||||
|
var arr = base64.split(',');
|
||||||
|
var mime = arr[0].match(/:(.*?);/)[1];
|
||||||
|
var bstr = atob(arr[1]);
|
||||||
|
var n = bstr.length;
|
||||||
|
var u8arr = new Uint8Array(n);
|
||||||
|
for(var i = 0; i < n; i++) {
|
||||||
|
u8arr[i] = bstr.charCodeAt(i);
|
||||||
|
}
|
||||||
|
var url = URL || webkitURL;
|
||||||
|
return url.createObjectURL(new Blob([u8arr], {type: mime}));
|
||||||
|
},
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<script module="mwx" lang="wxs">
|
||||||
|
var mode = "";
|
||||||
|
var rotate = 0;
|
||||||
|
var image = {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0
|
||||||
|
};
|
||||||
|
var frame = {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0
|
||||||
|
};
|
||||||
|
var touches = [];
|
||||||
|
var touchType = "";
|
||||||
|
var start = {
|
||||||
|
frame: {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0
|
||||||
|
},
|
||||||
|
image: {
|
||||||
|
left: 0,
|
||||||
|
top: 0,
|
||||||
|
width: 0,
|
||||||
|
height: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
function changeMode(value) {
|
||||||
|
mode = value;
|
||||||
|
}
|
||||||
|
function changeRotate(value, old, oi, instance) {
|
||||||
|
rotate = value;
|
||||||
|
delayUpdateStyle(oi);
|
||||||
|
}
|
||||||
|
function changeImage(value, old, oi, instance) {
|
||||||
|
image = value;
|
||||||
|
delayUpdateStyle(oi);
|
||||||
|
}
|
||||||
|
function changeFrame(value, old, oi, instance) {
|
||||||
|
frame = value;
|
||||||
|
delayUpdateStyle(oi);
|
||||||
|
}
|
||||||
|
function delayUpdateStyle(oi) {
|
||||||
|
// #ifdef APP-PLUS || H5
|
||||||
|
setTimeout(() => {
|
||||||
|
updateStyle(oi);
|
||||||
|
});
|
||||||
|
// #endif
|
||||||
|
// #ifdef MP-WEIXIN
|
||||||
|
updateStyle(oi);
|
||||||
|
// #endif
|
||||||
|
}
|
||||||
|
function touchstart(event, oi) {
|
||||||
|
// #ifdef APP-PLUS || H5
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
// #endif
|
||||||
|
touches = event.touches;
|
||||||
|
var instance = event.instance;
|
||||||
|
if (instance.hasClass("body")) {
|
||||||
|
touchType = "body";
|
||||||
|
} else if (instance.hasClass("frame-left-top")) {
|
||||||
|
touchType = "left-top";
|
||||||
|
} else if (instance.hasClass("frame-left-bottom")) {
|
||||||
|
touchType = "left-bottom";
|
||||||
|
} else if (instance.hasClass("frame-right-top")) {
|
||||||
|
touchType = "right-top";
|
||||||
|
} else if (instance.hasClass("frame-right-bottom")) {
|
||||||
|
touchType = "right-bottom";
|
||||||
|
}
|
||||||
|
start.frame.left = frame.left;
|
||||||
|
start.frame.top = frame.top;
|
||||||
|
start.frame.width = frame.width;
|
||||||
|
start.frame.height = frame.height;
|
||||||
|
start.image.left = image.left;
|
||||||
|
start.image.top = image.top;
|
||||||
|
start.image.width = image.width;
|
||||||
|
start.image.height = image.height;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
function touchmove(event, oi) {
|
||||||
|
// #ifdef APP-PLUS || H5
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
// #endif
|
||||||
|
var instance = event.instance;
|
||||||
|
if (touches.length == 1) {
|
||||||
|
if (touchType == "body") {
|
||||||
|
moveImage(touches[0], event.touches[0], oi);
|
||||||
|
} else {
|
||||||
|
scaleFrame(touches[0], event.touches[0], oi);
|
||||||
|
}
|
||||||
|
} else if (touches.length == 2 && event.touches.length == 2) {
|
||||||
|
var ta = touches[0];
|
||||||
|
var tb = touches[1];
|
||||||
|
var tc = event.touches[0];
|
||||||
|
var td = event.touches[1];
|
||||||
|
if (ta.identifier != tc.identifier) {
|
||||||
|
var temp = tc;
|
||||||
|
tc = td;
|
||||||
|
td = temp;
|
||||||
|
}
|
||||||
|
scaleImage(ta, tb, tc, td, oi);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function touchend(event, oi) {
|
||||||
|
touches = [];
|
||||||
|
oi.callMethod("updateData", {frame: frame, image: image});
|
||||||
|
}
|
||||||
|
function touchcancel(event, oi) {
|
||||||
|
touches = [];
|
||||||
|
oi.callMethod("updateData", {frame: frame, image: image});
|
||||||
|
}
|
||||||
|
function moveImage(ta, tb, oi) {
|
||||||
|
var ax = tb.clientX - ta.clientX;
|
||||||
|
var ay = tb.clientY - ta.clientY;
|
||||||
|
image.left = start.image.left + ax;
|
||||||
|
image.top = start.image.top + ay;
|
||||||
|
var left = frame.left;
|
||||||
|
var top = frame.top;
|
||||||
|
var width = frame.width;
|
||||||
|
var height = frame.height;
|
||||||
|
if (image.left > left) {
|
||||||
|
image.left = left;
|
||||||
|
}
|
||||||
|
if (image.top > top) {
|
||||||
|
image.top = top;
|
||||||
|
}
|
||||||
|
if (image.left + image.width < left + width) {
|
||||||
|
image.left = left + width - image.width;
|
||||||
|
}
|
||||||
|
if (image.top + image.height < top + height) {
|
||||||
|
image.top = top + height - image.height;
|
||||||
|
}
|
||||||
|
updateStyle(oi);
|
||||||
|
}
|
||||||
|
function scaleImage(ta, tb, tc, td, oi) {
|
||||||
|
var x1 = ta.clientX;
|
||||||
|
var y1 = ta.clientY;
|
||||||
|
var x2 = tb.clientX;
|
||||||
|
var y2 = tb.clientY;
|
||||||
|
var x3 = tc.clientX;
|
||||||
|
var y3 = tc.clientY;
|
||||||
|
var x4 = td.clientX;
|
||||||
|
var y4 = td.clientY;
|
||||||
|
var ol = Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
|
||||||
|
var el = Math.sqrt((x3 - x4) * (x3 - x4) + (y3 - y4) * (y3 - y4));
|
||||||
|
var ocx = (x1 + x2) / 2;
|
||||||
|
var ocy = (y1 + y2) / 2;
|
||||||
|
var ecx = (x3 + x4) / 2;
|
||||||
|
var ecy = (y3 + y4) / 2;
|
||||||
|
var ax = ecx - ocx;
|
||||||
|
var ay = ecy - ocy;
|
||||||
|
var scale = el / ol;
|
||||||
|
if (start.image.width * scale < frame.width) {
|
||||||
|
scale = frame.width / start.image.width;
|
||||||
|
}
|
||||||
|
if (start.image.height * scale < frame.height) {
|
||||||
|
scale = frame.height / start.image.height;
|
||||||
|
}
|
||||||
|
if (start.image.width * scale < frame.width) {
|
||||||
|
scale = frame.width / start.image.width;
|
||||||
|
}
|
||||||
|
image.left = start.image.left + ax - (ocx - start.image.left) * (scale - 1);
|
||||||
|
image.top = start.image.top + ay - (ocy - start.image.top) * (scale - 1);
|
||||||
|
image.width = start.image.width * scale;
|
||||||
|
image.height = start.image.height * scale;
|
||||||
|
if (image.left > frame.left) {
|
||||||
|
image.left = frame.left;
|
||||||
|
}
|
||||||
|
if (image.top > frame.top) {
|
||||||
|
image.top = frame.top;
|
||||||
|
}
|
||||||
|
if (image.left + image.width < frame.left + frame.width) {
|
||||||
|
image.left = frame.left + frame.width - image.width;
|
||||||
|
}
|
||||||
|
if (image.top + image.height < frame.top + frame.height) {
|
||||||
|
image.top = frame.top + frame.height - image.height;
|
||||||
|
}
|
||||||
|
updateStyle(oi);
|
||||||
|
}
|
||||||
|
function scaleFrame(ta, tb, oi) {
|
||||||
|
var ax = tb.clientX - ta.clientX;
|
||||||
|
var ay = tb.clientY - ta.clientY;
|
||||||
|
var x1 = start.frame.left;
|
||||||
|
var y1 = start.frame.top;
|
||||||
|
var x2 = start.frame.left + start.frame.width;
|
||||||
|
var y2 = start.frame.top + start.frame.height;
|
||||||
|
var cx1 = false;
|
||||||
|
var cy1 = false;
|
||||||
|
var cx2 = false;
|
||||||
|
var cy2 = false;
|
||||||
|
var mix = 30;
|
||||||
|
var rate = frame.width / frame.height;
|
||||||
|
if (touchType == "left-top") {
|
||||||
|
x1 += ax;
|
||||||
|
y1 += ay;
|
||||||
|
cx1 = true;
|
||||||
|
cy1 = true;
|
||||||
|
} else if (touchType == "left-bottom") {
|
||||||
|
x1 += ax;
|
||||||
|
y2 += ay;
|
||||||
|
cx1 = true;
|
||||||
|
cy2 = true;
|
||||||
|
} else if (touchType == "right-top") {
|
||||||
|
x2 += ax;
|
||||||
|
y1 += ay;
|
||||||
|
cx2 = true;
|
||||||
|
cy1 = true;
|
||||||
|
} else if (touchType == "right-bottom") {
|
||||||
|
x2 += ax;
|
||||||
|
y2 += ay;
|
||||||
|
cx2 = true;
|
||||||
|
cy2 = true;
|
||||||
|
}
|
||||||
|
if (x1 < image.left) {
|
||||||
|
x1 = image.left;
|
||||||
|
}
|
||||||
|
if (y1 < image.top) {
|
||||||
|
y1 = image.top;
|
||||||
|
}
|
||||||
|
if (x2 > image.left + image.width) {
|
||||||
|
x2 = image.left + image.width;
|
||||||
|
}
|
||||||
|
if (y2 > image.top + image.height) {
|
||||||
|
y2 = image.top + image.height;
|
||||||
|
}
|
||||||
|
if (cx1) {
|
||||||
|
if (x1 > x2 - mix) {
|
||||||
|
x1 = x2 - mix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cy1) {
|
||||||
|
if (y1 > y2 - mix) {
|
||||||
|
y1 = y2 - mix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cx2) {
|
||||||
|
if (x2 < x1 + mix) {
|
||||||
|
x2 = x1 + mix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cy2) {
|
||||||
|
if (y2 < y1 + mix) {
|
||||||
|
y2 = y1 + mix;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cx1) {
|
||||||
|
if (mode != "free") {
|
||||||
|
var val = x2 - rate * (y2 - y1);
|
||||||
|
if (x1 < val) {
|
||||||
|
x1 = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cy1) {
|
||||||
|
if (mode != "free") {
|
||||||
|
var val = y2 - (x2 - x1) / rate;
|
||||||
|
if (y1 < val) {
|
||||||
|
y1 = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cx2) {
|
||||||
|
if (mode != "free") {
|
||||||
|
var val = rate * (y2 - y1) + x1;
|
||||||
|
if (x2 > val) {
|
||||||
|
x2 = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cy2) {
|
||||||
|
if (mode != "free") {
|
||||||
|
var val = (x2 - x1) / rate + y1;
|
||||||
|
if (y2 > val) {
|
||||||
|
y2 = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
frame.left = x1;
|
||||||
|
frame.top = y1;
|
||||||
|
frame.width = x2 - x1;
|
||||||
|
frame.height = y2 - y1;
|
||||||
|
updateStyle(oi);
|
||||||
|
}
|
||||||
|
function updateStyle(oi) {
|
||||||
|
oi.selectComponent(".frame").setStyle({
|
||||||
|
"left": frame.left + "px",
|
||||||
|
"top": frame.top + "px",
|
||||||
|
"width": frame.width + "px",
|
||||||
|
"height": frame.height + "px"
|
||||||
|
});
|
||||||
|
oi.selectComponent(".image-wrap").setStyle({
|
||||||
|
"left": image.left + "px",
|
||||||
|
"top": image.top + "px",
|
||||||
|
"width": image.width + "px",
|
||||||
|
"height": image.height + "px"
|
||||||
|
});
|
||||||
|
oi.selectComponent(".image-rect").setStyle({
|
||||||
|
"left": image.left - frame.left + "px",
|
||||||
|
"top": image.top - frame.top + "px",
|
||||||
|
"width": image.width + "px",
|
||||||
|
"height": image.height + "px"
|
||||||
|
});
|
||||||
|
var left = 0;
|
||||||
|
var top = 0;
|
||||||
|
var width = image.width;
|
||||||
|
var height = image.height;
|
||||||
|
if (rotate % 180 != 0) {
|
||||||
|
width = image.height;
|
||||||
|
height = image.width;
|
||||||
|
top = width / 2 - height / 2;
|
||||||
|
left = height / 2 - width/ 2;
|
||||||
|
}
|
||||||
|
oi.selectComponent(".image-wrap .image").setStyle({
|
||||||
|
"left": left + "px",
|
||||||
|
"top": top + "px",
|
||||||
|
"width": width + "px",
|
||||||
|
"height": height + "px",
|
||||||
|
"transform": "rotate(" + rotate + "deg)"
|
||||||
|
});
|
||||||
|
oi.selectComponent(".image-rect .image").setStyle({
|
||||||
|
"left": left + "px",
|
||||||
|
"top": top + "px",
|
||||||
|
"width": width + "px",
|
||||||
|
"height": height + "px",
|
||||||
|
"transform": "rotate(" + rotate + "deg)"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
module.exports = {
|
||||||
|
changeMode: changeMode,
|
||||||
|
changeRotate: changeRotate,
|
||||||
|
changeImage: changeImage,
|
||||||
|
changeFrame: changeFrame,
|
||||||
|
touchstart: touchstart,
|
||||||
|
touchmove: touchmove,
|
||||||
|
touchend: touchend,
|
||||||
|
touchcancel: touchcancel
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.panel {
|
||||||
|
position: fixed;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
top: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 1000;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.canvas {
|
||||||
|
position: absolute;
|
||||||
|
top: 5000px;
|
||||||
|
left: 5000px;
|
||||||
|
}
|
||||||
|
.toolbar {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100rpx;
|
||||||
|
left: 0rpx;
|
||||||
|
bottom: 0rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.btn-cancel {
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #d5dfe5;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.btn-ok {
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #FFFFFF;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.btn-rotate {
|
||||||
|
font-size: 40rpx;
|
||||||
|
color: #d5dfe5;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
.body {
|
||||||
|
position: absolute;
|
||||||
|
left: 0rpx;
|
||||||
|
right: 0rpx;
|
||||||
|
top: 0rpx;
|
||||||
|
bottom: 0rpx;
|
||||||
|
background: black;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.mask {
|
||||||
|
position: absolute;
|
||||||
|
left: 0rpx;
|
||||||
|
right: 0rpx;
|
||||||
|
top: 0rpx;
|
||||||
|
bottom: 0rpx;
|
||||||
|
background: black;
|
||||||
|
opacity: 0.4;
|
||||||
|
}
|
||||||
|
.plank {
|
||||||
|
position: absolute;
|
||||||
|
left: 0rpx;
|
||||||
|
right: 0rpx;
|
||||||
|
top: 0rpx;
|
||||||
|
bottom: 0rpx;
|
||||||
|
}
|
||||||
|
.image-wrap {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.image-rect {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.image {
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
.frame {
|
||||||
|
position: absolute;
|
||||||
|
left: 100px;
|
||||||
|
top: 100px;
|
||||||
|
width: 200px;
|
||||||
|
height: 200px;
|
||||||
|
}
|
||||||
|
.rect {
|
||||||
|
position: absolute;
|
||||||
|
left: -2px;
|
||||||
|
top: -2px;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
border: 2px solid white;
|
||||||
|
overflow: hidden;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
.line-one {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
background: white;
|
||||||
|
left: 0;
|
||||||
|
top: 33.3%;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
.line-two {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 1px;
|
||||||
|
background: white;
|
||||||
|
left: 0;
|
||||||
|
top: 66.7%;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
.line-three {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 100%;
|
||||||
|
background: white;
|
||||||
|
top: 0;
|
||||||
|
left: 33.3%;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
.line-four {
|
||||||
|
position: absolute;
|
||||||
|
width: 1px;
|
||||||
|
height: 100%;
|
||||||
|
background: white;
|
||||||
|
top: 0;
|
||||||
|
left: 66.7%;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
.frame-left-top {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
left: -6px;
|
||||||
|
top: -6px;
|
||||||
|
border-left: 4px solid red;
|
||||||
|
border-top: 4px solid red;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
.frame-left-bottom {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
left: -6px;
|
||||||
|
bottom: -6px;
|
||||||
|
border-left: 4px solid red;
|
||||||
|
border-bottom: 4px solid red;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
.frame-right-top {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
right: -6px;
|
||||||
|
top: -6px;
|
||||||
|
border-right: 4px solid red;
|
||||||
|
border-top: 4px solid red;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
.frame-right-bottom {
|
||||||
|
position: absolute;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
right: -6px;
|
||||||
|
bottom: -6px;
|
||||||
|
border-right: 4px solid red;
|
||||||
|
border-bottom: 4px solid red;
|
||||||
|
box-sizing:content-box;
|
||||||
|
}
|
||||||
|
.transit {
|
||||||
|
transition: width 0.3s, height 0.3s, left 0.3s, top 0.3s, transform 0.3s;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
{
|
||||||
|
"id": "ksp-cropper",
|
||||||
|
"displayName": "ksp-cropper",
|
||||||
|
"version": "1.1.5",
|
||||||
|
"description": "高性能图片裁剪工具",
|
||||||
|
"keywords": [
|
||||||
|
"头像",
|
||||||
|
"图片",
|
||||||
|
"裁剪"
|
||||||
|
],
|
||||||
|
"repository": "",
|
||||||
|
"engines": {
|
||||||
|
"HBuilderX": "^3.1.0"
|
||||||
|
},
|
||||||
|
"dcloudext": {
|
||||||
|
"category": [
|
||||||
|
"前端组件",
|
||||||
|
"通用组件"
|
||||||
|
],
|
||||||
|
"sale": {
|
||||||
|
"regular": {
|
||||||
|
"price": "0.00"
|
||||||
|
},
|
||||||
|
"sourcecode": {
|
||||||
|
"price": "0.00"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"contact": {
|
||||||
|
"qq": ""
|
||||||
|
},
|
||||||
|
"declaration": {
|
||||||
|
"ads": "无",
|
||||||
|
"data": "插件不采集任何数据",
|
||||||
|
"permissions": "无"
|
||||||
|
},
|
||||||
|
"npmurl": ""
|
||||||
|
},
|
||||||
|
"uni_modules": {
|
||||||
|
"dependencies": [],
|
||||||
|
"encrypt": [],
|
||||||
|
"platforms": {
|
||||||
|
"cloud": {
|
||||||
|
"tcb": "y",
|
||||||
|
"aliyun": "y"
|
||||||
|
},
|
||||||
|
"client": {
|
||||||
|
"Vue": {
|
||||||
|
"vue2": "y",
|
||||||
|
"vue3": "y"
|
||||||
|
},
|
||||||
|
"App": {
|
||||||
|
"app-vue": "y",
|
||||||
|
"app-nvue": "u"
|
||||||
|
},
|
||||||
|
"H5-mobile": {
|
||||||
|
"Safari": "y",
|
||||||
|
"Android Browser": "y",
|
||||||
|
"微信浏览器(Android)": "y",
|
||||||
|
"QQ浏览器(Android)": "y"
|
||||||
|
},
|
||||||
|
"H5-pc": {
|
||||||
|
"Chrome": "u",
|
||||||
|
"IE": "u",
|
||||||
|
"Edge": "u",
|
||||||
|
"Firefox": "u",
|
||||||
|
"Safari": "u"
|
||||||
|
},
|
||||||
|
"小程序": {
|
||||||
|
"微信": {
|
||||||
|
"minVersion": "2.9.0"
|
||||||
|
},
|
||||||
|
"阿里": "n",
|
||||||
|
"百度": "n",
|
||||||
|
"字节跳动": "n",
|
||||||
|
"QQ": "u"
|
||||||
|
},
|
||||||
|
"快应用": {
|
||||||
|
"华为": "u",
|
||||||
|
"联盟": "u"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
# ksp-cropper
|
||||||
|
|
||||||
|
## 高性能图片裁剪工具
|
||||||
|
|
||||||
|
### 属性说明
|
||||||
|
|属性 |类型 |默认 |备注 |
|
||||||
|
| :--------: | :-----: | :----: | :----: |
|
||||||
|
| url |String | "" | 需要裁剪的图片路径,为空时控件隐藏,不为空时控件显示|
|
||||||
|
| mode |String | "free" | 裁剪模式|
|
||||||
|
| width |Number | 200 | 图片裁剪后的宽度,固定大小时有效|
|
||||||
|
| height |Number | 200 | 图片裁剪后的高度,固定大小时有效|
|
||||||
|
| maxWidth |Number | 1024 | 图片裁剪后的最大宽度 |
|
||||||
|
| maxHeight |Number | 1024 | 图片裁剪后的最大高度 |
|
||||||
|
|
||||||
|
### mode有效值
|
||||||
|
|
||||||
|
| 模式 |值 |说明 |
|
||||||
|
| :-----: | :-----: | :----: |
|
||||||
|
| 固定模式 |fixed | 裁剪出指定大小的图片,一般用于头像上传 |
|
||||||
|
| 等比缩放 |ratio | 限定宽高比,裁剪大小不固定 |
|
||||||
|
| 自由模式 |free | 不限定宽高比,裁剪大小不固定 |
|
||||||
|
|
||||||
|
### 事件说明
|
||||||
|
|事件名称 |说明 |返回 |
|
||||||
|
| :--------: | :-----: | :----: |
|
||||||
|
| ok |点击确定按钮 | e:{path} |
|
||||||
|
| cancel |点击取消按钮 | - |
|
||||||
|
|
||||||
|
|
||||||
|
### 示例
|
||||||
|
|
||||||
|
```html
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<view>
|
||||||
|
<button @click="select">选择图片</button>
|
||||||
|
<image mode="widthFix" :src="path"/>
|
||||||
|
<ksp-cropper mode="free" :width="200" :height="140" :maxWidth="1024" :maxHeight="1024" :url="url" @cancel="oncancel" @ok="onok"></ksp-cropper>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
url: "",
|
||||||
|
path: ""
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
select() {
|
||||||
|
uni.chooseImage({
|
||||||
|
count: 1,
|
||||||
|
success: (rst) => {
|
||||||
|
// 设置url的值,显示控件
|
||||||
|
this.url = rst.tempFilePaths[0];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onok(ev) {
|
||||||
|
this.url = "";
|
||||||
|
this.path = ev.path;
|
||||||
|
},
|
||||||
|
oncancel() {
|
||||||
|
// url设置为空,隐藏控件
|
||||||
|
this.url = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
```
|
||||||
Loading…
Reference in New Issue