2024-08-20 12:11:31 +00:00
|
|
|
|
<template>
|
|
|
|
|
<div class="vue-image-crop-upload" v-show="value">
|
|
|
|
|
<div class="vicp-wrap">
|
|
|
|
|
<div class="vicp-close" @click="off">
|
|
|
|
|
<i class="vicp-icon4"></i>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="vicp-step1" v-show="step == 1">
|
|
|
|
|
<div class="vicp-drop-area" @dragleave="preventDefault" @dragover="preventDefault" @dragenter="preventDefault" @click="handleClick" @drop="handleChange">
|
|
|
|
|
<i class="vicp-icon1" v-show="loading != 1">
|
|
|
|
|
<i class="vicp-icon1-arrow"></i>
|
|
|
|
|
<i class="vicp-icon1-body"></i>
|
|
|
|
|
<i class="vicp-icon1-bottom"></i>
|
|
|
|
|
</i>
|
|
|
|
|
<span class="vicp-hint" v-show="loading !== 1">{{ lang.hint }}</span>
|
|
|
|
|
<span class="vicp-no-supported-hint" v-show="!isSupported">{{ lang.noSupported }}</span>
|
2024-08-21 01:17:14 +00:00
|
|
|
|
<input type="file" v-show="false" v-if="step == 1" @change="handleChange" ref="fileinput" />
|
2024-08-20 12:11:31 +00:00
|
|
|
|
</div>
|
2024-08-21 01:17:14 +00:00
|
|
|
|
<div class="vicp-error" v-show="hasError"><i class="vicp-icon2"></i> {{ errorMsg }}</div>
|
2024-08-20 12:11:31 +00:00
|
|
|
|
<div class="vicp-operate">
|
|
|
|
|
<a @click="off" @mousedown="ripple">{{ lang.btn.off }}</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="vicp-step2" v-if="step == 2">
|
|
|
|
|
<div class="vicp-crop">
|
|
|
|
|
<div class="vicp-crop-left" v-show="true">
|
|
|
|
|
<div class="vicp-img-container">
|
2024-08-21 01:17:14 +00:00
|
|
|
|
<img
|
|
|
|
|
:src="sourceImgUrl"
|
|
|
|
|
:style="sourceImgStyle"
|
|
|
|
|
class="vicp-img"
|
|
|
|
|
draggable="false"
|
|
|
|
|
@drag="preventDefault"
|
|
|
|
|
@dragstart="preventDefault"
|
|
|
|
|
@dragend="preventDefault"
|
|
|
|
|
@dragleave="preventDefault"
|
|
|
|
|
@dragover="preventDefault"
|
|
|
|
|
@dragenter="preventDefault"
|
|
|
|
|
@drop="preventDefault"
|
|
|
|
|
@touchstart="imgStartMove"
|
|
|
|
|
@touchmove="imgMove"
|
|
|
|
|
@touchend="createImg"
|
|
|
|
|
@touchcancel="createImg"
|
|
|
|
|
@mousedown="imgStartMove"
|
|
|
|
|
@mousemove="imgMove"
|
|
|
|
|
@mouseup="createImg"
|
|
|
|
|
@mouseout="createImg"
|
|
|
|
|
ref="img"
|
|
|
|
|
/>
|
2024-08-20 12:11:31 +00:00
|
|
|
|
<div class="vicp-img-shade vicp-img-shade-1" :style="sourceImgShadeStyle"></div>
|
|
|
|
|
<div class="vicp-img-shade vicp-img-shade-2" :style="sourceImgShadeStyle"></div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="vicp-range">
|
2024-08-21 01:17:14 +00:00
|
|
|
|
<input type="range" :value="scale.range" step="1" min="0" max="100" @change="zoomChange" />
|
2024-08-20 12:11:31 +00:00
|
|
|
|
<i @mousedown="startZoomSub" @mouseout="endZoomSub" @mouseup="endZoomSub" class="vicp-icon5"></i>
|
|
|
|
|
<i @mousedown="startZoomAdd" @mouseout="endZoomAdd" @mouseup="endZoomAdd" class="vicp-icon6"></i>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="vicp-rotate" v-if="!noRotate">
|
|
|
|
|
<i @click="rotateImg">↻</i>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="vicp-crop-right" v-show="true">
|
|
|
|
|
<div class="vicp-preview">
|
|
|
|
|
<div class="vicp-preview-item" v-if="!noSquare">
|
2024-08-21 01:17:14 +00:00
|
|
|
|
<img :src="createImgUrl" :style="previewStyle" />
|
2024-08-20 12:11:31 +00:00
|
|
|
|
<span>{{ lang.preview }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="vicp-preview-item vicp-preview-item-circle" v-if="!noCircle">
|
2024-08-21 01:17:14 +00:00
|
|
|
|
<img :src="createImgUrl" :style="previewStyle" />
|
2024-08-20 12:11:31 +00:00
|
|
|
|
<span>{{ lang.preview }}</span>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<div class="vicp-operate">
|
|
|
|
|
<a @click="setStep(1)" @mousedown="ripple">{{ lang.btn.back }}</a>
|
|
|
|
|
<a class="vicp-operate-btn" @click="prepareUpload" @mousedown="ripple">{{ lang.btn.save }}</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
<div class="vicp-step3" v-if="step == 3">
|
|
|
|
|
<div class="vicp-upload">
|
|
|
|
|
<span class="vicp-loading" v-show="loading === 1">{{ lang.loading }}</span>
|
|
|
|
|
<div class="vicp-progress-wrap">
|
|
|
|
|
<span class="vicp-progress" v-show="loading === 1" :style="progressStyle"></span>
|
|
|
|
|
</div>
|
2024-08-21 01:17:14 +00:00
|
|
|
|
<div class="vicp-error" v-show="hasError"><i class="vicp-icon2"></i> {{ errorMsg }}</div>
|
|
|
|
|
<div class="vicp-success" v-show="loading === 2"><i class="vicp-icon3"></i> {{ lang.success }}</div>
|
2024-08-20 12:11:31 +00:00
|
|
|
|
</div>
|
|
|
|
|
<div class="vicp-operate">
|
|
|
|
|
<a @click="setStep(2)" @mousedown="ripple">{{ lang.btn.back }}</a>
|
|
|
|
|
<a @click="off" @mousedown="ripple">{{ lang.btn.close }}</a>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
<canvas v-show="false" :width="width" :height="height" ref="canvas"></canvas>
|
|
|
|
|
</div>
|
|
|
|
|
</div>
|
|
|
|
|
</template>
|
|
|
|
|
|
|
|
|
|
<script>
|
|
|
|
|
import language from './utils/language.js'
|
|
|
|
|
import mimes from './utils/mimes.js'
|
|
|
|
|
import data2blob from './utils/data2blob.js'
|
|
|
|
|
import effectRipple from './utils/effectRipple.js'
|
|
|
|
|
|
|
|
|
|
export default {
|
|
|
|
|
props: {
|
|
|
|
|
// 域,上传文件name,触发事件会带上(如果一个页面多个图片上传控件,可以做区分
|
|
|
|
|
field: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: 'avatar'
|
|
|
|
|
},
|
|
|
|
|
// 原名key,类似于id,触发事件会带上(如果一个页面多个图片上传控件,可以做区分
|
|
|
|
|
ki: {
|
|
|
|
|
default: 0
|
|
|
|
|
},
|
|
|
|
|
// 显示该控件与否
|
|
|
|
|
value: {
|
|
|
|
|
default: true
|
|
|
|
|
},
|
|
|
|
|
// 上传地址
|
|
|
|
|
url: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: ''
|
|
|
|
|
},
|
|
|
|
|
// 其他要上传文件附带的数据,对象格式
|
|
|
|
|
params: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: null
|
|
|
|
|
},
|
|
|
|
|
// Add custom headers
|
|
|
|
|
headers: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: null
|
|
|
|
|
},
|
|
|
|
|
// 剪裁图片的宽
|
|
|
|
|
width: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 200
|
|
|
|
|
},
|
|
|
|
|
// 剪裁图片的高
|
|
|
|
|
height: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 200
|
|
|
|
|
},
|
|
|
|
|
// 不显示旋转功能
|
|
|
|
|
noRotate: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: true
|
|
|
|
|
},
|
|
|
|
|
// 不预览圆形图片
|
|
|
|
|
noCircle: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false
|
|
|
|
|
},
|
|
|
|
|
// 不预览方形图片
|
|
|
|
|
noSquare: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false
|
|
|
|
|
},
|
|
|
|
|
// 单文件大小限制
|
|
|
|
|
maxSize: {
|
|
|
|
|
type: Number,
|
|
|
|
|
default: 10240
|
|
|
|
|
},
|
|
|
|
|
// 语言类型
|
|
|
|
|
langType: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: 'zh'
|
|
|
|
|
},
|
|
|
|
|
// 语言包
|
|
|
|
|
langExt: {
|
|
|
|
|
type: Object,
|
|
|
|
|
default: null
|
|
|
|
|
},
|
|
|
|
|
// 图片上传格式
|
|
|
|
|
imgFormat: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: 'png'
|
|
|
|
|
},
|
|
|
|
|
// 图片背景 jpg情况下生效
|
|
|
|
|
imgBgc: {
|
|
|
|
|
type: String,
|
|
|
|
|
default: '#fff'
|
|
|
|
|
},
|
|
|
|
|
// 是否支持跨域
|
|
|
|
|
withCredentials: {
|
|
|
|
|
type: Boolean,
|
|
|
|
|
default: false
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
data() {
|
|
|
|
|
const that = this,
|
|
|
|
|
{ imgFormat, langType, langExt, width, height } = that,
|
|
|
|
|
allowImgFormat = ['jpg', 'png'],
|
|
|
|
|
tempImgFormat = allowImgFormat.indexOf(imgFormat) === -1 ? 'jpg' : imgFormat,
|
|
|
|
|
lang = language[langType] ? language[langType] : language.en,
|
|
|
|
|
mime = mimes[tempImgFormat]
|
|
|
|
|
let isSupported = true
|
|
|
|
|
// 规范图片格式
|
|
|
|
|
that.imgFormat = tempImgFormat
|
|
|
|
|
|
|
|
|
|
if (langExt) {
|
|
|
|
|
Object.assign(lang, langExt)
|
|
|
|
|
}
|
|
|
|
|
if (typeof FormData != 'function') {
|
|
|
|
|
isSupported = false
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
// 图片的mime
|
|
|
|
|
mime,
|
|
|
|
|
|
|
|
|
|
// 语言包
|
|
|
|
|
lang,
|
|
|
|
|
|
|
|
|
|
// 浏览器是否支持该控件
|
|
|
|
|
isSupported,
|
|
|
|
|
// 浏览器是否支持触屏事件
|
|
|
|
|
// eslint-disable-next-line no-prototype-builtins
|
|
|
|
|
isSupportTouch: document.hasOwnProperty('ontouchstart'),
|
|
|
|
|
|
|
|
|
|
// 步骤
|
|
|
|
|
step: 1, // 1选择文件 2剪裁 3上传
|
|
|
|
|
|
|
|
|
|
// 上传状态及进度
|
|
|
|
|
loading: 0, // 0未开始 1正在 2成功 3错误
|
|
|
|
|
progress: 0,
|
|
|
|
|
|
|
|
|
|
// 是否有错误及错误信息
|
|
|
|
|
hasError: false,
|
|
|
|
|
errorMsg: '',
|
|
|
|
|
|
|
|
|
|
// 需求图宽高比
|
|
|
|
|
ratio: width / height,
|
|
|
|
|
|
|
|
|
|
// 原图地址、生成图片地址
|
|
|
|
|
sourceImg: null,
|
|
|
|
|
sourceImgUrl: '',
|
|
|
|
|
createImgUrl: '',
|
|
|
|
|
|
|
|
|
|
// 原图片拖动事件初始值
|
|
|
|
|
sourceImgMouseDown: {
|
|
|
|
|
on: false,
|
|
|
|
|
mX: 0, // 鼠标按下的坐标
|
|
|
|
|
mY: 0,
|
|
|
|
|
x: 0, // scale原图坐标
|
|
|
|
|
y: 0
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 生成图片预览的容器大小
|
|
|
|
|
previewContainer: {
|
|
|
|
|
width: 100,
|
|
|
|
|
height: 100
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 原图容器宽高
|
|
|
|
|
sourceImgContainer: {
|
|
|
|
|
// sic
|
|
|
|
|
width: 240,
|
|
|
|
|
height: 184 // 如果生成图比例与此一致会出现bug,先改成特殊的格式吧,哈哈哈
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 原图展示属性
|
|
|
|
|
scale: {
|
|
|
|
|
zoomAddOn: false, // 按钮缩放事件开启
|
|
|
|
|
zoomSubOn: false, // 按钮缩放事件开启
|
|
|
|
|
range: 1, // 最大100
|
|
|
|
|
|
|
|
|
|
x: 0,
|
|
|
|
|
y: 0,
|
|
|
|
|
width: 0,
|
|
|
|
|
height: 0,
|
|
|
|
|
maxWidth: 0,
|
|
|
|
|
maxHeight: 0,
|
|
|
|
|
minWidth: 0, // 最宽
|
|
|
|
|
minHeight: 0,
|
|
|
|
|
naturalWidth: 0, // 原宽
|
|
|
|
|
naturalHeight: 0
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
computed: {
|
|
|
|
|
// 进度条样式
|
|
|
|
|
progressStyle() {
|
|
|
|
|
const { progress } = this
|
|
|
|
|
return {
|
|
|
|
|
width: progress + '%'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 原图样式
|
|
|
|
|
sourceImgStyle() {
|
|
|
|
|
const { scale, sourceImgMasking } = this,
|
|
|
|
|
top = scale.y + sourceImgMasking.y + 'px',
|
|
|
|
|
left = scale.x + sourceImgMasking.x + 'px'
|
|
|
|
|
return {
|
|
|
|
|
top,
|
|
|
|
|
left,
|
|
|
|
|
width: scale.width + 'px',
|
|
|
|
|
height: scale.height + 'px' // 兼容 Opera
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 原图蒙版属性
|
|
|
|
|
sourceImgMasking() {
|
|
|
|
|
const { width, height, ratio, sourceImgContainer } = this,
|
|
|
|
|
sic = sourceImgContainer,
|
|
|
|
|
sicRatio = sic.width / sic.height // 原图容器宽高比
|
|
|
|
|
let x = 0,
|
|
|
|
|
y = 0,
|
|
|
|
|
w = sic.width,
|
|
|
|
|
h = sic.height,
|
|
|
|
|
scale = 1
|
|
|
|
|
if (ratio < sicRatio) {
|
|
|
|
|
scale = sic.height / height
|
|
|
|
|
w = sic.height * ratio
|
|
|
|
|
x = (sic.width - w) / 2
|
|
|
|
|
}
|
|
|
|
|
if (ratio > sicRatio) {
|
|
|
|
|
scale = sic.width / width
|
|
|
|
|
h = sic.width / ratio
|
|
|
|
|
y = (sic.height - h) / 2
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
scale, // 蒙版相对需求宽高的缩放
|
|
|
|
|
x,
|
|
|
|
|
y,
|
|
|
|
|
width: w,
|
|
|
|
|
height: h
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 原图遮罩样式
|
|
|
|
|
sourceImgShadeStyle() {
|
|
|
|
|
const { sourceImgMasking, sourceImgContainer } = this,
|
|
|
|
|
sic = sourceImgContainer,
|
|
|
|
|
sim = sourceImgMasking,
|
|
|
|
|
w = sim.width == sic.width ? sim.width : (sic.width - sim.width) / 2,
|
|
|
|
|
h = sim.height == sic.height ? sim.height : (sic.height - sim.height) / 2
|
|
|
|
|
return {
|
|
|
|
|
width: w + 'px',
|
|
|
|
|
height: h + 'px'
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
previewStyle() {
|
|
|
|
|
const { width, height, ratio, previewContainer } = this,
|
|
|
|
|
pc = previewContainer
|
|
|
|
|
let w = pc.width,
|
|
|
|
|
h = pc.height
|
|
|
|
|
const pcRatio = w / h
|
|
|
|
|
if (ratio < pcRatio) {
|
|
|
|
|
w = pc.height * ratio
|
|
|
|
|
}
|
|
|
|
|
if (ratio > pcRatio) {
|
|
|
|
|
h = pc.width / ratio
|
|
|
|
|
}
|
|
|
|
|
return {
|
|
|
|
|
width: w + 'px',
|
|
|
|
|
height: h + 'px'
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
watch: {
|
|
|
|
|
value(newValue) {
|
|
|
|
|
if (newValue && this.loading != 1) {
|
|
|
|
|
this.reset()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
methods: {
|
|
|
|
|
// 点击波纹效果
|
|
|
|
|
ripple(e) {
|
|
|
|
|
effectRipple(e)
|
|
|
|
|
},
|
|
|
|
|
// 关闭控件
|
|
|
|
|
off() {
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
this.$emit('input', false)
|
|
|
|
|
if (this.step == 3 && this.loading == 2) {
|
|
|
|
|
this.setStep(1)
|
|
|
|
|
}
|
|
|
|
|
}, 200)
|
|
|
|
|
},
|
|
|
|
|
// 设置步骤
|
|
|
|
|
setStep(no) {
|
|
|
|
|
// 延时是为了显示动画效果呢,哈哈哈
|
|
|
|
|
setTimeout(() => {
|
|
|
|
|
this.step = no
|
|
|
|
|
}, 200)
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
/* 图片选择区域函数绑定--------------------------------------------------------------- */
|
|
|
|
|
preventDefault(e) {
|
|
|
|
|
e.preventDefault()
|
|
|
|
|
return false
|
|
|
|
|
},
|
|
|
|
|
handleClick(e) {
|
|
|
|
|
if (this.loading !== 1) {
|
|
|
|
|
if (e.target !== this.$refs.fileinput) {
|
|
|
|
|
e.preventDefault()
|
|
|
|
|
if (document.activeElement !== this.$refs) {
|
|
|
|
|
this.$refs.fileinput.click()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
handleChange(e) {
|
|
|
|
|
e.preventDefault()
|
|
|
|
|
if (this.loading !== 1) {
|
|
|
|
|
const files = e.target.files || e.dataTransfer.files
|
|
|
|
|
this.reset()
|
|
|
|
|
if (this.checkFile(files[0])) {
|
|
|
|
|
this.setSourceImg(files[0])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
/* --------------------------------------------------------------- */
|
|
|
|
|
|
|
|
|
|
// 检测选择的文件是否合适
|
|
|
|
|
checkFile(file) {
|
|
|
|
|
const that = this,
|
|
|
|
|
{ lang, maxSize } = that
|
|
|
|
|
// 仅限图片
|
|
|
|
|
if (file.type.indexOf('image') === -1) {
|
|
|
|
|
that.hasError = true
|
|
|
|
|
that.errorMsg = lang.error.onlyImg
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 超出大小
|
|
|
|
|
if (file.size / 1024 > maxSize) {
|
|
|
|
|
that.hasError = true
|
|
|
|
|
that.errorMsg = lang.error.outOfSize + maxSize + 'kb'
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
return true
|
|
|
|
|
},
|
|
|
|
|
// 重置控件
|
|
|
|
|
reset() {
|
|
|
|
|
const that = this
|
|
|
|
|
that.loading = 0
|
|
|
|
|
that.hasError = false
|
|
|
|
|
that.errorMsg = ''
|
|
|
|
|
that.progress = 0
|
|
|
|
|
},
|
|
|
|
|
// 设置图片源
|
|
|
|
|
setSourceImg(file) {
|
|
|
|
|
const that = this,
|
|
|
|
|
fr = new FileReader()
|
|
|
|
|
fr.onload = function (e) {
|
|
|
|
|
that.sourceImgUrl = fr.result
|
|
|
|
|
that.startCrop()
|
|
|
|
|
}
|
|
|
|
|
fr.readAsDataURL(file)
|
|
|
|
|
},
|
|
|
|
|
// 剪裁前准备工作
|
|
|
|
|
startCrop() {
|
|
|
|
|
const that = this,
|
|
|
|
|
{ width, height, ratio, scale, sourceImgUrl, sourceImgMasking, lang } = that,
|
|
|
|
|
sim = sourceImgMasking,
|
|
|
|
|
img = new Image()
|
|
|
|
|
img.src = sourceImgUrl
|
|
|
|
|
img.onload = function () {
|
|
|
|
|
const nWidth = img.naturalWidth,
|
|
|
|
|
nHeight = img.naturalHeight,
|
|
|
|
|
nRatio = nWidth / nHeight
|
|
|
|
|
let w = sim.width,
|
|
|
|
|
h = sim.height,
|
|
|
|
|
x = 0,
|
|
|
|
|
y = 0
|
|
|
|
|
// 图片像素不达标
|
|
|
|
|
if (nWidth < width || nHeight < height) {
|
|
|
|
|
that.hasError = true
|
|
|
|
|
that.errorMsg = lang.error.lowestPx + width + '*' + height
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
if (ratio > nRatio) {
|
|
|
|
|
h = w / nRatio
|
|
|
|
|
y = (sim.height - h) / 2
|
|
|
|
|
}
|
|
|
|
|
if (ratio < nRatio) {
|
|
|
|
|
w = h * nRatio
|
|
|
|
|
x = (sim.width - w) / 2
|
|
|
|
|
}
|
|
|
|
|
scale.range = 0
|
|
|
|
|
scale.x = x
|
|
|
|
|
scale.y = y
|
|
|
|
|
scale.width = w
|
|
|
|
|
scale.height = h
|
|
|
|
|
scale.minWidth = w
|
|
|
|
|
scale.minHeight = h
|
|
|
|
|
scale.maxWidth = nWidth * sim.scale
|
|
|
|
|
scale.maxHeight = nHeight * sim.scale
|
|
|
|
|
scale.naturalWidth = nWidth
|
|
|
|
|
scale.naturalHeight = nHeight
|
|
|
|
|
that.sourceImg = img
|
|
|
|
|
that.createImg()
|
|
|
|
|
that.setStep(2)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 鼠标按下图片准备移动
|
|
|
|
|
imgStartMove(e) {
|
|
|
|
|
e.preventDefault()
|
|
|
|
|
// 支持触摸事件,则鼠标事件无效
|
|
|
|
|
if (this.isSupportTouch && !e.targetTouches) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
const et = e.targetTouches ? e.targetTouches[0] : e,
|
|
|
|
|
{ sourceImgMouseDown, scale } = this,
|
|
|
|
|
simd = sourceImgMouseDown
|
|
|
|
|
simd.mX = et.screenX
|
|
|
|
|
simd.mY = et.screenY
|
|
|
|
|
simd.x = scale.x
|
|
|
|
|
simd.y = scale.y
|
|
|
|
|
simd.on = true
|
|
|
|
|
},
|
|
|
|
|
// 鼠标按下状态下移动,图片移动
|
|
|
|
|
imgMove(e) {
|
|
|
|
|
e.preventDefault()
|
|
|
|
|
// 支持触摸事件,则鼠标事件无效
|
|
|
|
|
if (this.isSupportTouch && !e.targetTouches) {
|
|
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
const et = e.targetTouches ? e.targetTouches[0] : e,
|
|
|
|
|
{
|
|
|
|
|
sourceImgMouseDown: { on, mX, mY, x, y },
|
|
|
|
|
scale,
|
|
|
|
|
sourceImgMasking
|
|
|
|
|
} = this,
|
|
|
|
|
sim = sourceImgMasking,
|
|
|
|
|
nX = et.screenX,
|
|
|
|
|
nY = et.screenY,
|
|
|
|
|
dX = nX - mX,
|
|
|
|
|
dY = nY - mY
|
|
|
|
|
let rX = x + dX,
|
|
|
|
|
rY = y + dY
|
|
|
|
|
if (!on) return
|
|
|
|
|
if (rX > 0) {
|
|
|
|
|
rX = 0
|
|
|
|
|
}
|
|
|
|
|
if (rY > 0) {
|
|
|
|
|
rY = 0
|
|
|
|
|
}
|
|
|
|
|
if (rX < sim.width - scale.width) {
|
|
|
|
|
rX = sim.width - scale.width
|
|
|
|
|
}
|
|
|
|
|
if (rY < sim.height - scale.height) {
|
|
|
|
|
rY = sim.height - scale.height
|
|
|
|
|
}
|
|
|
|
|
scale.x = rX
|
|
|
|
|
scale.y = rY
|
|
|
|
|
},
|
|
|
|
|
// 顺时针旋转图片
|
|
|
|
|
rotateImg(e) {
|
|
|
|
|
const {
|
|
|
|
|
sourceImg,
|
|
|
|
|
scale: { naturalWidth, naturalHeight }
|
|
|
|
|
} = this,
|
|
|
|
|
width = naturalHeight,
|
|
|
|
|
height = naturalWidth,
|
|
|
|
|
canvas = this.$refs.canvas,
|
|
|
|
|
ctx = canvas.getContext('2d')
|
|
|
|
|
canvas.width = width
|
|
|
|
|
canvas.height = height
|
|
|
|
|
ctx.clearRect(0, 0, width, height)
|
|
|
|
|
|
|
|
|
|
ctx.fillStyle = 'rgba(0,0,0,0)'
|
|
|
|
|
ctx.fillRect(0, 0, width, height)
|
|
|
|
|
|
|
|
|
|
ctx.translate(width, 0)
|
|
|
|
|
ctx.rotate((Math.PI * 90) / 180)
|
|
|
|
|
|
|
|
|
|
ctx.drawImage(sourceImg, 0, 0, naturalWidth, naturalHeight)
|
|
|
|
|
const imgUrl = canvas.toDataURL(mimes.png)
|
|
|
|
|
|
|
|
|
|
this.sourceImgUrl = imgUrl
|
|
|
|
|
this.startCrop()
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
// 按钮按下开始放大
|
|
|
|
|
startZoomAdd(e) {
|
|
|
|
|
const that = this,
|
|
|
|
|
{ scale } = that
|
|
|
|
|
scale.zoomAddOn = true
|
|
|
|
|
|
|
|
|
|
function zoom() {
|
|
|
|
|
if (scale.zoomAddOn) {
|
|
|
|
|
const range = scale.range >= 100 ? 100 : ++scale.range
|
|
|
|
|
that.zoomImg(range)
|
|
|
|
|
setTimeout(function () {
|
|
|
|
|
zoom()
|
|
|
|
|
}, 60)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
zoom()
|
|
|
|
|
},
|
|
|
|
|
// 按钮松开或移开取消放大
|
|
|
|
|
endZoomAdd(e) {
|
|
|
|
|
this.scale.zoomAddOn = false
|
|
|
|
|
},
|
|
|
|
|
// 按钮按下开始缩小
|
|
|
|
|
startZoomSub(e) {
|
|
|
|
|
const that = this,
|
|
|
|
|
{ scale } = that
|
|
|
|
|
scale.zoomSubOn = true
|
|
|
|
|
|
|
|
|
|
function zoom() {
|
|
|
|
|
if (scale.zoomSubOn) {
|
|
|
|
|
const range = scale.range <= 0 ? 0 : --scale.range
|
|
|
|
|
that.zoomImg(range)
|
|
|
|
|
setTimeout(function () {
|
|
|
|
|
zoom()
|
|
|
|
|
}, 60)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
zoom()
|
|
|
|
|
},
|
|
|
|
|
// 按钮松开或移开取消缩小
|
|
|
|
|
endZoomSub(e) {
|
|
|
|
|
const { scale } = this
|
|
|
|
|
scale.zoomSubOn = false
|
|
|
|
|
},
|
|
|
|
|
zoomChange(e) {
|
|
|
|
|
this.zoomImg(e.target.value)
|
|
|
|
|
},
|
|
|
|
|
// 缩放原图
|
|
|
|
|
zoomImg(newRange) {
|
|
|
|
|
const that = this,
|
|
|
|
|
{ sourceImgMasking, sourceImgMouseDown, scale } = this,
|
|
|
|
|
{ maxWidth, maxHeight, minWidth, minHeight, width, height, x, y, range } = scale,
|
|
|
|
|
sim = sourceImgMasking,
|
|
|
|
|
// 蒙版宽高
|
|
|
|
|
sWidth = sim.width,
|
|
|
|
|
sHeight = sim.height,
|
|
|
|
|
// 新宽高
|
|
|
|
|
nWidth = minWidth + ((maxWidth - minWidth) * newRange) / 100,
|
|
|
|
|
nHeight = minHeight + ((maxHeight - minHeight) * newRange) / 100
|
|
|
|
|
// 新坐标(根据蒙版中心点缩放)
|
|
|
|
|
let nX = sWidth / 2 - (nWidth / width) * (sWidth / 2 - x),
|
|
|
|
|
nY = sHeight / 2 - (nHeight / height) * (sHeight / 2 - y)
|
|
|
|
|
|
|
|
|
|
// 判断新坐标是否超过蒙版限制
|
|
|
|
|
if (nX > 0) {
|
|
|
|
|
nX = 0
|
|
|
|
|
}
|
|
|
|
|
if (nY > 0) {
|
|
|
|
|
nY = 0
|
|
|
|
|
}
|
|
|
|
|
if (nX < sWidth - nWidth) {
|
|
|
|
|
nX = sWidth - nWidth
|
|
|
|
|
}
|
|
|
|
|
if (nY < sHeight - nHeight) {
|
|
|
|
|
nY = sHeight - nHeight
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 赋值处理
|
|
|
|
|
scale.x = nX
|
|
|
|
|
scale.y = nY
|
|
|
|
|
scale.width = nWidth
|
|
|
|
|
scale.height = nHeight
|
|
|
|
|
scale.range = newRange
|
|
|
|
|
setTimeout(function () {
|
|
|
|
|
if (scale.range == newRange) {
|
|
|
|
|
that.createImg()
|
|
|
|
|
}
|
|
|
|
|
}, 300)
|
|
|
|
|
},
|
|
|
|
|
// 生成需求图片
|
|
|
|
|
createImg(e) {
|
|
|
|
|
const that = this,
|
|
|
|
|
{
|
|
|
|
|
imgFormat,
|
|
|
|
|
imgBgc,
|
|
|
|
|
mime,
|
|
|
|
|
sourceImg,
|
|
|
|
|
scale: { x, y, width, height },
|
|
|
|
|
sourceImgMasking: { scale }
|
|
|
|
|
} = that,
|
|
|
|
|
canvas = that.$refs.canvas,
|
|
|
|
|
ctx = canvas.getContext('2d')
|
|
|
|
|
if (e) {
|
|
|
|
|
// 取消鼠标按下移动状态
|
|
|
|
|
that.sourceImgMouseDown.on = false
|
|
|
|
|
}
|
|
|
|
|
canvas.width = that.width
|
|
|
|
|
canvas.height = that.height
|
|
|
|
|
ctx.clearRect(0, 0, that.width, that.height)
|
|
|
|
|
|
|
|
|
|
if (imgFormat == 'png') {
|
|
|
|
|
ctx.fillStyle = 'rgba(0,0,0,0)'
|
|
|
|
|
} else {
|
|
|
|
|
// 如果jpg 为透明区域设置背景,默认白色
|
|
|
|
|
ctx.fillStyle = imgBgc
|
|
|
|
|
}
|
|
|
|
|
ctx.fillRect(0, 0, that.width, that.height)
|
|
|
|
|
|
|
|
|
|
ctx.drawImage(sourceImg, x / scale, y / scale, width / scale, height / scale)
|
|
|
|
|
that.createImgUrl = canvas.toDataURL(mime)
|
|
|
|
|
},
|
|
|
|
|
prepareUpload() {
|
|
|
|
|
const { url, createImgUrl, field, ki } = this
|
|
|
|
|
this.$emit('crop-success', createImgUrl, field, ki)
|
|
|
|
|
if (typeof url == 'string' && url) {
|
|
|
|
|
this.upload()
|
|
|
|
|
} else {
|
|
|
|
|
this.off()
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 上传图片
|
|
|
|
|
upload() {
|
|
|
|
|
const that = this,
|
|
|
|
|
{ lang, imgFormat, mime, url, params, headers, field, ki, createImgUrl, withCredentials } = this,
|
|
|
|
|
fmData = new FormData()
|
|
|
|
|
fmData.append(field, data2blob(createImgUrl, mime), field + '.' + imgFormat)
|
|
|
|
|
|
|
|
|
|
// 添加其他参数
|
|
|
|
|
if (typeof params == 'object' && params) {
|
2024-08-21 01:17:14 +00:00
|
|
|
|
Object.keys(params).forEach(k => {
|
2024-08-20 12:11:31 +00:00
|
|
|
|
fmData.append(k, params[k])
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 监听进度回调
|
|
|
|
|
const uploadProgress = function (event) {
|
|
|
|
|
if (event.lengthComputable) {
|
|
|
|
|
that.progress = (100 * Math.round(event.loaded)) / event.total
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 上传文件
|
|
|
|
|
that.reset()
|
|
|
|
|
that.loading = 1
|
|
|
|
|
that.setStep(3)
|
|
|
|
|
new Promise(function (resolve, reject) {
|
|
|
|
|
const client = new XMLHttpRequest()
|
|
|
|
|
client.open('POST', url, true)
|
|
|
|
|
client.withCredentials = withCredentials
|
|
|
|
|
client.onreadystatechange = function () {
|
|
|
|
|
if (this.readyState !== 4) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
if (this.status === 200 || this.status === 201) {
|
|
|
|
|
resolve(JSON.parse(this.responseText))
|
|
|
|
|
} else {
|
|
|
|
|
reject(this.status)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
client.upload.addEventListener('progress', uploadProgress, false) // 监听进度
|
|
|
|
|
// 设置header
|
|
|
|
|
if (typeof headers == 'object' && headers) {
|
2024-08-21 01:17:14 +00:00
|
|
|
|
Object.keys(headers).forEach(k => {
|
2024-08-20 12:11:31 +00:00
|
|
|
|
client.setRequestHeader(k, headers[k])
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
client.send(fmData)
|
|
|
|
|
}).then(
|
|
|
|
|
// 上传成功
|
|
|
|
|
function (resData) {
|
|
|
|
|
if (that.value) {
|
|
|
|
|
that.loading = 2
|
|
|
|
|
that.$emit('crop-upload-success', resData, field, ki)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
// 上传失败
|
|
|
|
|
function (sts) {
|
|
|
|
|
if (that.value) {
|
|
|
|
|
that.loading = 3
|
|
|
|
|
that.hasError = true
|
|
|
|
|
that.errorMsg = lang.fail
|
|
|
|
|
that.$emit('crop-upload-fail', sts, field, ki)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
created() {
|
|
|
|
|
// 绑定按键esc隐藏此插件事件
|
2024-08-21 01:17:14 +00:00
|
|
|
|
document.addEventListener('keyup', e => {
|
2024-08-20 12:11:31 +00:00
|
|
|
|
if (this.value && (e.key == 'Escape' || e.keyCode == 27)) {
|
|
|
|
|
this.off()
|
|
|
|
|
}
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
</script>
|
|
|
|
|
|
|
|
|
|
<style>
|
|
|
|
|
@charset "UTF-8";
|
|
|
|
|
@-webkit-keyframes vicp_progress {
|
|
|
|
|
0% {
|
|
|
|
|
background-position-y: 0;
|
|
|
|
|
}
|
|
|
|
|
100% {
|
|
|
|
|
background-position-y: 40px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@keyframes vicp_progress {
|
|
|
|
|
0% {
|
|
|
|
|
background-position-y: 0;
|
|
|
|
|
}
|
|
|
|
|
100% {
|
|
|
|
|
background-position-y: 40px;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@-webkit-keyframes vicp {
|
|
|
|
|
0% {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
-webkit-transform: scale(0) translatey(-60px);
|
|
|
|
|
transform: scale(0) translatey(-60px);
|
|
|
|
|
}
|
|
|
|
|
100% {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
-webkit-transform: scale(1) translatey(0);
|
|
|
|
|
transform: scale(1) translatey(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@keyframes vicp {
|
|
|
|
|
0% {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
-webkit-transform: scale(0) translatey(-60px);
|
|
|
|
|
transform: scale(0) translatey(-60px);
|
|
|
|
|
}
|
|
|
|
|
100% {
|
|
|
|
|
opacity: 1;
|
|
|
|
|
-webkit-transform: scale(1) translatey(0);
|
|
|
|
|
transform: scale(1) translatey(0);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.vue-image-crop-upload {
|
|
|
|
|
position: fixed;
|
|
|
|
|
display: block;
|
|
|
|
|
-webkit-box-sizing: border-box;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
z-index: 10000;
|
|
|
|
|
top: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 100%;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.65);
|
|
|
|
|
-webkit-tap-highlight-color: transparent;
|
|
|
|
|
-moz-tap-highlight-color: transparent;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap {
|
|
|
|
|
-webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
|
|
|
|
|
position: fixed;
|
|
|
|
|
display: block;
|
|
|
|
|
-webkit-box-sizing: border-box;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
z-index: 10000;
|
|
|
|
|
top: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
margin: auto;
|
|
|
|
|
width: 600px;
|
|
|
|
|
height: 330px;
|
|
|
|
|
padding: 25px;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
-webkit-animation: vicp 0.12s ease-in;
|
|
|
|
|
animation: vicp 0.12s ease-in;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-close {
|
|
|
|
|
position: absolute;
|
|
|
|
|
right: -30px;
|
|
|
|
|
top: -30px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4 {
|
|
|
|
|
position: relative;
|
|
|
|
|
display: block;
|
|
|
|
|
width: 30px;
|
|
|
|
|
height: 30px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
-webkit-transition: -webkit-transform 0.18s;
|
|
|
|
|
transition: -webkit-transform 0.18s;
|
|
|
|
|
transition: transform 0.18s;
|
|
|
|
|
transition: transform 0.18s, -webkit-transform 0.18s;
|
|
|
|
|
-webkit-transform: rotate(0);
|
|
|
|
|
-ms-transform: rotate(0);
|
|
|
|
|
transform: rotate(0);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4::after,
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4::before {
|
|
|
|
|
-webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 12px;
|
|
|
|
|
left: 4px;
|
|
|
|
|
width: 20px;
|
|
|
|
|
height: 3px;
|
|
|
|
|
-webkit-transform: rotate(45deg);
|
|
|
|
|
-ms-transform: rotate(45deg);
|
|
|
|
|
transform: rotate(45deg);
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4::after {
|
|
|
|
|
-webkit-transform: rotate(-45deg);
|
|
|
|
|
-ms-transform: rotate(-45deg);
|
|
|
|
|
transform: rotate(-45deg);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-close .vicp-icon4:hover {
|
|
|
|
|
-webkit-transform: rotate(90deg);
|
|
|
|
|
-ms-transform: rotate(90deg);
|
|
|
|
|
transform: rotate(90deg);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area {
|
|
|
|
|
position: relative;
|
|
|
|
|
-webkit-box-sizing: border-box;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
padding: 35px;
|
|
|
|
|
height: 170px;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.03);
|
|
|
|
|
text-align: center;
|
|
|
|
|
border: 1px dashed rgba(0, 0, 0, 0.08);
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-icon1 {
|
|
|
|
|
display: block;
|
|
|
|
|
margin: 0 auto 6px;
|
|
|
|
|
width: 42px;
|
|
|
|
|
height: 42px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-icon1 .vicp-icon1-arrow {
|
|
|
|
|
display: block;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
width: 0;
|
|
|
|
|
height: 0;
|
|
|
|
|
border-bottom: 14.7px solid rgba(0, 0, 0, 0.3);
|
|
|
|
|
border-left: 14.7px solid transparent;
|
|
|
|
|
border-right: 14.7px solid transparent;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-icon1 .vicp-icon1-body {
|
|
|
|
|
display: block;
|
|
|
|
|
width: 12.6px;
|
|
|
|
|
height: 14.7px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.3);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-icon1 .vicp-icon1-bottom {
|
|
|
|
|
-webkit-box-sizing: border-box;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
display: block;
|
|
|
|
|
height: 12.6px;
|
|
|
|
|
border: 6px solid rgba(0, 0, 0, 0.3);
|
|
|
|
|
border-top: none;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-hint {
|
|
|
|
|
display: block;
|
|
|
|
|
padding: 15px;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #666;
|
|
|
|
|
line-height: 30px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area .vicp-no-supported-hint {
|
|
|
|
|
display: block;
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
padding: 30px;
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 60px;
|
|
|
|
|
line-height: 30px;
|
|
|
|
|
background-color: #eee;
|
|
|
|
|
text-align: center;
|
|
|
|
|
color: #666;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step1 .vicp-drop-area:hover {
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-color: rgba(0, 0, 0, 0.1);
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.05);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop {
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left {
|
|
|
|
|
float: left;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-img-container {
|
|
|
|
|
position: relative;
|
|
|
|
|
display: block;
|
|
|
|
|
width: 240px;
|
|
|
|
|
height: 180px;
|
|
|
|
|
background-color: #e5e5e0;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-img-container .vicp-img {
|
|
|
|
|
position: absolute;
|
|
|
|
|
display: block;
|
|
|
|
|
cursor: move;
|
|
|
|
|
-webkit-user-select: none;
|
|
|
|
|
-moz-user-select: none;
|
|
|
|
|
-ms-user-select: none;
|
|
|
|
|
user-select: none;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-img-container .vicp-img-shade {
|
|
|
|
|
-webkit-box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
|
|
|
|
|
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
|
|
|
|
|
position: absolute;
|
|
|
|
|
background-color: rgba(241, 242, 243, 0.8);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-img-container .vicp-img-shade.vicp-img-shade-1 {
|
|
|
|
|
top: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-img-container .vicp-img-shade.vicp-img-shade-2 {
|
|
|
|
|
bottom: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-rotate {
|
|
|
|
|
position: relative;
|
|
|
|
|
width: 240px;
|
|
|
|
|
height: 18px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-rotate i {
|
|
|
|
|
display: block;
|
|
|
|
|
width: 18px;
|
|
|
|
|
height: 18px;
|
|
|
|
|
border-radius: 100%;
|
|
|
|
|
line-height: 18px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
font-size: 12px;
|
|
|
|
|
font-weight: bold;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.08);
|
|
|
|
|
color: #fff;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-rotate i:hover {
|
|
|
|
|
-webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.14);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-rotate i:first-child {
|
|
|
|
|
float: left;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-rotate i:last-child {
|
|
|
|
|
float: right;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range {
|
|
|
|
|
position: relative;
|
|
|
|
|
margin: 30px 0 10px 0;
|
|
|
|
|
width: 240px;
|
|
|
|
|
height: 18px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon5,
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6 {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 0;
|
|
|
|
|
width: 18px;
|
|
|
|
|
height: 18px;
|
|
|
|
|
border-radius: 100%;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.08);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon5:hover,
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6:hover {
|
|
|
|
|
-webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.14);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon5 {
|
|
|
|
|
left: 0;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon5::before {
|
|
|
|
|
position: absolute;
|
|
|
|
|
content: '';
|
|
|
|
|
display: block;
|
|
|
|
|
left: 3px;
|
|
|
|
|
top: 8px;
|
|
|
|
|
width: 12px;
|
|
|
|
|
height: 2px;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6 {
|
|
|
|
|
right: 0;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6::before {
|
|
|
|
|
position: absolute;
|
|
|
|
|
content: '';
|
|
|
|
|
display: block;
|
|
|
|
|
left: 3px;
|
|
|
|
|
top: 8px;
|
|
|
|
|
width: 12px;
|
|
|
|
|
height: 2px;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range .vicp-icon6::after {
|
|
|
|
|
position: absolute;
|
|
|
|
|
content: '';
|
|
|
|
|
display: block;
|
|
|
|
|
top: 3px;
|
|
|
|
|
left: 8px;
|
|
|
|
|
width: 2px;
|
|
|
|
|
height: 12px;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range'] {
|
|
|
|
|
display: block;
|
|
|
|
|
padding-top: 5px;
|
|
|
|
|
margin: 0 auto;
|
|
|
|
|
width: 180px;
|
|
|
|
|
height: 8px;
|
|
|
|
|
/* vertical-align: top; */
|
|
|
|
|
background: transparent;
|
|
|
|
|
-webkit-appearance: none;
|
|
|
|
|
-moz-appearance: none;
|
|
|
|
|
appearance: none;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
/* 滑块 ---------------------------------------------------------------*/
|
|
|
|
|
/* 轨道 ---------------------------------------------------------------*/
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']:focus {
|
|
|
|
|
outline: none;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']::-webkit-slider-thumb {
|
|
|
|
|
-webkit-box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
|
|
|
|
|
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
|
|
|
|
|
-webkit-appearance: none;
|
|
|
|
|
appearance: none;
|
|
|
|
|
margin-top: -3px;
|
|
|
|
|
width: 12px;
|
|
|
|
|
height: 12px;
|
|
|
|
|
background-color: #61c091;
|
|
|
|
|
border-radius: 100%;
|
|
|
|
|
border: none;
|
|
|
|
|
-webkit-transition: 0.2s;
|
|
|
|
|
transition: 0.2s;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']::-moz-range-thumb {
|
|
|
|
|
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
|
|
|
|
|
-moz-appearance: none;
|
|
|
|
|
appearance: none;
|
|
|
|
|
width: 12px;
|
|
|
|
|
height: 12px;
|
|
|
|
|
background-color: #61c091;
|
|
|
|
|
border-radius: 100%;
|
|
|
|
|
border: none;
|
|
|
|
|
-webkit-transition: 0.2s;
|
|
|
|
|
transition: 0.2s;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']::-ms-thumb {
|
|
|
|
|
box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.18);
|
|
|
|
|
appearance: none;
|
|
|
|
|
width: 12px;
|
|
|
|
|
height: 12px;
|
|
|
|
|
background-color: #61c091;
|
|
|
|
|
border: none;
|
|
|
|
|
border-radius: 100%;
|
|
|
|
|
-webkit-transition: 0.2s;
|
|
|
|
|
transition: 0.2s;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']:active::-moz-range-thumb {
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
|
|
|
|
|
width: 14px;
|
|
|
|
|
height: 14px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']:active::-ms-thumb {
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
|
|
|
|
|
width: 14px;
|
|
|
|
|
height: 14px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']:active::-webkit-slider-thumb {
|
|
|
|
|
-webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.23);
|
|
|
|
|
margin-top: -4px;
|
|
|
|
|
width: 14px;
|
|
|
|
|
height: 14px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']::-webkit-slider-runnable-track {
|
|
|
|
|
-webkit-box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 6px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
border: none;
|
|
|
|
|
background-color: rgba(68, 170, 119, 0.3);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']::-moz-range-track {
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
|
|
|
|
|
width: 100%;
|
|
|
|
|
height: 6px;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
border: none;
|
|
|
|
|
background-color: rgba(68, 170, 119, 0.3);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']::-ms-track {
|
|
|
|
|
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.12);
|
|
|
|
|
width: 100%;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
background: transparent;
|
|
|
|
|
border-color: transparent;
|
|
|
|
|
color: transparent;
|
|
|
|
|
height: 6px;
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
border: none;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']::-ms-fill-lower {
|
|
|
|
|
background-color: rgba(68, 170, 119, 0.3);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']::-ms-fill-upper {
|
|
|
|
|
background-color: rgba(68, 170, 119, 0.15);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']:focus::-webkit-slider-runnable-track {
|
|
|
|
|
background-color: rgba(68, 170, 119, 0.5);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']:focus::-moz-range-track {
|
|
|
|
|
background-color: rgba(68, 170, 119, 0.5);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']:focus::-ms-fill-lower {
|
|
|
|
|
background-color: rgba(68, 170, 119, 0.45);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-left .vicp-range input[type='range']:focus::-ms-fill-upper {
|
|
|
|
|
background-color: rgba(68, 170, 119, 0.25);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right {
|
|
|
|
|
float: right;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right .vicp-preview {
|
|
|
|
|
height: 150px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right .vicp-preview .vicp-preview-item {
|
|
|
|
|
position: relative;
|
|
|
|
|
padding: 5px;
|
|
|
|
|
width: 100px;
|
|
|
|
|
height: 100px;
|
|
|
|
|
float: left;
|
|
|
|
|
margin-right: 16px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right .vicp-preview .vicp-preview-item span {
|
|
|
|
|
position: absolute;
|
|
|
|
|
bottom: -30px;
|
|
|
|
|
width: 100%;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #bbb;
|
|
|
|
|
display: block;
|
|
|
|
|
text-align: center;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right .vicp-preview .vicp-preview-item img {
|
|
|
|
|
position: absolute;
|
|
|
|
|
display: block;
|
|
|
|
|
top: 0;
|
|
|
|
|
bottom: 0;
|
|
|
|
|
left: 0;
|
|
|
|
|
right: 0;
|
|
|
|
|
margin: auto;
|
|
|
|
|
padding: 3px;
|
|
|
|
|
background-color: #fff;
|
|
|
|
|
border: 1px solid rgba(0, 0, 0, 0.15);
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
-webkit-user-select: none;
|
|
|
|
|
-moz-user-select: none;
|
|
|
|
|
-ms-user-select: none;
|
|
|
|
|
user-select: none;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right .vicp-preview .vicp-preview-item.vicp-preview-item-circle {
|
|
|
|
|
margin-right: 0;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right .vicp-preview .vicp-preview-item.vicp-preview-item-circle img {
|
|
|
|
|
border-radius: 100%;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload {
|
|
|
|
|
position: relative;
|
|
|
|
|
-webkit-box-sizing: border-box;
|
|
|
|
|
box-sizing: border-box;
|
|
|
|
|
padding: 35px;
|
|
|
|
|
height: 170px;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.03);
|
|
|
|
|
text-align: center;
|
|
|
|
|
border: 1px dashed #ddd;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-loading {
|
|
|
|
|
display: block;
|
|
|
|
|
padding: 15px;
|
|
|
|
|
font-size: 16px;
|
|
|
|
|
color: #999;
|
|
|
|
|
line-height: 30px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-progress-wrap {
|
|
|
|
|
margin-top: 12px;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.08);
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-progress-wrap .vicp-progress {
|
|
|
|
|
position: relative;
|
|
|
|
|
display: block;
|
|
|
|
|
height: 5px;
|
|
|
|
|
border-radius: 3px;
|
|
|
|
|
background-color: #4a7;
|
|
|
|
|
-webkit-box-shadow: 0 2px 6px 0 rgba(68, 170, 119, 0.3);
|
|
|
|
|
box-shadow: 0 2px 6px 0 rgba(68, 170, 119, 0.3);
|
|
|
|
|
-webkit-transition: width 0.15s linear;
|
|
|
|
|
transition: width 0.15s linear;
|
2024-08-21 01:17:14 +00:00
|
|
|
|
background-image: -webkit-linear-gradient(
|
|
|
|
|
135deg,
|
|
|
|
|
rgba(255, 255, 255, 0.2) 25%,
|
|
|
|
|
transparent 25%,
|
|
|
|
|
transparent 50%,
|
|
|
|
|
rgba(255, 255, 255, 0.2) 50%,
|
|
|
|
|
rgba(255, 255, 255, 0.2) 75%,
|
|
|
|
|
transparent 75%,
|
|
|
|
|
transparent
|
|
|
|
|
);
|
2024-08-20 12:11:31 +00:00
|
|
|
|
background-image: linear-gradient(-45deg, rgba(255, 255, 255, 0.2) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.2) 50%, rgba(255, 255, 255, 0.2) 75%, transparent 75%, transparent);
|
|
|
|
|
background-size: 40px 40px;
|
|
|
|
|
-webkit-animation: vicp_progress 0.5s linear infinite;
|
|
|
|
|
animation: vicp_progress 0.5s linear infinite;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-progress-wrap .vicp-progress::after {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
display: block;
|
|
|
|
|
top: -3px;
|
|
|
|
|
right: -3px;
|
|
|
|
|
width: 9px;
|
|
|
|
|
height: 9px;
|
|
|
|
|
border: 1px solid rgba(245, 246, 247, 0.7);
|
|
|
|
|
-webkit-box-shadow: 0 1px 4px 0 rgba(68, 170, 119, 0.7);
|
|
|
|
|
box-shadow: 0 1px 4px 0 rgba(68, 170, 119, 0.7);
|
|
|
|
|
border-radius: 100%;
|
|
|
|
|
background-color: #4a7;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-error,
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload .vicp-success {
|
|
|
|
|
height: 100px;
|
|
|
|
|
line-height: 100px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-operate {
|
|
|
|
|
position: absolute;
|
|
|
|
|
right: 20px;
|
|
|
|
|
bottom: 20px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-operate a {
|
|
|
|
|
position: relative;
|
|
|
|
|
float: left;
|
|
|
|
|
display: block;
|
|
|
|
|
margin-left: 10px;
|
|
|
|
|
width: 100px;
|
|
|
|
|
height: 36px;
|
|
|
|
|
line-height: 36px;
|
|
|
|
|
text-align: center;
|
|
|
|
|
cursor: pointer;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
color: #4a7;
|
|
|
|
|
border-radius: 2px;
|
|
|
|
|
overflow: hidden;
|
|
|
|
|
-webkit-user-select: none;
|
|
|
|
|
-moz-user-select: none;
|
|
|
|
|
-ms-user-select: none;
|
|
|
|
|
user-select: none;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-operate a:hover {
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.03);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-error,
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-success {
|
|
|
|
|
display: block;
|
|
|
|
|
font-size: 14px;
|
|
|
|
|
line-height: 24px;
|
|
|
|
|
height: 24px;
|
|
|
|
|
color: #d10;
|
|
|
|
|
text-align: center;
|
|
|
|
|
/* vertical-align: top; */
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-success {
|
|
|
|
|
color: #4a7;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-icon3 {
|
|
|
|
|
position: relative;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 20px;
|
|
|
|
|
height: 20px;
|
|
|
|
|
top: 4px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-icon3::after {
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 3px;
|
|
|
|
|
left: 6px;
|
|
|
|
|
width: 6px;
|
|
|
|
|
height: 10px;
|
|
|
|
|
border-width: 0 2px 2px 0;
|
|
|
|
|
border-color: #4a7;
|
|
|
|
|
border-style: solid;
|
|
|
|
|
-webkit-transform: rotate(45deg);
|
|
|
|
|
-ms-transform: rotate(45deg);
|
|
|
|
|
transform: rotate(45deg);
|
|
|
|
|
content: '';
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-icon2 {
|
|
|
|
|
position: relative;
|
|
|
|
|
display: inline-block;
|
|
|
|
|
width: 20px;
|
|
|
|
|
height: 20px;
|
|
|
|
|
top: 4px;
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-icon2::after,
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-icon2::before {
|
|
|
|
|
content: '';
|
|
|
|
|
position: absolute;
|
|
|
|
|
top: 9px;
|
|
|
|
|
left: 4px;
|
|
|
|
|
width: 13px;
|
|
|
|
|
height: 2px;
|
|
|
|
|
background-color: #d10;
|
|
|
|
|
-webkit-transform: rotate(45deg);
|
|
|
|
|
-ms-transform: rotate(45deg);
|
|
|
|
|
transform: rotate(45deg);
|
|
|
|
|
}
|
|
|
|
|
.vue-image-crop-upload .vicp-wrap .vicp-icon2::after {
|
|
|
|
|
-webkit-transform: rotate(-45deg);
|
|
|
|
|
-ms-transform: rotate(-45deg);
|
|
|
|
|
transform: rotate(-45deg);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
.e-ripple {
|
|
|
|
|
position: absolute;
|
|
|
|
|
border-radius: 100%;
|
|
|
|
|
background-color: rgba(0, 0, 0, 0.15);
|
|
|
|
|
background-clip: padding-box;
|
|
|
|
|
pointer-events: none;
|
|
|
|
|
-webkit-user-select: none;
|
|
|
|
|
-moz-user-select: none;
|
|
|
|
|
-ms-user-select: none;
|
|
|
|
|
user-select: none;
|
|
|
|
|
-webkit-transform: scale(0);
|
|
|
|
|
-ms-transform: scale(0);
|
|
|
|
|
transform: scale(0);
|
|
|
|
|
opacity: 1;
|
|
|
|
|
}
|
|
|
|
|
.e-ripple.z-active {
|
|
|
|
|
opacity: 0;
|
|
|
|
|
-webkit-transform: scale(2);
|
|
|
|
|
-ms-transform: scale(2);
|
|
|
|
|
transform: scale(2);
|
|
|
|
|
-webkit-transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
|
|
|
|
|
transition: opacity 1.2s ease-out, -webkit-transform 0.6s ease-out;
|
|
|
|
|
transition: opacity 1.2s ease-out, transform 0.6s ease-out;
|
|
|
|
|
transition: opacity 1.2s ease-out, transform 0.6s ease-out, -webkit-transform 0.6s ease-out;
|
|
|
|
|
}
|
|
|
|
|
</style>
|