Skip to content

Commit

Permalink
Introduce key frame animation functionality for doe
Browse files Browse the repository at this point in the history
  • Loading branch information
richtr committed Jul 15, 2015
1 parent 8fe2437 commit 93454f9
Show file tree
Hide file tree
Showing 8 changed files with 722 additions and 183 deletions.
1 change: 1 addition & 0 deletions controller/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<script src="js/third_party/three.min.js"></script>
<script src="js/third_party/tween.min.js"></script>
<script src="js/third_party/fulltilt.min.js"></script>
<script src="js/DeviceOrientationEmulatorControls.js"></script>
<script src="js/utils.js"></script>
Expand Down
180 changes: 170 additions & 10 deletions controller/js/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ var APP = {
var rotation = new THREE.Euler( 0, 0, 0, 'YXZ' );
var rotQuat = new THREE.Quaternion();

var tweenInProgress = false;

this.load = function( json ) {

renderer = new THREE.WebGLRenderer( {
Expand Down Expand Up @@ -126,19 +128,173 @@ var APP = {

};

this.setManualOrientation = function( alpha, beta, gamma ) {
this.setManualOrientation = ( function() {

var _x = THREE.Math.degToRad( beta || 0 );
var _y = THREE.Math.degToRad( alpha || 0 );
var _z = THREE.Math.degToRad( gamma || 0 );
var _q = new THREE.Quaternion();

euler.set( _x, _y, -_z, 'YXZ' );
return function( alpha, beta, gamma ) {

// Apply provided deviceorientation values to controller
controls.object.quaternion.setFromEuler( euler );
controls.object.quaternion.multiply( worldQuat );
var _x = THREE.Math.degToRad( beta || 0 );
var _y = THREE.Math.degToRad( alpha || 0 );
var _z = THREE.Math.degToRad( gamma || 0 );

}
euler.set( _x, _y, -_z, 'YXZ' );

// Apply provided deviceorientation values to controller
_q.setFromEuler( euler );
_q.multiply( worldQuat );

controls.object.quaternion.copy( _q );

};

} )();

this.playback = ( function() {

var source, destination;
var _this;

var _a0, _b0, _g0;

return function( data ) {

_this = this;

// Store original device orientation values
_a0 = deviceOrientation.alpha;
_b0 = deviceOrientation.beta;
_g0 = deviceOrientation.gamma;

var frameNumber = 0;

// Tween through each of our animation frames
data.frames.reduce( function( chain, frame ) {
// Add these actions to the end of the promise chain
return chain.then( function() {
if ( frameNumber > 0 ) {
sendMessage(
window.parent, {
'action': 'updateActiveFrame',
'data': frameNumber
}
);
}
frameNumber++;

if ( frame.type === 0 ) { // SET
return _this.set( frame );
} else { // ANIMATION
return _this.tween( frame );
}
} );
}, Promise.resolve() ).then( function() {
// Rollback to original device orientation values
window.setTimeout( function() {
sendMessage(
window.parent, {
'action': 'resetTimeline'
}
);

_this.setManualOrientation( _a0, _b0, _g0 );
}, 1000 );
} );

};

} )();

this.set = ( function() {

var _this;

var waitTime, playTime;

return function( frame ) {

_this = this;

var setPromise = new Promise( function( resolve, reject ) {

waitTime = frame.offset * 1000;
playTime = frame.duration * 1000;

window.setTimeout( function() {

_this.setManualOrientation( frame.data.alpha, frame.data.beta, frame.data.gamma );

window.setTimeout( function() {
resolve(); // this Promise can never reject
}, playTime );

}, waitTime );

} );

return setPromise;

};

} )();

this.tween = ( function() {

var source, destination;
var _this;

var waitTime, playTime;

return function( frame ) {

_this = this;

var tweenPromise = new Promise( function( resolve, reject ) {

tweenInProgress = true;

source = {
alpha: deviceOrientation.alpha || 0,
beta: deviceOrientation.beta || 0,
gamma: deviceOrientation.gamma || 0
};

destination = {};

if ( frame.data.alpha !== source.alpha ) destination.alpha = frame.data.alpha;
if ( frame.data.beta !== source.beta ) destination.beta = frame.data.beta;
if ( frame.data.gamma !== source.gamma ) destination.gamma = frame.data.gamma;

waitTime = frame.offset * 1000;
playTime = frame.duration * 1000;

var throwError = window.setTimeout( function() {
tweenInProgress = false;
reject();
}, waitTime + 200 );

var tween = new TWEEN.Tween( source )
.delay( waitTime )
.to( destination, playTime )
.onStart( function() {
window.clearTimeout( throwError );
} )
.onUpdate( function() {
_this.setManualOrientation( this.alpha, this.beta, this.gamma );
} )
.onComplete( function() {
tweenInProgress = false;
resolve();
} )
.start();

} );

return tweenPromise;

};

} )();

this.updateScreenOrientation = function( data ) {

Expand Down Expand Up @@ -229,6 +385,10 @@ var APP = {
delta: time - prevTime
} );

if ( tweenInProgress ) {
TWEEN.update( time );
}

controls.update();

// *** Calculate device orientation quaternion (without affecting rendering)
Expand All @@ -238,7 +398,7 @@ var APP = {
camQuat.inverse();

// Derive Tait-Bryan angles from calculated device orientation quaternion
deviceOrientation.setFromQuaternion( camQuat );
deviceOrientation.setFromQuaternion( camQuat, 'YXZ' );

// Calculate required emulator screen roll compensation required
var rollZ = rotation.setFromQuaternion( controls.object.quaternion, 'YXZ' ).z;
Expand Down
8 changes: 8 additions & 0 deletions controller/js/controls.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ window.addEventListener( 'load', function() {
player.setSize( window.innerWidth, window.innerHeight );
} );

var currentScreenOrientation = 0;

// Listen for device orientation events fired from the emulator
// and dispatch them on to the parent window
window.addEventListener( 'deviceorientation', function( event ) {
Expand All @@ -30,6 +32,7 @@ window.addEventListener( 'load', function() {
'beta': event.beta,
'gamma': event.gamma,
'absolute': event.absolute,
'screen': currentScreenOrientation,
'roll': event.roll
}
},
Expand Down Expand Up @@ -61,6 +64,8 @@ window.addEventListener( 'load', function() {
'rotateScreen': function( data ) {
player.updateScreenOrientation( data );

currentScreenOrientation = ( 360 - data.totalRotation ) % 360;

if ( window.parent ) {
sendMessage(
window.parent, {
Expand All @@ -69,6 +74,9 @@ window.addEventListener( 'load', function() {
url.origin
);
}
},
'playback': function( data ) {
player.playback( data );
}
};

Expand Down
2 changes: 2 additions & 0 deletions controller/js/third_party/tween.min.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 33 additions & 0 deletions emulator/css/timeline.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#timeline {
line-height: 1;
position: fixed;
display: none;
bottom: 0;
left: 0;
padding: 10px;
}
#timeline ul {
font-size: 13px;
display: inline-block;
margin: -0.2em auto 0.2em;
-webkit-filter: drop-shadow(0 1px 5px rgba(0, 0, 0, .25));
-moz-filter: drop-shadow(0 1px 5px rgba(0, 0, 0, .25));
-ms-filter: drop-shadow(0 1px 5px rgba(0, 0, 0, .25));
-o-filter: drop-shadow(0 1px 5px rgba(0, 0, 0, .25));
filter: drop-shadow(0 1px 5px rgba(0, 0, 0, .25));
-ms-transform: translateZ(0);
-o-transform: translateZ(0);
-moz-transform: translateZ(0);
-webkit-transform: translateZ(0);
transform: translateZ(0);
}
div.frame {
display: block;
font-family: Helvetica, Arial, sans-serif;
font-size: 11px;
height: 27.5px;
padding: 8px 20px;
margin: 0 10px;
background-color: #383636;
color: #cccccc;
}
43 changes: 37 additions & 6 deletions emulator/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@
<title>doe - The Device and Screen Orientation Emulator</title>

<script type="text/javascript" src="js/libs/jquery-1.10.2.min.js"></script>
<link type="text/css" rel="stylesheet" href="css/groundwork.css">
<link type="text/css" rel="stylesheet" href="css/emulator.css">

<script type="text/javascript" src="js/utils.js"></script>
<script type="text/javascript" src="js/supports.js"></script>

<link type="text/css" rel="stylesheet" href="css/groundwork.css">
<link type="text/css" rel="stylesheet" href="css/emulator.css">
<script type="text/javascript" src="js/emulator.js"></script>

<link type="text/css" rel="stylesheet" href="css/timeline.css">
<script type="text/javascript" src="js/timeliner.js"></script>
</head>

<body class="emulator-page">
Expand Down Expand Up @@ -50,10 +54,8 @@
<li>
<div class="info" style="margin-right: 0px; padding-right:0px;" title="Current Device Orientation Data (in degrees)">
a:
<input type="number" id="orientationAlpha" value="-" tabindex="1">
b:
<input type="number" id="orientationBeta" value="-" tabindex="2">
g:
<input type="number" id="orientationAlpha" value="-" tabindex="1"> b:
<input type="number" id="orientationBeta" value="-" tabindex="2"> g:
<input type="number" id="orientationGamma" value="-" tabindex="3">
</div>
</li>
Expand All @@ -76,6 +78,35 @@
<iframe id="deviceFrame" class="relative" style="z-index:1;" src="" frameborder="0"></iframe>
</div>

<div id="timeline" class="bounceInUp animated" style="z-index:3;">
<ul class="button-group">
<li>
<button id="play" class="charcoal" title="Play timeline" tabindex="4"><i class="icon-play"></i></button>
</li>
<li>
<div class="info" style="margin-right:0px">
<span>Frames:</span>
</div>
</li>
</ul>
<ul id="frame-group" class="button-group">
<li>
<button class="frame asphalt active" data-frame-number="0" tabindex="-1">1</button>
</li>
<!-- additional timeline frames go here when created -->
</ul>
<ul class="button-group">
<li>
<button id="addNewFrame" class="frame blue" title="Add a new animation frame" tabindex="-1"><i class="icon-plus"></i></button>
</li>
</ul>
<ul class="button-group">
<li>
<button id="clearTimeline" class="frame red" title="Remove all animation frames" tabindex="-1"><i class="icon-trash"></i></button>
</li>
</ul>
</div>

</body>

</html>
Loading

0 comments on commit 93454f9

Please sign in to comment.