UNPKG

@curiousmedia/createjs-scene-container

Version:

A scene manager for CreateJS

223 lines (177 loc) 4.85 kB
const _scenes = {}; const _transitions = {}; let instance; export default class SceneContainer extends createjs.Container { constructor() { super(); if ( instance ) throw new Error( "Only one instance of SceneContainer allowed" ); this.anchorX = 0.5; this.anchorY = 0.5; this._last = null; this.lastID = ""; this.current = null; this.currentID = ""; } static get scenes() { return _scenes; } static get currentScene() { return SceneContainer.getCurrentScene(); } static getInstance() { if ( !instance ) instance = new SceneContainer(); return instance; } static getCurrentScene() { return instance && instance.current; } static registerScene( sceneId, SceneClass ) { // console.log( "Registering Scene: ", sceneId ); _scenes[sceneId] = { id: sceneId, sceneClass: SceneClass }; } static registerTransition( transitionId, TransitionClass ) { // console.log( "Registering Transition/Loader Scene: ", transitionId ); _transitions[transitionId] = { id: transitionId, instance: new TransitionClass( transitionId ) }; } static registerDefaultTransition( TransitionClass ) { this.registerTransition( "default", TransitionClass); } static getSceneDefinition( sceneId ) { return _scenes[sceneId] || false; } static getTransitionDefinition( transitionId ) { return _transitions[transitionId] || false; } static gotoScene( sceneId, options, transitionId, transitionOptions ) { instance.gotoScene( sceneId, options, transitionId, transitionOptions ); } gotoScene( sceneId, options, transitionId = "default", transitionOptions = {} ) { const current = this.current; const nextSceneDef = SceneContainer.getSceneDefinition( sceneId ); if ( !nextSceneDef ) { throw new Error( "No Scene with id: " + sceneId ); } _log(" ------ "); _log("Starting Scene Change"); // Start promise chain let promiseChain = Promise.resolve(); let transition; // If there's a current scene if ( current ) { _log("Removing Current Scene"); promiseChain = promiseChain.then( () => current.end() ); // end it promiseChain = promiseChain.then( () => current.animateOut() ); // animate out // Transition const transitionDef = SceneContainer.getTransitionDefinition( transitionId ); transition = transitionDef.instance; if ( transition ) { _log("Adding Transition"); promiseChain = promiseChain.then( () => this.addTransition( transition ) ); promiseChain = promiseChain.then( () => transition.setup( transitionOptions ) ); promiseChain = promiseChain.then( () => transition.animateIn() ); promiseChain = promiseChain.then( () => transition.loadAssets() ); } } _log("Next Scene: " + nextSceneDef.id); // Start prepping next scene const NextSceneClass = nextSceneDef.sceneClass; _log("Loading Next Scene"); promiseChain = promiseChain.then( () => NextSceneClass.preload() ); _log("Creating Next Scene"); // Now make the next scene let next; promiseChain = promiseChain.then( () => { next = new NextSceneClass( nextSceneDef.id, options ); return Promise.resolve(); } ); // swap scenes promiseChain = promiseChain.then( () => this.swapScenes( current, next ) ); promiseChain = promiseChain.then( () => next.setup( options ) ); promiseChain = promiseChain.then( () => next.reset() ); if ( transition ) { _log("Removing Transition"); promiseChain = promiseChain.then( () => transition.animateOut() ); promiseChain = promiseChain.then( () => { this.removeChild( transition ); return Promise.resolve(); } ); } promiseChain = promiseChain.then( () => next.animateIn() ); promiseChain.then( () => next.start() ); } setScreenAnchors( anchorX = 0.5, anchorY = 0.5 ) { this.anchorX = anchorX; this.anchorY = anchorY; } swapScenes( current, next ) { if ( current ) { current.destroy(); this.removeChild( current ); } this.addChildAt( next, 0 ); this.current = next; const event = new Event( "change" ); event.current = this.current; event.previous = current; this.dispatchEvent( event ); return Promise.resolve(); } addTransition( loaderOfTransition ) { this.addChild( loaderOfTransition ); return Promise.resolve(); } transitOut() { return this.transitionOverlay.transitOut(); } transitIn() { return this.transitionOverlay.transitIn(); } _tick( evt ) { super._tick( evt ); const stage = this.stage; if ( stage && this.parent === stage ) { this.x = Math.floor( stage.canvas.width * this.anchorX ); this.y = Math.floor( stage.canvas.height * this.anchorY ); } if ( this.current ) { this.current.update( evt.delta / 1000 ); } } } function _log( message ) { const promise = new Promise( resolve => { console.log(message); resolve(); }); return promise; }