/ * *
* TimelineJS
* Designed and built by Zach Wise at VéritéCo
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
* http : //www.gnu.org/licenses/
* /
/ * * C o d e K i t I m p o r t
* http : //incident57.com/codekit/
=== === === === === === === === === === === === === === === === == * /
// @codekit-prepend "VMM.Timeline.License.js";
// @codekit-prepend "Core/VMM.StoryJS.js";
// @codekit-append "VMM.Timeline.TimeNav.js";
// @codekit-append "VMM.Timeline.DataObj.js";
/ * T i m e l i n e
=== === === === === === === === === === === === === === === === == * /
if ( typeof VMM != 'undefined' && typeof VMM . Timeline == 'undefined' ) {
VMM . Timeline = function ( _timeline _id , w , h ) {
var $timeline ,
$container ,
$feature ,
$feedback ,
$slider ,
$navigation ,
slider ,
timenav ,
version = "2.01" ,
timeline _id = "#timelinejs" ,
events = { } ,
data = { } ,
_dates = [ ] ,
config = { } ,
has _width = false ,
has _height = false ,
ie7 = false ,
is _moving = false ;
if ( type . of ( _timeline _id ) == "string" ) {
if ( _timeline _id . match ( "#" ) ) {
timeline _id = _timeline _id ;
} else {
timeline _id = "#" + _timeline _id ;
}
} else {
timeline _id = "#timelinejs" ;
}
trace ( "VERSION " + version ) ;
/ * C O N F I G
=== === === === === === === === === === === === === === === === == * /
config = {
embed : false ,
events : {
data _ready : "DATAREADY" ,
messege : "MESSEGE" ,
headline : "HEADLINE" ,
slide _change : "SLIDE_CHANGE" ,
resize : "resize"
} ,
id : timeline _id ,
source : "nothing" ,
type : "timeline" ,
touch : false ,
maptype : "toner" ,
preload : 4 ,
current _slide : 0 ,
hash _bookmark : false ,
start _at _end : false ,
start _at _slide : 0 ,
start _zoom _adjust : 0 ,
start _page : false ,
api _keys : {
google : "" ,
flickr : "" ,
twitter : ""
} ,
interval : 10 ,
something : 0 ,
width : 960 ,
height : 540 ,
spacing : 15 ,
loaded : {
slider : false ,
timenav : false ,
percentloaded : 0
} ,
nav : {
start _page : false ,
interval _width : 200 ,
density : 4 ,
minor _width : 0 ,
minor _left : 0 ,
constraint : {
left : 0 ,
right : 0 ,
right _min : 0 ,
right _max : 0
} ,
zoom : {
adjust : 0
} ,
multiplier : {
current : 6 ,
min : . 1 ,
max : 50
} ,
rows : [ 1 , 1 , 1 ] ,
width : 960 ,
height : 200 ,
marker : {
width : 150 ,
height : 50
}
} ,
feature : {
width : 960 ,
height : 540
} ,
slider : {
width : 720 ,
height : 400 ,
content : {
width : 720 ,
height : 400 ,
padding : 130
} ,
nav : {
width : 100 ,
height : 200
}
} ,
ease : "easeInOutExpo" ,
duration : 1000 ,
language : VMM . Language
} ;
if ( w != null && w != "" ) {
config . width = w ;
has _width = true ;
}
if ( h != null && h != "" ) {
config . height = h ;
has _height = true ;
}
if ( window . location . hash ) {
var hash = window . location . hash . substring ( 1 ) ;
if ( ! isNaN ( hash ) ) {
config . current _slide = parseInt ( hash ) ;
}
}
window . onhashchange = function ( ) {
var hash = window . location . hash . substring ( 1 ) ;
if ( config . hash _bookmark ) {
if ( is _moving ) {
goToEvent ( parseInt ( hash ) ) ;
} else {
is _moving = false ;
}
} else {
goToEvent ( parseInt ( hash ) ) ;
}
}
/ * C R E A T E C O N F I G
=== === === === === === === === === === === === === === === === == * /
function createConfig ( conf ) {
// APPLY SUPPLIED CONFIG TO TIMELINE CONFIG
if ( typeof embed _config == 'object' ) {
timeline _config = embed _config ;
}
if ( typeof timeline _config == 'object' ) {
trace ( "HAS TIMELINE CONFIG" ) ;
config = VMM . Util . mergeConfig ( config , timeline _config ) ;
} else if ( typeof conf == 'object' ) {
config = VMM . Util . mergeConfig ( config , conf ) ;
}
if ( VMM . Browser . device == "mobile" || VMM . Browser . device == "tablet" ) {
config . touch = true ;
}
config . nav . width = config . width ;
config . nav . height = 200 ;
config . feature . width = config . width ;
config . feature . height = config . height - config . nav . height ;
config . nav . zoom . adjust = parseInt ( config . start _zoom _adjust , 10 ) ;
VMM . Timeline . Config = config ;
VMM . master _config . Timeline = VMM . Timeline . Config ;
this . events = config . events ;
}
/ * C R E A T E T I M E L I N E S T R U C T U R E
=== === === === === === === === === === === === === === === === == * /
function createStructure ( ) {
// CREATE DOM STRUCTURE
$timeline = VMM . getElement ( timeline _id ) ;
VMM . Lib . addClass ( $timeline , "vco-timeline" ) ;
VMM . Lib . addClass ( $timeline , "vco-storyjs" ) ;
$container = VMM . appendAndGetElement ( $timeline , "<div>" , "vco-container vco-main" ) ;
$feature = VMM . appendAndGetElement ( $container , "<div>" , "vco-feature" ) ;
$slider = VMM . appendAndGetElement ( $feature , "<div>" , "vco-slider" ) ;
$navigation = VMM . appendAndGetElement ( $container , "<div>" , "vco-navigation" ) ;
$feedback = VMM . appendAndGetElement ( $timeline , "<div>" , "vco-feedback" , "" ) ;
if ( config . touch ) {
VMM . Lib . addClass ( $timeline , "vco-touch" ) ;
} else {
VMM . Lib . addClass ( $timeline , "vco-notouch" ) ;
}
if ( typeof config . language . right _to _left != 'undefined' ) {
VMM . Lib . addClass ( $timeline , "vco-right-to-left" ) ;
}
slider = new VMM . Slider ( $slider , config ) ;
timenav = new VMM . Timeline . TimeNav ( $navigation ) ;
if ( ! has _width ) {
config . width = VMM . Lib . width ( $timeline ) ;
} else {
VMM . Lib . width ( $timeline , config . width ) ;
}
if ( ! has _height ) {
config . height = VMM . Lib . height ( $timeline ) ;
} else {
VMM . Lib . height ( $timeline , config . height ) ;
}
}
/ * O N E V E N T
=== === === === === === === === === === === === === === === === == * /
function onDataReady ( e , d ) {
trace ( "onDataReady" ) ;
trace ( d ) ;
data = d . timeline ;
if ( type . of ( data . era ) != "array" ) {
data . era = [ ] ;
}
buildDates ( ) ;
} ;
function onDatesProcessed ( ) {
build ( ) ;
}
function reSize ( ) {
updateSize ( ) ;
slider . setSize ( config . feature . width , config . feature . height ) ;
timenav . setSize ( config . width , config . height ) ;
} ;
function onSliderLoaded ( e ) {
config . loaded . slider = true ;
onComponentLoaded ( ) ;
} ;
function onComponentLoaded ( e ) {
config . loaded . percentloaded = config . loaded . percentloaded + 25 ;
if ( config . loaded . slider && config . loaded . timenav ) {
hideMessege ( ) ;
}
}
function onTimeNavLoaded ( e ) {
config . loaded . timenav = true ;
onComponentLoaded ( ) ;
}
function onSlideUpdate ( e ) {
is _moving = true ;
config . current _slide = slider . getCurrentNumber ( ) ;
setHash ( config . current _slide ) ;
timenav . setMarker ( config . current _slide , config . ease , config . duration ) ;
} ;
function onMarkerUpdate ( e ) {
is _moving = true ;
config . current _slide = timenav . getCurrentNumber ( ) ;
setHash ( config . current _slide ) ;
slider . setSlide ( config . current _slide ) ;
} ;
function goToEvent ( n ) {
if ( n <= _dates . length - 1 && n >= 0 ) {
config . current _slide = n ;
slider . setSlide ( config . current _slide ) ;
timenav . setMarker ( config . current _slide , config . ease , config . duration ) ;
}
}
function setHash ( n ) {
if ( config . hash _bookmark ) {
window . location . hash = "#" + n . toString ( ) ;
}
}
/ * P U B L I C F U N C T I O N S
=== === === === === === === === === === === === === === === === == * /
this . init = function ( c , _data ) {
trace ( 'INIT' ) ;
createConfig ( c ) ;
createStructure ( ) ;
if ( type . of ( _data ) == "string" ) {
config . source = _data ;
}
// LANGUAGE
VMM . Date . setLanguage ( config . language ) ;
VMM . master _config . language = config . language ;
// EXTERNAL API
VMM . ExternalAPI . setKeys ( config . api _keys ) ;
VMM . ExternalAPI . googlemaps . setMapType ( config . maptype ) ;
// EVENTS
VMM . bindEvent ( global , onDataReady , config . events . data _ready ) ;
VMM . bindEvent ( global , showMessege , config . events . messege ) ;
VMM . fireEvent ( global , config . events . messege , config . language . messages . loading _timeline ) ;
/ * G E T D A T A
=== === === === === === === === === === === === === === === === == * /
if ( VMM . Browser . browser == "Explorer" || VMM . Browser . browser == "MSIE" ) {
if ( parseInt ( VMM . Browser . version , 10 ) <= 7 ) {
ie7 = true ;
}
}
if ( type . of ( config . source ) == "string" || type . of ( config . source ) == "object" ) {
VMM . Timeline . DataObj . getData ( config . source ) ;
} else {
VMM . Timeline . DataObj . getData ( VMM . getElement ( timeline _id ) ) ;
}
} ;
this . iframeLoaded = function ( ) {
trace ( "iframeLoaded" ) ;
} ;
this . reload = function ( _d ) {
trace ( "loadNewDates" + _d ) ;
VMM . fireEvent ( global , config . events . messege , config . language . messages . loading _timeline ) ;
data = { } ;
VMM . Timeline . DataObj . getData ( _d ) ;
} ;
/ * D A T A
=== === === === === === === === === === === === === === === === == * /
function getData ( url ) {
VMM . getJSON ( url , function ( d ) {
data = VMM . Timeline . DataObj . getData ( d ) ;
VMM . fireEvent ( global , config . events . data _ready ) ;
} ) ;
} ;
/ * M E S S E G E S
=== === === === === === === === === === === === === === === === == * /
function showMessege ( e , msg ) {
trace ( "showMessege " + msg ) ;
//VMM.attachElement($messege, msg);
VMM . attachElement ( $feedback , VMM . MediaElement . loadingmessage ( msg ) ) ;
} ;
function hideMessege ( ) {
VMM . Lib . animate ( $feedback , config . duration , config . ease * 4 , { "opacity" : 0 } , detachMessege ) ;
} ;
function detachMessege ( ) {
VMM . Lib . detach ( $feedback ) ;
}
/ * B U I L D D I S P L A Y
=== === === === === === === === === === === === === === === === == * /
function build ( ) {
// START AT SLIDE
if ( parseInt ( config . start _at _slide ) > 0 && config . current _slide == 0 ) {
config . current _slide = parseInt ( config . start _at _slide ) ;
}
// START AT END
if ( config . start _at _end && config . current _slide == 0 ) {
config . current _slide = _dates . length - 1 ;
}
// IE7
if ( ie7 ) {
ie7 = true ;
VMM . fireEvent ( global , config . events . messege , "Internet Explorer " + VMM . Browser . version + " is not supported by TimelineJS. Please update your browser to version 8 or higher." ) ;
} else {
detachMessege ( ) ;
reSize ( ) ;
// EVENT LISTENERS
VMM . bindEvent ( $slider , onSliderLoaded , "LOADED" ) ;
VMM . bindEvent ( $navigation , onTimeNavLoaded , "LOADED" ) ;
VMM . bindEvent ( $slider , onSlideUpdate , "UPDATE" ) ;
VMM . bindEvent ( $navigation , onMarkerUpdate , "UPDATE" ) ;
// INITIALIZE COMPONENTS
slider . init ( _dates ) ;
timenav . init ( _dates , data . era ) ;
// RESIZE EVENT LISTENERS
VMM . bindEvent ( global , reSize , config . events . resize ) ;
}
} ;
function ie7Build ( ) {
trace ( "IE7 or lower" ) ;
for ( var i = 0 ; i < _dates . length ; i ++ ) {
trace ( _dates [ i ] ) ;
/ *
var st = VMM . Date . prettyDate ( data . startdate ) ;
var en = VMM . Date . prettyDate ( data . enddate ) ;
var tag = "" ;
if ( data . tag != null && data . tag != "" ) {
tag = VMM . createElement ( "span" , data . tag , "slide-tag" ) ;
}
if ( st != en ) {
c . text += VMM . createElement ( "h2" , st + " — " + en + tag , "date" ) ;
} else {
c . text += VMM . createElement ( "h2" , st + tag , "date" ) ;
}
* /
}
} ;
function updateSize ( ) {
trace ( "UPDATE SIZE" ) ;
config . width = VMM . Lib . width ( $timeline ) ;
config . height = VMM . Lib . height ( $timeline ) ;
config . nav . width = config . width ;
config . feature . width = config . width ;
if ( VMM . Browser . device == "mobile" ) {
//config.feature.height = config.height;
} else {
//config.feature.height = config.height - config.nav.height - 3;
}
config . feature . height = config . height - config . nav . height - 3 ;
} ;
// BUILD DATE OBJECTS
function buildDates ( ) {
_dates = [ ] ;
VMM . fireEvent ( global , config . events . messege , "Building Dates" ) ;
updateSize ( ) ;
for ( var i = 0 ; i < data . date . length ; i ++ ) {
if ( data . date [ i ] . startDate != null && data . date [ i ] . startDate != "" ) {
var _date = { } ;
// START DATE
if ( data . date [ i ] . type == "tweets" ) {
_date . startdate = VMM . ExternalAPI . twitter . parseTwitterDate ( data . date [ i ] . startDate ) ;
} else {
_date . startdate = VMM . Date . parse ( data . date [ i ] . startDate ) ;
}
if ( ! isNaN ( _date . startdate ) ) {
// END DATE
if ( data . date [ i ] . endDate != null && data . date [ i ] . endDate != "" ) {
if ( data . date [ i ] . type == "tweets" ) {
_date . enddate = VMM . ExternalAPI . twitter . parseTwitterDate ( data . date [ i ] . endDate ) ;
} else {
_date . enddate = VMM . Date . parse ( data . date [ i ] . endDate ) ;
}
} else {
_date . enddate = _date . startdate ;
}
_date . needs _slug = false ;
if ( data . date [ i ] . headline == "" ) {
if ( data . date [ i ] . slug != null && data . date [ i ] . slug != "" ) {
_date . needs _slug = true ;
}
}
_date . title = data . date [ i ] . headline ;
_date . headline = data . date [ i ] . headline ;
_date . type = data . date [ i ] . type ;
_date . date = VMM . Date . prettyDate ( _date . startdate ) ;
_date . asset = data . date [ i ] . asset ;
_date . fulldate = _date . startdate . getTime ( ) ;
_date . text = data . date [ i ] . text ;
_date . content = "" ;
_date . tag = data . date [ i ] . tag ;
_date . slug = data . date [ i ] . slug ;
_date . uniqueid = VMM . Util . unique _ID ( 7 ) ;
_dates . push ( _date ) ;
}
}
} ;
/ * C U S T O M S O R T
=== === === === === === === === === === === === === === === === == * /
if ( data . type != "storify" ) {
_dates . sort ( function ( a , b ) {
return a . fulldate - b . fulldate
} ) ;
}
/ * C R E A T E S T A R T P A G E I F A V A I L A B L E
=== === === === === === === === === === === === === === === === == * /
if ( data . headline != null && data . headline != "" && data . text != null && data . text != "" ) {
trace ( "HAS STARTPAGE" ) ;
var _date = { } , td _num = 0 , td ;
td = _dates [ 0 ] . startdate ;
_date . startdate = new Date ( _dates [ 0 ] . startdate ) ;
if ( td . getMonth ( ) === 0 && td . getDate ( ) == 1 && td . getHours ( ) === 0 && td . getMinutes ( ) === 0 ) {
// trace("YEAR ONLY");
_date . startdate . setFullYear ( td . getFullYear ( ) - 1 ) ;
} else if ( td . getDate ( ) <= 1 && td . getHours ( ) === 0 && td . getMinutes ( ) === 0 ) {
// trace("YEAR MONTH");
_date . startdate . setMonth ( td . getMonth ( ) - 1 ) ;
} else if ( td . getHours ( ) === 0 && td . getMinutes ( ) === 0 ) {
// trace("YEAR MONTH DAY");
_date . startdate . setDate ( td . getDate ( ) - 1 ) ;
} else if ( td . getMinutes ( ) === 0 ) {
// trace("YEAR MONTH DAY HOUR");
_date . startdate . setHours ( td . getHours ( ) - 1 ) ;
} else {
// trace("YEAR MONTH DAY HOUR MINUTE");
_date . startdate . setMinutes ( td . getMinutes ( ) - 1 ) ;
}
_date . uniqueid = VMM . Util . unique _ID ( 7 ) ;
_date . enddate = _date . startdate ;
_date . title = data . headline ;
_date . headline = data . headline ;
_date . text = data . text ;
_date . type = "start" ;
_date . date = VMM . Date . prettyDate ( data . startDate ) ;
_date . asset = data . asset ;
_date . slug = false ;
_date . needs _slug = false ;
_date . fulldate = _date . startdate . getTime ( ) ;
if ( config . embed ) {
VMM . fireEvent ( global , config . events . headline , _date . headline ) ;
}
_dates . unshift ( _date ) ;
}
/ * C U S T O M S O R T
=== === === === === === === === === === === === === === === === == * /
if ( data . type != "storify" ) {
_dates . sort ( function ( a , b ) {
return a . fulldate - b . fulldate
} ) ;
}
onDatesProcessed ( ) ;
}
} ;
VMM . Timeline . Config = { } ;
} ;