import * as Utils from '../utils' ; import { callbackNames , defaults , eventNames , eventsToPrevent , namespace } from './constants' ; import { applyLayout } from './layout' ; import { Data , Options } from './models' ; import { applyAnimation , stopAnimation } from './playback' ; import { applyPlugins } from './plugins' ; const $ = Utils . $ ; let counter = 0 ; /**
 * Collection of all SpriteSpin instances
 */ export const instances = { } ; function pushInstance ( data ) { counter += 1 ; data . id = String ( counter ) ; instances [ data . id ] = data ; } function popInstance ( data ) { delete instances [ data . id ] ; } function eachInstance ( cb ) { for ( const id in instances ) { if ( instances . hasOwnProperty ( id ) ) { cb ( instances [ id ] ) ; } } } let lazyinit = ( ) => { lazyinit = ( ) => { } ; function onEvent ( eventName , e ) { eachInstance ( ( data ) => { for ( const module of data . plugins ) { if ( typeof module [ eventName ] === 'function' ) { module [ eventName ] . apply ( data . target , [ e , data ] ) ; } } } ) ; } function onResize ( ) { eachInstance ( ( data ) => { if ( data . responsive ) { boot ( data ) ; } } ) ; } for ( const eventName of eventNames ) { $ ( window . document ) . bind ( eventName + '.' + namespace , ( e ) => { onEvent ( 'document' + eventName , e ) ; } ) ; } let resizeTimeout = null ; $ ( window ) . on ( 'resize' , ( ) => { window . clearTimeout ( resizeTimeout ) ; resizeTimeout = window . setTimeout ( onResize , 100 ) ; } ) ; } ; internal export function applyEvents ( data ) { const target = data . target ; Utils . unbind ( target ) ; for ( const eName of eventsToPrevent ) { Utils . bind ( target , eName , Utils . prevent ) ; } for ( const plugin of data . plugins ) { for ( const eName of eventNames ) { Utils . bind ( target , eName , plugin [ eName ] ) ; } for ( const eName of callbackNames ) { Utils . bind ( target , eName , plugin [ eName ] ) ; } } Utils . bind ( target , 'onLoad' , ( e , d ) => { applyAnimation ( d ) ; } ) ; for ( const eName of callbackNames ) { Utils . bind ( target , eName , data [ eName ] ) ; } } function applyMetrics ( data ) { if ( ! data . images ) { data . metrics = [ ] ; } data . metrics = Utils . measure ( data . images , data ) ; const spec = Utils . findSpecs ( data . metrics , data . frames , 0 , 0 ) ; if ( spec . sprite ) { data . frameWidth = spec . sprite . width ; data . frameHeight = spec . sprite . height ; } } remarks internal export function boot ( data ) { applyPlugins ( data ) ; applyEvents ( data ) ; applyLayout ( data ) ; data . source = Utils . toArray ( data . source ) ; data . loading = true ; data . target . addClass ( 'loading' ) . trigger ( 'onInit.' + namespace , data ) ; Utils . preload ( { source : data . source , crossOrigin : data . crossOrigin , preloadCount : data . preloadCount , progress : ( progress ) => { data . progress = progress ; data . target . trigger ( 'onProgress.' + namespace , data ) ; } , complete : ( images ) => { data . images = images ; data . loading = false ; data . frames = data . frames || images . length ; applyMetrics ( data ) ; applyLayout ( data ) ; data . stage . show ( ) ; data . target . removeClass ( 'loading' ) . trigger ( 'onLoad.' + namespace , data ) . trigger ( 'onFrame.' + namespace , data ) . trigger ( 'onDraw.' + namespace , data ) . trigger ( 'onComplete.' + namespace , data ) ; } } ) ; } public export function create ( options ) { const target = options . target ; const data = $ . extend ( true , { } , defaults , options ) as Data ; data . source = data . source || [ ] ; data . plugins = data . plugins || [ '360' , 'drag' ] ; target . find ( 'img' ) . each ( ( ) => { if ( ! Array . isArray ( data . source ) ) { data . source = [ ] ; } data . source . push ( $ ( this ) . attr ( 'src' ) ) ; } ) ; target . empty ( ) . addClass ( 'spritespin-instance' ) . append ( "<div class='spritespin-stage'></div>" ) ; if ( data . renderer === 'canvas' ) { const canvas = document . createElement ( 'canvas' ) ; if ( ! ! ( canvas . getContext && canvas . getContext ( '2d' ) ) ) { data . canvas = $ ( canvas ) . addClass ( 'spritespin-canvas' ) as any ; data . context = canvas . getContext ( '2d' ) ; target . append ( data . canvas ) ; target . addClass ( 'with-canvas' ) ; } else { data . renderer = 'image' ; } } data . target = target ; data . stage = target . find ( '.spritespin-stage' ) ; target . data ( namespace , data ) ; pushInstance ( data ) ; return data ; } public export function createOrUpdate ( options ) { lazyinit ( ) ; let data = options . target . data ( namespace ) as Data ; if ( ! data ) { data = create ( options ) ; } else { $ . extend ( data , options ) ; } boot ( data ) ; return data ; } remarks public export function destroy ( data ) { popInstance ( data ) ; stopAnimation ( data ) ; data . target . trigger ( 'onDestroy' , data ) . html ( null ) . attr ( 'style' , null ) . attr ( 'unselectable' , null ) . removeClass ( [ 'spritespin-instance' , 'with-canvas' ] ) ; Utils . unbind ( data . target ) ; data . target . removeData ( namespace ) ; }