Skip to content

Commit 02a0dd7

Browse files
author
zhaolongfei
committed
feat(api): add previewImage api
1 parent e45d51b commit 02a0dd7

File tree

2 files changed

+198
-3
lines changed

2 files changed

+198
-3
lines changed

packages/mars-api/api/file/image.js

Lines changed: 195 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,201 @@ export function getImageInfo() {
3535
// TODO
3636
}
3737

38-
export function previewImage() {
39-
// TODO
38+
export function previewImage(options = {}) {
39+
const {
40+
current,
41+
urls,
42+
success,
43+
fail,
44+
complete
45+
} = options;
46+
if (!urls || !urls.length) {
47+
const err = {
48+
errCode: 904,
49+
errMsg: '[jsNative Argument Error]urls is required.'
50+
};
51+
callback(fail, err);
52+
return Promise.reject(err);
53+
}
54+
55+
const swiperStyle = {
56+
position: 'fixed',
57+
zIndex: 10000,
58+
top: 0,
59+
left: 0,
60+
right: 0,
61+
bottom: 0,
62+
background: '#000',
63+
overflow: 'hidden'
64+
};
65+
const swiperDom = document.createElement('div');
66+
swiperDom.className = 'mars-swiper';
67+
Object.keys(swiperStyle).forEach(key => {
68+
swiperDom.style[key] = swiperStyle[key];
69+
});
70+
71+
const swiperWrapperStyle = {
72+
position: 'absolute',
73+
top: 0,
74+
left: 0,
75+
width: urls.length + '00%',
76+
height: '100%'
77+
};
78+
const swiperWrapperDom = document.createElement('div');
79+
swiperWrapperDom.className = 'mars-swiper-wrapper';
80+
Object.keys(swiperWrapperStyle).forEach(key => {
81+
swiperWrapperDom.style[key] = swiperWrapperStyle[key];
82+
});
83+
84+
const swiperItemSyle = {
85+
position: 'relative',
86+
float: 'left',
87+
width: 100 / urls.length + '%',
88+
height: '100%',
89+
display: 'flex',
90+
background: 'url(https://mms-graph.cdn.bcebos.com/activity/mp_loading.gif) no-repeat center',
91+
backgroundSize: '30px auto'
92+
};
93+
94+
for (const url of urls) {
95+
const swiperItemDom = document.createElement('div');
96+
swiperItemDom.className = 'mars-swiper-item';
97+
Object.keys(swiperItemSyle).forEach(key => {
98+
swiperItemDom.style[key] = swiperItemSyle[key];
99+
});
100+
101+
swiperItemDom.addEventListener('click', e => {
102+
swiperDom.remove();
103+
}, false);
104+
105+
const imgStyle = {
106+
position: 'absolute',
107+
top: 0,
108+
left: 0,
109+
display: 'none'
110+
};
111+
const img = document.createElement('img');
112+
img.src = url;
113+
Object.keys(imgStyle).forEach(key => {
114+
img.style[key] = imgStyle[key];
115+
});
116+
img.onload = e => {
117+
img.ratio = img.height / img.width;
118+
swiperDom.ratio = swiperDom.ratio || swiperDom.offsetHeight / swiperDom.offsetWidth;
119+
if (img.ratio > swiperDom.ratio) {
120+
img.style.height = swiperDom.offsetHeight + 'px';
121+
img.realWidth = swiperDom.offsetHeight / img.ratio;
122+
img.style.width = img.realWidth + 'px';
123+
img.style.left = (swiperDom.offsetWidth - img.realWidth) / 2 + 'px';
124+
} else {
125+
img.style.width = swiperDom.offsetWidth + 'px';
126+
img.realHeight = swiperDom.offsetWidth * img.ratio;
127+
img.style.height = img.realHeight + 'px';
128+
img.style.top = (swiperDom.offsetHeight - img.realHeight) / 2 + 'px';
129+
}
130+
img.style.display = 'block';
131+
};
132+
swiperItemDom.appendChild(img);
133+
swiperWrapperDom.appendChild(swiperItemDom);
134+
}
135+
136+
// 进度条
137+
const swiperProgressStyle = {
138+
position: 'absolute',
139+
left: '17px',
140+
bottom: '20px',
141+
fontSize: '14px',
142+
color: '#fff',
143+
'text-shadow': '1px 1px 3px #000'
144+
};
145+
const swiperProgress = document.createElement('label');
146+
swiperProgress.className = 'mars-swiper-progress';
147+
Object.keys(swiperProgressStyle).forEach(key => {
148+
swiperProgress.style[key] = swiperProgressStyle[key];
149+
});
150+
151+
swiperDom.appendChild(swiperWrapperDom);
152+
swiperDom.appendChild(swiperProgress);
153+
document.body.appendChild(swiperDom);
154+
155+
// 设置初始位置
156+
let initLoc = 0;
157+
for (let i = 0; i < urls.length; i++) {
158+
if (urls[i] === current) {
159+
initLoc = i;
160+
break;
161+
}
162+
}
163+
swiperProgress.innerHTML = (initLoc + 1) + '/' + urls.length;
164+
// 初始偏移位置
165+
const initOffset = -swiperDom.offsetWidth * initLoc;
166+
swiperWrapperDom.style.left = initOffset + 'px';
167+
168+
// 滑动事件
169+
const touches = {
170+
startX: 0,
171+
oriStartX: 0,
172+
sliding: false,
173+
transformX: initOffset,
174+
lastTransformX: 0,
175+
transition: '0.32s ease-in-out',
176+
slideLimit: [0, swiperDom.offsetWidth * (urls.length - 1)]
177+
};
178+
179+
swiperWrapperDom.addEventListener('touchstart', e => {
180+
if (touches.sliding) {
181+
return;
182+
}
183+
touches.startX = e.touches[0].pageX || e.touches[0].clientX;
184+
touches.oriStartX = e.touches[0].pageX || e.touches[0].clientX;
185+
}, false);
186+
187+
swiperWrapperDom.addEventListener('touchmove', e => {
188+
if (touches.sliding) {
189+
return;
190+
}
191+
const moveX = e.touches[0].pageX || e.touches[0].clientX;
192+
193+
touches.transformX += moveX - touches.startX;
194+
195+
if (touches.transformX > touches.slideLimit[0]) {
196+
// 滑到第一个不能再右滑
197+
touches.transformX = 0;
198+
} else if (touches.transformX < -touches.slideLimit[1]) {
199+
// 滑到最后一个不能再左滑
200+
touches.transformX = -touches.slideLimit[1];
201+
}
202+
swiperWrapperDom.style.left = touches.transformX + 'px';
203+
touches.startX = moveX;
204+
}, false);
205+
206+
swiperWrapperDom.addEventListener('touchend', e => {
207+
if (touches.sliding) {
208+
return;
209+
}
210+
const endX = e.changedTouches[0].pageX || e.changedTouches[0].clientX;
211+
const distX = endX - touches.oriStartX;
212+
if (Math.abs(distX) < 30) {
213+
touches.transformX = touches.lastTransformX;
214+
} else {
215+
const passX = Math.abs(touches.transformX) / swiperDom.offsetWidth;
216+
const slideTo = distX < 0 ? Math.ceil(passX) : Math.floor(passX);
217+
touches.transformX = -swiperDom.offsetWidth * slideTo;
218+
swiperProgress.innerHTML = (slideTo + 1) + '/' + urls.length;
219+
}
220+
swiperWrapperDom.style.left = touches.transformX + 'px';
221+
swiperWrapperDom.style.transition = touches.transition;
222+
touches.sliding = true;
223+
setTimeout(_ => {
224+
swiperWrapperDom.style.transition = 'none';
225+
touches.sliding = false;
226+
touches.lastTransformX = touches.transformX;
227+
}, 320);
228+
}, false);
229+
230+
callback(success, {});
231+
callback(complete, {});
232+
return Promise.resolve({});
40233
}
41234

42235
export function saveImageToPhotosAlbum() {

packages/mars-api/api/file/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,8 @@
44
*/
55

66
import {
7-
chooseImage
7+
chooseImage,
8+
previewImage
89
} from './image';
910

1011
import {
@@ -13,5 +14,6 @@ import {
1314

1415
export {
1516
chooseImage,
17+
previewImage,
1618
uploadFile
1719
};

0 commit comments

Comments
 (0)