Last active
August 29, 2015 14:18
-
-
Save simplesthing/b33a953e9c8864cda3d4 to your computer and use it in GitHub Desktop.
timeline code to be optimized
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
app | |
.directive('journeyStep', function ($window, $state, $rootScope, $document, _){ | |
return { | |
restrict: 'AE', | |
scope: { | |
challenge: '=', | |
index: '@', | |
total: '@', | |
ready: '@' | |
}, | |
templateUrl: 'modules/shared/directives/journey-step.html', | |
link: function (scope, elem){ | |
// set background - could do this in ng-sttr-style but liked having it here to dev the animation | |
elem.css({ | |
'background-image': 'linear-gradient(hsla(0, 0%, 100%, .8), hsla(0, 0%, 100%, .8)), url(images/challenges/'+scope.challenge.attributes.image+')', | |
'background-position': 'top center, center center', | |
'background-repeat': 'no-repeat', | |
'background-size': 'cover', | |
'background-origin': 'border-box' | |
}); | |
// dirty hack since scope is nested in an ng-repeat 2 way binding is not working | |
scope.$on('journey-coach-mark', function (e, d){ | |
scope.ready = d; | |
}); | |
elem.click(function journeyClickHandler(){ | |
if ((scope.challenge && scope.challenge.state && scope.challenge.state !== 'locked' && scope.ready === 'false') || $rootScope.override) { | |
// hide footer | |
// angular.element('.journey-footer').hide(); | |
document.querySelector('.journey-footer').classList.add('hide'); | |
// remove table displays | |
angular.element('#journey-wrapper, .journey').css('display', 'block'); | |
// remove overlay | |
angular.element('.content').removeClass('overlay'); | |
// calculate a width - they are all logging as the size of the background image so have to switch to an avergae width on click | |
var avgWidth = angular.element('#journey-wrapper').innerWidth()/scope.total; | |
// set css for each repeated section | |
angular.element('.challenge').each(function (){ | |
var self = angular.element(this); | |
// determine direction of slide and apply styles | |
if(self.data('position') > scope.index) { | |
self.addClass('right'); | |
self.css({ | |
'display': 'block', | |
'width': avgWidth + 'px', | |
'float': 'left' | |
}); | |
} | |
if(self.data('position') < scope.index) { | |
self.addClass('left'); | |
self.css({ | |
'display': 'block', | |
'width': avgWidth + 'px', | |
'float': 'left' | |
}); | |
} | |
// element clicked | |
if(self.data('position') === parseInt(scope.index)) { | |
self.css({ | |
'display': 'block', | |
'width': avgWidth + 'px', | |
'float': 'left', | |
'background-image': 'linear-gradient(rgba(0, 0, 0, 0.0),rgba(0, 0, 0, .25)), url(images/challenges/hero-background.png), url(images/challenges/'+scope.challenge.attributes.image+')', | |
'background-position': 'center center', | |
'background-repeat': 'no-repeat', | |
'background-size': 'cover', | |
'background-origin': 'border-box' | |
}); | |
// hide inner content | |
self.find('.content').hide(); | |
} | |
}); | |
// wrap in a directional floated parent | |
angular.element('.right').wrapAll('<div style="float: right; height:100%;"></div>'); | |
angular.element('.left').wrapAll('<div style="float: left; height: 100%; "></div>'); | |
// animate wrapper width | |
angular.element('#journey-wrapper').animate({ | |
'left': '-' + avgWidth * parseInt(scope.index) + 'px', | |
'width': ($window.innerWidth) * 2 +'px', | |
'height': '100%' | |
}, 1000, 'linear'); | |
// animate element width | |
elem.animate({ | |
'width': $window.innerWidth + 'px' | |
}, 1000, 'linear', function (){ | |
// then go to exercise | |
$state.go('auth.accepted.challenge.view', { | |
challengeId: scope.challenge.identifier, | |
view: 'overview', | |
anchor: 'journey' | |
}); | |
}); | |
} | |
}); | |
// needed a flag that is visible to all repeated steps | |
scope.$parent.$parent.isScrolling = false; | |
// TODO: need to remove this event when scrolling or transitioning | |
elem.on('mouseenter', _.debounce(function (){ | |
if(!scope.$parent.$parent.isScrolling) { | |
doScroll(); | |
} | |
},100)); | |
function doScroll (){ | |
var offset = elem.offset(), | |
pageX = $window.pageXOffset, | |
parent = angular.element('.journey'), | |
// isFirst = elem.prev('article').length === 0, | |
// isLast = elem.next('article').length === 0, | |
leftHidden = pageX > offset.left, | |
rightHidden = elem.innerWidth()> (($window.innerWidth + pageX) - offset.left), | |
inViewport = !leftHidden && !rightHidden; | |
if(!inViewport) { | |
var destination = function (){ | |
if(leftHidden) { | |
return offset.left - elem.innerWidth() * 0.1; | |
} else if(rightHidden){ | |
var totalSteps = angular.element('.challenge').length, | |
thisStep = (elem.data('position')+ 1), | |
leftOffset = totalSteps - thisStep; | |
return (parent.innerWidth() - $window.innerWidth) - (elem.innerWidth() * leftOffset) + (elem.innerWidth() * 0.2); | |
} else { | |
return null; | |
} | |
}; | |
if(destination()) { | |
scope.$parent.$parent.isScrolling = true; | |
// use scrollTo since scrollLeft method is sometimes there/not depending upon minification | |
$document.scrollTo(destination(), $document.scrollTop(), 500).then(function (){ | |
scope.$parent.$parent.isScrolling = false; | |
}); | |
} | |
} | |
} | |
} | |
}; | |
}); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment