689 lines
19 KiB
Vue
689 lines
19 KiB
Vue
<template>
|
||
<view class="_vphoto" :class="{left}">
|
||
<input type="hidden" :maxlength="-1" :name="name" :value="tvalue.value" style="display:none;" />
|
||
<view class="_btn" :class="{_disabled:disabled}" @tap="photo_select" v-if="tvalue.imgs.length < num">
|
||
<view class="_icon _photo"></view>
|
||
</view>
|
||
<ciy-gesture class="_pimg" v-for="(item,index) in tvalue.imgs" :key="index" :style="{'display':'block','width':showwh}" @toleft="toleft(index)" @toright="toright(index)">
|
||
<view class="_del" :data-idx="index" @tap="photo_delone"></view>
|
||
<image v-if="isimg(item)" :src="file_stor(item, '?50')" @tap="preview(index)" mode="widthFix" style="display:block;"></image>
|
||
<video v-else-if="isvideo(item)" :id="'video' + index" :src="file_stor(item)" controls @tap="fullvideo('video' + index)" :show-fullscreen-btn="false" :style="{width:showwh,height:showwh}"></video>
|
||
<view v-else class="_file">{{file_ext(item)}}</view>
|
||
</ciy-gesture>
|
||
<view class="_tip">{{tip}}</view>
|
||
<canvas type="2d" id="canvas" :style="{'width':cvwidth+'px','height':cvheight+'px','top':-cvheight+'px'}" style="position:fixed;z-index:-999;left:100vw;"></canvas>
|
||
</view>
|
||
<view v-if="showrecam" :style="{top:header_height+'px'}" style="z-index:50005;position: fixed;left:0;right:0;bottom:0;background:linear-gradient(327deg,var(--bg1),var(--man3))">
|
||
<image v-if="cammaskpng" :src="file_stor(cammaskpng)" class="abs t0 l0" :style="{pointerEvents: 'none',zIndex:50006,opacity:0.8,width: '100%', height: cameraheight + 'vw'}"></image>
|
||
<camera style="border: 1px solid #cccccc;" device-position="back" flash="off" :style="{width: '100%', height: cameraheight + 'vw'}"></camera>
|
||
<view>
|
||
|
||
</view>
|
||
<view style="opacity: 0.7;position: absolute;bottom:8em;left:0;right:0;text-align:center;">
|
||
<button class="btn lg cc" @tap="recamphoto" style="margin-top:0.5em;">拍照</button>
|
||
</view>
|
||
<view style="position: absolute;bottom:1em;left:0;right:0;">
|
||
<view v-if="!camheight">
|
||
<view style="position: absolute;bottom:0.5em;right:0.8em;">
|
||
<ciy-select :rows="2" itemalign="center" :minselectsearch="20" :range="recamrange" v-model="cameraheight" @change="setcamheight"></ciy-select>
|
||
</view>
|
||
<view style="position: absolute;bottom:0.2em;left:0.5em;">
|
||
<button class="btn def" @tap="setcamaddheight(2)">↓</button>
|
||
<button class="btn def" @tap="setcamaddheight(-2)">↑</button>
|
||
<button class="btn smm def" @tap="setcamswapheight()" style="padding:0.8em 1em;">转向</button>
|
||
</view>
|
||
</view>
|
||
<view class="px3 flex flex-center" style="gap:0.2em;" v-if="recamimgs.length > 0">
|
||
<image v-for="img in recamimgs.slice(-6)" :src="img" style="height:3em;width:3em;border:1px solid var(--bg9);border-radius: 5px;"></image>
|
||
<view class="flex1 px2" style="font-size:1.5em;">x{{recamimgs.length}}</view>
|
||
</view>
|
||
<view style="text-align: center;">
|
||
<button class="btn cc" @tap="closerecam" style="margin-top:0.5em;">完成</button>
|
||
<!-- <view @tap="showrecam=false" style="display:inline-block;background: var(--man6);color: #ffffff;width: 1.5em;height: 1.5em;line-height:1.5em;border-radius: 50%;text-align: center;font-size: 2em;">✔</view> -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
export default {
|
||
behaviors: ['uni://form-field-group'],
|
||
emits: ['change', 'update:modelValue'],
|
||
props: {
|
||
name: {
|
||
type: String
|
||
},
|
||
modelValue: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
value: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
disabled: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
initevent: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
left: {
|
||
type: Boolean,
|
||
default: false
|
||
},
|
||
action: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
sourcetype: {
|
||
type: String,
|
||
default: 'camera,album,message' //rehcam
|
||
},
|
||
camheight: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
cammaskpng: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
filetype: {
|
||
type: String,
|
||
default: 'image' //all image video
|
||
},
|
||
ext: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
num: {
|
||
type: [String, Number],
|
||
default: 1
|
||
},
|
||
stor: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
imgwidth: {
|
||
type: [String, Number],
|
||
default: 0
|
||
},
|
||
imgheight: {
|
||
type: [String, Number],
|
||
default: 0
|
||
},
|
||
maxkb: {
|
||
type: [String, Number],
|
||
default: 0
|
||
},
|
||
zipjpg: {
|
||
type: [String, Number],
|
||
default: 70
|
||
},
|
||
waterfont: {
|
||
type: String,
|
||
default: '28px Arial'
|
||
},
|
||
watertext: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
watertype: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
watercolors: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
wateralpha: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
waterpadding: {
|
||
type: String,
|
||
default: '30'
|
||
},
|
||
waterangle: {
|
||
type: String,
|
||
default: '-20'
|
||
},
|
||
showwh: {
|
||
type: String,
|
||
default: '4em'
|
||
},
|
||
path: {
|
||
type: String,
|
||
default: 'nopath'
|
||
},
|
||
saas: {
|
||
type: String,
|
||
default: ''
|
||
},
|
||
},
|
||
data() {
|
||
return {
|
||
tip: '',
|
||
updatevalue: false,
|
||
val: '',
|
||
showrecam: false,
|
||
header_height: 0,
|
||
cameraheight: '141.4',
|
||
recamrange: [],
|
||
recamimgs: [],
|
||
cvwidth: 0,
|
||
cvheight: 0
|
||
};
|
||
},
|
||
watch: {
|
||
value: {
|
||
async handler(newD, oldD) {
|
||
this.val = newD;
|
||
},
|
||
immediate: true
|
||
},
|
||
modelValue: {
|
||
async handler(newD, oldD) {
|
||
if (this.updatevalue) {
|
||
this.updatevalue = false;
|
||
return;
|
||
}
|
||
this.val = newD;
|
||
},
|
||
immediate: true
|
||
},
|
||
camheight: {
|
||
async handler(newD, oldD) {
|
||
var val = 0;
|
||
if (newD)
|
||
val = this.tofloat(newD);
|
||
else {
|
||
var dh = this.getstorage('_cameraheight_' + this.name);
|
||
if (dh)
|
||
val = this.tofloat(dh);
|
||
}
|
||
if (val < 10 || val > 200)
|
||
return;
|
||
this.cameraheight = val + '';
|
||
},
|
||
immediate: true
|
||
},
|
||
camrefheight: {
|
||
async handler(newD, oldD) {
|
||
if (newD) {
|
||
var url = this.file_stor(newD);
|
||
url = url.replace('http://', 'https://');
|
||
uni.getImageInfo({
|
||
src: url,
|
||
success: res => {
|
||
this.cameraheight = this.toint(res.height * 100 / res.width) + '';
|
||
}
|
||
});
|
||
}
|
||
},
|
||
immediate: true
|
||
},
|
||
},
|
||
computed: {
|
||
tvalue() {
|
||
// 修复:若 this.val 是 null/undefined,默认赋值为空字符串
|
||
var v = this.val || '';
|
||
var ret = {};
|
||
ret.value = v;
|
||
var pimgs = v.split('~'); // 此时v不会是null,split可安全调用
|
||
ret.imgs = [];
|
||
for (var i in pimgs) {
|
||
if (!pimgs[i])
|
||
continue;
|
||
ret.imgs.push(pimgs[i]);
|
||
}
|
||
return ret;
|
||
}
|
||
},
|
||
mounted() {
|
||
var app = getApp();
|
||
this.header_height = app.globalData._header_statusbar_height;
|
||
this.recamrange.push({
|
||
id: '100',
|
||
name: '1:1'
|
||
});
|
||
this.recamrange.push({
|
||
id: '63',
|
||
name: '名片'
|
||
});
|
||
this.recamrange.push({
|
||
id: '75',
|
||
name: '4:3'
|
||
});
|
||
this.recamrange.push({
|
||
id: '134',
|
||
name: '3:4'
|
||
});
|
||
this.recamrange.push({
|
||
id: '56',
|
||
name: '16:9'
|
||
});
|
||
this.recamrange.push({
|
||
id: '179',
|
||
name: '9:16'
|
||
});
|
||
this.recamrange.push({
|
||
id: '162',
|
||
name: '黄金 纵向'
|
||
});
|
||
this.recamrange.push({
|
||
id: '62',
|
||
name: '黄金 横向'
|
||
});
|
||
this.recamrange.push({
|
||
id: '141',
|
||
name: 'A4 纵向'
|
||
});
|
||
this.recamrange.push({
|
||
id: '71',
|
||
name: 'A4 横向'
|
||
});
|
||
if (this.initevent) {
|
||
this.$emit('change', {
|
||
name: this.name,
|
||
from: 'init',
|
||
value: this.tvalue.value
|
||
});
|
||
}
|
||
},
|
||
methods: {
|
||
toleft(idx) {
|
||
if (idx == 0)
|
||
return;
|
||
var imgs = [...this.tvalue.imgs];
|
||
var swap = imgs[idx];
|
||
imgs[idx] = imgs[idx - 1];
|
||
imgs[idx - 1] = swap;
|
||
this.val = imgs.join('~');
|
||
this.updatevalue = true;
|
||
this.$emit('update:modelValue', this.val);
|
||
this.$emit('change', {
|
||
name: this.name,
|
||
from: 'toleft',
|
||
value: this.val
|
||
});
|
||
},
|
||
toright(idx) {
|
||
if (this.tvalue.imgs.length == idx + 1)
|
||
return;
|
||
var imgs = [...this.tvalue.imgs];
|
||
var swap = imgs[idx];
|
||
imgs[idx] = imgs[idx + 1];
|
||
imgs[idx + 1] = swap;
|
||
this.val = imgs.join('~');
|
||
this.updatevalue = true;
|
||
this.$emit('update:modelValue', this.val);
|
||
this.$emit('change', {
|
||
name: this.name,
|
||
from: 'toright',
|
||
value: this.val
|
||
});
|
||
},
|
||
preview(idx) {
|
||
var imgs = [...this.tvalue.imgs];
|
||
for (var i in imgs) {
|
||
imgs[i] = this.file_stor(imgs[i]);
|
||
}
|
||
uni.previewImage({
|
||
current: idx,
|
||
indicator: 'default',
|
||
urls: imgs
|
||
});
|
||
},
|
||
fullvideo(id) {
|
||
const videoContext = uni.createVideoContext(id, this);
|
||
videoContext.requestFullScreen({
|
||
direction: 0
|
||
})
|
||
},
|
||
async photo_select(b) {
|
||
if (this.disabled)
|
||
return;
|
||
if (this.tip)
|
||
return this.toast(this.lang('upload.uploadingmsg'));
|
||
|
||
var items = [];
|
||
var sourcetypes = this.sourcetype.split(',');
|
||
if (sourcetypes.includes('rehcam')) {
|
||
items.push({
|
||
act: 'rehcam',
|
||
name: this.lang('upload.menu_rehcam')
|
||
});
|
||
}
|
||
if (sourcetypes.includes('camera')) {
|
||
items.push({
|
||
act: 'camera',
|
||
name: this.lang('upload.menu_camera')
|
||
});
|
||
}
|
||
if (sourcetypes.includes('album')) {
|
||
items.push({
|
||
act: 'album',
|
||
name: this.lang('upload.menu_album')
|
||
});
|
||
}
|
||
if (sourcetypes.includes('message')) {
|
||
items.push({
|
||
act: 'message',
|
||
name: this.lang('upload.menu_message')
|
||
});
|
||
}
|
||
var item = await this.popmenu({
|
||
items,
|
||
one: true
|
||
});
|
||
if (item.act == 'rehcam')
|
||
this.vrehcam();
|
||
if (item.act == 'camera')
|
||
this.vcamera();
|
||
if (item.act == 'album')
|
||
this.valbum();
|
||
if (item.act == 'message')
|
||
this.vmessage();
|
||
},
|
||
photo_delone(b) {
|
||
if (this.disabled)
|
||
return;
|
||
if (this.tip)
|
||
return this.toast(this.lang('upload.uploading'));
|
||
var imgs = [...this.tvalue.imgs];
|
||
imgs.splice(b.currentTarget.dataset.idx, 1);
|
||
this.val = imgs.join('~');
|
||
this.updatevalue = true;
|
||
this.$emit('update:modelValue', this.val);
|
||
this.$emit('change', {
|
||
name: this.name,
|
||
from: 'del',
|
||
value: this.val
|
||
});
|
||
},
|
||
addfile(url, from) {
|
||
var imgs = [...this.tvalue.imgs, url];
|
||
this.val = imgs.join('~');
|
||
if (!from)
|
||
return;
|
||
this.updatevalue = true;
|
||
this.$emit('update:modelValue', this.val);
|
||
this.$emit('change', {
|
||
name: this.name,
|
||
from: from,
|
||
value: this.val
|
||
});
|
||
if (from == 'rehcam') {
|
||
if (this.tvalue.imgs.length < this.num) {
|
||
this.vrehcam();
|
||
}
|
||
}
|
||
},
|
||
setcamheight(e) {
|
||
this.cameraheight = e.value.id;
|
||
this.setstorage('_cameraheight_' + this.name, this.cameraheight);
|
||
},
|
||
setcamaddheight(hei) {
|
||
var h = this.tofloat(this.cameraheight) + hei;
|
||
if (h < 10)
|
||
return;
|
||
this.cameraheight = h + '';
|
||
this.setstorage('_cameraheight_' + this.name, this.cameraheight);
|
||
},
|
||
setcamswapheight(hei) {
|
||
var h = this.tofloat(this.cameraheight);
|
||
this.cameraheight = Math.ceil(10000 / h) + '';
|
||
this.setstorage('_cameraheight_' + this.name, this.cameraheight);
|
||
},
|
||
recamphoto() {
|
||
const ctx = wx.createCameraContext();
|
||
ctx.takePhoto({
|
||
quality: 'high',
|
||
success: async (res) => {
|
||
this.showrecam = false;
|
||
this.recamimgs.push(res.tempImagePath);
|
||
this.upfiles([res], 'rehcam');
|
||
}
|
||
});
|
||
},
|
||
closerecam() {
|
||
this.showrecam = false;
|
||
this.recamimgs = [];
|
||
},
|
||
async vrehcam(b) {
|
||
this.showrecam = true;
|
||
},
|
||
async vcamera(b) {
|
||
if (!uni.chooseMedia) {
|
||
return this.vh5();
|
||
}
|
||
var count = this.toint(this.num) - this.tvalue.imgs.length;
|
||
if (count <= 0)
|
||
return this.toast(this.lang('upload.maxmsg').replace('{n}', this.num));
|
||
var opt = {};
|
||
opt.count = 1;
|
||
if (this.filetype == 'all') {
|
||
opt.mediaType = ['mix'];
|
||
}
|
||
if (this.filetype == 'image') {
|
||
opt.mediaType = ['image'];
|
||
}
|
||
if (this.filetype == 'video') {
|
||
opt.mediaType = ['video'];
|
||
}
|
||
opt.sizeType = ['original', 'compressed'];
|
||
opt.sourceType = ['camera'];
|
||
opt.maxDuration = 60;
|
||
var [err, retchoose] = await this.go(uni.chooseMedia(opt));
|
||
if (err)
|
||
return console.warn('chooseMedia', err);
|
||
this.upfiles(retchoose.tempFiles, 'camera');
|
||
},
|
||
async valbum(b) {
|
||
if (!uni.chooseMedia) {
|
||
return this.vh5();
|
||
}
|
||
var count = this.toint(this.num) - this.tvalue.imgs.length;
|
||
if (count <= 0)
|
||
return this.toast(this.lang('upload.maxmsg').replace('{n}', this.num));
|
||
var opt = {};
|
||
opt.count = count;
|
||
if (this.filetype == 'all') {
|
||
opt.mediaType = ['mix'];
|
||
}
|
||
if (this.filetype == 'image') {
|
||
opt.mediaType = ['image'];
|
||
}
|
||
if (this.filetype == 'video') {
|
||
opt.mediaType = ['video'];
|
||
}
|
||
opt.sizeType = ['original', 'compressed'];
|
||
opt.sourceType = ['album'];
|
||
var [err, retchoose] = await this.go(uni.chooseMedia(opt));
|
||
if (err)
|
||
return console.warn('chooseMedia', err);
|
||
this.upfiles(retchoose.tempFiles, 'album');
|
||
},
|
||
async vmessage(b) {
|
||
if (!uni.chooseMessageFile) {
|
||
return this.vh5();
|
||
}
|
||
var count = this.toint(this.num) - this.tvalue.imgs.length;
|
||
if (count <= 0)
|
||
return this.toast(this.lang('upload.maxmsg').replace('{n}', this.num));
|
||
var opt = {};
|
||
opt.count = count;
|
||
if (this.filetype == 'all') {
|
||
if (this.ext) {
|
||
opt.type = 'file';
|
||
opt.extension = this.ext.split(',');
|
||
} else {
|
||
opt.type = 'all';
|
||
}
|
||
}
|
||
if (this.filetype == 'image') {
|
||
opt.type = 'image';
|
||
}
|
||
if (this.filetype == 'video') {
|
||
opt.type = 'video';
|
||
}
|
||
var [err, retchoose] = await this.go(uni.chooseMessageFile(opt));
|
||
if (err)
|
||
return console.warn('chooseMessageFile', err);
|
||
this.upfiles(retchoose.tempFiles, 'message');
|
||
},
|
||
async vh5(b) {
|
||
var count = this.toint(this.num) - this.tvalue.imgs.length;
|
||
if (count <= 0)
|
||
return this.toast(this.lang('upload.maxmsg').replace('{n}', this.num));
|
||
var opt = {};
|
||
opt.count = count;
|
||
opt.sizeType = ['original', 'compressed'];
|
||
opt.sourceType = ['camera', 'album'];
|
||
var [err, retchoose] = await this.go(uni.chooseImage(opt));
|
||
if (err)
|
||
return console.warn('chooseImage', err);
|
||
await this.upfiles(retchoose.tempFiles, 'h5');
|
||
},
|
||
async upfiles(temps, from) {
|
||
var thos = this;
|
||
var app = getApp();
|
||
this.upcount = temps.length;
|
||
this.tip = this.lang('upload.tip') + ' 0/' + this.upcount;
|
||
this.upidx = 0;
|
||
var opn = {};
|
||
//opn.canvasid = 'canvas';
|
||
opn.post = {
|
||
from: from
|
||
};
|
||
opn.basepath = this.path;
|
||
opn.saas = this.saas;
|
||
if(this.stor)
|
||
opn.stor = this.stor;
|
||
else
|
||
opn.stor = app.globalData.storselect;
|
||
opn.action = this.action;
|
||
opn.maxkb = this.toint(this.maxkb);
|
||
opn.imgwidth = this.toint(this.imgwidth);
|
||
opn.imgheight = this.toint(this.imgheight);
|
||
opn.zipjpg = this.toint(this.zipjpg);
|
||
opn.watertext = this.watertext;
|
||
opn.watertype = this.watertype;
|
||
opn.waterpadding = this.toint(this.waterpadding);
|
||
opn.waterangle = this.toint(this.waterangle);
|
||
opn.wateralpha = this.tofloat(this.wateralpha);
|
||
if (opn.wateralpha <= 0) {
|
||
if (this.watertype == 'full')
|
||
opn.wateralpha = 0.1;
|
||
else
|
||
opn.wateralpha = 1;
|
||
}
|
||
if (this.watercolors)
|
||
opn.watercolors = this.watercolors.split(',');
|
||
await this.file_uploads(temps, opn, {
|
||
success(url, file) {
|
||
thos.upidx++;
|
||
thos.tip = thos.lang('upload.tip') + ' ' + thos.upidx + '/' + thos.upcount;
|
||
if (thos.upidx == thos.upcount) {
|
||
thos.tip = '';
|
||
thos.addfile(url, from);
|
||
} else {
|
||
thos.addfile(url);
|
||
}
|
||
},
|
||
fail(err, gf, al) {
|
||
console.warn(err, gf, al);
|
||
thos.upidx++;
|
||
thos.tip = '';
|
||
return thos.alert('Upload Fail:' + err);
|
||
}
|
||
});
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
._vphoto ._photo {
|
||
background-image: url("data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PScwIDAgMTAyNCAxMDI0JyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zycgd2lkdGg9JzIwMCcgaGVpZ2h0PScyMDAnPjxwYXRoIGQ9J00xMjUuOTUyIDIzNC40OTZoMTY2LjkxMmMyMS41MDQgMCAyOS42OTYtNDguMTI4IDU0LjI3Mi03MS42OCA3LjE2OC03LjE2OCAyOC42NzItMTIuMjg4IDM2Ljg2NC0xMi4yODhoMjc4LjUyOGM4LjE5MiAwIDI5LjY5NiAxMS4yNjQgMzYuODY0IDI1LjYgMTMuMzEyIDI0LjU3NiAxMi4yODggNTguMzY4IDI1LjYgNTguMzY4aDE4MS4yNDhjNDYuMDggMCA4My45NjggMzcuODg4IDgzLjk2OCA4My45Njh2NDc0LjExMmMwIDQ2LjA4LTM3Ljg4OCA4My45NjgtODMuOTY4IDgzLjk2OEgxMjUuOTUyYy00Ni4wOCAwLTgzLjk2OC0zNy44ODgtODMuOTY4LTgzLjk2OFYzMTcuNDRjMS4wMjQtNDYuMDggMzcuODg4LTgyLjk0NCA4My45NjgtODIuOTQ0eicgZmlsbD0nIzNFQkRGRic+PC9wYXRoPjxwYXRoIGQ9J002MzQuODggMjc1LjQ1NmgxNC4zMzZjMTEuMjY0IDAgMjAuNDggOS4yMTYgMjAuNDggMjAuNDhzLTkuMjE2IDIwLjQ4LTIwLjQ4IDIwLjQ4SDYzNC44OGMtMTEuMjY0IDAtMjAuNDgtOS4yMTYtMjAuNDgtMjAuNDggMC0xMC4yNCA5LjIxNi0yMC40OCAyMC40OC0yMC40OHpNNzMyLjE2IDI3NS40NTZoMTY2LjkxMmMxMS4yNjQgMCAyMC40OCA5LjIxNiAyMC40OCAyMC40OHMtOS4yMTYgMjAuNDgtMjAuNDggMjAuNDhINzMyLjE2Yy0xMS4yNjQgMC0yMC40OC05LjIxNi0yMC40OC0yMC40OCAwLTEwLjI0IDkuMjE2LTIwLjQ4IDIwLjQ4LTIwLjQ4eicgZmlsbD0nI0ZGRkZGRic+PC9wYXRoPjxwYXRoIGQ9J001MzAuNDMyIDM1OS40MjRjMTIyLjg4IDAgMjIzLjIzMiA5OS4zMjggMjIzLjIzMiAyMjMuMjMyIDAgMTIyLjg4LTk5LjMyOCAyMjMuMjMyLTIyMy4yMzIgMjIzLjIzMi0xMjIuODggMC0yMjMuMjMyLTk5LjMyOC0yMjMuMjMyLTIyMy4yMzIgMC0xMjIuODggMTAwLjM1Mi0yMjMuMjMyIDIyMy4yMzItMjIzLjIzMnonIGZpbGw9JyNBMkRFRkQnPjwvcGF0aD48L3N2Zz4=");
|
||
}
|
||
|
||
._vphoto {
|
||
margin: 0.5em auto 0 auto;
|
||
padding: 0;
|
||
display: flex;
|
||
flex-wrap: wrap;
|
||
align-items: flex-start;
|
||
justify-content: flex-end;
|
||
position: relative;
|
||
}
|
||
|
||
._vphoto.left {
|
||
justify-content: flex-start;
|
||
}
|
||
|
||
._vphoto ._tip {
|
||
position: absolute;
|
||
top: 0.1em;
|
||
left: 0.2em;
|
||
line-height: 1em;
|
||
font-size: 0.7em;
|
||
color: #999999;
|
||
}
|
||
|
||
._vphoto>._btn {
|
||
padding: 0.5em;
|
||
width: 3em;
|
||
height: 3em;
|
||
margin: 0 0.5em 0.5em 0;
|
||
border: 1px solid #cccccc;
|
||
display: inline-block;
|
||
border-radius: 0.3em;
|
||
background: #ffffff;
|
||
}
|
||
|
||
._vphoto>._btn._disabled {
|
||
background: #ebebeb;
|
||
filter: grayscale(0.8);
|
||
}
|
||
|
||
._vphoto ._icon {
|
||
width: 100%;
|
||
height: 100%;
|
||
margin: 0 auto;
|
||
background-size: cover;
|
||
}
|
||
|
||
._vphoto ._pimg {
|
||
margin: 0 0.5em 0.5em 0;
|
||
background: #ffffff;
|
||
position: relative;
|
||
border: 1px solid #ffffff;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
}
|
||
|
||
._vphoto ._pimg ._file {
|
||
margin: 1.2em 0;
|
||
text-align: center;
|
||
}
|
||
|
||
._vphoto ._pimg image {
|
||
width: 100%;
|
||
height: 100%;
|
||
border-radius: 0.3em;
|
||
}
|
||
|
||
._vphoto ._pimg ._del {
|
||
background-image: url("data:image/svg+xml;charset=utf-8;base64,PHN2ZyB2aWV3Qm94PScwIDAgMTAyNCAxMDI0JyB2ZXJzaW9uPScxLjEnIHhtbG5zPSdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc+PHBhdGggZD0nTTUxMiAzMC4xMTc2NDdhNDgxLjg4MjM1MyA0ODEuODgyMzUzIDAgMSAwIDQ4MS44ODIzNTMgNDgxLjg4MjM1MyA0ODEuODgyMzUzIDQ4MS44ODIzNTMgMCAwIDAtNDgxLjg4MjM1My00ODEuODgyMzUzeicgZmlsbD0nI0ZENDgzNyc+PC9wYXRoPjxwYXRoIGQ9J003MDUuMTc0NTg4IDY1Ny43MDkxNzZhMzMuOTcyNzA2IDMzLjk3MjcwNiAwIDEgMS00OC4xODgyMzUgNDcuODI2ODI0TDUxMiA1NjAuMDA3NTI5bC0xNDUuMjI3Mjk0IDE0NS44ODk4ODNhMzMuOTcyNzA2IDMzLjk3MjcwNiAwIDEgMS00OC4xODgyMzUtNDcuODI2ODI0bDE0NS40MDgtMTQ1Ljc2OTQxMkwzMTguNzY1MTc2IDM2Ni4yMzA1ODhhMzMuOTcyNzA2IDMzLjk3MjcwNiAwIDAgMSA0OC4xODgyMzYtNDcuODI2ODIzTDUxMiA0NjMuOTkyNDcxbDE0NS4yMjcyOTQtMTQ1LjcwOTE3N2EzMy45NzI3MDYgMzMuOTcyNzA2IDAgMSAxIDQ4LjE4ODIzNSA0Ny44MjY4MjRMNTU5Ljc2NjU4OCA1MTJ6JyBmaWxsPScjRkZGRkZGJz48L3BhdGg+PC9zdmc+");
|
||
width: 1.2em;
|
||
height: 1.2em;
|
||
position: absolute;
|
||
top: -0.3em;
|
||
right: -0.3em;
|
||
z-index: 10;
|
||
}
|
||
</style> |