Skip to content

Commit c4e9505

Browse files
committed
update new doc
1 parent 26ce24a commit c4e9505

19 files changed

+1047
-16
lines changed

dist/crop.vue

Lines changed: 339 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,339 @@
1+
<template>
2+
<div class="g-crop-image-principal">
3+
<div class="image-wrap" :style="{ width:width + 'px',height: height + 'px' }">
4+
<img ref="crop-image" :src="src" :style="{ width:'100%',height: '100%', }">
5+
</div>
6+
<div class="image-mask" v-if="!hideCrop">
7+
<div class="mask top" :style="{ top:0, height: cropCSS.top + 'px', left: 0, width: '100%'}"></div>
8+
<div class="mask bottom" :style="{ bottom:0, top: (cropCSS.top + cropCSS.height) + 'px', left: 0, width: '100%'}"></div>
9+
<div class="mask left" :style="{top: cropCSS.top + 'px', height: cropCSS.height + 'px', left:0, width: cropCSS.left + 'px'}"></div>
10+
<div class="mask right" :style="{top: cropCSS.top + 'px', height: cropCSS.height + 'px', left: (cropCSS.left + cropCSS.width) + 'px', right: 0}"></div>
11+
</div>
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'}">
13+
<div class="reference-line v"></div>
14+
<div class="reference-line h"></div>
15+
<a class="g-resize" v-on:touchstart.self="resize" v-on:mousedown.self="resize"></a>
16+
</div>
17+
</div>
18+
</template>
19+
20+
<style scoped>
21+
.image-mask{
22+
position: absolute;
23+
left: 0;
24+
top: 0;
25+
width:100%;
26+
height: 100%;
27+
}
28+
.image-mask .mask {
29+
position: absolute;
30+
background-color: rgba(255,255,255,.6);
31+
}
32+
.crop-box{
33+
box-sizing: border-box;
34+
position: absolute;
35+
background: none;
36+
cursor: move;
37+
width:100px;
38+
height: 100px;
39+
border:1px solid rgba(255,255,255, .95);
40+
}
41+
.crop-box:after,
42+
.crop-box:before{
43+
content: '';
44+
display: block;
45+
opacity: 0;
46+
position: absolute;
47+
left: 33.3333%;
48+
top: 0;
49+
width: 33.334%;
50+
height: 100%;
51+
background-color: transparent;
52+
border-color: rgba(255,255,255,.7);
53+
border-style: solid;
54+
border-width: 0;
55+
}
56+
.crop-box:active::before,
57+
.crop-box:active::after{
58+
opacity: 1;
59+
}
60+
.crop-box:before{
61+
border-left-width: 1px;
62+
border-right-width: 1px;
63+
}
64+
.crop-box:after{
65+
top: 33.3333%;
66+
left: 0;
67+
height: 33.3334%;
68+
width: 100%;
69+
border-top-width: 1px;
70+
border-bottom-width: 1px;
71+
72+
}
73+
.crop-box .g-resize{
74+
display: inline-block;
75+
z-index: 1910;
76+
position: absolute;
77+
bottom: -8px;
78+
right: -8px;
79+
width: 16px;
80+
height: 16px;
81+
cursor: se-resize;
82+
border-radius: 10px;
83+
background-color: #fff;
84+
box-shadow: 0 2px 4px -2px rgba(0,0,0,.25);
85+
}
86+
</style>
87+
88+
<script>
89+
import drag from './lib/drag';
90+
import resize from './lib/resize';
91+
import GIF_LOADING_SRC from './lib/loading-gif';
92+
import helper from './lib/helper';
93+
// set cropbox size in image
94+
const CROPBOX_PERCENT = 75;
95+
export default {
96+
props: {
97+
formId: {
98+
type: String,
99+
default: '',
100+
},
101+
ratio: {
102+
type: String,
103+
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,
116+
}
117+
},
118+
119+
data() {
120+
return {
121+
src: GIF_LOADING_SRC,
122+
width: 24,
123+
height: 24,
124+
cropCSS: {
125+
126+
}
127+
}
128+
},
129+
130+
methods: {
131+
setImage(src, w, h) {
132+
this.src = src;
133+
if (this.ratio.indexOf(':') > 0) {
134+
this.ratioW = this.ratio.split(':')[0];
135+
this.ratioH = this.ratio.split(':')[1];
136+
this.ratioVal = this.ratioW / this.ratioH;
137+
} else {
138+
this.ratioW = 1;
139+
this.ratioH = 1;
140+
this.ratioVal = this.ratio;
141+
}
142+
this.setLayout(w, h);
143+
this.setCropBox();
144+
this.natrualWidth = w;
145+
this.natrualHeight = h;
146+
return this.imgChangeRatio;
147+
},
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+
159+
setLayout(w, h) {
160+
let H = window.innerHeight - 80,
161+
W = window.innerWidth - 60,
162+
width = w,
163+
height = h,
164+
marginLeft = 0;
165+
166+
// caculate the image ratio
167+
let R = width / height;
168+
let Rs = W / H;
169+
if (R > Rs) {
170+
width = W;
171+
height = W / R;
172+
marginLeft = (H - W / R) / 2;
173+
} else {
174+
width = H * R,
175+
height = H;
176+
marginLeft = (W - H * R) / 2;
177+
}
178+
this.marginLeft = marginLeft;
179+
this.marginTop = 0;
180+
this.imgChangeRatio = width / w;
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;
194+
},
195+
196+
setCropBox() {
197+
if (this.hideCrop) {
198+
return;
199+
}
200+
let $selectCropBox = this.__find('.crop-box');
201+
let $wrap = this.$el;
202+
let imageWidth = this.width,
203+
imageHeight = this.height;
204+
let ratioW = this.ratioW,
205+
ratioH = this.ratioH;
206+
const baseCropWidth = (imageWidth / 100) * CROPBOX_PERCENT;
207+
const CSSObj = {
208+
width: baseCropWidth,
209+
height: (baseCropWidth / ratioW) * ratioH,
210+
}
211+
CSSObj.left = (imageWidth - baseCropWidth) / 2;
212+
CSSObj.top = (imageHeight - CSSObj.height) / 2;
213+
$selectCropBox.style.cssText = helper.setCssText(CSSObj);
214+
if (CSSObj.height > imageHeight) {
215+
const baseCropHeight = (imageHeight / 100) * CROPBOX_PERCENT
216+
CSSObj.height = baseCropHeight;
217+
CSSObj.width = (CSSObj.height * ratioW) / ratioH;
218+
CSSObj.left = (imageWidth - CSSObj.width) / 2,
219+
CSSObj.top = (imageHeight - CSSObj.height) / 2,
220+
$selectCropBox.style.cssText = helper.setCssText(CSSObj);
221+
};
222+
this.cropCSS = CSSObj;
223+
},
224+
225+
getCropData() {
226+
// 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+
}
236+
return {
237+
toCropImgX: this.cropCSS.left / this.imgChangeRatio,
238+
toCropImgY: this.cropCSS.top / this.imgChangeRatio,
239+
toCropImgW: this.cropCSS.width / this.imgChangeRatio,
240+
toCropImgH: this.cropCSS.height / this.imgChangeRatio,
241+
};
242+
},
243+
244+
getCropImage() {
245+
return this.$refs['crop-image'];
246+
},
247+
248+
__find(str) {
249+
let dq = document.querySelector('#vciu-modal-' + this.formId);
250+
return dq.querySelector(str);
251+
},
252+
// resize and drag move
253+
resize(e) {
254+
e.stopPropagation();
255+
let $el = e.target.parentElement;
256+
let $container = this.__find('.g-crop-image-principal');
257+
if (this._$container) {
258+
this._$container = container;
259+
}
260+
const self = this;
261+
const coor = {
262+
x: helper.isMobile ? e.touches[0].clientX : e.clientX,
263+
y: helper.isMobile ? e.touches[0].clientY : e.clientY,
264+
w: parseInt(window.getComputedStyle($el).width, 10),
265+
h: parseInt(window.getComputedStyle($el).height, 10)
266+
};
267+
this.el = $el;
268+
this.container = $container;
269+
const move = function (ev) {
270+
const newCropStyle = resize(ev, self.el, $container, coor, self.ratioVal);
271+
if (newCropStyle) {
272+
self.cropCSS.width = newCropStyle.width;
273+
self.cropCSS.height = newCropStyle.height;
274+
}
275+
276+
};
277+
const end = function (ev) {
278+
this.el = null;
279+
if (helper.isMobile) {
280+
document.removeEventListener('touchmove', move, false);
281+
document.removeEventListener('touchend', end, false);
282+
}
283+
document.removeEventListener('mousemove', move, false);
284+
document.removeEventListener('mouseup', end, false);
285+
};
286+
287+
if (helper.isMobile) {
288+
document.addEventListener('touchmove', move, false);
289+
document.addEventListener('touchend', end, false);
290+
}
291+
document.addEventListener('mousemove', move, false);
292+
document.addEventListener('mouseup', end, false);
293+
},
294+
295+
drag(e) {
296+
e.preventDefault();
297+
const $el = e.target;
298+
this.el = $el;
299+
const $container = this.$el;
300+
const $infoAside = document.getElementsByClassName('image-aside')[0];
301+
const self = this;
302+
const isMobile = helper.isMobile;
303+
const coor = {
304+
x: (isMobile ? e.touches[0]['clientX'] : e.clientX) - $el.offsetLeft - $el.parentElement.offsetLeft - $infoAside.offsetLeft,
305+
y: (isMobile ? e.touches[0]['clientY'] : e.clientY) - $el.offsetTop - $el.parentElement.offsetTop - $infoAside.offsetTop,
306+
posX: isMobile ? e.touches[0]['clientX'] : e.clientX,
307+
posy: isMobile ? e.touches[0]['clientY'] : e.clientY,
308+
maxLeft: parseInt($container.style.width) - parseInt($el.style.width),
309+
maxTop: parseInt($container.style.height) - parseInt($el.style.height),
310+
};
311+
const move = function (ev) {
312+
const newCropStyle = drag(ev, self.el, coor);
313+
if (newCropStyle) {
314+
self.cropCSS.left = newCropStyle.left;
315+
self.cropCSS.top = newCropStyle.top;
316+
}
317+
};
318+
const stopMove = function (ev) {
319+
self.el = null;
320+
if (isMobile) {
321+
document.removeEventListener('touchmove', move, false);
322+
document.removeEventListener('touchend', stopMove, false);
323+
return;
324+
}
325+
document.removeEventListener('mousemove', move, false);
326+
document.removeEventListener('mouseup', stopMove, false);
327+
};
328+
if (isMobile) {
329+
document.addEventListener('touchmove', move, false);
330+
document.addEventListener('touchend', stopMove, false);
331+
return;
332+
}
333+
document.addEventListener('mousemove', move, false);
334+
document.addEventListener('mouseup', stopMove, false);
335+
},
336+
},
337+
338+
}
339+
</script>

dist/index.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import VueCoreImageUpload from './vue-core-image-upload.vue';
2+
export default VueCoreImageUpload;

dist/lib/canvas-helper.js

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

dist/lib/drag.js

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

dist/lib/helper.js

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

dist/lib/loading-gif.js

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

0 commit comments

Comments
 (0)