vue图片裁剪功能组件
首先说明一下,这个组件实际的裁剪图片功能是交给后台实现的,前端需要提供的是几个参数,具体如下
最终效果图:(可以滚动鼠标滚轮放大缩小图片,可以拖拽图片,兼容谷歌火狐等浏览器)
- 创建cropper.vue组件,组件代码如下:
<template>
<div>
<el-upload
class="upload-demo"
:action="cropperData.updateimgSrc"
:on-success="upDateSuccess"
multiple
:limit="1"
:show-file-list="false"
:file-list="fileList"
:modal="false"
:disabled="cropperData.uploadBtnIs && Boolean(cropperData.cropperShowImgUrl)">
<div v-if="!cropperData.uploadBtnIs" :style="{width:(cropperData.showWidth+'px'),height:(showBoxheight)}" class="cropper-img-show">
<img v-if="cropperData.cropperShowImgUrl" :src="cropperData.cropperShowImgUrl" />
<span v-if="!cropperData.cropperShowImgUrl" class="el-icon-plus"></span>
</div>
<div v-if="cropperData.uploadBtnIs">
<el-button :disabled="Boolean(cropperData.cropperShowImgUrl)" size="small" type="primary">{{cropperData.uploadBtnText}}</el-button>
</div>
</el-upload>
<el-dialog title="图片裁剪" id="cropperBoxMainOuter" :visible.sync="cropperVisible" width="640px" @close="closeDialog" :append-to-body="true">
<div ref="cropperBoxMain" class="cropperBoxMain" @mousemove.stop="cropperBoxMainMove">
<div class="cropper-box" ref="cropperBox" id="cropper-box-wheel" @mousedown.stop="cropperBoxDown" @mousemove.stop="cropperBoxMove" @mouseup.stop="cropperBoxUp" @mouseout.stop="cropperBoxOut">
<div class="cropper-box-000">
<img id="cropper-img1" ref="cropperImg1" class="cropper-img1" :src="imgSrc" :style="{width:(imgData.width+'px'),height:(imgData.height+'px'),marginLeft:(imgData.img1Left+'px'),marginTop:(imgData.img1Top+'px'),transform:(imgData.scale),transformOrigin:(imgData.originXY)}" />
<div class="cropper-box-000-div">
</div>
</div>
<div id="cropper-cutting-box" ref="cropperCuttingBox" :style="{width:(cropperData.width+'px'),height:(cropperData.height+'px'),left:(cropperData.cuttingLeft+'px'),top:(cropperData.cuttingTop+'px')}" @mousedown.stop="cropperDown" @mousemove.stop="cropperMove" @mouseup.stop="cropperUp" @mouseout.stop="cropperOut">
<div class="cropper-cutting-box-img">
<img class="cropper-img2" :src="imgSrc" :style="{width:(imgData.width+'px'),height:(imgData.height+'px'),marginLeft:(imgData.img2Left+'px'),marginTop:(imgData.img2Top+'px'),transform:(imgData.scale),transformOrigin:(imgData.originXY)}" />
<div class="cropper-img2-alert"><!-- 图片的盖层 禁止拖动出虚影 --></div>
</div>
<!--<span v-show="!cropperData.sizeChangeIs" class="cropper-dot cutting-left-top"></span>
<span v-show="!cropperData.sizeChangeIs" class="cropper-dot cutting-left-bottom"></span>
<span v-show="!cropperData.sizeChangeIs" class="cropper-dot cutting-right-top"></span>
<span v-show="!cropperData.sizeChangeIs" class="cropper-dot cutting-right-bottom"></span>-->
<span class="cropper-dot cropper-dot-move cutting-move-left-top" @mousedown.stop="topDragDown($event,'lefttop')" @mousemove.stop="topDragMove($event,'lefttop')" @mouseup.stop="topDragUp($event,'lefttop')" @mouseout.stop="topDragOut($event,'lefttop')">
<span></span>
</span>
<span class="cropper-dot cropper-dot-move cutting-move-left-bottom" @mousedown.stop="topDragDown($event,'leftbottom')" @mousemove.stop="topDragMove($event,'leftbottom')" @mouseup.stop="topDragUp($event,'leftbottom')" @mouseout.stop="topDragOut($event,'leftbottom')">
<span></span>
</span>
<span class="cropper-dot cropper-dot-move cutting-move-right-top" @mousedown.stop="topDragDown($event,'righttop')" @mousemove.stop="topDragMove($event,'righttop')" @mouseup.stop="topDragUp($event,'righttop')" @mouseout.stop="topDragOut($event,'righttop')">
<span></span>
</span>
<span class="cropper-dot cropper-dot-move cutting-move-right-bottom" @mousedown.stop="topDragDown($event,'rightbottom')" @mousemove.stop="topDragMove($event,'rightbottom')" @mouseup.stop="topDragUp($event,'rightbottom')" @mouseout.stop="topDragOut($event,'rightbottom')">
<span></span>
</span>
<span v-show="cropperData.sizeChangeIs" class="cropper-dot cropper-dot-move cropper-dot-moveX cutting-top-center" @mousedown.stop="topDragDown($event,'topcenter')" @mousemove.stop="topDragMove($event,'topcenter')" @mouseup.stop="topDragUp($event,'topcenter')" @mouseout.stop="topDragOut($event,'topcenter')">
<span></span>
</span>
<span v-show="cropperData.sizeChangeIs" class="cropper-dot cropper-dot-move cropper-dot-moveY cutting-right-center" @mousedown.stop="topDragDown($event,'rightcenter')" @mousemove.stop="topDragMove($event,'rightcenter')" @mouseup.stop="topDragUp($event,'rightcenter')" @mouseout.stop="topDragOut($event,'rightcenter')">
<span></span>
</span>
<span v-show="cropperData.sizeChangeIs" class="cropper-dot cropper-dot-move cropper-dot-moveX cutting-bottom-center" @mousedown.stop="topDragDown($event,'bottomcenter')" @mousemove.stop="topDragMove($event,'bottomcenter')" @mouseup.stop="topDragUp($event,'bottomcenter')" @mouseout.stop="topDragOut($event,'bottomcenter')">
<span></span>
</span>
<span v-show="cropperData.sizeChangeIs" class="cropper-dot cropper-dot-move cropper-dot-moveY cutting-left-center" @mousedown.stop="topDragDown($event,'leftcenter')" @mousemove.stop="topDragMove($event,'leftcenter')" @mouseup.stop="topDragUp($event,'leftcenter')" @mouseout.stop="topDragOut($event,'leftcenter')">
<span></span>
</span>
</div>
</div>
</div>
<div class="cropper-img-set">
<span class="cropper-img-set-title">图片设置:</span>
<div class="cropper-img-set-one">
<b>宽</b>
<el-input-number style="height:40px;width:120px;padding:0 0 0 8px;" v-model="imgData.width" controls-position="right" :min="Number(cropperData.width)" @change="cropperImgWidthChange"></el-input-number>
</div>
<div class="cropper-img-set-one">
<b>高</b>
<el-input-number style="height:40px;width:120px;padding:0 0 0 8px;" v-model="imgData.height" controls-position="right" :min="Number(cropperData.height)" @change="cropperImgHeightChange"></el-input-number>
</div>
</div>
<span slot="footer" class="dialog-footer">
<div style="float:left;margin:0 0 10px 0;">
<el-button type="primary" style="display:block;" :disabled="updateOriginalIs" @click="cutoutImgSub('intrinsic')">上传原图</el-button>
<p class="update-Intrinsic-explain"><span>注:</span>上传图片与规定尺寸不符时此功能禁用</p>
</div>
<el-button type="primary" @click="cutoutImgSub">确定</el-button>
</span>
</el-dialog>
</div>
</template>
<script>
import { imgCutFun } from '@/api/login'
export default {
name: 'cropper',
data() {
return {
// 图片上传地址
cropperData: this.cropperMsg,
showBoxheight:'', //页面显示框的高度
fileList:[],
cropperVisible:false,
imgSrc:'', //最初上传返回的原始图片
cuttingData:{}, //截图框的数据
imgData:{}, //图片数据
imgWheelBoxId:'',
img1Id:'',
img1Html:'',
myimageHtml:'',
imgStartWidth:'', //刚上传图片展示的图片大小
imgStartHeight:'',
imgScaleFize:'1', //图片的原始比例,设置为1
mouseDownIs:false, //鼠标是否按下(拖动截取框用到)
mouseDownClientX:'', //鼠标按下时的坐标位置
mouseDownClientY:'',
cropperStartLeft:'', //鼠标在截图框刚按下时截图框初始的left,top
cropperStartTop:'',
mouseDownBoxIs:false, //鼠标是否按下(拖动图片用)
mouseDownBoxClientX:'',
mouseDownBoxClientY:'',
cropperImgStartLeft:'', //拖动图片之前的left,top
cropperImgStartTop:'',
originalImageWidth:'', //获取图片原始宽高
originalImageHeight:'',
modaleIs:true,
topDragDownIs:false, //鼠标拖拽截图框改变大小,是否按下
initialCuttingWidth:'', //截图框鼠标按下拖拽改变大小时的初始宽,高,left,top
initialCuttingHeight:'',
initialCuttingLeft:'',
initialCuttingTop:'',
updateOriginalIs:true, //是否可下载原图
moveDotType:'', //点击拖拽的八个点的类型 (lefttop、leftcenter等)
}
},
props:['cropperMsg'],
watch:{ //检测父组件变化
cropperMsg(val,oldval){
this.cropperData = val
this.getShowBoxheight()
},
imgWheelBoxId(val) {
this.imgWheelBox = val
this.myimageHtml =document.getElementById(this.imgWheelBoxId);
this.img1Html = document.getElementById(this.img1Id)
if (this.myimageHtml.addEventListener) {
// IE9, Chrome, Safari, Opera
this.myimageHtml.addEventListener("mousewheel", this.MouseWheelHandler, false);
// Firefox
this.myimageHtml.addEventListener("DOMMouseScroll", this.MouseWheelHandler, false);
}
},
deep: true
},
methods: {
//获取页面显示框高度
getShowBoxheight() {
if(this.cropperData.cropperShowImgUrl){
this.showBoxheight = 'auto'
}else{
this.showBoxheight = this.cropperData.showHeight + 'px'
}
},
//图片原图上传成功
upDateSuccess(res, file) {
this.cropperVisible = true
this.topDragDownIs = false
this.mouseDownBoxIs = false
this.mouseDownIs = false
if(file.response.img_url_list){
this.imgSrc = file.response.img_url_list[0]
}else if(file.response.data){
this.imgSrc = file.response.data.url
}
if(this.cropperData.isAvatar){
this.imgSrc +='?v='+ Math.floor(Math.random()*1000)
}
var that = this
setTimeout(function(){
that.imgWheelBoxId = 'cropper-box-wheel'
that.img1Id = 'cropper-img1'
that.getImgOriginalData()
},100)
},
//获取截图框的数据
getCuttingData() {
var cropperBoxWidth = this.$refs.cropperBox.clientWidth
var cropperBoxHeight = this.$refs.cropperBox.clientHeight
this.cropperData.cuttingLeft = ((cropperBoxWidth - this.cropperData.width)/2)
this.cropperData.cuttingTop = ((cropperBoxHeight - this.cropperData.height)/2)
this.cropperData = JSON.parse(JSON.stringify(this.cropperData))
this.imgData.width = this.$refs.cropperBox.clientWidth
this.imgStartWidth = this.$refs.cropperBox.clientWidth
this.imgStartHeight = Math.round((this.imgData.width/this.originalImageWidth)*this.originalImageHeight)
this.imgData.height = Math.round((this.imgData.width/this.originalImageWidth)*this.originalImageHeight)
this.imgData.img1Left = '0'
this.imgData.img1Top = '0'
this.imgData.img2Left = Number(this.imgData.img1Left) - this.cropperData.cuttingLeft
this.imgData.img2Top = Number(this.imgData.img1Top) - this.cropperData.cuttingTop
},
//鼠标滚轮事件
MouseWheelHandler(e) {
if(e.wheelDelta){
if(e.wheelDelta > 0) {
// console.log('谷歌向上滚动')
this.imgScaleMaxFun(e.offsetX,e.offsetY)
}else{
// console.log('谷歌向下滚动')
this.imgScaleMinFun(e.offsetX,e.offsetY)
}
}else if(e.detail){
if(e.detail > 0 ){
// console.log('火狐向下滚动')
this.imgScaleMinFun(e.layerX,e.layerY)
}else{
// console.log('火狐向上滚动')
this.imgScaleMaxFun(e.layerX,e.layerY)
}
}
},
//滚动事件后图片放大缩小
imgScaleMaxFun(x,y){
this.imgScaleFize = Number(this.imgScaleFize)+0.04
//水平
var prevWidth = this.imgData.width
this.imgData.width = Math.round(this.imgStartWidth*this.imgScaleFize)
var imgX = x - Number(this.imgData.img1Left)
this.imgData.img1Left = Number(this.imgData.img1Left) - Number((imgX/prevWidth)*(this.imgData.width - prevWidth))
//垂直
var prevHeight = this.$refs.cropperImg1.clientHeight
this.imgData.height = Math.round(this.imgStartHeight*this.imgScaleFize)
var imgY = y - Number(this.imgData.img1Top)
this.imgData.img1Top = Number(this.imgData.img1Top) - Number((imgY/prevHeight)*(this.imgData.height - prevHeight))
//框中图
this.imgData.img2Left = this.imgData.img1Left - this.cropperData.cuttingLeft
this.imgData.img2Top = this.imgData.img1Top - this.cropperData.cuttingTop
this.imgData = JSON.parse(JSON.stringify(this.imgData))
},
imgScaleMinFun(x,y){
if(this.imgData.width > this.cropperData.width && this.imgData.height > this.cropperData.height){
this.imgScaleFize = Number(this.imgScaleFize)-0.04
//水平
var prevWidth = this.imgData.width
this.imgData.width = Math.round(this.imgStartWidth*this.imgScaleFize)
var imgX = x - Number(this.imgData.img1Left)
this.imgData.img1Left = Number(this.imgData.img1Left) + Number((imgX/prevWidth)*(prevWidth - this.imgData.width))
//垂直
var prevHeight = this.$refs.cropperImg1.clientHeight
this.imgData.height = Math.round(this.imgStartHeight*this.imgScaleFize)
var imgY = y - Number(this.imgData.img1Top)
this.imgData.img1Top = Number(this.imgData.img1Top) + Number((imgY/prevHeight)*(prevHeight - this.imgData.height))
//框中图
this.imgData.img2Left = this.imgData.img1Left - this.cropperData.cuttingLeft
this.imgData.img2Top = this.imgData.img1Top - this.cropperData.cuttingTop
this.imgData = JSON.parse(JSON.stringify(this.imgData))
}
},
//鼠标拖动截取框
cropperDown(e) {
this.mouseDownIs = true
this.mouseDownClientX = e.clientX
this.mouseDownClientY = e.clientY
this.cropperStartLeft = this.cropperData.cuttingLeft
this.cropperStartTop = this.cropperData.cuttingTop
},
cropperMove(e) {
if(this.mouseDownIs){
//判断水平不超出范围
if(Number(this.cropperStartLeft) + (e.clientX - this.mouseDownClientX) < 0){
this.cropperData.cuttingLeft = 0
}else if(Number(this.cropperStartLeft) + (e.clientX - this.mouseDownClientX) > (this.$refs.cropperBox.clientWidth - this.$refs.cropperCuttingBox.clientWidth)){
this.cropperData.cuttingLeft = this.$refs.cropperBox.clientWidth - this.$refs.cropperCuttingBox.clientWidth -2
}else{
this.cropperData.cuttingLeft = Number(this.cropperStartLeft) + (e.clientX - this.mouseDownClientX)
}
//判断垂直不超出范围
if(Number(this.cropperStartTop) + (e.clientY - this.mouseDownClientY) < 0){
this.cropperData.cuttingTop = 0
}else if(Number(this.cropperStartTop) + (e.clientY - this.mouseDownClientY) > (this.$refs.cropperBox.clientHeight - this.$refs.cropperCuttingBox.clientHeight)){
this.cropperData.cuttingTop = this.$refs.cropperBox.clientHeight - this.$refs.cropperCuttingBox.clientHeight -2
}else{
this.cropperData.cuttingTop = Number(this.cropperStartTop) + (e.clientY - this.mouseDownClientY)
}
//框中图
this.imgData.img2Left = this.imgData.img1Left - this.cropperData.cuttingLeft
this.imgData.img2Top = this.imgData.img1Top - this.cropperData.cuttingTop
}else if(this.mouseDownBoxIs){
this.imgData.img1Left = Number( this.cropperImgStartLeft) + (e.clientX - this.mouseDownBoxClientX)
this.imgData.img1Top = Number(this.cropperImgStartTop) + (e.clientY - this.mouseDownBoxClientY)
this.imgData.img2Left = this.imgData.img1Left - this.cropperData.cuttingLeft
this.imgData.img2Top = this.imgData.img1Top - this.cropperData.cuttingTop
this.imgData = JSON.parse(JSON.stringify(this.imgData))
}else if(this.topDragDownIs){
this.topDragMove(e,this.moveDotType)
}
},
cropperUp() {
this.mouseDownIs = false
this.topDragDownIs = false
this.mouseDownBoxIs = false
},
cropperOut() {
this.mouseDownIs = false
},
//鼠标拖动图片
cropperBoxDown(e) {
this.mouseDownBoxIs = true
this.mouseDownBoxClientX = e.clientX
this.mouseDownBoxClientY = e.clientY
this.cropperImgStartLeft = this.imgData.img1Left
this.cropperImgStartTop = this.imgData.img1Top
},
cropperBoxMove(e) {
if(this.mouseDownBoxIs){
this.imgData.img1Left = Number( this.cropperImgStartLeft) + (e.clientX - this.mouseDownBoxClientX)
this.imgData.img1Top = Number(this.cropperImgStartTop) + (e.clientY - this.mouseDownBoxClientY)
this.imgData.img2Left = this.imgData.img1Left - this.cropperData.cuttingLeft
this.imgData.img2Top = this.imgData.img1Top - this.cropperData.cuttingTop
this.imgData = JSON.parse(JSON.stringify(this.imgData))
}else if(this.topDragDownIs){
this.topDragMove(e,this.moveDotType)
}
},
cropperBoxUp() {
this.mouseDownBoxIs = false
this.topDragDownIs = false
},
cropperBoxOut(e) {
if((e.offsetX <= 0 || e.offsetY <= 0) || (e.offsetX >= this.$refs.cropperBox.clientWidth || e.offsetY >= this.$refs.cropperBox.clientHeight)){
this.mouseDownBoxIs = false
this.topDragDownIs = false
}
},
//当手动改变图片宽度时
cropperImgWidthChange() {
this.imgData.height = Math.round((this.imgData.width/this.imgStartWidth)*this.imgStartHeight)
},
//手动改变图片高度
cropperImgHeightChange() {
this.imgData.width = Math.round((this.imgData.height/this.imgStartHeight)*this.imgStartWidth)
},
//获取图片原始宽高
getImgOriginalData() {
var img = new Image();
img.src = this.imgSrc;
var that = this
setTimeout(function() {
if(img.complete){
that.originalImageWidth = img.width
that.originalImageHeight = img.height
that.getCuttingData()
}else{
img.onload = function(){
that.originalImageWidth = img.width
that.originalImageHeight = img.height
that.getCuttingData()
img.onload=null;//避免重复加载
}
}
if(that.cropperData.sizeChangeIs){
that.updateOriginalIs = false
}else {
var rateWidth = that.originalImageWidth / that.originalImageHeight
var rateHeight = that.cropperData.practicalWidth / that.cropperData.practicalHeight
if(rateWidth == rateHeight){
that.updateOriginalIs = false
}else{
that.updateOriginalIs = true
}
}
},100)
},
//确定截取图片
cutoutImgSub(type) {
var formData = {}
formData.file = this.imgSrc
if(type == 'intrinsic'){ //上传原图
this.cropperData.cropperShowImgUrl = this.imgSrc
this.cropperMsg.cropperShowImgUrl =this.imgSrc
this.cropperVisible = false
this.fileList = []
this.$emit('func',this.cropperData.cropperShowImgUrl)
if(this.cropperData.sizeChangeIs){ //不限制图片大小尺寸时
this.cropperData.showHeight = 'auto'
}
this.getShowBoxheight()
}else{
formData.left_upper_x = Math.round((Math.abs(this.imgData.img2Left)/this.imgData.width)*this.originalImageWidth)
formData.left_upper_y = Math.round((Math.abs(this.imgData.img2Top)/this.imgData.height)*this.originalImageHeight)
formData.lower_right_x = Math.round(((Math.abs(Number(this.imgData.img2Left)) + Number(this.cropperData.width))/this.imgData.width)*this.originalImageWidth)
formData.lower_right_y = Math.round(((Math.abs(Number(this.imgData.img2Top)) + Number(this.cropperData.height))/this.imgData.height)*this.originalImageHeight)
formData.width = this.cropperData.practicalWidth
formData.height = this.cropperData.practicalHeight
if(this.cropperData.isAvatar){
formData.is_avatar = '1'
formData.uid = this.cropperData.uid
}
if(this.cropperData.sizeChangeIs){ //不限制图片大小尺寸时
formData.width = Math.abs(formData.lower_right_x - formData.left_upper_x)
formData.height = Math.abs(formData.lower_right_y - formData.left_upper_y)
}
var that = this
imgCutFun(formData).then(function(data){
if(data.errcode == '0'){
that.cropperData.cropperShowImgUrl = data.img_url
that.cropperMsg.cropperShowImgUrl = data.img_url
that.cropperVisible = false
that.fileList = []
that.$emit('func',that.cropperData.cropperShowImgUrl)
if(that.cropperData.sizeChangeIs){ //不限制图片大小尺寸时
that.cropperData.showHeight = 'auto'
}
that.getShowBoxheight()
}
})
}
},
//关闭弹窗
closeDialog() {
this.fileList = []
},
//拖拽截图框改变截图大小
topDragDown(e,type) { //正上
this.moveDotType = type
this.topDragDownIs = true
this.mouseDownClientX = e.clientX
this.mouseDownClientY = e.clientY
this.initialCuttingWidth = this.cropperData.width
this.initialCuttingHeight = this.cropperData.height
this.initialCuttingLeft = this.cropperData.cuttingLeft
this.initialCuttingTop = this.cropperData.cuttingTop
},
topDragMove(e,type) {
if(this.topDragDownIs){
if(type == 'topcenter'){
if(this.cropperData.cuttingTop >= 0){
if(this.cropperData.cuttingTop == 0){
if((Number(this.initialCuttingHeight) + (this.mouseDownClientY - e.clientY)) - this.cropperData.height > 0){
return false
}
}
this.cropperData.height = Number(this.initialCuttingHeight) + (this.mouseDownClientY - e.clientY)
if(this.cropperData.height < 50){
this.cropperData.height = 50
}else{
this.cropperData.cuttingTop = Number(this.initialCuttingTop) + (e.clientY - this.mouseDownClientY)
}
}
}else if(type == 'rightcenter'){
if(Math.round(this.$refs.cropperBox.clientWidth - this.cropperData.width - this.cropperData.cuttingLeft) >= 0){
if(Math.round(this.$refs.cropperBox.clientWidth - this.cropperData.width - this.cropperData.cuttingLeft) == 0){
if((Number(this.initialCuttingWidth) + (e.clientX - this.mouseDownClientX)) - this.cropperData.width > 0){
return false
}
}
this.cropperData.width = Number(this.initialCuttingWidth) + (e.clientX - this.mouseDownClientX)
if(this.cropperData.width < 50){
this.cropperData.width = 50
}
}
}else if(type == 'bottomcenter'){
if(Math.round(this.$refs.cropperBox.clientHeight - this.cropperData.height - this.cropperData.cuttingTop) >= 0){
if(Math.round(this.$refs.cropperBox.clientHeight - this.cropperData.height - this.cropperData.cuttingTop) == 0){
if((Number(this.initialCuttingHeight) + (e.clientY - this.mouseDownClientY)) - this.cropperData.height > 0){
return false
}
}
this.cropperData.height = Number(this.initialCuttingHeight) + (e.clientY - this.mouseDownClientY)
if(this.cropperData.height < 50){
this.cropperData.height = 50
}
}
}else if(type == 'leftcenter'){
if(this.cropperData.cuttingLeft >= 0){
if(this.cropperData.cuttingLeft == 0){
if((Number(this.initialCuttingWidth) + (this.mouseDownClientX - e.clientX)) - this.cropperData.width > 0){
return false
}
}
this.cropperData.width = Number(this.initialCuttingWidth) + (this.mouseDownClientX - e.clientX)
if(this.cropperData.width < 50){
this.cropperData.width = 50
}else{
this.cropperData.cuttingLeft = Number(this.initialCuttingLeft) + (e.clientX - this.mouseDownClientX)
}
}
}else if(type == 'lefttop'){
if(this.cropperData.cuttingLeft >= 0 && this.cropperData.cuttingTop >= 0){
this.cropperData.width = Number(this.initialCuttingWidth) + (this.mouseDownClientX - e.clientX)
if(this.cropperData.width < 50){
this.cropperData.width = 50
}else{
this.cropperData.cuttingLeft = Number(this.initialCuttingLeft) + (e.clientX - this.mouseDownClientX)
}
if(this.cropperData.sizeChangeIs){
this.cropperData.height = Number(this.initialCuttingHeight) + (this.mouseDownClientY - e.clientY)
if(this.cropperData.height < 50){
this.cropperData.height = 50
}else{
this.cropperData.cuttingTop = Number(this.initialCuttingTop) + (e.clientY - this.mouseDownClientY)
}
}else{ //等比例缩放
this.cropperData.height = (this.cropperData.width/this.cropperMsg.practicalWidth)*this.cropperMsg.practicalHeight
this.cropperData.cuttingTop = Number(this.initialCuttingTop) - (this.cropperData.height - this.initialCuttingHeight)
}
}
}else if(type == 'righttop'){
if(Math.round(this.$refs.cropperBox.clientWidth - this.cropperData.width - this.cropperData.cuttingLeft) >= 0 && this.cropperData.cuttingTop >= 0){
this.cropperData.width = Number(this.initialCuttingWidth) + (e.clientX - this.mouseDownClientX)
if(this.cropperData.width < 50){
this.cropperData.width = 50
}
if(this.cropperData.sizeChangeIs){
this.cropperData.height = Number(this.initialCuttingHeight) + (this.mouseDownClientY - e.clientY)
if(this.cropperData.height < 50){
this.cropperData.height = 50
}else{
this.cropperData.cuttingTop = Number(this.initialCuttingTop) + (e.clientY - this.mouseDownClientY)
}
}else{ //等比例缩放
this.cropperData.height = (this.cropperData.width/this.cropperMsg.practicalWidth)*this.cropperMsg.practicalHeight
this.cropperData.cuttingTop = Number(this.initialCuttingTop) - (this.cropperData.height - this.initialCuttingHeight)
}
}
}else if(type == 'rightbottom'){
if(Math.round(this.$refs.cropperBox.clientWidth - this.cropperData.width - this.cropperData.cuttingLeft) >= 0 && Math.round(this.$refs.cropperBox.clientHeight - this.cropperData.height - this.cropperData.cuttingTop) >= 0){
this.cropperData.width = Number(this.initialCuttingWidth) + (e.clientX - this.mouseDownClientX)
if(this.cropperData.width < 50){
this.cropperData.width = 50
}else{
if(this.cropperData.sizeChangeIs){
this.cropperData.height = Number(this.initialCuttingHeight) + (e.clientY - this.mouseDownClientY)
}else{ //等比例缩放
this.cropperData.height = (this.cropperData.width/this.cropperMsg.practicalWidth)*this.cropperMsg.practicalHeight
}
}
if(this.cropperData.sizeChangeIs){
if(this.cropperData.height < 50){
this.cropperData.height = 50
}
}
}
}else if(type == 'leftbottom'){
if(this.cropperData.cuttingLeft >= 0 && Math.round(this.$refs.cropperBox.clientHeight - this.cropperData.height - this.cropperData.cuttingTop) >= 0){
this.cropperData.width = Number(this.initialCuttingWidth) + (this.mouseDownClientX - e.clientX)
if(this.cropperData.width < 50){
this.cropperData.width = 50
}else{
this.cropperData.cuttingLeft = Number(this.initialCuttingLeft) + (e.clientX - this.mouseDownClientX)
}
if(this.cropperData.sizeChangeIs){
this.cropperData.height = Number(this.initialCuttingHeight) + (e.clientY - this.mouseDownClientY)
if(this.cropperData.height < 50){
this.cropperData.height = 50
}
}else{ //等比例缩放
this.cropperData.height = (this.cropperData.width/this.cropperMsg.practicalWidth)*this.cropperMsg.practicalHeight
}
}
}
//框中图
this.imgData.img2Left = this.imgData.img1Left - this.cropperData.cuttingLeft
this.imgData.img2Top = this.imgData.img1Top - this.cropperData.cuttingTop
}else if(this.mouseDownBoxIs){
this.imgData.img1Left = Number( this.cropperImgStartLeft) + (e.clientX - this.mouseDownBoxClientX)
this.imgData.img1Top = Number(this.cropperImgStartTop) + (e.clientY - this.mouseDownBoxClientY)
this.imgData.img2Left = this.imgData.img1Left - this.cropperData.cuttingLeft
this.imgData.img2Top = this.imgData.img1Top - this.cropperData.cuttingTop
this.imgData = JSON.parse(JSON.stringify(this.imgData))
}
},
topDragUp() {
this.topDragDownIs = false
this.mouseDownBoxIs = false
},
topDragOut(e) {
// this.topDragDownIs = false
},
//当鼠标移动出去时
cropperBoxMainMove() {
this.topDragDownIs = false
this.mouseDownBoxIs = false
this.mouseDownIs = false
}
},
mounted:function(){
this.getShowBoxheight()
},
}
</script>
<style>
.cropperBoxMain{
padding: 30px 20px;
}
#cropperBoxMainOuter .el-dialog__body{
padding: 0;
}
.cropper-img-show{
border:1px dashed #aaa;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
overflow:hidden;
position:relative;
}
.cropper-img-show img{
display:block;
width:100%;
height:100%;
}
.cropper-img-show span{
position:absolute;
left:50%;
top:50%;
-webkit-transform: translate(-50%,-50%);
-moz-transform: translate(-50%,-50%);
-ms-transform: translate(-50%,-50%);
-o-transform: translate(-50%,-50%);
transform: translate(-50%,-50%);
font-size:16px;
color:#ccc;
}
.cropper-box{
width: 600px;
height:456px;
background:url(../../images/bghb.jpg);
position:relative;
moz-user-select: -moz-none;
-moz-user-select: none;
-o-user-select:none;
-khtml-user-select:none;
-webkit-user-select:none;
-ms-user-select:none;
user-select:none;
-webkit-touch-callout: none;
cursor:move;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;;
}
#cropper-cutting-box{
border:1px solid #007bff;
position:absolute;
background:rgba(0,0,0,0);
cursor:move;
box-sizing: border-box;
}
.cropper-cutting-box-img{
width:100%;
height:100%;
overflow:hidden;
}
#cropper-cutting-box .cropper-dot{
position:absolute;
width:7px;
height:7px;
background:#007bff;
}
#cropper-cutting-box .cropper-dot-move{
width:auto;
height:auto;
/*padding:20px;*/
background:none;
box-sizing:content-box;
}
.cropper-dot-move span{
background:#007bff;
width:7px;
height:7px;
display:block;
}
.cutting-left-top{
left:-3px;
top:-3px;
}
.cutting-left-bottom{
left:-3px;
bottom:-3px;
}
.cutting-right-top{
right:-3px;
top:-3px;
}
.cutting-right-bottom{
right:-3px;
bottom:-3px;
}
#cropper-cutting-box .cutting-move-left-top{
left:-3px;
top:-3px;
cursor:se-resize;
}
#cropper-cutting-box .cutting-move-left-bottom{
left:-3px;
bottom:-3px;
cursor:ne-resize;
}
#cropper-cutting-box .cutting-move-right-top{
right:-3px;
top:-3px;
cursor:ne-resize;
}
#cropper-cutting-box .cutting-move-right-bottom{
right:-3px;
bottom:-3px;
cursor:se-resize;
}
#cropper-cutting-box .cropper-dot-moveX span{
width:30px;
height:7px;
}
#cropper-cutting-box .cropper-dot-moveY span{
height:30px;
width:7px;
}
.cutting-top-center{
top:-4px;
left:50%;
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
-o-transform: translateX(-50%);
transform: translateX(-50%);
cursor:s-resize;
}
.cutting-right-center{
right:-4px;
top:50%;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
cursor:w-resize;
}
.cutting-bottom-center{
bottom:-4px;
left:50%;
-webkit-transform: translateX(-50%);
-moz-transform: translateX(-50%);
-ms-transform: translateX(-50%);
-o-transform: translateX(-50%);
transform: translateX(-50%);
cursor:s-resize;
}
.cutting-left-center{
left:-4px;
top:50%;
-webkit-transform: translateY(-50%);
-moz-transform: translateY(-50%);
-ms-transform: translateY(-50%);
-o-transform: translateY(-50%);
transform: translateY(-50%);
cursor:w-resize;
}
.cropper-box-000{
width:100%;
height:100%;
overflow:hidden;
}
.cropper-box-000 .cropper-box-000-div{
width:100%;
height:100%;
background:#000;
opacity:0.4;
position:absolute;
left:0;
top:0;
}
.cropper-img1,.cropper-img2{
}
.cropper-img2{
z-index:9;
}
.cropper-img2-alert{
position:absolute;
left:0;
top:0;
width:100%;
height:100%;
z-index:10;
}
.cropper-img-set{
height:40px;
margin:20px 0 0;
}
.cropper-img-set-title{
float:left;
height:40px;
line-height:40px;
padding:0 20px 0 0;
}
.cropper-img-set-one{
float:left;
margin:0 20px 0 0;
}
.cropper-img-set-one .el-input__inner{
height:40px;
}
.update-Intrinsic-explain{
color:#999;
font-size:12px;
height:22px;
line-height:22px;
}
.update-Intrinsic-explain span{
color:#e40112;
}
.dialog-footer{
display:block;
margin:-20px 0 0;
overflow:hidden;
}
</style>
2.父组件的代码如下:
<template>
<div>
<cropper :cropperMsg="cropperMsg" @func="getMsgUrl"></cropper>
</div>
</template>
<script>
import cropper from '@/components/Common/cropper'
export default {
components:{
cropper
},
data(){
return{
cropperMsg:{
width:'400', //透明框的宽高
height:'92',
practicalWidth:'400', //实际要截取的图片的宽高
practicalHeight:'92',
showWidth:'200', //页面中展示的虚线框的宽高(类似父组件上传图片按钮,只不过可以直接在父组件展示截取后的图片)
showHeight:'46',
updateimgSrc:'', //上传文件地址
cropperShowImgUrl:'', //图片url(原有的或截取成功后返回的)
modal:true, //是否需要遮罩层(当本身是弹窗修改时不需要)
sizeChangeIs:false, //当原图没做限制时,可以自己拖动截取框宽高
},
}
},
methods:{
//获取到组件传过来的url
getMsgUrl(data){
this.imgSrc = data
},
//原有图片时需要给cropperMsg.cropperShowImgUrl 赋值
}
}
</script>
就这两个代码,有问题请留言