Commit fecdd9f7 authored by Zenon Mousmoulas's avatar Zenon Mousmoulas

* Introduce a scrolling area on the right side of full screen maps, using

MapEscape[1].
* Set up a js callback to automatically move Google maps controls
out of the scroll area (LEFT_CENTER, opposite of scroll helper).
* Use a simple jquery plugin to auto-limit map height to usable viewport
height upon load/resize/rotation (perhaps use CSS3 in the future).

[1] http://labs.codecomputerlove.com/MapEscape/
parent 48f24114
......@@ -63,8 +63,14 @@
</div>
{% endblock %}
{% block extrahead %}
<link href="{% static 'css/mapescape.css' %}" rel="stylesheet">
{% endblock %}
{% block extrajs %}
<script type="text/javascript" src="{% static 'js/markerclusterer.js' %}"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="{% static 'js/jquery.adapt_height.js' %}"></script>
<script type="text/javascript" src="{% static 'js/mapescape.js' %}"></script>
<script type="text/javascript" src="{% static 'js/home-page-map.js' %}"></script>
{% endblock %}
......@@ -15,8 +15,14 @@
{% endblock %}
{% block extrahead %}
<link href="{% static 'css/mapescape.css' %}" rel="stylesheet">
{% endblock %}
{% block extrajs %}
<script type="text/javascript" src="{% static 'js/markerclusterer.js' %}"></script>
<script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?sensor=false"></script>
<script type="text/javascript" src="{% static 'js/jquery.adapt_height.js' %}"></script>
<script type="text/javascript" src="{% static 'js/mapescape.js' %}"></script>
<script type="text/javascript" src="{% static 'js/world-map.js' %}"></script>
{% endblock %}
/* default */
.map { top: 0px; left: 0; width: 100%; height: 350px;}
.map-wrapper { position: relative; overflow: hidden; }
/* top is set to 30px to allow for google maps controls. set to 0 if not using google maps */
.mapescape-scroll { background: transparent; z-index: 1; width: 40px; right: 0; top: 0px; position: absolute;
transition:right .3s;
-moz-transition:right .3s; /* Firefox 4 */
-webkit-transition:right .3s; /* Safari and Chrome */
}
.mapescape-scroll.scroll-inactive { right: -40px; }
.mapescape-scroll-tab { width: 35px; height: 70px; right: 0; border-radius: 55px 0 0 55px; position: absolute; background: rgba(29,74,116,.7) url(../img/scroll-icon.png) 70% 50% no-repeat; color: #fff; background-size: 12px 25px;
transition:top .3s;
-moz-transition:top .3s; /* Firefox 4 */
-webkit-transition:top .3s; /* Safari and Chrome */
}
/* active state */
.scroll-active .mapescape-scroll-tab:before { content: ' '; z-index: -1; display: block; position: absolute; left: -10px; top: -10px; width: 45px; height: 90px; right: 0; border-radius: 55px 0 0 55px; position: absolute; background: rgba(255,255,255,.9);
transition:top .3s;
-moz-transition:top .3s; /* Firefox 4 */
-webkit-transition:top .3s; /* Safari and Chrome */
}
\ No newline at end of file
......@@ -318,6 +318,25 @@
}
function mapescape_callback(mapescape_active) {
var defControlOptions = {},
curControlOptions = {},
objCmp = function(a, b) {
return JSON.stringify(a) == JSON.stringify(b);
}
for (var k in mapescapeControlOptions) {
defControlOptions[k] = {};
curControlOptions[k] = map[k];
}
if (mapescape_active &&
!objCmp(curControlOptions, mapescapeControlOptions)) {
map.setOptions(mapescapeControlOptions);
} else if (!mapescape_active &&
!objCmp(curControlOptions, defControlOptions)) {
map.setOptions(defControlOptions);
}
}
$(document).ready(function() {
mapDiv = $('#map_canvas')
lat = mapDiv.data("map-center-lat");
......@@ -354,11 +373,24 @@
textColor : '#ffffff',
textSize : 11
}];
mapescapeControlOptions = {
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_CENTER
},
streetViewControlOptions: {
position: google.maps.ControlPosition.LEFT_CENTER
}
};
markersUrl = mapDiv.data('markers');
initialize();
marks = placeMarkers();
clusterMarkers(marks);
$('#map_canvas').mapescape({
callback: mapescape_callback
}).adapt_height(function($tgt, height) {
$tgt.css('max-height', height);
});
});
/**
* jQuery adapt height
* @author Zenon Mousmoulas
*/
(function($) {
$.fn.adapt_height = function(callback) {
return this.each(function() {
var $this = $(this),
ah = function($tgt, callback) {
var realWindowHeight = (typeof(window.innerHeight) == 'number' &&
$(window).height() < window.innerHeight) ?
window.innerHeight :
$(window).height(),
topoffset = $tgt.offset().top;
if (topoffset + $tgt.height() != realWindowHeight)
callback($tgt, realWindowHeight - topoffset);
}
ah($this, callback);
$(window).on('resize orientationchange', function() {
ah($this, callback);
});
});
};
})(jQuery);
(function($){
MapEscape = function(el, settings){
var obj = this,
$el = $(el);
$.extend(obj, {
mapWrapperCssClass: 'map-wrapper',
scrollAreaCssClass: 'mapescape-scroll',
scrollTabCssClass: 'mapescape-scroll-tab',
helperCSSClass: 'scroll-active',
init: function(){
this.initScrollHelper();
var scroll = '';
if(settings.scrollFollow){ scroll = 'scroll ' }
$(window).on(scroll + 'resize orientationchange', $.proxy(this, 'toggleScrollHelperOn'));
},
initScrollHelper: function(){
this.$scrollHelper = $('<div class="' + this.scrollAreaCssClass + ' ' + settings.hiddenClass + '"></div>');
this.$scrollHelperTab = $('<div class="' + this.scrollTabCssClass + '"></div>');
if(settings.scrollText){this.$scrollHelperTab.text(settings.scrollText);}
this.addScrollHelper();
},
addScrollHelper: function(){
$el.wrap('<div class="' + this.mapWrapperCssClass + '"></div>');
this.$scrollHelper.insertAfter($el);
this.$scrollHelper.html(this.$scrollHelperTab);
this.mapControls = this.$scrollHelper.css('top');
if(this.mapControls === 'auto'){
this.mapControls = 0;
this.$scrollHelper.css({'top': '0'});
}
var h = $el.height();
if(!typeof Zepto === 'undefined'){
h = $el.outerHeight();
}
this.mapHeight = (h - parseInt(this.mapControls));
this.$scrollHelper.height(this.mapHeight);
this.$scrollHelper.on('touchstart mousedown', $.proxy(this, 'touchstartHandler'));
this.$scrollHelper.on('touchend mouseup', $.proxy(this, 'touchendHandler'));
if(settings.tabCenter){this.positionScrollTab();}
this.toggleScrollHelperOn();
},
positionScrollTab: function(){
this.tabHeight = this.$scrollHelperTab.height();
if(!typeof Zepto === 'undefined'){
this.tabHeight = this.$scrollHelperTab.outerHeight();
}
this.pos = (this.mapHeight/2) - (this.tabHeight/2);
this.$scrollHelperTab.css({
'top': this.pos + 'px'
});
},
checkMapVsWindow: function(){
var winHeight = $(window).height(),
scrollPos = $(window).scrollTop(),
mapTop = $el.offset().top - scrollPos,
mapBottom = mapTop + (this.mapHeight + parseInt(this.mapControls));
if(mapTop <= 0){
var pos = ((this.mapHeight - mapTop) / 2) - (this.tabHeight/2);
if(pos + (this.tabHeight) > this.mapHeight){
this.pos = this.mapHeight - this.tabHeight;
}else{
this.pos = pos;
}
}
if(mapBottom > winHeight){
var h = (mapTop + this.mapHeight) - winHeight,
pos = ((this.mapHeight - h)/2) - (this.tabHeight/2);
if(pos < 0){
this.pos = 0;
}else{
this.pos = pos;
}
}
if(mapTop < 0 && mapBottom > winHeight){
var pos = (Math.abs(mapTop)) + (winHeight/2) - (this.tabHeight/2);
this.pos = pos;
}
this.$scrollHelperTab.css({
'top': this.pos + 'px'
});
},
toggleScrollHelperOn: function(){
if(settings.alwaysOn){
this.showScrollHelper();
return;
}
this.checkMapVsWindow();
var mapBottom = ($el.offset().top + (this.mapHeight + parseInt(this.mapControls))) + settings.threshhold;
var h = $(window).height();
if(!typeof Zepto === 'undefined'){
h = $(window).innerHeight();
}
if(mapBottom > h){
this.showScrollHelper();
}else{
this.removeScrollHelper();
}
},
removeScrollHelper: function(){
this.$scrollHelper.addClass(settings.hiddenClass);
if (typeof settings.callback === 'function')
settings.callback(false);
},
showScrollHelper: function(){
this.$scrollHelper.removeClass(settings.hiddenClass);
if (typeof settings.callback === 'function')
settings.callback(true);
},
touchstartHandler: function(e){
$(e.currentTarget).addClass(this.helperCSSClass);
},
touchendHandler: function(e){
$(e.currentTarget).removeClass(this.helperCSSClass);
}
});
obj.init();
};
$.fn.mapescape = function(options){
return this.each(function(){
var $this = $(this),
settings = {
alwaysOn: false, // if false map height is measured against window height - true always shows scoll area
hiddenClass: 'scroll-inactive', // class of the hidden controls
scrollText: null, // text on scroll indicator - leave blank for none
threshhold: 0, // amount of viewable scroll area below the map
tabCenter: true, // if false don't position the scroll tab with javascript
scrollFollow: true, // set to false for static scroll tab
callback: undefined // callback to execute when scroll helper shown or hidden
};
if (options) {
$.extend(settings, options);
}
// create new instance of the map excape object
new MapEscape($this, settings);
});
};
})(window.jQuery || window.Zepto);
\ No newline at end of file
......@@ -248,6 +248,25 @@
}
function mapescape_callback(mapescape_active) {
var defControlOptions = {},
curControlOptions = {},
objCmp = function(a, b) {
return JSON.stringify(a) == JSON.stringify(b);
}
for (var k in mapescapeControlOptions) {
defControlOptions[k] = {};
curControlOptions[k] = map[k];
}
if (mapescape_active &&
!objCmp(curControlOptions, mapescapeControlOptions)) {
map.setOptions(mapescapeControlOptions);
} else if (!mapescape_active &&
!objCmp(curControlOptions, defControlOptions)) {
map.setOptions(defControlOptions);
}
}
$(document).ready(function() {
mapDiv = $('#map_canvas');
lat = mapDiv.data('center-lat');
......@@ -279,7 +298,20 @@
textColor : '#ffffff',
textSize : 11
} ];
mapescapeControlOptions = {
zoomControlOptions: {
position: google.maps.ControlPosition.LEFT_CENTER
},
streetViewControlOptions: {
position: google.maps.ControlPosition.LEFT_CENTER
}
};
initialize();
marks = placeMarkers();
clusterMarkers(marks);
$('#map_canvas').mapescape({
callback: mapescape_callback
}).adapt_height(function($tgt, height) {
$tgt.css('max-height', height);
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment