Skip to content

Instantly share code, notes, and snippets.

@fd
Created October 28, 2010 13:00
Show Gist options
  • Select an option

  • Save fd/651277 to your computer and use it in GitHub Desktop.

Select an option

Save fd/651277 to your computer and use it in GitHub Desktop.
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<script src="http://simonmenke.me/chains.js/build/jquery.stacks.min.js" type="text/javascript" charset="utf-8"></script>
<script type="text/javascript" charset="utf-8">
(function(exports){
exports.state_machine = function(def){
var state_machine = function(){};
state_machine.current_state = def.initial;
var name, state_func;
for (name in def.states) {
state_func = function(ctx, clb){
var state_machine = arguments.callee.state_machine;
var old_state_name = state_machine.current_state;
var old_state = state_machine['to_'+old_state_name];
var new_state = arguments.callee;
var transition = old_state.transitions[new_state.state_name];
if (typeof(transition) == 'function') {
transition = transition(ctx);
}
if (transition) {
var s_steps = [], p_steps;
p_steps = [];
if (old_state.before_leave)
p_steps.push(old_state.before_leave);
if (new_state.before_enter)
p_steps.push(new_state.before_enter);
if (p_steps.length > 0)
s_steps.push(exports.stacks.parallel(p_steps));
p_steps = [];
if (old_state.leave)
p_steps.push(old_state.leave);
if (new_state.enter)
p_steps.push(new_state.enter);
if (p_steps.length > 0)
s_steps.push(exports.stacks.parallel(p_steps));
s_steps.push(function(ctx, clb){
state_machine.current_state = new_state.state_name;
clb(ctx);
});
p_steps = [];
if (old_state.after_leave)
p_steps.push(old_state.after_leave);
if (new_state.after_enter)
p_steps.push(new_state.after_enter);
if (p_steps.length > 0)
s_steps.push(exports.stacks.parallel(p_steps));
exports.stacks.serial(s_steps)(ctx, clb);
return true;
} else {
return false;
}
};
state_func.state_name = name;
state_func.state_machine = state_machine;
state_func.before_enter = def.states[name].before_enter;
state_func.before_leave = def.states[name].before_leave;
state_func.enter = def.states[name].enter;
state_func.leave = def.states[name].leave;
state_func.after_enter = def.states[name].after_enter;
state_func.after_leave = def.states[name].after_leave;
state_func.transitions = def.transitions[name];
state_machine['to_'+name] = state_func;
}
return state_machine;
};
})($);
var navigation = $.state_machine({
initial: 'projects',
states: {
projects: {
enter: function(ctx, clb){
$('#projects').animate({ width: '100%' }, 1000, 'linear', clb);
},
leave: function(ctx, clb){
$('#projects').animate({ width: '0' }, 1000, 'linear', clb);
}
},
contact: {
enter: function(ctx, clb){
$('#contact').animate({ width: '100%' }, 1000, 'linear', clb);
},
leave: function(ctx, clb){
$('#contact').animate({ width: '0' }, 1000, 'linear', clb);
}
},
details: {
enter: function(ctx, clb){
$('#details').animate({ height: '100%' }, 1000, 'linear', clb);
},
leave: function(ctx, clb){
$('#details').animate({ height: '0' }, 1000, 'linear', clb);
}
}
},
transitions: {
projects: {
details: function(ctx){
// console.log('guard details');
return true; },
contact: true
},
contact: {
projects: true
},
details: {
projects: true
}
}
});
$(function(){
$('a.projects').click(navigation.to_projects);
$('a.details').click(navigation.to_details);
$('a.contact').click(navigation.to_contact);
});
</script>
<style>
html { height: 100%; }
body { margin: 0; position:relative; height: 100%; }
#menu {
position: absolute; top:0; left:0; right:0; width: auto; height: 50px;
background-color:#eee; }
#projects {
position: absolute; top:50px; left:0; bottom:0; height:auto; width:100%;
background-color:#00f; opacity: 0.25; }
#details {
position: absolute; top:50px; left:0; right:0; width:auto; height:0%;
background-color:#0f0; opacity: 0.25; }
#contact {
position: absolute; top:50px; right:0; bottom:0; height:auto; width:0%;
background-color:#f00; opacity: 0.25; }
</style>
</head>
<body>
<div id="menu">
<a class="projects" href="#">Projects</a>
<a class="details" href="#">Details</a>
<a class="contact" href="#">Contact</a>
</div>
<div id="projects"></div>
<div id="details"></div>
<div id="contact"></div>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment