Skip to content

Commit f6a9f3f

Browse files
committed
add new resize support
1 parent 2f23b12 commit f6a9f3f

File tree

10 files changed

+166
-82
lines changed

10 files changed

+166
-82
lines changed

index.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

site/client/components/doc/en/CropImage.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<li><code>maxHeight</code>: The maximum height of the crop image</li>
3636
</ul>
3737
<h4>Code example</h4>
38-
<p>上传图片后可以看到裁剪的参数</p>
38+
<p>Click button to upload and you can view some post params.</p>
3939
<div class="center">
4040
<div class="user">
4141
<img class="avatar" :src="cropSrc"/>
@@ -84,7 +84,7 @@
8484
</template>
8585

8686
<script>
87-
import VueCoreImageUpload from 'vue-core-image-upload'
87+
import VueCoreImageUpload from 'vue-core-image-upload';
8888
export default {
8989
components: {
9090
VueCoreImageUpload

src/crop.vue

Lines changed: 64 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
<template>
22
<div class="g-crop-image-principal">
33
<div class="image-wrap" :style="{ width:width + 'px',height: height + 'px' }">
4-
<img ref="crop-image" :src="src" :style="{ width:width + 'px',height: height + 'px' }">
4+
<img ref="crop-image" :src="src" :style="{ width:'100%',height: '100%', }">
55
</div>
6-
<div class="image-mask">
6+
<div class="image-mask" v-if="!hideCrop">
77
<div class="mask top" :style="{ top:0, height: cropCSS.top + 'px', left: 0, width: '100%'}"></div>
88
<div class="mask bottom" :style="{ bottom:0, top: (cropCSS.top + cropCSS.height) + 'px', left: 0, width: '100%'}"></div>
99
<div class="mask left" :style="{top: cropCSS.top + 'px', height: cropCSS.height + 'px', left:0, width: cropCSS.left + 'px'}"></div>
1010
<div class="mask right" :style="{top: cropCSS.top + 'px', height: cropCSS.height + 'px', left: (cropCSS.left + cropCSS.width) + 'px', right: 0}"></div>
1111
</div>
12-
<div class="crop-box" v-on:touchstart.self="drag" v-on:mousedown.self="drag" :style="{top: cropCSS.top + 'px', left: cropCSS.left + 'px', height: cropCSS.height + 'px', width: cropCSS.width + 'px'}">
12+
<div class="crop-box" v-if="!hideCrop" v-on:touchstart.self="drag" v-on:mousedown.self="drag" :style="{top: cropCSS.top + 'px', left: cropCSS.left + 'px', height: cropCSS.height + 'px', width: cropCSS.width + 'px'}">
1313
<div class="reference-line v"></div>
1414
<div class="reference-line h"></div>
1515
<a class="g-resize" v-on:touchstart.self="resize" v-on:mousedown.self="resize"></a>
@@ -30,6 +30,7 @@
3030
background-color: rgba(255,255,255,.6);
3131
}
3232
.crop-box{
33+
box-sizing: border-box;
3334
position: absolute;
3435
background: none;
3536
cursor: move;
@@ -71,7 +72,7 @@
7172
}
7273
.crop-box .g-resize{
7374
display: inline-block;
74-
z-index: 90;
75+
z-index: 1910;
7576
position: absolute;
7677
bottom: -8px;
7778
right: -8px;
@@ -100,6 +101,18 @@ export default {
100101
ratio: {
101102
type: String,
102103
default: '1:1'
104+
},
105+
minWidth: {
106+
type: Number,
107+
default: 50,
108+
},
109+
minHeight: {
110+
type: Number,
111+
default: 50,
112+
},
113+
hideCrop: {
114+
type: [String, Boolean],
115+
default: false,
103116
}
104117
},
105118
@@ -120,40 +133,70 @@ export default {
120133
if (this.ratio.indexOf(':') > 0) {
121134
this.ratioW = this.ratio.split(':')[0];
122135
this.ratioH = this.ratio.split(':')[1];
123-
this.ratioVal = this.ratioW / this.ratioH;
136+
this.ratioVal = this.ratioW / this.ratioH;
124137
} else {
125138
this.ratioW = 1;
126139
this.ratioH = 1;
127140
this.ratioVal = this.ratio;
128141
}
129142
this.setLayout(w, h);
130143
this.setCropBox();
144+
this.natrualWidth = w;
145+
this.natrualHeight = h;
146+
return this.imgChangeRatio;
131147
},
148+
149+
resizeImage(progress) {
150+
const w = this.natrualWidth * this.imgChangeRatio * progress;
151+
const h = this.natrualHeight * this.imgChangeRatio * progress;
152+
if (w <= this.minWidth || h < this.minHeight) {
153+
return;
154+
}
155+
this._setStyle(w, h, w/h);
156+
this.setCropBox();
157+
},
158+
132159
setLayout(w, h) {
133160
let H = window.innerHeight - 80,
134161
W = window.innerWidth - 60,
135162
width = w,
136-
height = h;
163+
height = h,
164+
marginLeft = 0;
165+
137166
// caculate the image ratio
138167
let R = width / height;
139168
let Rs = W / H;
140-
let $container = this.$el;
141169
if (R > Rs) {
142170
width = W;
143171
height = W / R;
144-
// I don't hope to use a state to change the container stye
145-
$container.style.cssText = 'width:' + W + 'px;height:' + W / R + 'px;margin-top:' + (H - W / R) / 2 + 'px';
172+
marginLeft = (H - W / R) / 2;
146173
} else {
147174
width = H * R,
148175
height = H;
149-
$container.style.cssText = 'width:' + H * R + 'px;height:' + H + 'px;margin-left:' + (W - H * R) / 2 + 'px;';
176+
marginLeft = (W - H * R) / 2;
150177
}
178+
this.marginLeft = marginLeft;
179+
this.marginTop = 0;
151180
this.imgChangeRatio = width / w;
152-
this.width = width;
153-
this.height = height;
181+
this._setStyle(width, height, R, true);
182+
},
183+
184+
_setStyle(w, h, r, isInit) {
185+
const $container = this.$el;
186+
if(!isInit) {
187+
this.marginLeft = this.marginLeft + (this.width - w) / 2;
188+
this.marginTop = this.marginTop + (this.height - h) / 2;
189+
}
190+
$container.style.cssText = 'width:' + w + 'px;height:' + h + 'px;margin-left:'
191+
+ this.marginLeft + 'px;' + 'margin-top:' + this.marginTop + 'px';
192+
this.width = w;
193+
this.height = h;
154194
},
155195
156196
setCropBox() {
197+
if (this.hideCrop) {
198+
return;
199+
}
157200
let $selectCropBox = this.__find('.crop-box');
158201
let $wrap = this.$el;
159202
let imageWidth = this.width,
@@ -181,6 +224,15 @@ export default {
181224
182225
getCropData() {
183226
// keep compatible with old api
227+
if (this.hideCrop) {
228+
return {
229+
imgChangeRatio: this.imgChangeRatio,
230+
toCropImgX: 0,
231+
toCropImgY: 0,
232+
toCropImgW: this.natrualWidth,
233+
toCropImgH: this.natrualHeight,
234+
};
235+
}
184236
return {
185237
toCropImgX: this.cropCSS.left / this.imgChangeRatio,
186238
toCropImgY: this.cropCSS.top / this.imgChangeRatio,

src/lib/canvas-helper.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,21 @@ export default {
5555
}
5656
},
5757

58+
resize(image, options, callback) {
59+
const checkNumber = function(num) {
60+
return (typeof num === 'number');
61+
};
62+
if(checkNumber(options.toCropImgX) && checkNumber(options.toCropImgY) && options.toCropImgW > 0 && options.toCropImgH > 0) {
63+
let w = options.toCropImgW * options.imgChangeRatio;
64+
let h = options.toCropImgH * options.imgChangeRatio;
65+
const cvs = this._getCanvas(w, h);
66+
const ctx = cvs.getContext('2d').drawImage(image, 0, 0, options.toCropImgW, options.toCropImgH, 0 , 0, w , h);
67+
const mimeType = this._getImageType(image.src);
68+
const data = cvs.toDataURL(mimeType, options.compress/100);
69+
callback(data);
70+
}
71+
},
72+
5873
_loadImage(data, callback) {
5974
const image = new Image();
6075
image.src = data;

src/lib/drag.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ export default function drag(e, el, coor) {
88
const currentX = isMobile ? e.changedTouches[0]['clientX'] : e.clientX;
99
const currentY = isMobile ? e.changedTouches[0]['clientY'] : e.clientY;
1010

11-
let left = currentX - el.parentElement.offsetLeft - document.getElementsByClassName('image-aside')[0].offsetLeft - coor.x;
11+
let left = currentX - el.parentElement.offsetLeft - coor.x;
1212
let top = currentY - el.parentElement.offsetTop - document.getElementsByClassName('image-aside')[0].offsetTop - coor.y;
1313
if (left <= 0) {
1414
left = 0;

src/lib/resize.js

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,7 @@
77
import helper from './helper';
88

99
const isMobile = helper.isMobile;
10-
1110
const W = document.body.offsetWidth;
12-
13-
14-
1511
export default function resize(e, el, container, coor, ratio) {
1612
if (!el) {
1713
return ;
@@ -70,10 +66,10 @@ export default function resize(e, el, container, coor, ratio) {
7066
} else if(ratio == 'auto' && resetY <= (halfY + dotBoxH + topH) && resetX <= halfY + dotBoxW) {
7167
CSSObj.height = (coor.h + resetY - coor.y);
7268
CSSObj.width = (coor.w + resetX - coor.x);
73-
} else if (resetX <= $halfX + dotBoxW) {
69+
} else if (resetX <= halfX + dotBoxW) {
7470
CSSObj.width = (coor.w + resetX - coor.x);
7571
CSSObj.height = el.style.width;
76-
// limit the copr box area
72+
// limit the crop box area
7773
if (dotBoxW > dotBoxH) {
7874
if (elOffsetHeight >= dotBoxH) {
7975
CSSObj.height = dotBoxH;

src/lib/xhr.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* simple ajax handler
33
**/
4+
45
//ADD sendAsBinary compatibilty to older browsers
56
if (XMLHttpRequest.prototype.sendAsBinary === undefined) {
67
XMLHttpRequest.prototype.sendAsBinary = function(string) {

src/props.js

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,11 @@ export default {
4343
},
4444
ResizeBtn: {
4545
type: Object,
46-
default: return {
47-
ok: 'Ok',
48-
cancel: 'Cancel'
46+
default: function() {
47+
return {
48+
ok: 'Ok',
49+
cancel: 'Cancel'
50+
}
4951
}
5052
},
5153
maxFileSize:{
@@ -86,6 +88,10 @@ export default {
8688
type: Number,
8789
default: 0
8890
},
91+
minWidth: {
92+
type: Number,
93+
default: 50,
94+
},
8995
compress: {
9096
type: [Number, String],
9197
default: 0,

src/style/style.css

Lines changed: 0 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@
3939
color:#f1f1f1;
4040
}
4141
.g-core-image-corp-container .image-aside{
42-
overflow: hidden;
4342
position: absolute;
4443
right: 30px;
4544
left:30px;
@@ -67,33 +66,6 @@
6766
background: #fefefe;
6867
color:#777;
6968
}
70-
.g-core-image-corp-container .info-aside .image-corp-preview{
71-
position: relative;
72-
overflow: hidden;
73-
text-align: center;
74-
border:2px solid #ccc;
75-
}
76-
.g-core-image-corp-container .info-aside .image-corp-preview.circled{
77-
border-radius: 160px;
78-
}
79-
.g-core-image-corp-container .info-aside .image-corp-preview img{
80-
width: 100%;
81-
}
82-
.g-core-image-corp-container .info-aside .config-info .image-details{
83-
width: 100%;
84-
color:#999;
85-
}
86-
87-
.g-core-image-corp-container .info-aside .config-info .image-details td{
88-
border:none;
89-
line-height: 24px;
90-
}
91-
.g-core-image-corp-container .info-aside .config-info .image-details tr td:first-child{
92-
width:36%;
93-
}
94-
.g-core-image-corp-container .info-aside .config-info .image-details tr td:last-child{
95-
color:#555;
96-
}
9769
.g-core-image-corp-container .btn-groups{
9870
text-align: right;
9971
margin: 5px 0 0;
@@ -135,5 +107,4 @@
135107
}
136108
.g-core-image-corp-container .g-crop-image-box,.g-core-image-corp-container .g-crop-image-box .g-crop-image-principal{
137109
position: relative;
138-
139110
}

0 commit comments

Comments
 (0)