Skip to content

Commit 95ece85

Browse files
committed
update: 动画逻辑代码重构 🎨
1 parent b7dbb38 commit 95ece85

File tree

3 files changed

+45
-134
lines changed

3 files changed

+45
-134
lines changed

src/common/utils.js

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,7 @@ const isPlainObject = value => {
1616
return Object.prototype.toString.call(value) === '[object Object]';
1717
};
1818

19-
/**
20-
* 比较两个值(取绝对值)
21-
* @param a
22-
* @param b
23-
*/
24-
const compareNumberABS = (a = 0, b = 0) => {
25-
return Math.abs(a - b) > 0.05;
26-
};
27-
2819
export {
2920
isNumber,
30-
isPlainObject,
31-
compareNumberABS
21+
isPlainObject
3222
};

src/core/imageViewer.js

Lines changed: 43 additions & 123 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,7 @@ import {
1515
} from '../common/profile';
1616
import {
1717
isNumber,
18-
isPlainObject,
19-
compareNumberABS
18+
isPlainObject
2019
} from '../common/utils';
2120
import lock from '../common/lock';
2221
import Touch from './touch';
@@ -281,67 +280,49 @@ class ImageViewer {
281280
}
282281
}
283282

283+
_animation(url, type, callback) {
284+
const duration = this.duration;
285+
const style = this.animationEl.style;
286+
const currentViewer = this._getCurrentViewer();
287+
const start = type === 1 ? this.opt.fadeInFn(this.currentIndex) : currentViewer.el;
288+
const end = type === 1 ? currentViewer.el : this.opt.fadeInFn(this.currentIndex);
289+
const data = this._getPositionAndSize(start);
290+
const target = this._getPositionAndSize(end);
291+
const stepTop = (target.top - data.top) / duration;
292+
const stepLeft = (target.left - data.left) / duration;
293+
const stepScaleX = (target.width - data.width) / data.width / duration;
294+
const stepScaleY = (target.height - data.height) / data.height / duration;
295+
let stepOpacity = 1 / duration;
296+
let count = 0;
297+
298+
style.top = data.top + 'px';
299+
style.left = data.left + 'px';
300+
style.width = data.width + 'px';
301+
style.height = data.height + 'px';
302+
const animationFn = () => {
303+
count++;
304+
if (count <= duration) {
305+
style.width = (1 + stepScaleX * count) * data.width + 'px';
306+
style.height = (1 + stepScaleY * count) * data.height + 'px';
307+
setTranslateStyle(this.animationEl, stepLeft * count, stepTop * count);
308+
this.bodyEl.style.opacity = type === 1 ? (stepOpacity * count) : (1 - stepOpacity * count);
309+
window.requestAnimationFrame(animationFn);
310+
} else {
311+
window.requestAnimationFrame(() => {
312+
this.animationEl.classList.add('hide');
313+
callback();
314+
});
315+
}
316+
};
317+
this.animationEl.children[0].src = url;
318+
this.animationEl.classList.remove('hide');
319+
animationFn();
320+
}
321+
284322
_fadeIn(callback) {
285323
if (this.opt.fadeInFn) {
286324
const image = this._getCurrentImage();
287-
const duration = this.duration;
288-
const data = this._getPositionAndSize(this.opt.fadeInFn(this.currentIndex));
289-
const style = this.animationEl.style;
290-
style.top = data.top + 'px';
291-
style.left = data.left + 'px';
292-
style.width = data.width + 'px';
293-
style.height = data.height + 'px';
294-
295-
const currentViewer = this._getCurrentViewer();
296-
const rect = this._getPositionAndSize(currentViewer.el);
297-
let stepTop = (rect.top - data.top) / duration;
298-
let stepLeft = (rect.left - data.left) / duration;
299-
let stepWidth = (rect.width - data.width) / duration;
300-
let stepHeight = (rect.height - data.height) / duration;
301-
let stepOpacity = 1 / duration;
302-
let currentOpacity = 0;
303-
let offsetTop = 0;
304-
let offsetLeft = 0;
305-
let nextAnimation = true;
306-
307-
const animationFn = () => {
308-
if (nextAnimation) {
309-
nextAnimation = false;
310-
if (compareNumberABS(rect.top, data.top + offsetTop)) {
311-
offsetTop += stepTop;
312-
nextAnimation = true;
313-
}
314-
if (compareNumberABS(rect.left, data.left + offsetLeft)) {
315-
offsetLeft += stepLeft;
316-
nextAnimation = true;
317-
}
318-
if (compareNumberABS(rect.width, data.width)) {
319-
data.width += stepWidth;
320-
style.width = data.width + 'px';
321-
nextAnimation = true;
322-
}
323-
if (compareNumberABS(rect.height, data.height)) {
324-
data.height += stepHeight;
325-
style.height = data.height + 'px';
326-
nextAnimation = true;
327-
}
328-
if (currentOpacity < 1) {
329-
currentOpacity += stepOpacity;
330-
this.bodyEl.style.opacity = currentOpacity;
331-
nextAnimation = true;
332-
}
333-
setTranslateStyle(this.animationEl, offsetLeft.toFixed(4), offsetTop.toFixed(4));
334-
window.requestAnimationFrame(animationFn);
335-
} else {
336-
window.requestAnimationFrame(() => {
337-
this.animationEl.classList.add('hide');
338-
callback();
339-
});
340-
}
341-
};
342-
this.animationEl.children[0].src = image.thumbnail || image.url;
343-
this.animationEl.classList.remove('hide');
344-
animationFn();
325+
this._animation(image.thumbnail || image.url, 1, callback);
345326
} else {
346327
callback();
347328
}
@@ -350,69 +331,7 @@ class ImageViewer {
350331
_fadeOut(callback) {
351332
if (this.opt.fadeOutFn) {
352333
const image = this._getCurrentImage();
353-
const duration = this.duration;
354-
const data = this._getPositionAndSize(this.opt.fadeInFn(this.currentIndex));
355-
const style = this.animationEl.style;
356-
style.top = data.top + 'px';
357-
style.left = data.left + 'px';
358-
359-
const currentViewer = this._getCurrentViewer();
360-
const rect = this._getPositionAndSize(currentViewer.el);
361-
let differTop = rect.top - data.top;
362-
let differLeft = rect.left - data.left;
363-
let stepTop = differTop / duration;
364-
let stepLeft = differLeft / duration;
365-
let stepWidth = (rect.width - data.width) / duration;
366-
let stepHeight = (rect.height - data.height) / duration;
367-
let stepOpacity = 1 / duration;
368-
let currentOpacity = 1;
369-
let currentWidth = rect.width;
370-
let currentHeight = rect.height;
371-
let nextAnimation = true;
372-
373-
setTranslateStyle(this.animationEl, differLeft, differTop);
374-
style.width = rect.width + 'px';
375-
style.height = rect.height + 'px';
376-
const animationFn = () => {
377-
if (nextAnimation) {
378-
nextAnimation = false;
379-
if (compareNumberABS(differTop)) {
380-
differTop -= stepTop;
381-
nextAnimation = true;
382-
}
383-
if (compareNumberABS(differLeft)) {
384-
differLeft -= stepLeft;
385-
nextAnimation = true;
386-
}
387-
if (compareNumberABS(currentWidth, data.width)) {
388-
currentWidth -= stepWidth;
389-
currentWidth = compareNumberABS(currentWidth, data.width) ? currentWidth : data.width;
390-
style.width = currentWidth + 'px';
391-
nextAnimation = true;
392-
}
393-
if (compareNumberABS(currentHeight, data.height)) {
394-
currentHeight -= stepHeight;
395-
currentHeight = compareNumberABS(currentHeight, data.height) ? currentHeight : data.height;
396-
style.height = currentHeight + 'px';
397-
nextAnimation = true;
398-
}
399-
if (currentOpacity > 0) {
400-
currentOpacity -= stepOpacity;
401-
this.bodyEl.style.opacity = currentOpacity >= 0 ? currentOpacity : 0;
402-
nextAnimation = true;
403-
}
404-
setTranslateStyle(this.animationEl, differLeft.toFixed(4), differTop.toFixed(4));
405-
window.requestAnimationFrame(animationFn);
406-
} else {
407-
window.requestAnimationFrame(() => {
408-
this.animationEl.classList.add('hide');
409-
callback();
410-
});
411-
}
412-
};
413-
this.animationEl.children[0].src = image.url;
414-
this.animationEl.classList.remove('hide');
415-
animationFn();
334+
this._animation(image.url, 2, callback);
416335
} else {
417336
callback();
418337
}
@@ -559,6 +478,7 @@ class ImageViewer {
559478
}
560479
this.el.style.display = 'block';
561480
this.swipeInByIndex(this.currentIndex, false, () => {
481+
this._getCurrentViewer().removeAnimation();
562482
window.requestAnimationFrame(() => {
563483
this._fadeIn(() => {
564484
this.bodyEl.style.opacity = 1;

src/css/index.styl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@
7272
position absolute
7373
z-index 5
7474
will-change transform, width, height
75+
backface-visibility hidden
7576

7677
img {
7778
max-width 100%

0 commit comments

Comments
 (0)