@@ -15,8 +15,7 @@ import {
1515} from '../common/profile' ;
1616import {
1717 isNumber ,
18- isPlainObject ,
19- compareNumberABS
18+ isPlainObject
2019} from '../common/utils' ;
2120import lock from '../common/lock' ;
2221import 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 ;
0 commit comments