( function () { /** * Creates a tile with bent capability * @constructor * @param {number} [width=10] - Width along the X axis * @param {number} [height=5] - Height along the Y axis * @param {number} [widthSegments=20] - Width segments * @param {number} [heightSegments=20] - Height segments * @param {THREE.Vector3} [forceDirection=THREE.Vector3( 0, 0, 1 )] - Force direction * @param {THREE.Vector3} [forceAxis=THREE.Vector3( 0, 1, 0 )] - Along this axis * @param {number} [forceAngle=Math.PI/12] - Angle to bend in radians */ PANOLENS.Tile = function ( width, height, widthSegments, heightSegments, forceDirection, forceAxis, forceAngle ) { var scope = this; this.parameters = { width: width, height: height, widthSegments: widthSegments, heightSegments: heightSegments, forceDirection: forceDirection, forceAxis: forceAxis, forceAngle: forceAngle }; width = width || 10; height = height || 5; widthSegments = widthSegments || 1; heightSegments = heightSegments || 1; forceDirection = forceDirection || new THREE.Vector3( 0, 0, 1 ); forceAxis = forceAxis || new THREE.Vector3( 0, 1, 0 ); forceAngle = forceAngle !== undefined ? forceAngle : 0; THREE.Mesh.call( this, new THREE.PlaneGeometry( width, height, widthSegments, heightSegments ), new THREE.MeshBasicMaterial( { color: 0xffffff, transparent: true } ) ); this.bendModifier = new THREE.BendModifier(); this.entity = undefined; this.animationDuration = 500; this.animationFadeOut = undefined; this.animationFadeIn = undefined; this.animationTranslation = undefined; this.tweens = {}; if ( forceAngle !== 0 ) { this.bend( forceDirection, forceAxis, forceAngle ); } this.originalGeometry = this.geometry.clone(); } PANOLENS.Tile.prototype = Object.create( THREE.Mesh.prototype ); PANOLENS.Tile.prototype.constructor = PANOLENS.Tile; PANOLENS.Tile.prototype.clone = function (){ var parameters = this.parameters, tile; tile = new PANOLENS.Tile( parameters.width, parameters.height, parameters.widthSegments, parameters.heightSegments, parameters.forceDirection, parameters.forceAxis, parameters.forceAngle ); tile.setEntity( this.entity ); tile.material = this.material.clone(); return tile; }; /** * Bend panel with direction, axis, and angle * @param {THREE.Vector3} direction - Force direction * @param {THREE.Vector3} axis - Along this axis * @param {number} angle - Angle to bend in radians */ PANOLENS.Tile.prototype.bend = function ( direction, axis, angle ) { this.bendModifier.set( direction, axis, angle ).modify( this.geometry ); }; /** * Restore geometry back to initial state */ PANOLENS.Tile.prototype.unbend = function () { var geometry = this.geometry; this.geometry = this.originalGeometry; this.originalGeometry = this.geometry.clone(); geometry.dispose(); geometry = null; }; /** * Create a tween object for animation * based on - {@link https://github.com/tweenjs/tween.js} * @param {string} name - Name of the tween animation * @param {object} object - Object to be tweened * @param {object} toState - Final state of the object's properties * @param {number} duration - Tweening duration * @param {TWEEN.Easing} easing - Easing function * @param {number} delay - Animation delay time * @param {Function} onStart - On start function * @param {Function} onUpdate - On update function * @param {Function} onComplete - On complete function * @return {TWEEN.Tween} - Tween object */ PANOLENS.Tile.prototype.tween = function ( name, object, toState, duration, easing, delay, onStart, onUpdate, onComplete ) { object = object || this; toState = toState || {}; duration = duration || this.animationDuration; easing = easing || TWEEN.Easing.Exponential.Out; delay = delay !== undefined ? delay : 0; onStart = onStart ? onStart : null; onUpdate = onUpdate ? onUpdate : null; onComplete = onComplete ? onComplete : null; if ( !this.tweens[name] ) { this.tweens[name] = new TWEEN.Tween( object ) .to( toState, duration ) .easing( easing ) .delay( delay ) .onStart( onStart ) .onUpdate( onUpdate ) .onComplete( onComplete ); } return this.tweens[name]; }; /** * Short-hand for displaying a single ripple effect * by duplicating itself and fadeout * @param {number} scale - The duplicated self fadeout scale * @param {number} duration - Effect duration * @param {TWEEN.Easing} easing - Easing function */ PANOLENS.Tile.prototype.ripple = function ( scale, duration, easing ) { scale = scale || 2; duration = duration || 200; easing = easing || TWEEN.Easing.Cubic.Out; var scope = this, ripple = this.clone(); new TWEEN.Tween( ripple.scale ) .to({x: scale, y: scale}, duration ) .easing( easing ) .start(); new TWEEN.Tween( ripple.material ) .to({opacity: 0}, duration ) .easing( easing ) .onComplete(function(){ scope.remove( ripple ); ripple.geometry.dispose(); ripple.material.dispose(); }) .start(); this.add( ripple ); }; /** * Set entity if multiple objects are considered as one entity * @param {object} entity - Entity represents whole group structure */ PANOLENS.Tile.prototype.setEntity = function ( entity ) { this.entity = entity; }; } )();