UNPKG

@curiousmedia/createjs-scene-container

Version:

A scene manager for CreateJS

356 lines (287 loc) 7 kB
class Scene extends createjs.Container { constructor( name, options ) { super(); // console.log( "Scene Created: ", name, options ); this.name = name; this.options = options; this.active = false; } static preload() { return Promise.resolve(); } setup() { // console.log("Set up....", this.name); return Promise.resolve(); } reset() { // console.log("Resetting....", this.name); return Promise.resolve(); } start() { this.setActive( true ); return Promise.resolve(); } end() { this.setActive( false ); return Promise.resolve(); } setActive( active ) { // console.log("Set Active", active); this.active = active; } animateIn() { // console.log("Animating in....", this.name); return Promise.resolve(); } animateOut() { // console.log("Animating out....", this.name); return Promise.resolve(); } resize( width, height ) { } update() { } destroy() { this.setActive( false ); } } const _scenes = {}; const _transitions = {}; let instance; 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; } class SceneTransition extends Scene { constructor( name, options ) { super( name, options ); } loadAssets() { return Promise.resolve(); } } class DefaultSceneTransition extends SceneTransition { constructor( name, options, color = "#000" ) { super( name, options ); // TODO: Reference app settings const width = 1664; const height = 768; this.regX = width / 2; this.regY = height / 2; this.overlay = new createjs.Shape(); this.overlay.graphics.f( color ).dr( 0, 0, width, height ); this.overlay.set( { alpha: 0, visible: false } ); this.addChild( this.overlay ); } animateIn() { // console.log("Animating in....", this.name); return new Promise( resolve => { createjs.Tween.get( this.overlay ) .set( { visible: true } ) .to( { alpha: 1 }, 250, createjs.Ease.quadInOut ) .call( resolve ); } ); } animateOut() { // console.log("Animating in....", this.name); return new Promise( resolve => { createjs.Tween.get( this.overlay ) .to( { alpha: 0 }, 250, createjs.Ease.quadInOut ) .set( { visible: false } ) .call( resolve ); } ); } } export { DefaultSceneTransition, Scene, SceneContainer, SceneTransition };