init
This commit is contained in:
676
src/components/ImageCropper/index.vue
Normal file
676
src/components/ImageCropper/index.vue
Normal file
@@ -0,0 +1,676 @@
|
||||
<template>
|
||||
<div class="vue-image-crop-upload" v-show="show">
|
||||
<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>
|
||||
<input type="file" v-show="false" @change="handleChange" ref="fileinput">
|
||||
</div>
|
||||
<div class="vicp-error" v-show="hasError">
|
||||
<i class="vicp-icon2"></i> {{ errorMsg }}
|
||||
</div>
|
||||
<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">
|
||||
<img :src="sourceImgUrl"
|
||||
:style="sourceImgStyle"
|
||||
class="vicp-img"
|
||||
draggable="false"
|
||||
@drag="preventDefault"
|
||||
@dragstart="preventDefault"
|
||||
@dragend="preventDefault"
|
||||
@dragleave="preventDefault"
|
||||
@dragover="preventDefault"
|
||||
@dragenter="preventDefault"
|
||||
@drop="preventDefault"
|
||||
@mousedown="imgStartMove"
|
||||
@mousemove="imgMove"
|
||||
@mouseup="createImg"
|
||||
@mouseout="createImg"
|
||||
ref="img">
|
||||
<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">
|
||||
<input type="range" :value="scale.range" step="1" min="0" max="100" @change="zoomChange">
|
||||
<i @mousedown="startZoomSub" @mouseout="endZoomSub" @mouseup="endZoomSub"
|
||||
class="vicp-icon5"></i>
|
||||
<i @mousedown="startZoomAdd" @mouseout="endZoomAdd" @mouseup="endZoomAdd"
|
||||
class="vicp-icon6"></i>
|
||||
</div>
|
||||
</div>
|
||||
<div class="vicp-crop-right" v-show="true">
|
||||
<div class="vicp-preview">
|
||||
<div class="vicp-preview-item">
|
||||
<img :src="createImgUrl" :style="previewStyle">
|
||||
<span>{{ lang.preview }}</span>
|
||||
</div>
|
||||
<div class="vicp-preview-item">
|
||||
<img :src="createImgUrl" :style="previewStyle" v-if="!noCircle">
|
||||
<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="upload" @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>
|
||||
<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>
|
||||
</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>
|
||||
/* eslint-disable */
|
||||
import {getToken, upload} from 'api/qiniu';
|
||||
import {effectRipple, data2blob} from './utils';
|
||||
import langBag from './lang';
|
||||
const mimes = {
|
||||
'jpg': 'image/jpeg',
|
||||
'png': 'image/png',
|
||||
'gif': 'image/gif',
|
||||
'svg': 'image/svg+xml',
|
||||
'psd': 'image/photoshop'
|
||||
};
|
||||
|
||||
export default {
|
||||
props: {
|
||||
// 域,上传文件name,触发事件会带上(如果一个页面多个图片上传控件,可以做区分
|
||||
field: {
|
||||
type: String,
|
||||
default: 'avatar'
|
||||
},
|
||||
// 上传地址
|
||||
url: {
|
||||
type: String,
|
||||
default: ''
|
||||
},
|
||||
// 其他要上传文件附带的数据,对象格式
|
||||
params: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
// 剪裁图片的宽
|
||||
width: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
// 剪裁图片的高
|
||||
height: {
|
||||
type: Number,
|
||||
default: 200
|
||||
},
|
||||
// 不预览圆形图片
|
||||
noCircle: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
// 单文件大小限制
|
||||
maxSize: {
|
||||
type: Number,
|
||||
default: 10240
|
||||
},
|
||||
// 语言类型
|
||||
langType: {
|
||||
type: String,
|
||||
'default': 'zh'
|
||||
},
|
||||
|
||||
},
|
||||
data() {
|
||||
let that = this,
|
||||
{
|
||||
langType,
|
||||
width,
|
||||
height
|
||||
} = that,
|
||||
isSupported = true,
|
||||
lang = langBag[langType] ? langBag[langType] : lang['zh'];
|
||||
|
||||
if (typeof FormData != 'function') {
|
||||
isSupported = false;
|
||||
}
|
||||
return {
|
||||
show: true,
|
||||
// 图片的mime
|
||||
mime:mimes['jpg'],
|
||||
// 语言包
|
||||
lang,
|
||||
// 浏览器是否支持该控件
|
||||
isSupported,
|
||||
// 步骤
|
||||
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: 180
|
||||
},
|
||||
// 原图展示属性
|
||||
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() {
|
||||
let {
|
||||
progress
|
||||
} = this;
|
||||
return {
|
||||
width: progress + '%'
|
||||
}
|
||||
},
|
||||
// 原图样式
|
||||
sourceImgStyle() {
|
||||
let {
|
||||
scale,
|
||||
sourceImgMasking
|
||||
} = this;
|
||||
return {
|
||||
top: scale.y + sourceImgMasking.y + 'px',
|
||||
left: scale.x + sourceImgMasking.x + 'px',
|
||||
width: scale.width + 'px',
|
||||
height: scale.height + 'px'
|
||||
}
|
||||
},
|
||||
// 原图蒙版属性
|
||||
sourceImgMasking() {
|
||||
let {
|
||||
width,
|
||||
height,
|
||||
ratio,
|
||||
sourceImgContainer
|
||||
} = this,
|
||||
sic = sourceImgContainer,
|
||||
sicRatio = sic.width / sic.height, // 原图容器宽高比
|
||||
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() {
|
||||
let sic = this.sourceImgContainer,
|
||||
sim = this.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() {
|
||||
let {
|
||||
width,
|
||||
height,
|
||||
ratio,
|
||||
previewContainer
|
||||
} = this,
|
||||
pc = previewContainer,
|
||||
w = pc.width,
|
||||
h = pc.height,
|
||||
pcRatio = w / h;
|
||||
if (ratio < pcRatio) {
|
||||
w = pc.height * ratio;
|
||||
}
|
||||
if (ratio > pcRatio) {
|
||||
h = pc.width / ratio;
|
||||
}
|
||||
return {
|
||||
width: w + 'px',
|
||||
height: h + 'px'
|
||||
};
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
// 点击波纹效果
|
||||
ripple(e) {
|
||||
effectRipple(e);
|
||||
},
|
||||
// 关闭控件
|
||||
off() {
|
||||
this.show = false;
|
||||
},
|
||||
// 设置步骤
|
||||
setStep(step) {
|
||||
let that = this;
|
||||
setTimeout(function () {
|
||||
that.step = step;
|
||||
}, 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) {
|
||||
let files = e.target.files || e.dataTransfer.files;
|
||||
this.reset();
|
||||
if (this.checkFile(files[0])) {
|
||||
this.setSourceImg(files[0]);
|
||||
}
|
||||
}
|
||||
},
|
||||
/* ---------------------------------------------------------------*/
|
||||
// 检测选择的文件是否合适
|
||||
checkFile(file) {
|
||||
let that = this,
|
||||
{
|
||||
lang,
|
||||
maxSize
|
||||
} = that;
|
||||
// 仅限图片
|
||||
if (file.type.indexOf('image') === -1) {
|
||||
that.hasError = true;
|
||||
that.errorMsg = lang.error.onlyImg;
|
||||
return false;
|
||||
}
|
||||
this.mime=file.type;
|
||||
// 超出大小
|
||||
if (file.size / 1024 > maxSize) {
|
||||
that.hasError = true;
|
||||
that.errorMsg = lang.error.outOfSize + maxSize + 'kb';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
},
|
||||
// 重置控件
|
||||
reset() {
|
||||
let that = this;
|
||||
that.step = 1;
|
||||
that.loading = 0;
|
||||
that.hasError = false;
|
||||
that.errorMsg = '';
|
||||
that.progress = 0;
|
||||
},
|
||||
// 设置图片源
|
||||
setSourceImg(file) {
|
||||
let that = this,
|
||||
fr = new FileReader();
|
||||
fr.onload = function (e) {
|
||||
that.sourceImgUrl = fr.result;
|
||||
that.startCrop();
|
||||
};
|
||||
fr.readAsDataURL(file);
|
||||
},
|
||||
// 剪裁前准备工作
|
||||
startCrop() {
|
||||
let that = this,
|
||||
{
|
||||
width,
|
||||
height,
|
||||
ratio,
|
||||
scale,
|
||||
sourceImgUrl,
|
||||
sourceImgMasking,
|
||||
lang
|
||||
} = that,
|
||||
sim = sourceImgMasking,
|
||||
img = new Image();
|
||||
img.src = sourceImgUrl;
|
||||
img.onload = function () {
|
||||
let nWidth = img.naturalWidth,
|
||||
nHeight = img.naturalHeight,
|
||||
nRatio = nWidth / nHeight,
|
||||
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) {
|
||||
let {
|
||||
sourceImgMouseDown,
|
||||
scale
|
||||
} = this,
|
||||
simd = sourceImgMouseDown;
|
||||
simd.mX = e.screenX;
|
||||
simd.mY = e.screenY;
|
||||
simd.x = scale.x;
|
||||
simd.y = scale.y;
|
||||
simd.on = true;
|
||||
},
|
||||
// 鼠标按下状态下移动,图片移动
|
||||
imgMove(e) {
|
||||
let {
|
||||
sourceImgMouseDown: {
|
||||
on,
|
||||
mX,
|
||||
mY,
|
||||
x,
|
||||
y
|
||||
},
|
||||
scale,
|
||||
sourceImgMasking
|
||||
} = this,
|
||||
sim = sourceImgMasking,
|
||||
nX = e.screenX,
|
||||
nY = e.screenY,
|
||||
dX = nX - mX,
|
||||
dY = nY - mY,
|
||||
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;
|
||||
},
|
||||
// 按钮按下开始放大
|
||||
startZoomAdd(e) {
|
||||
let that = this,
|
||||
{
|
||||
scale
|
||||
} = that;
|
||||
scale.zoomAddOn = true;
|
||||
function zoom() {
|
||||
if (scale.zoomAddOn) {
|
||||
let range = scale.range >= 100 ? 100 : ++scale.range;
|
||||
that.zoomImg(range);
|
||||
setTimeout(function () {
|
||||
zoom();
|
||||
}, 60);
|
||||
}
|
||||
}
|
||||
|
||||
zoom();
|
||||
},
|
||||
// 按钮松开或移开取消放大
|
||||
endZoomAdd(e) {
|
||||
this.scale.zoomAddOn = false;
|
||||
},
|
||||
// 按钮按下开始缩小
|
||||
startZoomSub(e) {
|
||||
let that = this,
|
||||
{
|
||||
scale
|
||||
} = that;
|
||||
scale.zoomSubOn = true;
|
||||
function zoom() {
|
||||
if (scale.zoomSubOn) {
|
||||
let range = scale.range <= 0 ? 0 : --scale.range;
|
||||
that.zoomImg(range);
|
||||
setTimeout(function () {
|
||||
zoom();
|
||||
}, 60);
|
||||
}
|
||||
}
|
||||
|
||||
zoom();
|
||||
},
|
||||
// 按钮松开或移开取消缩小
|
||||
endZoomSub(e) {
|
||||
let {
|
||||
scale
|
||||
} = this;
|
||||
scale.zoomSubOn = false;
|
||||
},
|
||||
zoomChange(e) {
|
||||
this.zoomImg(e.target.value);
|
||||
},
|
||||
// 缩放原图
|
||||
zoomImg(newRange) {
|
||||
let 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,
|
||||
// 新坐标(根据蒙版中心点缩放)
|
||||
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) {
|
||||
let that = this,
|
||||
{
|
||||
mime,
|
||||
sourceImg,
|
||||
scale: {
|
||||
x,
|
||||
y,
|
||||
width,
|
||||
height
|
||||
},
|
||||
sourceImgMasking: {
|
||||
scale
|
||||
}
|
||||
} = that,
|
||||
canvas = that.$refs.canvas,
|
||||
ctx = canvas.getContext('2d');
|
||||
if (e) {
|
||||
// 取消鼠标按下移动状态
|
||||
that.sourceImgMouseDown.on = false;
|
||||
}
|
||||
ctx.drawImage(sourceImg, x / scale, y / scale, width / scale, height / scale);
|
||||
that.createImgUrl = canvas.toDataURL(mime);
|
||||
},
|
||||
// 上传图片
|
||||
upload() {
|
||||
let that = this,
|
||||
{
|
||||
lang,
|
||||
mime,
|
||||
createImgUrl
|
||||
} = this,
|
||||
formData = new FormData();
|
||||
// 上传文件
|
||||
that.loading = 1;
|
||||
that.progress = 0;
|
||||
that.setStep(3);
|
||||
formData.append('file', data2blob(createImgUrl, mime));
|
||||
const token = this.$store.getters.token;
|
||||
getToken(token).then((response)=> {
|
||||
const url = response.data.qiniu_url;
|
||||
formData.append('token', response.data.qiniu_token);
|
||||
formData.append('key', response.data.qiniu_key);
|
||||
upload(formData).then((response)=> {
|
||||
that.loading = 2;
|
||||
that.$emit('crop-upload-success', url);
|
||||
}).catch(err => {
|
||||
that.loading = 3;
|
||||
that.hasError = true;
|
||||
that.errorMsg = lang.fail;
|
||||
that.$emit('crop-upload-fail');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
@import "./upload.css";
|
||||
</style>
|
41
src/components/ImageCropper/lang.js
Normal file
41
src/components/ImageCropper/lang.js
Normal file
@@ -0,0 +1,41 @@
|
||||
const langBag = {
|
||||
zh: {
|
||||
hint: '点击,或拖动图片至此处',
|
||||
loading: '正在上传……',
|
||||
noSupported: '浏览器不支持该功能,请使用IE10以上或其他现在浏览器!',
|
||||
success: '上传成功',
|
||||
fail: '图片上传失败',
|
||||
preview: '头像预览',
|
||||
btn: {
|
||||
off: '取消',
|
||||
close: '关闭',
|
||||
back: '上一步',
|
||||
save: '保存'
|
||||
},
|
||||
error: {
|
||||
onlyImg: '仅限图片格式',
|
||||
outOfSize: '单文件大小不能超过 ',
|
||||
lowestPx: '图片最低像素为(宽*高):'
|
||||
}
|
||||
},
|
||||
en: {
|
||||
hint: 'Click, or drag the file here',
|
||||
loading: 'Uploading……',
|
||||
noSupported: 'Browser does not support, please use IE10+ or other browsers',
|
||||
success: 'Upload success',
|
||||
fail: 'Upload failed',
|
||||
preview: 'Preview',
|
||||
btn: {
|
||||
off: 'Cancel',
|
||||
close: 'Close',
|
||||
back: 'Back',
|
||||
save: 'Save'
|
||||
},
|
||||
error: {
|
||||
onlyImg: 'Image only',
|
||||
outOfSize: 'Image exceeds size limit: ',
|
||||
lowestPx: 'The lowest pixel in the image: '
|
||||
}
|
||||
}
|
||||
};
|
||||
export default langBag;
|
691
src/components/ImageCropper/upload.css
Normal file
691
src/components/ImageCropper/upload.css
Normal file
@@ -0,0 +1,691 @@
|
||||
@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;
|
||||
padding: 35px;
|
||||
height: 200px;
|
||||
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-range {
|
||||
position: relative;
|
||||
margin: 30px 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:last-child {
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
.vue-image-crop-upload .vicp-wrap .vicp-step2 .vicp-crop .vicp-crop-right .vicp-preview .vicp-preview-item:last-child img {
|
||||
border-radius: 100%;
|
||||
}
|
||||
|
||||
.vue-image-crop-upload .vicp-wrap .vicp-step3 .vicp-upload {
|
||||
position: relative;
|
||||
padding: 35px;
|
||||
height: 200px;
|
||||
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;
|
||||
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);
|
||||
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;
|
||||
}
|
58
src/components/ImageCropper/utils.js
Normal file
58
src/components/ImageCropper/utils.js
Normal file
@@ -0,0 +1,58 @@
|
||||
/* eslint-disable */
|
||||
|
||||
/**
|
||||
*
|
||||
* @param e
|
||||
* @param arg_opts
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export function effectRipple(e, arg_opts) {
|
||||
let opts = Object.assign({
|
||||
ele: e.target, // 波纹作用元素
|
||||
type: 'hit', // hit点击位置扩散 center中心点扩展
|
||||
bgc: 'rgba(0, 0, 0, 0.15)' // 波纹颜色
|
||||
}, arg_opts),
|
||||
target = opts.ele;
|
||||
if (target) {
|
||||
let rect = target.getBoundingClientRect(),
|
||||
ripple = target.querySelector('.e-ripple');
|
||||
if (!ripple) {
|
||||
ripple = document.createElement('span');
|
||||
ripple.className = 'e-ripple';
|
||||
ripple.style.height = ripple.style.width = Math.max(rect.width, rect.height) + 'px';
|
||||
target.appendChild(ripple);
|
||||
} else {
|
||||
ripple.className = 'e-ripple';
|
||||
}
|
||||
switch (opts.type) {
|
||||
case 'center':
|
||||
ripple.style.top = (rect.height / 2 - ripple.offsetHeight / 2) + 'px';
|
||||
ripple.style.left = (rect.width / 2 - ripple.offsetWidth / 2) + 'px';
|
||||
break;
|
||||
default:
|
||||
ripple.style.top = (e.pageY - rect.top - ripple.offsetHeight / 2 - document.body.scrollTop) + 'px';
|
||||
ripple.style.left = (e.pageX - rect.left - ripple.offsetWidth / 2 - document.body.scrollLeft) + 'px';
|
||||
}
|
||||
ripple.style.backgroundColor = opts.bgc;
|
||||
ripple.className = 'e-ripple z-active';
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// database64文件格式转换为2进制
|
||||
/**
|
||||
*
|
||||
* @param data
|
||||
* @param mime
|
||||
* @returns {*}
|
||||
*/
|
||||
export function data2blob(data, mime) {
|
||||
// dataURL 的格式为 “data:image/png;base64,****”,逗号之前都是一些说明性的文字,我们只需要逗号之后的就行了
|
||||
data = data.split(',')[1];
|
||||
data = window.atob(data);
|
||||
var ia = new Uint8Array(data.length);
|
||||
for (var i = 0; i < data.length; i++) {
|
||||
ia[i] = data.charCodeAt(i);
|
||||
}
|
||||
// canvas.toDataURL 返回的默认格式就是 image/png
|
||||
return new Blob([ia], {type: mime});
|
||||
};
|
Reference in New Issue
Block a user