(function(){ 'use strict'; /** * Group consists of tile array * @constructor * @param {array} tileArray - Tile array of PANOLENS.Tile * @param {number} verticalGap - Vertical gap between each tile * @param {number} depthGap - Depth gap between each tile * @param {number} animationDuration - Animation duration * @param {number} offset - Offset index */ PANOLENS.TileGroup = function ( tileArray, verticalGap, depthGap, animationDuration, offset ) { var scope = this, textureLoader; THREE.Object3D.call( this ); this.tileArray = tileArray || []; this.offset = offset !== undefined ? offset : 0; this.v_gap = verticalGap !== undefined ? verticalGap : 6; this.d_gap = depthGap !== undefined ? depthGap : 2; this.animationDuration = animationDuration !== undefined ? animationDuration : 200; this.animationEasing = TWEEN.Easing.Exponential.Out; this.visibleDelta = 2; this.tileArray.map( function ( tile, index ) { if ( tile.image ) { PANOLENS.Utils.TextureLoader.load( tile.image, scope.setTexture.bind( tile ) ); } tile.position.set( 0, index * -scope.v_gap, index * -scope.d_gap ); tile.originalPosition = tile.position.clone(); tile.setEntity( scope ); scope.add( tile ); } ); this.updateVisbility(); } PANOLENS.TileGroup.prototype = Object.create( THREE.Object3D.prototype ); PANOLENS.TileGroup.prototype.constructor = PANOLENS.TileGroup; /** * Update corresponding tile textures * @param {array} imageArray - Image array with index to index image update */ PANOLENS.TileGroup.prototype.updateTexture = function ( imageArray ) { var scope = this; imageArray = imageArray || []; this.children.map( function ( child, index ) { if ( child instanceof PANOLENS.Tile && imageArray[index] ) { PANOLENS.Utils.TextureLoader.load( imageArray[index], scope.setTexture.bind( child ) ); if ( child.outline ) { child.outline.material.visible = true; } } } ); }; /** * Update all tile textures and hide the remaining ones * @param {array} imageArray - Image array with index to index image update */ PANOLENS.TileGroup.prototype.updateAllTexture = function ( imageArray ) { this.updateTexture( imageArray ); if ( imageArray.length < this.children.length ) { for ( var i = imageArray.length; i < this.children.length; i++ ) { if ( this.children[i] instanceof PANOLENS.Tile ) { this.children[i].material.visible = false; if ( this.children[i].outline ) { this.children[i].outline.material.visible = false; } } } } } /** * Set individual texture * @param {THREE.Texture} texture - Texture to be updated */ PANOLENS.TileGroup.prototype.setTexture = function ( texture ) { texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter; this.material.visible = true; this.material.map = texture; this.material.needsUpdate = true; }; /** * Update visibility */ PANOLENS.TileGroup.prototype.updateVisbility = function () { this.children[this.offset].visible = true; new TWEEN.Tween( this.children[this.offset].material ) .to( { opacity: 1 }, this.animationDuration ) .easing( this.animationEasing ) .start(); if ( this.children[this.offset].outline ) { this.children[this.offset].outline.visible = true; } // Backward for ( var i = this.offset - 1; i >= 0 ; i-- ) { if ( this.tileArray.indexOf(this.children[i]) === -1 ) { continue; } if ( this.offset - i <= this.visibleDelta ) { this.children[i].visible = true; new TWEEN.Tween( this.children[i].material ) .to( { opacity: 1 / ( this.offset - i ) * 0.5 }, this.animationDuration ) .easing( this.animationEasing ) .start(); } else { this.children[i].visible = false; } this.children[i].outline && (this.children[i].outline.visible = false); } // Forward for ( var i = this.offset + 1; i < this.children.length ; i++ ) { if ( this.tileArray.indexOf(this.children[i]) === -1 ) { continue; } if ( i - this.offset <= this.visibleDelta ) { this.children[i].visible = true; new TWEEN.Tween( this.children[i].material ) .to( { opacity: 1 / ( i - this.offset ) * 0.5 }, this.animationDuration ) .easing( this.animationEasing ) .start(); } else { this.children[i].visible = false; } this.children[i].outline && (this.children[i].outline.visible = false); } }; /** * Scroll up * @param {number} duration - Scroll up duration */ PANOLENS.TileGroup.prototype.scrollUp = function ( duration ) { var tiles = this.tileArray, offset; duration = duration !== undefined ? duration : this.animationDuration; offset = this.offset + 1; if ( this.offset < tiles.length - 1 && tiles[ this.offset + 1 ].material.visible ) { for ( var i = tiles.length - 1; i >= 0; i-- ) { new TWEEN.Tween( tiles[i].position ) .to({ y: ( i - offset ) * -this.v_gap, z: Math.abs( i - offset ) * -this.d_gap }, duration ) .easing( this.animationEasing ) .start(); } this.offset ++; this.updateVisbility(); this.dispatchEvent( { type: 'scroll', direction: 'up' } ); } }; /** * Scroll down * @param {number} duration - Scroll up duration */ PANOLENS.TileGroup.prototype.scrollDown = function ( duration ) { var tiles = this.tileArray, offset; duration = duration !== undefined ? duration : this.animationDuration; offset = this.offset - 1; if ( this.offset > 0 && tiles[ this.offset - 1 ].material.visible ) { for ( var i = 0; i < tiles.length; i++ ) { new TWEEN.Tween( tiles[i].position ) .to({ y: ( i - offset ) * -this.v_gap, z: Math.abs( i - offset ) * -this.d_gap }, duration ) .easing( this.animationEasing ) .start(); } this.offset --; this.updateVisbility(); this.dispatchEvent( { type: 'scroll', direction: 'down' } ); } }; PANOLENS.TileGroup.prototype.reset = function () { this.tileArray.map( function ( child, index ) { child.position.copy( child.originalPosition ); } ); this.offset = 0; this.updateVisbility(); }; /** * Get current index * @return {number} Index of the group. Range from 0 to this.tileArray.length */ PANOLENS.TileGroup.prototype.getIndex = function () { return this.offset; }; /** * Get visible tile counts * @return {number} Number of visible tiles */ PANOLENS.TileGroup.prototype.getTileCount = function () { var count = 0; this.tileArray.map( function ( tile ) { if ( tile.material.visible ) { count ++; } } ); return count; }; })();