/* * Mapplic - Custom Interactive Map Plugin by @sekler * Version 7.1.2 * https://www.mapplic.com/ */ ;(function($) { "use strict"; var Mapplic = function(element) { var self = this; self.o = { source: 'locations.json', selector: '[id^=MLOC] > *, [id^=landmark] > *, svg > #items > *', external: '.mapplic-external', scope: null, customcss: null, iconfile: null, height: 'auto', minheight: 400, maxheight: 800, csv: false, landmark: false, portrait: 860, minimap: false, deeplinking: true, lightbox: true, fullscreen: false, hovertip: true, defaultstyle: null, moretext: null, action: 'default', marker: '', developer: false, smartip: false, animations: false, hovertipdesc: false, // sidebar sidebar: true, sidebartoggle: false, filtersopened: false, search: true, searchlength: 1, searchfields: ['title', 'about', 'category'], searchdescription: false, highlight: true, thumbholder: false, autopopulate: false, sortby: 'title', // zoom zoom: true, clearbutton: true, zoombuttons: true, zoomoutclose: false, closezoomout: true, linknewtab: false, mousewheel: true, mapfill: false, zoommargin: 200, maxscale: 3, // UI Colors basecolor: null, bgcolor: null, bgcolor2: null, headingcolor: null, textcolor: null, accentcolor: null }; self.loc = { more: 'More', search: 'Search', zoomin: 'Zoom in', zoomout: 'Zoom out', resetzoom: 'Reset zoom', levelup: 'Level up', leveldown: 'Level down', clearsearch: 'Clear search', closepopup: 'Close popup', clearfilter: 'Clear filter', iconfile: 'mapplic/images/icons.svg' } self.el = element; self.init = function(options) { // merging options with defaults self.o = $.extend(self.o, options); if (typeof mapplic_localization !== 'undefined') self.loc = $.extend(self.loc, mapplic_localization); if (self.o.iconfile) self.loc.iconfile = self.o.iconfile; self.el.addClass('mapplic-element mapplic-loading'); // trigger event self.el.trigger('mapload', self); // scope if (self.o.scope) self.scope = $(self.o.scope); else self.scope = self.el; // process map data var data = self.el.data('mapdata'); if (self.el.data('mapdata')) { var mapdata = self.el.data('mapdata'); self.el.removeAttr('data-mapdata').removeData('mapdata'); processData(mapdata); self.el.removeClass('mapplic-loading'); } else if (typeof self.o.source === 'string') { // loading .json file with AJAX $.getJSON(self.o.source, function(data) { processData(data); self.el.removeClass('mapplic-loading'); }).fail(function() { // Failure: couldn't load JSON file or it is invalid. console.error('Couldn\'t load map data. (Make sure to run the script through web server)'); self.el.removeClass('mapplic-loading').addClass('mapplic-error'); alert('Data file missing or invalid!\nMake sure to run the script through web server.'); }); } else { // inline json object processData(self.o.source); self.el.removeClass('mapplic-loading'); } return self; } // tooltip function Tooltip() { this.el = null; this.pin = null; this.shift = 6; this.drop = 0; this.location = null; this.init = function(location, check) { var s = this; // markup this.el = $('
').addClass('mapplic-tooltip'); this.wrap = $('
').addClass('mapplic-tooltip-wrap').appendTo(this.el); this.close = $('').append(getIcon('icon-cross')).addClass('mapplic-tooltip-close').attr('aria-label', self.loc.closepopup).on('click touchend', function(e) { e.preventDefault(); self.hideLocation(); if (!self.o.zoom || self.o.zoomoutclose) self.moveTo(0.5, 0.5, self.fitscale, 400); }).appendTo(this.wrap); this.image = $('').addClass('mapplic-image').attr('alt', 'Location image').hide().appendTo(this.wrap); this.body = $('
').addClass('mapplic-tooltip-body').attr('aria-modal','true').appendTo(this.wrap); this.title = $('

').addClass('mapplic-tooltip-title').appendTo(this.body); this.content = $('
').addClass('mapplic-tooltip-content').appendTo(this.body); this.desc = $('
').addClass('mapplic-tooltip-description').appendTo(this.content); this.link = $('' + self.loc.more + '').addClass('mapplic-popup-link').attr('href', '#').hide().appendTo(this.body); if (self.o.linknewtab) this.link.attr('target', '_blank'); this.triangle = $('
').addClass('mapplic-tooltip-triangle').prependTo(this.wrap); // no focus on deeplink if (!check) this.body.attr('tabindex', '-1'); $('.mapplic-layer.mapplic-visible', self.map).append(this.el); if (self.o.smartip) self.el.on('positionchanged', {s: s}, this.repos); this.el.css({'transform': 'scale(' + 1/self.scale + ')'}); if (location) this.show(location); // close tooltip $(document).on('keyup.mapplic', function(e) { e.stopImmediatePropagation(); if ((e.keyCode === 27)) { self.hideLocation(); if (!self.o.zoom || self.o.zoomoutclose) self.moveTo(0.5, 0.5, self.fitscale, 400); } }); return this; } this.repos = function(e) { var s = e.data.s, tx = '-50%', ty = '-100%'; // vertical var rtop = s.el.offset().top - self.container.el.offset().top; if (rtop < s.wrap.outerHeight() + 36) { s.el.addClass('mapplic-tooltip-bottom'); ty = "0%"; } else { s.el.removeClass('mapplic-tooltip-bottom'); ty = "-100%"; } // horizontal var rleft = s.el.offset().left - self.container.el.offset().left; if (rleft < s.wrap.outerWidth() / 2) { if (rleft > 12) tx = -(100 + rleft / s.wrap.outerWidth() * 100) + 100 + "%"; else tx = "-10%"; } else if (rleft > self.container.el.outerWidth() - s.wrap.outerWidth() / 2) { if (rleft < self.container.el.outerWidth() - 12) tx = (self.container.el.outerWidth() - rleft) / s.wrap.outerWidth() * 100 - 100 + "%"; else tx = "-90%"; } else tx = "-50%" s.wrap.css({ 'transform': 'translate(' + tx + ', ' + ty + ')' }); } this.show = function(location) { if (location) { var s = this; this.el.attr('data-location', location.id); this.location = location; if (self.hovertip) self.hovertip.hide(); if (location.image) { this.image.attr('src', ''); this.image.attr('src', location.image).show(); } else this.image.hide(); if (location.link) { this.link.attr('href', location.link).css('background-color', '').show(); if (location.color) this.link.css('background-color', location.color); } else this.link.hide(); this.title.text(location.title); if (location.description) this.desc.html(location.description); else this.desc.empty(); this.content[0].scrollTop = 0; // shift this.pin = $('.mapplic-pin[data-location="' + location.id + '"]'); if (this.pin.length == 0) { this.shift = 20; } else this.shift = Math.abs(parseFloat(this.pin.css('margin-top'))) + 20; // making it visible this.el.stop().css({opacity: 1}).show(); setTimeout(function() {s.body.focus() }, 600); this.position(); if (self.o.zoom) this.zoom(location); // loading & positioning /* $('img', this.el).off('load').on('load', function() { s.position(); if (self.o.zoom) s.zoom(location); });*/ } } this.position = function() { if (this.location) { this.el.css({ left: (this.location.x * 100) + '%', top: (this.location.y * 100) + '%' }); this.drop = this.el.outerHeight() + this.shift; if (self.o.smartip) this.repos({ data: { s: this}}); } } this.zoom = function(location) { var ry = 0.5, zoom = location.zoom ? parseFloat(location.zoom)/self.o.maxscale : 1; ry = (self.container.el.height()/2 + this.drop/2) / self.container.el.height(); self.moveTo(location.x, location.y, zoom, 600, ry); } this.hide = function() { var s = this; this.location = null; this.el.stop().fadeOut(200, function() { $(this).remove(); }); if (self.o.smartip) self.el.off('positionchanged', this.repos); } } // hover tooltip function HoverTooltip() { this.el = null; this.pin = null; this.shift = 6; this.init = function() { var s = this; // construct this.el = $('
').addClass('mapplic-tooltip mapplic-hovertip'); this.wrap = $('
').addClass('mapplic-tooltip-wrap').appendTo(this.el); this.title = $('

').addClass('mapplic-tooltip-title').appendTo(this.wrap); if (self.o.hovertipdesc) this.desc = $('
').addClass('mapplic-tooltip-description').appendTo(this.wrap); this.triangle = $('
').addClass('mapplic-tooltip-triangle').appendTo(this.wrap); // events // markers + old svg $(self.map).on('mouseover', '.mapplic-pin', function() { var id = $(this).data('location'); s.pin = $('.mapplic-pin[data-location="' + id + '"]'); s.shift = Math.abs(parseFloat(s.pin.css('margin-top'))) + 20; var location = self.l[id]; if (location && location.title) s.show(location); }).on('mouseout', function() { s.hide(); }); // new svg if (self.o.selector) { $(self.map).on('mouseover touchstart', self.o.selector, function() { var location = self.l[$(this).attr('id')]; s.shift = 20; if (location && location.title) s.show(location); }).on('mouseout touchend', function() { s.hide(); }); } self.el.on('positionchanged', {s: s}, this.repos); self.map.append(this.el); return this; } this.repos = function(e) { var s = e.data.s, tx = '-50%', ty = '-100%'; // vertical var rtop = s.el.offset().top - self.container.el.offset().top; if (rtop < s.wrap.outerHeight() + 36) { s.el.addClass('mapplic-tooltip-bottom'); ty = "0%"; } else { s.el.removeClass('mapplic-tooltip-bottom'); ty = "-100%"; } // horizontal var rleft = s.el.offset().left - self.container.el.offset().left; if (rleft < s.wrap.outerWidth() / 2) { if (rleft > 12) tx = -(100 + rleft / s.wrap.outerWidth() * 100) + 100 + "%"; else tx = "-10%"; } else if (rleft > self.container.el.outerWidth() - s.wrap.outerWidth() / 2) { if (rleft < self.container.el.outerWidth() - 12) tx = (self.container.el.outerWidth() - rleft) / s.wrap.outerWidth() * 100 - 100 + "%"; else tx = "-90%"; } else tx = "-50%" s.wrap.css({ 'transform': 'translate(' + tx + ', ' + ty + ')' }); } this.show = function(location) { if (self.location != location) { this.title.text(location.title); if (self.o.hovertipdesc) { if (location.description) this.desc.html(location.description); else this.desc.empty(); } this.position(location); this.el.stop().fadeIn(100); } this.repos({ data: { s: this}}); } this.position = function(location) { if (location) { this.el.css({ left: (location.x * 100) + '%', top: (location.y * 100) + '%' }); this.drop = this.el.outerHeight() + this.shift; } } this.hide = function() { this.el.stop().fadeOut(200); } } // lightbox function Lightbox() { this.el = null; this.init = function() { // construct this.el = $('
').addClass('mapplic-lightbox mfp-hide'); this.title = $('

').addClass('mapplic-lightbox-title').appendTo(this.el); this.desc = $('
').addClass('mapplic-lightbox-description').appendTo(this.el); this.link = $('' + self.loc.more + '').addClass('mapplic-popup-link').attr('href', '#').hide().appendTo(this.el); if (self.o.linknewtab) this.link.attr('target', '_blank'); // append self.el.append(this.el); return this; } this.show = function(location) { this.location = location; this.title.text(location.title); this.desc.html(location.description); if (location.link) { this.link.attr('href', location.link).css('background-color', '').show(); if (location.color) this.link.css('background-color', location.color); } else this.link.hide(); var s = this; $.magnificPopup.open({ items: { src: this.el }, type: 'inline', removalDelay: 300, mainClass: 'mfp-fade', callbacks: { beforeClose: function() { s.hide(); } } }); // zoom var zoom = location.zoom ? parseFloat(location.zoom) : 1; if (self.o.zoom) self.moveTo(location.x, location.y, zoom, 600); return this.el[0]; } this.showImage = function(location) { this.location = location; var s = this; $.magnificPopup.open({ items: { src: location.image }, type: 'image', removalDelay: 300, mainClass: 'mfp-fade', callbacks: { beforeClose: function() { s.hide(); } } }); // zoom var zoom = location.zoom ? parseFloat(location.zoom) : 1; if (self.o.zoom) self.moveTo(location.x, location.y, zoom, 600); } this.hide = function() { this.location = null; this.desc.empty(); self.hideLocation(); if (!self.o.zoom || self.o.zoomoutclose) self.moveTo(0.5, 0.5, self.fitscale, 400); } } // external function External() { this.el = null; this.init = function() { this.el = $('
').addClass('mapplic-external-content').hide(); this.title = $('

').addClass('mapplic-external-title').appendTo(this.el); this.desc = $('
').addClass('mapplic-external-description').appendTo(this.el); this.initial = $(self.o.external + ' > *:not(.mapplic-external-content)'); $(self.o.external).append(this.el); return this; } this.show = function(location) { this.title.text(location.title); this.desc.html(location.description); this.initial.hide(); this.el.show(); } this.hide = function() { this.initial.show(); this.el.hide(); } } // deeplinking function Deeplinking() { this.param = 'location'; this.resolved = false; this.init = function() { var s = this; window.onpopstate = function(e) { if (e.state) s.check(600); return false; } } this.check = function(duration) { var id = this.getUrlParam(this.param); if (id) { self.showLocation(id, duration, true); this.resolved = true; } } this.getUrlParam = function(name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); } this.update = function(id) { var url; if (typeof window.URL !== 'undefined') { url = new URL(window.location.href); url.searchParams.set(this.param, id); url = url.href } else { url = window.location.protocol + "//" + window.location.host + window.location.pathname + '?' + this.param + '=' + id; } window.history.pushState({path: url}, '', url); } this.clear = function() { var url; if (typeof window.URL !== 'undefined') { url = new URL(window.location.href); url.searchParams.delete(this.param); url = url.href; } else { url = window.location.pathname; } history.pushState('', document.title, url); } } // old hash deeplinking method for old browsers (starting IE9) function DeeplinkingHash() { this.param = 'location'; this.resolved = false; this.init = function() { var s = this; this.check(0); $(window).on('hashchange', function() { //s.check(600); }); } this.check = function(duration) { var id = location.hash.slice(this.param.length + 2); if (id) { self.showLocation(id, duration, true); this.resolved = true; } } this.update = function(id) { window.location.hash = this.param + '-' + id; } this.clear = function() { window.location.hash = this.param; } } // minimap function Minimap() { this.el = null; this.opacity = null; this.init = function() { this.el = $('
').addClass('mapplic-minimap').appendTo(self.container.el); this.el.click(function(e) { e.preventDefault(); var x = (e.pageX - $(this).offset().left) / $(this).width(), y = (e.pageY - $(this).offset().top) / $(this).height(); self.moveTo(x, y, self.scale / self.fitscale, 100); }); return this; } this.addLayer = function(data) { var layer = $('
').addClass('mapplic-minimap-layer').attr('data-floor', data.id).appendTo(this.el), s = this; $('').attr('src', data.minimap).addClass('mapplic-minimap-background').attr('aria-hidden', 'true').appendTo(layer); $('
').addClass('mapplic-minimap-overlay').appendTo(layer); $('').attr('src', data.minimap).addClass('mapplic-minimap-active').attr('aria-hidden', 'true').on('load', function() { s.update(); }).appendTo(layer); } this.show = function(target) { $('.mapplic-minimap-layer', this.el).hide(); $('.mapplic-minimap-layer[data-floor="' + target + '"]', this.el).show(); } this.update = function(x, y) { var active = $('.mapplic-minimap-active', this.el); if (x === undefined) x = self.x; if (y === undefined) y = self.y; var width = (self.container.el.width() / self.contentWidth / self.scale * this.el.width()), height = (self.container.el.height() / self.contentHeight / self.scale * this.el.height()), top = (-y / self.contentHeight / self.scale * this.el.height()), left = (-x / self.contentWidth / self.scale * this.el.width()), right = left + width, bottom = top + height; active.each(function() { $(this)[0].style.clip = 'rect(' + top + 'px, ' + right + 'px, ' + bottom + 'px, ' + left + 'px)'; }); // fade out effect var s = this; this.el.show(); this.el.css('opacity', 1.0); clearTimeout(this.opacity); this.opacity = setTimeout(function() { s.el.css('opacity', 0); setTimeout(function() { s.el.hide(); }, 600); }, 2000); } } // legend function Legend() { this.el = null; this.nr = 0; this.init = function() { this.el = $('
').addClass('mapplic-legend'); return this; } this.build = function(categories) { var s = this; $.each(categories, function(index, category) { if (category.legend == 'true') s.add(category); }); if (this.nr > 0) this.el.appendTo(self.container.el); } this.add = function(group) { var toggle = this.newToggle(group, true); if (toggle) toggle.appendTo(this.el); else { var key = $('').addClass('mapplic-legend-key'); if (group.color) key.css('background-color', group.color); $('').addClass('mapplic-legend-label').text(group.title).prepend(key).appendTo(this.el); } this.nr++; } this.toggle = function(group, state) { $('*[id="' + group + '"]', self.map).toggle(state); $('*[data-category*="' + group + '"]', self.map).each(function() { var attr = $(this).attr('data-category'); if (attr == group) $(this).toggle(state); else { // multi-group support var groups = attr.split(','), show = false; groups.forEach(function(g) { if ($('.mapplic-toggle > input[data-group="' + g + '"]')[0] && $('.mapplic-toggle > input[data-group="' + g + '"]')[0].checked) show = true; }); $(this).toggle(show); } }); } this.newToggle = function(group, title) { var s = this, toggle = null; if (group.toggle == 'true') { toggle = $(''); var input = $('').attr('data-group', group.id).appendTo(toggle); var circle = $('').addClass('mapplic-toggle-circle').appendTo(toggle); if (title) $('').addClass('mapplic-legend-label').text(group.title).appendTo(toggle); if (group.switchoff == 'true') input.prop('checked', false); if (group.color) circle.css('background-color', group.color); input.change(function() { $('.mapplic-toggle > input[data-group="' + group.id + '"]', self.el).prop('checked', this.checked); s.toggle(group.id, this.checked); }); } return toggle; } this.applyToggles = function() { var s = this; $('.mapplic-toggle > input', self.el).each(function() { s.toggle($(this).attr('data-group'), this.checked); }); } } // groups function Groups() { this.init = function() {} this.addGroups = function(groups) { if (groups) { $.each(groups, function(index, group) { self.g[group.id] = group; if (group.style && self.s[group.style] && self.s[group.style].base) group.color = self.s[group.style].base.fill; // overwrite color with style }); } if (self.o.sidebar) self.sidebar.addCategories(groups); } } // directory function Directory() { this.dirs = []; this.filters = {}; this.init = function() { var s = this, event = 'mapready'; if (self.o.csv) event = 'csvready'; self.el.on(event, function(e, self) { // dir $('.mapplic-dir:not(.mapplic-dir-results)').each(function() { var attribute = $(this).data('attribute'), pattern = $(this).data('pattern'), title = $(this).text(); if (title) $('

' + title + '

').appendTo($(this).empty()); s.getDirectory(attribute, pattern, attribute).appendTo($(this)); }); // filter $('.mapplic-dir-filter').each(function() { var el = $(this), attribute = el.data('attribute'), options = []; // generate options if ($(this).hasClass('mapplic-dir-filter-generate')) { $.each(self.l, function(id, location) { if (location[attribute]) { var atts = location[attribute].toString().split(','); atts.forEach(function(att) { if (options.indexOf(att) === -1) options.push(att); }); } }); options.forEach(function(option) { var text = option; if (attribute == 'category' && self.g[option]) text = self.g[option].title; $('').attr('value', option).text(text).appendTo(el); }); } // changed $(this).on('change', function() { if (this.value) s.filters[attribute] = this.value; else delete s.filters[attribute]; s.search(); }); }); }); // search $('.mapplic-dir-search').keyup(function(e) { var val = $(this).val(); if (val) s.filters['keyword'] = val; else delete s.filters['keyword']; s.search(); if (e.keyCode == 13) $('.mapplic-dir-results li > a').filter(':first').click(); else if (e.keyCode == 27) s.clearFilters(); }); // results var restitle = $('

0 found

').appendTo($('.mapplic-dir-results')); $('
    ').appendTo($('.mapplic-dir-results')); $('').text('Clear').append(getIcon('icon-cross')).addClass('mapplic-dir-results-clear').appendTo(restitle).on('click', function() { s.clearFilters(); }); // list/grid var directories = $('.mapplic-dir-view').parent().find('.mapplic-dir'); $('.mapplic-dir-view-list').click(function() { $(this).hide(); $('.mapplic-dir-view-grid').show(); directories.removeClass('mapplic-dir-grid'); }); $('.mapplic-dir-view-grid').click(function() { $(this).hide(); $('.mapplic-dir-view-list').show(); directories.addClass('mapplic-dir-grid'); }); return this; } this.getDirectory = function(attribute, pattern, sortby) { var s = this, dir = $('
      '), regex = new RegExp(pattern, 'i'); $.each(self.l, function(id, location) { if (attribute && pattern && !regex.test(location[attribute])) return true; // skip if no match if (String(location.hide) != 'true') dir.append(s.getItem(location)); }); if (sortby) this.sortby(dir, sortby); this.dirs.push(dir); // trigger event self.el.trigger('dirready', dir); return dir; } this.getItem = function(location) { if (!location.id) location = self.l[location]; var item = $('
    • ').addClass('mapplic-dir-item').attr('data-location', location.id); var link = $('').attr('href', '#').click(function(e) { e.preventDefault(); self.showLocation(location.id, 600); // scroll back to map on mobile if (($(window).width() < 668) && (location.action || self.o.action) != 'lightbox') { $('html, body').animate({ scrollTop: self.container.el.offset().top }, 400); } }).appendTo(item); if (self.o.sortby) item.data('sort', location[self.o.sortby]); if (self.o.thumbholder) { var thumbnail = this.thumbnail(location.title, location.thumbnail); if (thumbnail) thumbnail.appendTo(link); } $('

      ').text(location.title).appendTo(link); $('').html(location.about).addClass('mapplic-about').appendTo(link); if (location.color) item.css('border-color', location.color); location.list = item; return item; } this.thumbnail = function(name, field) { var elem = null; if (field) { if (field.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g)) elem = $('').attr('src', field).attr('alt', name).addClass('mapplic-thumbnail'); else elem = $('
      ').addClass('mapplic-thumbnail mapplic-thumbnail-placeholder').attr('aria-hidden', 'true').html(field); } else if (name) { var words = name.split(' '), text = ''; if (words[0]) text += words[0][0]; if (words[1]) text += words[1][0]; elem = $('
      ').addClass('mapplic-thumbnail mapplic-thumbnail-placeholder').attr('aria-hidden', 'true').text(text.toUpperCase()); } return elem; } this.search = function() { var s = this; $('.mapplic-dir-results ul').empty(); if (self.o.highlight) { self.map.removeClass('mapplic-filtered'); $('.mapplic-highlight', self.map).removeClass('mapplic-highlight'); } $.each(self.l, function(i, location) { var matched = true; // matched false, current || $.each(s.filters, function(attribute, filter) { var current = false; if (attribute == 'keyword') $.each(self.o.searchfields, function(i, field) { if (location[field] && !current) current = !(s.normalizeString(location[field]).indexOf(s.normalizeString(filter)) == -1); }); else if (location[attribute] && location[attribute].indexOf(filter) != -1) current = true; matched = matched && current; }); if (matched) { $('.mapplic-dir-item[data-location="' + location.id + '"]').clone(true).appendTo($('.mapplic-dir-results ul')); // results if (self.o.highlight && !$.isEmptyObject(s.filters) && location.el) location.el.addClass('mapplic-highlight'); // highlight } }); s.sortby($('.mapplic-dir-results ul'), 'title'); // alphabetic sort by title if ($.isEmptyObject(s.filters)) { $('.mapplic-dir').show(); $('.mapplic-dir-results').hide(); } else { $('.mapplic-dir').hide(); $('.mapplic-dir-results').show(); if (self.o.highlight) self.map.addClass('mapplic-filtered'); } $('.mapplic-dir-results h3 span').text($('.mapplic-dir-results .mapplic-dir-item').length); // count } this.clearFilters = function() { this.filters = {}; $('.mapplic-dir-search').val(''); $('.mapplic-dir-filter').val(''); this.search(); } this.normalizeString = function(s) { if (s) return s.toString().toLowerCase().normalize('NFD').replace(/[\u0300-\u036f]/g, ""); else return ''; } this.sort = function(dir, order) { if (order === undefined) order = 1; var items = dir.children('.mapplic-dir-item'); items.sort(function(a, b) { var a = $(a).data('sort'), b = $(b).data('sort'); if (isNaN(a) || isNaN(b)) { return (a < b) ? -1 * order : 1 * order; } else return (a - b) * order; }).appendTo(dir); } this.sortby = function(dir, attribute, order) { var s = this; if (order === undefined) order = 1; var items = dir.children('.mapplic-dir-item'); items.each(function() { $(this).data('sort', s.normalizeString(self.l[$(this).data('location')][attribute])); }); this.sort(dir, order); } } // sidebar function Sidebar() { this.el = null; this.header = null; this.clear = null; this.input = null; this.list = null; this.tags = null; this.toggle = null; this.init = function() { var s = this; this.el = $('
      ').addClass('mapplic-sidebar').appendTo(self.el); if (self.o.filtersopened) this.el.addClass('mapplic-sidebar-header-opened'); if (self.o.sidebartoggle) { self.el.addClass('mapplic-dynamic-sidebar'); this.toggle = $('').append(getIcon('icon-sidebar')).addClass('mapplic-button mapplic-sidebar-toggle').appendTo(self.container.el); this.toggle.on('click touchstart', function(e) { e.preventDefault(); self.el.toggleClass('mapplic-hidden-sidebar'); setTimeout(function() { var wr = self.container.el.width() / self.contentWidth, hr = self.container.el.height() / self.contentHeight; if (self.o.mapfill) { if (wr > hr) self.fitscale = wr; else self.fitscale = hr; } else { if (wr < hr) self.fitscale = wr; else self.fitscale = hr; } if (self.container.oldW != self.container.el.width() || self.container.oldH != self.container.el.height()) { self.container.oldW = self.container.el.width(); self.container.oldH = self.container.el.height(); if (self.scale*self.contentWidth < self.container.el.width()) self.moveTo(self.x, self.y, self.scale, 600); } }, 400); }); } if (self.o.search) { this.header = $('
      ').addClass('mapplic-sidebar-header').append(getIcon('icon-magnifier')).appendTo(this.el); this.clear = $('').addClass('mapplic-search-clear').append(getIcon('icon-cross')).appendTo(this.header); this.headerwrap = $('
      ').appendTo(this.header); this.input = $('').attr({'type': 'text', 'spellcheck': 'false', 'placeholder': self.loc.search}).addClass('mapplic-search-input').keyup(function(e) { var val = $(this).val(); if (val) self.directory.filters['keyword'] = val; else delete self.directory.filters['keyword']; s.el.toggleClass('mapplic-sidebar-header-opened', val.length < 1); s.search(); if (e.keyCode == 13) $('.mapplic-list-container li > a').filter(':visible:first').click(); else if (e.keyCode == 27) $(this).blur(); }); this.input.focus(function() { if ($(this).val().length < 1) s.el.addClass('mapplic-sidebar-header-opened'); }); $('body').click(function(e) { if (!$.contains(s.header[0], e.target) && s.header[0] != e.target) s.el.removeClass('mapplic-sidebar-header-opened'); }); this.input.appendTo(this.headerwrap); // clear search this.clear.on('click touchstart', function(e) { e.preventDefault(); s.input.val(''); s.tags.empty(); if (s.tags.children().length < 1) s.el.removeClass('mapplic-sidebar-tagsrow'); self.directory.filters = {}; s.search(); }); this.toggle = $('').append(getIcon('icon-filter')).addClass('mapplic-search-toggle').click(function(e) { e.preventDefault(); s.el.toggleClass('mapplic-sidebar-header-opened'); }).appendTo(this.headerwrap); // tags this.tags = $('
      ').addClass('mapplic-filter-tags').appendTo(this.headerwrap); // filters this.filter = $('
      ').addClass('mapplic-filter').appendTo(this.header); // dim this.dim = $('
      ').addClass('mapplic-sidebar-dim').click(function() { s.el.removeClass('mapplic-sidebar-header-opened'); }).appendTo(this.el); } else this.el.addClass('mapplic-sidebar-nosearch'); // items var event = 'mapready'; if (self.o.csv) event = 'csvready'; self.el.on(event, function(e, self) { s.dir = self.directory.getDirectory().addClass('mapplic-list-container').appendTo(s.el); // alphabetic sort by title if (self.o.alphabetic) self.directory.sortby(s.dir, 'title'); }); if (self.o.searchdescription && self.o.searchfields.indexOf('description') === -1) self.o.searchfields.push('description'); } this.addTag = function(item) { var s = this, categories = []; if (self.directory.filters['category']) categories = self.directory.filters['category'].split(','); if (!categories.includes(item.id)) { categories.push(item.id); self.directory.filters['category'] = categories.toString(); this.el.addClass('mapplic-sidebar-tagsrow'); var tag = $('').addClass('mapplic-tag').text(item.title).attr('aria-label', self.loc.clearfilter + ': ' + item.title).prependTo(this.tags); $('').appendTo(tag); if (item.color) tag.css('background-color', item.color); if (item.id) tag.attr('data-id', item.id); tag.click(function() { tag.remove(); if (s.tags.children().length < 1) s.el.removeClass('mapplic-sidebar-tagsrow'); if (self.directory.filters['category'] == item.id) delete self.directory.filters['category']; else if (self.directory.filters['category']) { categories = self.directory.filters['category'].split(','); var i = categories.indexOf(item.id); if (i > -1) { categories.splice(i, 1) self.directory.filters['category'] = categories.toString(); } } s.search(); }).appendTo(tag); s.search(); this.el.removeClass('mapplic-sidebar-header-opened'); } } this.addCategories = function(categories) { var s = this, list = $('
        '), add = false; if (categories) { $.each(categories, function(index, category) { category.nr = 0; if (!(category.hide == 'true')) { var item = $('
      • ').addClass('mapplic-list-category').attr('data-category', category.id); var link = $('').attr('href', '#').prependTo(item); var thumbnail = self.directory.thumbnail(category.title, category.icon).appendTo(link); if (category.color && thumbnail) thumbnail.css({'background-color': category.color, 'border-color': category.color }); var title = $('

        ').addClass('mapplic-about').html(category.about).appendTo(link); category.count = $('').text('(0)').addClass('mapplic-list-count').appendTo(title); var toggle = self.legend.newToggle(category) if (toggle) toggle.appendTo(item); link.on('click', function(e) { e.preventDefault(); if (category.nr < 1 && toggle) $('> input', toggle).trigger('click'); else { //s.input.val(''); s.addTag(category); } }); category.list = item; item.appendTo(list); add = true; } }); if (add) { s.el.addClass('mapplic-sidebar-filterable'); //$('

        ').text('CATEGORIES').appendTo(s.filter); list.appendTo(s.filter); } } } this.countCategory = function() { $.each(self.g, function(i, group) { if (group.count) { group.count.text('(' + group.nr + ')'); if (group.nr < 1) group.count.hide(); else group.count.show(); } }); } // search this.search = function() { var s = this; if (self.o.highlight) { self.map.removeClass('mapplic-filtered'); $('.mapplic-highlight', self.map).removeClass('mapplic-highlight'); } $.each(self.l, function(i, location) { var matched = true; // matched false, current || $.each(self.directory.filters, function(attribute, filter) { var current = false; if (attribute == 'keyword') $.each(self.o.searchfields, function(i, field) { if (location[field] && !current) current = !(self.directory.normalizeString(location[field]).indexOf(self.directory.normalizeString(filter)) == -1); }); else if (location.category && attribute == 'category') { var categories = location.category; if (typeof categories == 'string') categories = categories.split(','); categories.forEach(function(category) { if (self.directory.filters['category'].split(',').includes(category)) current = true; }); } else if (location[attribute] && location[attribute].indexOf(filter) != -1) current = true; matched = matched && current; }); var item = $('.mapplic-dir-item[data-location="' + location.id + '"]', self.el); if (matched) { item.show(); if (self.o.highlight && !$.isEmptyObject(self.directory.filters) && location.el) location.el.addClass('mapplic-highlight'); // highlight } else item.hide(); }); if (!$.isEmptyObject(self.directory.filters)) { if (self.o.highlight) self.map.addClass('mapplic-filtered'); self.el.addClass('mapplic-search-active'); } else self.el.removeClass('mapplic-search-active'); } } // developer tools function DevTools() { this.el = null; this.init = function() { this.el = $('
        ').addClass('mapplic-coordinates').appendTo(self.container.el); this.el.append('x: '); $('').addClass('mapplic-coordinates-x').appendTo(this.el); this.el.append(' y: '); $('').addClass('mapplic-coordinates-y').appendTo(this.el); $('.mapplic-layer', self.map).on('mousemove', function(e) { var x = (e.pageX - self.map.offset().left) / self.map.width() / self.scale, y = (e.pageY - self.map.offset().top) / self.map.height() / self.scale; $('.mapplic-coordinates-x').text(parseFloat(x).toFixed(4)); $('.mapplic-coordinates-y').text(parseFloat(y).toFixed(4)); }); return this; } } // clear button function ClearButton() { this.el = null; this.init = function() { this.el = $('').text(self.loc.resetzoom).append(getIcon('icon-reset')).addClass('mapplic-button mapplic-clear-button').appendTo(self.container.el); if (!self.o.zoombuttons) this.el.css('bottom', '0'); this.el.on('click touchstart', function(e) { e.preventDefault(); self.hideLocation(); self.moveTo(0.5, 0.5, self.fitscale, 400); }); return this; } this.update = function(scale) { if (scale == self.fitscale) this.el.stop().fadeOut(200); else this.el.stop().fadeIn(200); } } // zoom buttons function ZoomButtons() { this.el = null; this.init = function() { this.el = $('
        ').addClass('mapplic-zoom-buttons').appendTo(self.container.el); // zoom-in button this.zoomin = $('').attr('aria-label', self.loc.zoomin).append(getIcon('icon-plus')).addClass('mapplic-button mapplic-zoomin-button').appendTo(this.el); this.zoomin.on('click touchstart', function(e) { e.preventDefault(); self.container.stopMomentum(); var scale = self.scale; self.scale = normalizeScale(scale + scale * 0.8); self.x = normalizeX(self.x - (self.container.el.width() / 2 - self.x) * (self.scale / scale - 1)); self.y = normalizeY(self.y - (self.container.el.height() / 2 - self.y) * (self.scale / scale - 1)); zoomTo(self.x, self.y, self.scale, 400, 'ease'); }); // zoom-out button this.zoomout = $('').attr('aria-label', self.loc.zoomout).append(getIcon('icon-minus')).addClass('mapplic-button mapplic-zoomout-button').appendTo(this.el); this.zoomout.on('click touchstart', function(e) { e.preventDefault(); self.container.stopMomentum(); var scale = self.scale; self.scale = normalizeScale(scale - scale * 0.4); self.x = normalizeX(self.x - (self.container.el.width() / 2 - self.x) * (self.scale / scale - 1)); self.y = normalizeY(self.y - (self.container.el.height() / 2 - self.y) * (self.scale / scale - 1)); zoomTo(self.x, self.y, self.scale, 400, 'ease'); }); return this; } this.update = function(scale) { this.zoomin.removeAttr('disabled'); this.zoomout.removeAttr('disabled'); if (scale == self.fitscale) this.zoomout.attr('disabled','disabled'); else if (scale == 1) this.zoomin.attr('disabled','disabled'); } } // fullscreen function Fullscreen() { this.el = null; this.fsh = null; // fullscreen placeholder this.esh = null; // element placeholder this.init = function() { var s = this; this.fph = $('
        ').addClass('mapplic-fsh').prependTo('body'); this.eph = $('
        ').addClass('mapplic-esh').insertBefore(self.el); // fullscreen button this.el = $('').append(getIcon('icon-fullscreen')).append(getIcon('icon-fullscreen-exit')).addClass('mapplic-button mapplic-fullscreen-button').click(function(e) { self.el.toggleClass('mapplic-fullscreen'); if (self.el.hasClass('mapplic-fullscreen')) self.el.insertBefore(s.fph); else self.el.insertBefore(s.eph); $(document).resize(); }).appendTo(self.container.el); // esc key $(document).on('keyup.mapplic', function(e) { if ((e.keyCode === 27) && $('.mapplic-fullscreen')[0]) { $('.mapplic-element.mapplic-fullscreen').removeClass('mapplic-fullscreen'); self.el.insertBefore(s.eph); $(document).resize(); } }); } } // styles function Styles() { this.data = null; this.init = function(data) { this.data = data; this.process(data); return this; } this.process = function(styles) { var css = ''; // basecolor if (self.o.basecolor) css += this.rule('.mapplic-fullscreen, .mapplic-legend', 'background-color', self.o.basecolor); // bgcolor if (self.o.bgcolor) { css += this.rule( '.mapplic-button, .mapplic-tooltip-close .mapplic-icon, .mapplic-levels-select, .mapplic-levels button, .mapplic-level-switcher button.mapplic-selected, .mapplic-element *::-webkit-scrollbar-track, .mapplic-list-container, .mapplic-filter, .mapplic-sidebar-header, .mapplic-tooltip-wrap, .mapplic-lightbox, .mapplic-toggle:before', 'background-color', self.o.bgcolor ); css += this.rule('.mapplic-legend-key, .mapplic-element *::-webkit-scrollbar-thumb', 'border-color', self.o.bgcolor); css += this.rule('.mapplic-tooltip:after', 'border-color', self.o.bgcolor + ' transparent transparent transparent !important'); css += this.rule('.mapplic-tooltip-bottom.mapplic-tooltip:after', 'border-color', 'transparent transparent ' + self.o.bgcolor + ' transparent !important'); } // bgcolor2 if (self.o.bgcolor2) { css += this.rule( '.mapplic-thumbnail-placeholder, .mapplic-level-switcher button, .mapplic-sidebar .mapplic-dir-item > a:hover, .mapplic-sidebar-header-opened.mapplic-sidebar-filterable .mapplic-search-toggle, .mapplic-sidebar .mapplic-dir-item > a:focus, .mapplic-sidebar .mapplic-dir-item.mapplic-active > a, .mapplic-list-category > a:hover, .mapplic-zoom-buttons button:disabled, .mapplic-levels button:disabled', 'background-color', self.o.bgcolor2 ); css += this.rule('a.mapplic-zoomin-button', 'border-color', self.o.bgcolor2); } // headingcolor if (self.o.headingcolor) { css += this.rule('.mapplic-search-input, .mapplic-level-switcher button.mapplic-selected, .mapplic-list-category > a, .mapplic-tooltip-title, .mapplic-lightbox-title, .mapplic-sidebar .mapplic-dir-item h4, .mapplic-element strong, .mapplic-levels-select, .mapplic-list-category h4', 'color', self.o.headingcolor); css += this.rule('.mapplic-icon', 'fill', self.o.headingcolor); } // textcolor if (self.o.textcolor) css += this.rule('.mapplic-element, .mapplic-element a, .mapplic-level-switcher button, .mapplic-about, .mapplic-list-category > a .mapplic-list-count, .mapplic-search-input::placeholder, .mapplic-lightbox-description', 'color', self.o.textcolor); // accentcolor if (self.o.accentcolor) css += this.rule('.mapplic-popup-link, .mapplic-accentcolor', 'background-color', self.o.accentcolor); if (styles) { self.s = []; styles.forEach(function(s) { // styles object self.s[s.class] = s; if (s.base) { css += '.' + s.class + '.mapplic-clickable:not(g), g.' + s.class + '.mapplic-clickable > * { '; $.each(s.base, function(prop, val) { css += prop + ': ' + val + '; '; }); css += '}\n'; css += '.' + s.class + '.mapplic-pin {\n'; $.each(s.base, function(prop, val) { css += ' background-color: ' + val + ';\n'; css += ' border-color: ' + val + ';\n'; }); css += '}\n\n'; } if (s.hover) { css += '.' + s.class + '.mapplic-highlight:not(g), g.' + s.class + '.mapplic-highlight > *, .' + s.class + '.mapplic-clickable:not(g):hover, g.' + s.class + '.mapplic-clickable:hover > * { '; $.each(s.hover, function(prop, val) { css += prop + ': ' + val + '; ' }); css += '}\n'; css += '.' + s.class + '.mapplic-pin.mapplic-highlight, .' + s.class + '.mapplic-pin:hover {\n'; $.each(s.hover, function(prop, val) { css += ' background-color: ' + val + ';\n'; css += ' border-color: ' + val + ';\n'; }); css += '}\n\n'; } if (s.active) { css += '.'+ s.class + '.mapplic-active:not(g), g.' + s.class + '.mapplic-active > * { '; $.each(s.active, function(prop, val) { css += prop + ': ' + val + ' !important; ' }); css += '}\n'; css += '.' + s.class + '.mapplic-pin.mapplic-active {\n'; $.each(s.active, function(prop, val) { css += ' background-color: ' + val + ';\n'; css += ' border-color: ' + val + ';\n'; }); css += '}\n\n'; } }); } if (self.o.customcss) css += self.o.customcss; var style = $('').html(css).appendTo('body'); } this.rule = function(selector, attribute, value) { var css = selector + ' {\n'; css += ' ' + attribute + ': ' + value + ';\n'; css += '}\n\n'; return css; } } function Container() { this.el = null; this.oldW = 0; this.oldH = 0; this.position = {x: 0, y: 0}, this.momentum = null; this.levels = {}; this.init = function() { this.el = $('
        ').addClass('mapplic-container').appendTo(self.el); self.map = $('
        ').addClass('mapplic-map').appendTo(this.el); self.map.css({ 'width': self.contentWidth, 'height': self.contentHeight }); return this; } // returns container height (px) this.calcHeight = function(v) { var val = Math.min(Math.max(this.getHeight(v), this.getHeight(self.o.minheight)), this.getHeight(self.o.maxheight)); if ($.isNumeric(val)) return val; else return false; } this.getHeight = function(v) { var val = v.toString().replace('px', ''); if ((val == 'auto') && (self.container.el)) val = self.container.el.width() * self.contentHeight / self.contentWidth; else if (val.slice(-1) == '%') val = $(window).height() * val.replace('%', '') / 100; return val; } this.resetZoom = function() { var init = self.l['init']; if (init) { self.switchLevel(init.level); if (!self.bboxZoom(init.el)) self.zoomLocation(init); } else self.moveTo(0.5, 0.5, self.fitscale, 0); } this.revealChild = function(parent) { $('.mapplic-pin[data-location^=' + parent.id + '-]', self.map).addClass('mapplic-revealed'); $('.mapplic-map-image [id^=' + parent.id + '-]', self.map).addClass('mapplic-revealed'); } this.revealZoom = function(zoom) { $('.mapplic-pin[data-reveal]', self.map).each(function() { var reveal = $(this).data('reveal'); if (zoom * self.o.maxscale >= reveal) $(this).addClass('mapplic-revealed'); else $(this).removeClass('mapplic-revealed'); }); } this.coverAll = function() { $('.mapplic-revealed', self.map).removeClass('mapplic-revealed'); } this.stopMomentum = function() { cancelAnimationFrame(this.momentum); if (this.momentum != null) { self.x = this.position.x; self.y = this.position.y; } this.momentum = null; } this.addLevelSwitcher = function() { if (self.data.levels.length > 1) { var control = $('
        ').addClass('mapplic-level-switcher'); self.data.levels.forEach(function(level, i) { var button = $('').attr('data-level', level.id).text(level.title).prependTo(control).click(function(e) { e.preventDefault(); self.switchLevel(level.id); }); if (level.show) button.addClass('mapplic-selected'); }); this.el.append(control); self.el.on('levelswitched', function(e, target) { $('button', control).removeClass('mapplic-selected'); $('button[data-level="' + target + '"]', control).addClass('mapplic-selected'); }); } } this.addControls = function() { self.map.addClass('mapplic-zoomable'); document.ondragstart = function() { return false; } // IE drag fix // momentum var friction = 0.85, mouse = {x: 0, y: 0}, pre = {x: 0, y: 0}, previous = {x: this.position.x, y: this.position.y}, velocity = {x: 0, y: 0}; var s = this; var momentumStep = function() { s.momentum = requestAnimationFrame(momentumStep); if (self.map.hasClass('mapplic-dragging')) { pre.x = previous.x; pre.y = previous.y; previous.x = s.position.x; previous.y = s.position.y; s.position.x = mouse.x; s.position.y = mouse.y; velocity.x = previous.x - pre.x; velocity.y = previous.y - pre.y; } else { s.position.x += velocity.x; s.position.y += velocity.y; velocity.x *= friction; velocity.y *= friction; if (Math.abs(velocity.x) + Math.abs(velocity.y) < 0.1) { s.stopMomentum(); self.x = s.position.x; self.y = s.position.y; } } s.position.x = normalizeX(s.position.x); s.position.y = normalizeY(s.position.y); zoomTo(s.position.x, s.position.y); } // drag & drop $('.mapplic-map-image', self.map).on('mousedown', function(e) { self.dragging = false; self.map.addClass('mapplic-dragging'); s.stopMomentum(); var initial = { x: e.pageX - self.x, y: e.pageY - self.y }; mouse.x = normalizeX(e.pageX - initial.x); mouse.y = normalizeY(e.pageY - initial.y); momentumStep(); self.map.on('mousemove', function(e) { self.dragging = true; mouse.x = normalizeX(e.pageX - initial.x); mouse.y = normalizeY(e.pageY - initial.y); }); $(document).on('mouseup.mapplic', function() { $(document).off('mouseup.mapplic'); self.map.off('mousemove'); self.map.removeClass('mapplic-dragging'); }); }); // mousewheel if (self.o.mousewheel) $('.mapplic-map-image', self.el).on('mousewheel DOMMouseScroll', self.mouseWheel); // touch var init1 = null, init2 = null, initD = 0, initScale = null; $('.mapplic-map-image', self.map).on('touchstart', function(e) { e.preventDefault(); var eo = e.originalEvent; if (eo.touches.length == 1) { self.map.addClass('mapplic-dragging'); self.dragging = false; s.stopMomentum(); init1 = { x: eo.touches[0].pageX - self.x, y: eo.touches[0].pageY - self.y }; self.firstcoord = { x: eo.touches[0].pageX, y: eo.touches[0].pageY }; mouse = { x: normalizeX(eo.touches[0].pageX - init1.x), y: normalizeY(eo.touches[0].pageY - init1.y) }; momentumStep(); self.map.on('touchmove', function(e) { e.preventDefault(); self.dragging = true; var eo = e.originalEvent; if (eo.touches.length == 1) { mouse.x = normalizeX(eo.touches[0].pageX - init1.x); mouse.y = normalizeY(eo.touches[0].pageY - init1.y); self.lastcoord = { x: eo.touches[0].pageX, y: eo.touches[0].pageY }; } else if (eo.touches.length > 1) { var pos = { x: (eo.touches[0].pageX + eo.touches[1].pageX)/2, y: (eo.touches[0].pageY + eo.touches[1].pageY)/2 } var dist = Math.sqrt(Math.pow(eo.touches[0].pageX - eo.touches[1].pageX, 2) + Math.pow(eo.touches[0].pageY - eo.touches[1].pageY, 2)) / initD; var scale = self.scale; self.scale = normalizeScale(initScale * dist); self.x = normalizeX(self.x - (pos.x - self.container.el.offset().left - self.x) * (self.scale/scale - 1)); self.y = normalizeY(self.y - (pos.y - self.container.el.offset().top - self.y) * (self.scale/scale - 1)); zoomTo(self.x, self.y, self.scale, 100, 'ease'); } }); $(document).on('touchend.mapplic', function(e) { e.preventDefault(); var dragback = null, eo = e.originalEvent; if (eo.touches.length == 0) { clearTimeout(dragback); $(document).off('touchend.mapplic'); self.map.off('touchmove'); self.map.removeClass('mapplic-dragging'); self.dragging = false; } else if (eo.touches.length == 1) { dragback = setTimeout(function() { self.map.addClass('mapplic-dragging'); self.dragging = true; s.stopMomentum(); init1 = { x: eo.touches[0].pageX - self.x, y: eo.touches[0].pageY - self.y }; mouse = { x: normalizeX(eo.touches[0].pageX - init1.x), y: normalizeY(eo.touches[0].pageY - init1.y) }; momentumStep(); }, 60); } }); } // pinch else if (eo.touches.length == 2) { self.dragging = true; self.map.addClass('mapplic-dragging'); s.stopMomentum(); init2 = { x: eo.touches[1].pageX - self.x, y: eo.touches[1].pageY - self.y }; initD = Math.sqrt(Math.pow(init1.x - init2.x, 2) + Math.pow(init1.y - init2.y, 2)); initScale = self.scale; } }); } } // functions var processData = function(data) { self.data = data; self.g = {}; self.l = {}; var shownLevel = null; // extend options self.o = $.extend(self.o, data); $.each(self.el.data(), function(i, v) { self.o[i] = v; }); self.o.zoommargin = parseFloat(self.o.zoommargin); self.o.maxscale = parseFloat(self.o.maxscale); // more text if (self.o.moretext) self.loc.more = self.o.moretext; // height of container if (self.el.data('height')) self.o.height = self.el.data('height'); self.contentWidth = parseFloat(data.mapwidth); self.contentHeight = parseFloat(data.mapheight); // limiting to scale 1 self.contentWidth = self.contentWidth * self.o.maxscale; self.contentHeight = self.contentHeight * self.o.maxscale; // create container self.container = new Container().init(); // styles self.styles = new Styles().init(self.o.styles); // create minimap if (self.o.minimap) self.minimap = new Minimap().init(); // create legend self.legend = new Legend().init(); self.legend.build(data.groups || data.categories); // directory self.directory = new Directory().init(); // create sidebar if (self.o.sidebar) { self.sidebar = new Sidebar(); self.sidebar.init(); } else self.container.el.css('width', '100%'); // groups self.groups = new Groups(); self.groups.addGroups(data.groups || data.categories); // trigger event self.el.trigger('mapstart', self); // iterate through levels var levelnr = 0, toload = 0; if (data.levels) { $.each(data.levels, function(index, level) { var source = level.map, extension = source.substr((source.lastIndexOf('.') + 1)).toLowerCase(); // new map layer var layer = $('
        ').addClass('mapplic-layer').attr('data-floor', level.id).appendTo(self.map); switch (extension) { // image formats case 'jpg': case 'jpeg': case 'png': case 'gif': var mapimage = $('
        ').addClass('mapplic-map-image').appendTo(layer); $('').attr('src', source).attr('aria-hidden', 'true').addClass('mapplic-map-image').appendTo(mapimage); if (level.locations) self.addLocations(level.locations, level.id); break; // vector format case 'svg': toload++; var mapimage = $('
        ').addClass('mapplic-map-image').appendTo(layer); $('
        ').load(source, function() { // sanitize svg - XSS protection $('script', this).remove(); mapimage.html($(this).html()); // illustrator duplicate id fix $(self.o.selector, mapimage).each(function() { var id = $(this).attr('id'); if (id) $(this).attr('id', id.replace(/_[1-9]+_$/g, '')); }); // add locations if (level.locations) self.addLocations(level.locations, level.id); // click event $(self.o.selector, mapimage).on('click touchend', function(e) { var shift = Math.abs(self.firstcoord.x - self.lastcoord.x) + Math.abs(self.firstcoord.y - self.lastcoord.y); if (!self.dragging || shift < 4) self.showLocation($(this).attr('id'), 600); }); // autopopulate if (self.o.autopopulate) { var ap = []; $(self.o.selector, mapimage).each(function() { var id = $(this).attr('id'), location = self.l[id]; if (!location) { location = { id: id, title: id.charAt(0).toUpperCase() + id.slice(1), pin: 'hidden' }; ap.push(location); } }); self.addLocations(ap, level.id); } // trigger event(s) self.el.trigger('svgloaded', [mapimage, level.id]); toload--; if (toload == 0) mapReady(); }); break; // others default: alert('File type ' + extension + ' is not supported!'); } // create new minimap layer if (self.minimap) self.minimap.addLayer(level); // shown level if (!shownLevel || level.show) shownLevel = level.id; levelnr++; }); } // COMPONENTS self.tooltips = Array(); if (self.o.lightbox && $.magnificPopup) self.lightbox = new Lightbox().init(); if (self.o.hovertip) self.hovertip = new HoverTooltip().init(); if (self.o.external) self.external = new External().init(); if (self.o.clearbutton) self.clearbutton = new ClearButton().init(); if (self.o.zoombuttons) self.zoombuttons = new ZoomButtons().init(); if (self.o.fullscreen) self.fullscreen = new Fullscreen().init(); if (self.o.developer) self.devtools = new DevTools().init(); self.container.addLevelSwitcher(); self.switchLevel(shownLevel); if (self.o.portrait === 'true') self.o.portrait = true; // resize $(window).resize(function() { if (self.o.portrait == true || $.isNumeric(self.o.portrait) && self.el.width() < parseFloat(self.o.portrait)) { self.el.addClass('mapplic-portrait'); if (self.el.hasClass('mapplic-fullscreen')) self.container.el.height($(window).height()); else self.container.el.height(self.container.calcHeight(self.o.height)); } else { self.el.removeClass('mapplic-portrait'); self.container.el.height('100%'); self.el.height(self.container.calcHeight(self.o.height)); } var wr = self.container.el.width() / self.contentWidth, hr = self.container.el.height() / self.contentHeight; if (self.o.mapfill) { if (wr > hr) self.fitscale = wr; else self.fitscale = hr; } else { if (wr < hr) self.fitscale = wr; else self.fitscale = hr; } if (self.container.oldW != self.container.el.width() || self.container.oldH != self.container.el.height()) { self.container.oldW = self.container.el.width(); self.container.oldH = self.container.el.height(); self.container.resetZoom(); } }).resize(); // deeplinking if (self.o.deeplinking) { if (history.pushState && (typeof URL == 'function')) self.deeplinking = new Deeplinking(); else self.deeplinking = new DeeplinkingHash(); self.deeplinking.init(); } // trigger event if (toload == 0) mapReady(); // controls if (self.o.zoom) self.container.addControls(); self.firstcoord = self.lastcoord = {}; // link to locations $(document).on('click', '.mapplic-location', function(e) { e.preventDefault(); self.showLocation($(this).attr('href').substr(1), 400); $('html, body').animate({ scrollTop: self.container.el.offset().top }, 400); }); } var mapReady = function() { // separate location array self.addLocations(self.data.locations); // apply toggle self.legend.applyToggles(); // CSV support if (self.o.csv) { if (typeof Papa === 'undefined') { console.warn('CSV parser missing. Please make sure the library is loaded.'); } else { Papa.parse(self.o.csv, { header: true, download: true, encoding: "UTF-8", skipEmptyLines: true, complete: function(results, file) { self.addLocations(results.data); $('.mapplic-pin', self.map).css({ 'transform': 'scale(' + 1/self.scale + ')' }); if (self.deeplinking) self.deeplinking.check(0); self.el.trigger('csvready', self); } }); } } self.container.resetZoom(); if (self.deeplinking) self.deeplinking.check(0); // landmark mode if (self.el.data('landmark')) self.o.landmark = self.el.data('landmark'); if (self.o.landmark) { // Custom settings self.o.sidebar = false; self.o.zoombuttons = false; self.o.deeplinking = false; self.showLocation(self.o.landmark, 0, true); } // trigger event self.el.trigger('mapready', self); } /* PRIVATE METHODS */ // Web Mercator (EPSG:3857) lat/lng projection var latlngToPos = function(lat, lng) { var deltaLng = self.data.rightLng - self.data.leftLng, bottomLatDegree = self.data.bottomLat * Math.PI / 180, mapWidth = ((self.data.mapwidth / deltaLng) * 360) / (2 * Math.PI), mapOffsetY = (mapWidth / 2 * Math.log((1 + Math.sin(bottomLatDegree)) / (1 - Math.sin(bottomLatDegree)))); lat = lat * Math.PI / 180; return { x: ((lng - self.data.leftLng) * (self.data.mapwidth / deltaLng)) / self.data.mapwidth, y: (self.data.mapheight - ((mapWidth / 2 * Math.log((1 + Math.sin(lat)) / (1 - Math.sin(lat)))) - mapOffsetY)) / self.data.mapheight }; } var estimatedPosition = function(element) { if (!element || !(element[0] instanceof SVGElement)) return false; var bbox = element[0].getBBox(); var padding = 40, wr = self.container.el.width() / (bbox.width + padding), hr = self.container.el.height() / (bbox.height + padding); return { x: (bbox.x + bbox.width/2) / self.contentWidth * self.o.maxscale, y: (bbox.y + bbox.height/2) / self.contentHeight * self.o.maxscale, scale: Math.min(wr, hr) / self.o.maxscale } } var getIcon = function(name) { return ''; } // normalizing x, y and scale var normalizeX = function(x) { var minX = (self.container.el.width() - self.contentWidth * self.scale).toFixed(4); if (minX < 0) { if (x > self.o.zoommargin) x = self.o.zoommargin; else if (x < minX - self.o.zoommargin) x = minX - self.o.zoommargin; } else x = minX/2; return x; } var normalizeY = function(y) { var minY = (self.container.el.height() - self.contentHeight * self.scale).toFixed(4); if (minY < 0) { if (y > self.o.zoommargin) y = self.o.zoommargin; else if (y < minY - self.o.zoommargin) y = minY - self.o.zoommargin; } else y = minY/2; return y; } var normalizeScale = function(scale) { if (self.fitscale > 1) return self.fitscale; // no zoom if (scale <= self.fitscale) scale = self.fitscale; else if (scale > 1) scale = 1; // zoom timeout clearTimeout(self.zoomTimeout); self.zoomTimeout = setTimeout(function() { if (self.zoombuttons) self.zoombuttons.update(scale); if (self.clearbutton) self.clearbutton.update(scale); if (scale == self.fitscale) { self.container.coverAll(); if (self.o.closezoomout) self.hideLocation(); } self.container.revealZoom(scale); }, 200); return scale; } var moveTimeout = null; var zoomTo = function(x, y, scale, d) { d = typeof d !== 'undefined' ? d/1000 : 0; // move class self.el.addClass('mapplic-move'); clearTimeout(moveTimeout); moveTimeout = setTimeout(function() { self.el.removeClass('mapplic-move'); self.el.trigger('positionchanged', location); }, 400); // transforms self.map.css({ 'transition': 'transform ' + d + 's', 'transform': 'translate(' + x.toFixed(3) + 'px ,' + y.toFixed(3) + 'px) scale(' + self.scale.toFixed(3) + ')' }); if (scale) { $('.mapplic-pin, .mapplic-tooltip', self.map).css({ 'transition': 'transform ' + d + 's', 'transform': 'scale(' + 1/scale + ')' }); } if (self.minimap) self.minimap.update(x, y); // trigger event self.el.trigger('positionchanged', location); } var replaceVars = function(template, location) { template = template.replace(/\{\{([^}]+)\}\}/g, function (match) { match = match.slice(2, -2); var sub = match.split('.'); if (sub.length > 1) { var temp = location; sub.forEach(function (item) { if (!temp[item]) { temp = '{{' + match + '}}'; return; } temp = temp[item]; }); return temp; } else { if (!location[match]) return '{{' + match + '}}'; return location[match]; } }); return template; } /* PUBLIC METHODS */ var levelTimeout = null; self.switchLevel = function(target) { // no such layer if (!target) return; var layer = $('.mapplic-layer[data-floor="' + target + '"]', self.map); // target layer is already active if (layer.hasClass('mapplic-visible')) return; // show target layer layer.removeClass('mapplic-hidden'); setTimeout(function() { var old = $('.mapplic-layer.mapplic-visible', self.map).removeClass('mapplic-visible'); layer.addClass('mapplic-visible'); clearTimeout(levelTimeout); levelTimeout = setTimeout(function() { $('.mapplic-layer:not([data-floor="' + target + '"])', self.map).addClass('mapplic-hidden'); }, 300); // slide animation if (self.o.animations) { var found = false; $('.mapplic-layer', self.map).each(function() { if ($(this).data('floor') == target) { $(this).removeClass('mapplic-layer-up').removeClass('mapplic-layer-down'); found = true; } else if (found) $(this).addClass('mapplic-layer-up'); else $(this).addClass('mapplic-layer-down'); }); } }, 1); // show target minimap layer if (self.minimap) self.minimap.show(target); self.level = target; // trigger event self.el.trigger('levelswitched', target); } self.mouseWheel = function(e, delta) { e.preventDefault(); self.container.stopMomentum(); var scale = self.scale; self.scale = normalizeScale(scale + scale * delta / 5); self.x = normalizeX(self.x - (e.pageX - self.container.el.offset().left - self.x) * (self.scale/scale - 1)); self.y = normalizeY(self.y - (e.pageY - self.container.el.offset().top - self.y) * (self.scale/scale - 1)); zoomTo(self.x, self.y, self.scale, 200, 'ease'); } self.addTooltip = function(location, check) { var tooltip = new Tooltip().init(location, check); self.tooltips.push(tooltip); return tooltip.wrap[0]; } self.closeTooltips = function() { self.tooltips.forEach(function(t, i) { t.hide(); self.tooltips.splice(i, 1); }); } self.moveTo = function(x, y, s, duration, ry) { duration = typeof duration !== 'undefined' ? duration : 400; ry = typeof ry !== 'undefined' ? ry : 0.5; s = typeof s !== 'undefined' ? s : self.scale/self.fitscale; self.container.stopMomentum(); self.scale = normalizeScale(s); self.x = normalizeX(self.container.el.width() * 0.5 - self.scale * self.contentWidth * x); self.y = normalizeY(self.container.el.height() * ry - self.scale * self.contentHeight * y); zoomTo(self.x, self.y, self.scale, duration); } self.bboxZoom = function(element) { var pos = estimatedPosition(element); if (!pos) return false; self.moveTo(pos.x, pos.y, pos.scale, 600); return true; } // adding locations self.addLocations = function(locations, levelid) { $.each(locations, function(index, location) { if (location.id) self.addLocation(location, levelid); }); } self.addLocation = function(location, levelid) { // jump if location ID exists if (self.l[location.id]) return true; // building the location object self.l[location.id] = location; // groups var groups = location.category; if (groups) { if (typeof groups == 'string') groups = groups.toString().split(','); groups.forEach(function(group) { if (self.g[group]) self.g[group].nr++; }); } // cascaded fill var fill = (location && location.fill) || (location.category && self.g[location.category] && self.g[location.category].color) || (location.category && location.category[0] && self.g[location.category[0]] && self.g[location.category[0]].color) || self.o.fillcolor || false; // cascade style to attribute styleD! location.styled = (location && location.style) || (location.category && self.g[location.category] && self.g[location.category].style) || (location.category && location.category[0] && self.g[location.category[0]] && self.g[location.category[0]].style) || self.o.defaultstyle || false; if (fill) location.color = fill; else if (location.styled) location.color = location.styled.base; // interactive element var elem = $('[id^=MLOC] > *[id="' + location.id + '"], [id^=landmark] > *[id="' + location.id + '"]', self.map); if (elem.length > 0) { location.el = elem; location.el.addClass('mapplic-clickable'); if (location.styled) { location.el.addClass(location.styled); } else if (fill) { location.el.css('fill', fill); $('> *', location.el).css('fill', fill); } } // first level if not set if (!location.level) { if (levelid) location.level = levelid; else if (location.el && location.el.closest('.mapplic-layer').data('floor')) location.level = location.el.closest('.mapplic-layer').data('floor'); else location.level = self.data.levels[0].id; } // description vars if (location.description) location.description = replaceVars(location.description, location); // geolocation if (location.lat && location.lng) { var pos = latlngToPos(location.lat, location.lng); location.x = pos.x; location.y = pos.y; } // estimated position if ((!location.x || !location.y) && elem) { var pos = estimatedPosition(location.el); location.x = pos.x; location.y = pos.y; } // marker if (!location.pin) location.pin = self.o.marker; location.marker = self.addMarker(location); // reveal mode if (location.action == 'reveal') $('.mapplic-pin[data-location^=' + location.id + ']', self.map).css('visibility', 'hidden'); if (self.sidebar) self.sidebar.countCategory(); } self.addMarker = function(location) { // hidden marker if (location.pin.indexOf('hidden') != -1) return false; var parent = $('.mapplic-layer[data-floor=' + location.level + '] .mapplic-map-image', self.el); var marker = $('').addClass('mapplic-pin').addClass(location.pin.replace('hidden', '')).attr('aria-label', location.title + ' marker').css({'top': (location.y * 100) + '%', 'left': (location.x * 100) + '%'}).appendTo(parent); marker.on('click touchend', function(e) { if (e.cancelable) e.preventDefault(); var shift = Math.abs(self.firstcoord.x - self.lastcoord.x) + Math.abs(self.firstcoord.y - self.lastcoord.y); if (!self.dragging || shift < 4) self.showLocation(location.id, 600); }); if (location.label) { if (location.label.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g)) marker.css('background-image', 'url(' + location.label + ')'); else $('' + location.label + '').appendTo(marker); } if (location.reveal) marker.attr('data-reveal', location.reveal).css('visibility', 'hidden'); if (location.category) { location.category = location.category.toString(); marker.attr('data-category', location.category); } marker.attr('data-location', location.id); if (self.o.zoom && self.o.mousewheel) marker.on('mousewheel DOMMouseScroll', self.mouseWheel); if (location.styled) marker.addClass(location.styled); if (location.color && location.pin.indexOf('pin-text') > -1) marker.css('color', location.color); else if (location.color) marker.css({'background-color': location.color, 'border-color': location.color }); location.el = marker; return marker; } // removing locations self.removeLocations = function() { $.each(self.l, function(i, location) { self.removeLocation(location.id); }); } self.removeLocation = function(location) { if (location.id) location = location.id; delete self.l[location]; $('.mapplic-pin[data-location="' + location + '"]', self.map).remove(); $('.mapplic-tooltip[data-location="' + location + '"]', self.el).remove(); $('.mapplic-list-location[data-location="' + location + '"]', self.el).remove(); $('svg #' + location, self.map).removeClass(); } self.getLocationData = function(id) { return self.l[id]; } self.showLocation = function(id, duration, check) { var location = self.location = self.l[id]; if (!location) return false; // trigger event self.el.trigger('locationopen', location); var action = (location.action && location.action != 'default') ? location.action : self.o.action; if (action == 'disabled') return false; var content = null; self.closeTooltips(); switch (action) { case 'open-link': window.location.href = location.link; return false; case 'open-link-new-tab': window.open(location.link); self.location = null; return false; case 'select': if (location.el) { if (location.el.hasClass('mapplic-active')) { location.el.removeClass('mapplic-active'); if (location.list) location.list.removeClass('mapplic-active'); } else { location.el.addClass('mapplic-active'); if (location.list) location.list.addClass('mapplic-active'); } } return false; case 'none': self.hideLocation(); self.switchLevel(location.level); if (!self.bboxZoom(location.el)) self.zoomLocation(location); break; case 'reveal': self.hideLocation(); self.switchLevel(location.level); self.container.revealChild(location); if (self.o.zoom) self.bboxZoom(location.el); break; case 'external': self.hideLocation(); self.switchLevel(location.level); if (!self.bboxZoom(location.el)) self.zoomLocation(location); if (self.external) self.external.show(location); break; case 'lightbox': self.hideLocation(); self.switchLevel(location.level); content = self.lightbox.show(location); break; case 'image': self.hideLocation(); self.switchLevel(location.level); self.lightbox.showImage(location); break; case 'route': check = true; break; default: self.hideLocation(); self.switchLevel(location.level); setTimeout(function() { content = self.addTooltip(location, check); }, 2); } self.location = self.l[id]; // active state $('.mapplic-active', self.scope).removeClass('mapplic-active'); if (location.el) location.el.addClass('mapplic-active'); if (location.list) location.list.addClass('mapplic-active'); // deeplinking if ((self.deeplinking) && (!check)) self.deeplinking.update(id); // trigger event self.el.trigger('locationopened', [location, content]); } self.zoomLocation = function(loc) { var zoom = loc.zoom ? parseFloat(loc.zoom)/self.o.maxscale : 1; if (self.o.zoom) self.moveTo(loc.x, loc.y, zoom, 600); } self.hideLocation = function() { $('.mapplic-active', self.scope).removeClass('mapplic-active'); if (self.deeplinking && self.deeplinking.resolved) self.deeplinking.clear(); if (self.external) self.external.hide(); self.closeTooltips(); self.location = null; // trigger event self.el.trigger('locationclosed'); } self.updateLocation = function(id) { // remove + add var location = self.l[id]; if ((location.id == id) && (location.el.is('a'))) { // Geolocation if (location.lat && location.lng) { var pos = latlngToPos(location.lat, location.lng); location.x = pos.x; location.y = pos.y; } var top = location.y * 100, left = location.x * 100; location.el.css({'top': top + '%', 'left': left + '%'}); } } }; // jQuery plugin $.fn.mapplic = function(options) { return this.each(function() { var element = $(this); // plugin already initiated on element if (element.data('mapplic')) return; var instance = (new Mapplic(element)).init(options); // store plugin object in element's data element.data('mapplic', instance); }); }; })(jQuery); // call plugin on map instances jQuery(document).ready(function($) { $('[id^=mapplic-id]').mapplic(); // dynamic element var observer = new MutationObserver(function(mutations) { mutations.forEach(function(mutation) { var newNodes = mutation.addedNodes; if (newNodes !== null) { $(newNodes).each(function() { var node = $(this); if (node.is('[id^=mapplic-id]')) node.mapplic(); }); } }); }); observer.observe(document, {attributes: false, childList: true, characterData: false, subtree: true}); });
        /* * Mapplic - Custom Interactive Map Plugin by @sekler * Version 7.1.2 * https://www.mapplic.com/ */ /* STYLES */ .mapplic-element { position: relative; overflow: hidden; font-size: 0; height: 420px; } .mapplic-element input, .mapplic-element button, .mapplic-element a, .mapplic-element a:active { outline: none; box-shadow: none; text-decoration: none !important; } .mapplic-element a:focus { outline: none; } .mapplic-element > * { opacity: 1; transition: opacity 0.4s; } .mapplic-element.mapplic-loading > * { opacity: 0; } .mapplic-element strong { color: #333; } /* Preloader & Error */ .mapplic-element.mapplic-loading { background: url(/images/loader.gif) no-repeat center; } .mapplic-element.mapplic-error { background: url(/images/error-icon.png) no-repeat center; } /* Scrollbars */ /* Firefox */ .mapplic-element * { scrollbar-width: thin; scrollbar-color: #ddd #fdfdfd; } /* Chrome, Edge, and Safari */ .mapplic-element *::-webkit-scrollbar { width: 12px; } .mapplic-element *::-webkit-scrollbar-track { background-color: #fdfdfd; } .mapplic-element *::-webkit-scrollbar-thumb { background-color: #ddd; border-radius: 20px; border: 3px solid #fdfdfd; box-sizing: border-box; } .mapplic-element .mapplic-tooltip * { scrollbar-color: #ddd #fff; } .mapplic-element .mapplic-tooltip *::-webkit-scrollbar-track { background-color: #fff; } .mapplic-element .mapplic-tooltip *::-webkit-scrollbar-thumb { border: 3px solid #fff; } /* Map container */ .mapplic-container { display: inline-block; position: relative; width: 70%; height: 100%; } .mapplic-map { transform-origin: 0 0; } /* Map layer */ .mapplic-layer img { width: 100%; } .mapplic-map .mapplic-map-image { position: absolute; width: 100%; height: 100%; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } /* Animation and stuff */ .mapplic-layer { height: 100%; width: 100%; position: absolute; opacity: 0; display: block; transition: transform 0.3s, opacity 0.3s; } .mapplic-layer.mapplic-visible { visibility: visible; opacity: 1; transform: translateY(0); } .mapplic-layer.mapplic-hidden { pointer-events: none; display: none; } .mapplic-layer.mapplic-layer-up { transform: /*scale(1.1)*/ translateY(-100px); } .mapplic-layer.mapplic-layer-down { transform: /*scale(0.9)*/ translateY(100px); } /* Hand cursor */ .mapplic-map.mapplic-zoomable .mapplic-map-image { cursor: url(/images/openhand.cur), default; } .mapplic-map.mapplic-zoomable.mapplic-dragging .mapplic-map-image { cursor: url(/images/closedhand.cur), move; } /* Marker types */ .mapplic-pin { background-color: #fb7575; background-image: none; background-position: center; background-repeat: no-repeat; border-radius: 6px; box-shadow: 0 -2px 0 rgba(0, 0, 0, 0.1) inset; box-sizing: border-box; cursor: pointer; font-size: 0; width: 12px; height: 12px; margin-left: -6px; margin-top: -6px; position: absolute !important; transform-origin: 50% 50%; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .mapplic-pin:before { box-sizing: content-box !important; } .mapplic-pin.hide { display: none; } .mapplic-pin.mapplic-active { display: block !important; } .mapplic-pin.pin-label { color: #fff; font-size: 10px; font-weight: 600; text-align: center; text-decoration: none; } .mapplic-pin.pin-text { background: transparent !important; border-radius: 0; color: #666; } .mapplic-pin { background-color: #dd3333; border-color: #dd3333; background-image: none; background-size: contain; border-radius: 50%; box-sizing: border-box; line-height: 21px; font-size: 12px; width: 20px; height: 20px; margin: -10px 0 0 -10px; transform-origin: 50% 50%; } .mapplic-pin.pin-square { background-color: #0071A1; border-color: #0071A1; border-radius: 0; } .mapplic-pin.pin-square.pin-bordered:before { border-radius: 0; } .mapplic-pin.pin-rounded { background-color: #6b9b26; border-color: #6b9b26; border-radius: 4px; } .mapplic-pin.pin-rounded.pin-bordered:before { border-radius: 7px; } .mapplic-pin.pin-sm { margin: -5px 0 0 -5px; font-size: 0; width: 10px; height: 10px; } .mapplic-pin.pin-sm.pin-rounded { border-radius: 3px; } .mapplic-pin.pin-lg { margin: -14px 0 0 -14px; font-size: 15px; line-height: 30px; width: 28px; height: 28px; box-sizing: border-box; } .mapplic-pin.pin-bordered { background-color: white !important; background-image: none; color: #333 !important; line-height: 18px; width: 18px; height: 18px; margin: -9px 0 0 -9px; } .mapplic-pin.pin-bordered:before { border-color: inherit; border-style: solid; border-radius: 50%; border-width: 3px; content: ''; display: block; width: 18px; height: 18px; position: absolute; left: -3px; top: -3px; } .mapplic-pin.pin-triangle { margin-top: -20px; transform-origin: 50% 140%; } .mapplic-pin.pin-triangle:before { border-style: solid; border-width: 9px 8px 0 8px; border-color: inherit; border-right-color: transparent; border-bottom-color: transparent; border-left-color: transparent; content: ''; display: block; position: absolute; top: 16px; left: 2px; } /* classic */ .mapplic-pin.pin-classic { background-color: #f23543; background-image: none; border-color: #f23543; border-radius: 10px; line-height: 22px !important; width: 20px; height: 20px; margin-top: -22px; margin-left: -10px; transform-origin: 50% 140%; } .mapplic-pin.pin-classic:before { border-style: solid; border-width: 9px 8px 0 8px; border-color: inherit; border-right-color: transparent; border-bottom-color: transparent; border-left-color: transparent; content: ''; display: block; position: absolute; top: 16px; left: 2px; } .mapplic-pin.pin-marker { background-color: #fcac2b; border-color: #fcac2b; background-image: none; border-radius: 50%; width: 18px; height: 18px; line-height: 20px; margin-top: -9px; margin-left: -9px; transform-origin: 50% 50%; } .mapplic-pin.pin-marker:before { border-color: inherit; border-style: solid; border-width: 6px; border-radius: 50%; content: ''; display: block; opacity: 0.2; width: 18px; height: 18px; position: absolute; left: -6px; top: -6px; } .mapplic-pin.pin-disk { background-color: white !important; background-image: none; border-color: #f19819; border-radius: 8px; color: #333 !important; width: 16px; height: 16px; margin-top: -8px; margin-left: -8px; transform-origin: 50% 50%; } .mapplic-pin.pin-disk:before { border-color: inherit; border-style: solid; border-width: 3px; border-radius: 16px; content: ''; display: block; width: 16px; height: 16px; position: absolute; left: -3px; top: -3px; } .mapplic-pin.pin-ribbon { background-color: #46b450; background-image: none; border-color: #46b450; border-radius: 2px 2px 2px 0; height: 16px; line-height: 16px; min-width: 10px; width: auto; padding: 0 3px; margin-left: -8px; margin-top: -20px; transform-origin: 8px 20px; } .mapplic-pin.pin-ribbon:after { border-style: solid; border-width: 0 8px 4px 0; border-color: transparent rgba(0, 0, 0, 0.5) transparent transparent; content: ''; display: block; position: absolute; top: 16px; left: 0px; } .mapplic-pin.pin-ribbon:before { border-style: solid; border-width: 0 8px 4px 0; border-color: inherit; border-top-color: transparent; border-bottom-color: transparent; border-left-color: transparent; content: ''; display: block; position: absolute; top: 16px; left: 0px; } .mapplic-pin.pin-dot { background-color: transparent !important; background-image: none; border-color: #29afa1; border-radius: 0; color: #333 !important; height: 16px; line-height: 16px; font-size: 11px; min-width: 10px; width: auto; padding: 0 3px; margin-left: 4px; margin-top: -8px; transform-origin: -4px 8px; } .mapplic-pin.pin-dot:before { border-color: inherit; border-style: solid; border-width: 3px; border-radius: 12px; content: ''; display: block; width: 0px; height: 0px; position: absolute; top: 5px; left: -7px; } .mapplic-pin.pin-image { background-size: 32px; border: 2px solid #fff; border-radius: 50%; box-sizing: border-box; box-shadow: 0 0 10px rgba(0, 0, 0, 0.15); font-size: 0 !important; width: 32px; height: 32px; margin-top: -16px; margin-left: -16px; transform-origin: 50%; } .mapplic-pin.pin-icon { background-size: 16px; background-color: transparent; border: none; border-radius: 0; font-size: 0 !important; width: 16px; height: 16px; margin-top: -8px; margin-left: -8px; transform-origin: 50%; } .mapplic-pin.pin-circle { background: none !important; border: 2px solid #fb7575; width: 8px; height: 8px; margin-left: -6px; margin-top: -6px; transform-origin: 50% 50%; } .mapplic-pin.pin-transparent { background-image: none; background-color: #795ecd; border-radius: 10px; width: 20px; height: 20px; margin-left: -10px; margin-top: -10px; opacity: 0.5 !important; transform-origin: 50% 50%; } .mapplic-pin.pin-md { border-radius: 50%; margin-left: -10px; margin-top: -10px; line-height: 20px; width: 20px; height: 20px; } .mapplic-pin.pin-pulse { background-color: #007CBA; } .mapplic-pin.pin-pulse:before { content: ''; border: 2px solid #888; border-radius: 30px; height: inherit; width: inherit; top: -2px; left: -2px; position: absolute; animation: pulsate 1.8s ease-out; animation-iteration-count: infinite; animation-delay: 1s; opacity: 0; box-sizing: content-box; } @-webkit-keyframes pulsate { 0% {-webkit-transform: scale(1, 1); opacity: 0.0;} 25% {opacity: 0.5; } 50% {-webkit-transform: scale(1.6, 1.6); opacity: 0.0;} } /* Minimap */ .mapplic-minimap { border: 1px solid rgba(0, 0, 0, 0.1); position: absolute; margin: 12px; bottom: 0; left: 0; opacity: 0.5; overflow: hidden; transition: opacity 0.4s; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none; user-select: none; } .mapplic-minimap-layer { line-height: 0; } .mapplic-minimap img { width: 100%; } .mapplic-minimap-overlay { background-color: rgba(0, 0, 0, 0.4); position: absolute; width: 100%; height: 100%; top: 0; left: 0; } .mapplic-minimap .mapplic-minimap-active { position: absolute; opacity: 1; top: 0; left: 0; } .mapplic-minimap-background { width: 140px !important; -webkit-filter: blur(2px); } /* UI Buttons */ .mapplic-button { background-color: #fff; background-repeat: no-repeat; background-position: center; border: none !important; border-radius: 0; cursor: pointer; width: 28px; height: 28px; padding: 0; position: relative; transition: background-color 0.2s; } .mapplic-element .mapplic-button:focus, .mapplic-button:hover, .mapplic-button:focus { background-color: #fff; } .mapplic-container > .mapplic-button { box-shadow: 0 0 12px rgba(0, 0, 0, 0.06); position: absolute; margin: 12px; } .mapplic-icon { box-sizing: content-box; fill: #222; width: 16px; height: 16px; margin: 6px; position: absolute; top: 0; left: 0; } /* Clear Button */ .mapplic-clear-button { background-size: 16px 16px; display: none; font-size: 0; bottom: 69px; right: 0; } /* Zoom Buttons */ .mapplic-zoom-buttons { box-shadow: 0 0 12px rgba(0, 0, 0, 0.06); margin: 12px; position: absolute; right: 0; bottom: 0; } .mapplic-zoom-buttons button { display: block; } .mapplic-zoom-buttons button:disabled { background-color: #eee; cursor: default; } button.mapplic-zoomin-button { background-size: 10px 10px; border-bottom: 1px solid #eee; } button.mapplic-zoomout-button { background-size: 10px 10px; } /* Fullscreen */ .mapplic-fullscreen { background-color: #fafafa; position: fixed !important; top: 0; left: 0; width: 100%; height: 100% !important; margin: 0 !important; max-width: 100% !important; max-height: 100% !important; z-index: 99980; } .mapplic-fullscreen-button { background-size: 14px 14px; top: 0; left: 0; } .mapplic-fullscreen-button .mapplic-icon-fullscreen-exit, .mapplic-fullscreen .mapplic-fullscreen-button .mapplic-icon-fullscreen { display: none; } .mapplic-fullscreen .mapplic-fullscreen-button .mapplic-icon-fullscreen-exit { display: block; } .mapplic-fullscreen .mapplic-container { width: 80%; } .mapplic-fullscreen .mapplic-sidebar { width: 20%; } /* Levels (old) */ .mapplic-levels { box-shadow: 0 0 10px rgba(0, 0, 0, 0.04); position: absolute; top: 0; right: 0; margin: 12px; } .mapplic-levels > * { display: block; box-sizing: border-box; } .mapplic-levels-select { background-color: #fff; border: none; border-radius: 0; color: #2f3435; margin: 0; padding: 8px; margin-right: 20px; font-size: 14px; line-height: 20px; font-weight: 600; outline: none; -webkit-appearance: none; } .mapplic-levels button { background-color: #fff; background-repeat: no-repeat; background-position: center; background-size: 8px 4px; border: none; border-radius: 0; cursor: pointer; padding: 0; height: 50%; width: 20px; position: absolute; right: 0; } .mapplic-levels .mapplic-levels-down { bottom: 0; } .mapplic-levels .mapplic-icon { width: 8px; height: 4px; margin: 0; margin-left: -4px; margin-top: -2px; left: 50%; top: 50%; } .mapplic-levels button:disabled { background-color: #eee; cursor: default; } .mapplic-levels { display: none; } /* new switcher */ .mapplic-level-switcher { position: absolute; right: 0; top: 0px; margin: 12px; } .mapplic-level-switcher button { background-color: #f8f8f8; border-radius: 0; color: #888; cursor: pointer; display: block; font-size: 11px; font-weight: 600; line-height: 20px; padding: 4px 10px; text-align: center; user-select: none; width: 100%; border: none; transition: transform 0.2s; position: relative; } .mapplic-level-switcher button:hover { background-color: #f8f8f8; } .mapplic-level-switcher button:focus { outline: none; } .mapplic-level-switcher button.mapplic-selected { box-shadow: 0 0 12px rgba(0, 0, 0, 0.06); background-color: #fff; color: #222; transform: scale(1.15); z-index: 100; } /* SIDEBAR */ .mapplic-sidebar { width: 30%; height: 100%; padding: 12px; position: relative; box-sizing: border-box; } .mapplic-sidebar-right .mapplic-sidebar { float: right; } .mapplic-sidebar-right .mapplic-container { float: none; } .mapplic-sidebar > * { pointer-events: auto; } .mapplic-container { float: right; } /* toggle */ .mapplic-sidebar-toggle { border-radius: 50%; top: 50%; left: 0; margin: 0 !important; transition: opacity 0.2s; } .mapplic-dynamic-sidebar:not(.mapplic-portrait) .mapplic-container { transition: width 0.4s; } .mapplic-portrait .mapplic-sidebar-toggle { display: none; } .mapplic-sidebar-right .mapplic-sidebar-toggle { left: auto; right: 0; transform: rotate(180deg); } .mapplic-sidebar-toggle, .mapplic-sidebar-toggle:hover, .mapplic-element .mapplic-sidebar-toggle:focus, .mapplic-element .mapplic-sidebar-toggle:active { background-color: rgba(0, 0, 0, 0.2); } .mapplic-hidden-sidebar .mapplic-sidebar-toggle { margin: 0 12px !important; } .mapplic-sidebar-toggle .mapplic-icon-sidebar { fill: #fff; transition: transform 0.4s; } .mapplic-hidden-sidebar .mapplic-sidebar-toggle .mapplic-icon-sidebar { transform: rotate(180deg); } .mapplic-sidebar { transition: margin 0.4s, opacity 0.4s; } .mapplic-hidden-sidebar .mapplic-container { width: 100%; } .mapplic-element.mapplic-hidden-sidebar:not(.mapplic-portrait) .mapplic-sidebar { margin-left: -30%; opacity: 0; } .mapplic-sidebar-right.mapplic-hidden-sidebar:not(.mapplic-portrait) .mapplic-sidebar { margin-left: 0; margin-right: -30%; } /* tags row */ .mapplic-sidebar.mapplic-sidebar-tagsrow .mapplic-filter-tags { display: block; } .mapplic-sidebar.mapplic-sidebar-tagsrow .mapplic-sidebar-header { max-height: 110px; } .mapplic-sidebar.mapplic-sidebar-tagsrow .mapplic-list-container { top: 122px; } /* dim */ .mapplic-sidebar-dim { background-color: #000; opacity: 0; position: absolute; top: 12px; right: 12px; left: 12px; bottom: 12px; transition: opacity 0.2s; z-index: 1; pointer-events: none; } .mapplic-sidebar-header-opened.mapplic-sidebar-filterable .mapplic-sidebar-dim { opacity: 0.1; pointer-events: auto; } /* search */ .mapplic-sidebar-header { background-color: #fff; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.04); box-sizing: border-box; display: flex; flex-direction: column; overflow: hidden; padding: 16px 20px; position: absolute; right: 12px; left: 12px; z-index: 2; max-height: 80px; transition: max-height 0.2s; } .mapplic-sidebar.mapplic-sidebar-header-opened.mapplic-sidebar-filterable .mapplic-sidebar-header { max-height: 80%; } .mapplic-sidebar-header > .mapplic-icon { margin-left: 20px; margin-top: 32px; } .mapplic-search-input { background: none !important; border: none !important; box-shadow: none !important; box-sizing: border-box; border-radius: 0; font-size: 22px !important; font-family: inherit; line-height: 22px; width: 100%; height: 48px !important; margin: 0 !important; padding: 0 50px 0 30px !important; } .mapplic-search-input::placeholder { opacity: 0.5; font-weight: 400; } input.mapplic-search-input:focus { outline: none !important; } .mapplic-search-input::-ms-clear { display: none; width:0; height:0; } .mapplic-search-clear { background: none; box-shadow: none; border: none; cursor: pointer; display: none; position: absolute; margin: 0; padding: 0; top: 28px; left: 16px; width: 24px; height: 24px; } .mapplic-search-active .mapplic-search-clear { display: block; } .mapplic-search-active .mapplic-icon.mapplic-icon-magnifier { display: none; } .mapplic-search-clear:hover, .mapplic-search-clear:active, .mapplic-search-clear:focus { background: none; outline: none; } .mapplic-search-clear .mapplic-icon.mapplic-icon-cross { width: 12px; height: 12px; padding: 0; transition: transform 0.4s; } /* .mapplic-search-clear:hover .mapplic-icon-cross { transform: rotate(180deg); } */ .mapplic-search-toggle { background: transparent; border-radius: 50% !important; box-shadow: none; border: none; cursor: pointer; display: none; position: absolute; margin: 0; padding: 4px; top: 24px; right: 20px; width: 34px; height: 34px; transition: background-color 0.2s; } .mapplic-search-toggle:hover, .mapplic-search-toggle:focus { background-color: transparent; } .mapplic-sidebar-filterable .mapplic-search-toggle { display: block; } .mapplic-search-toggle .mapplic-icon { margin: 9px; } .mapplic-sidebar-header-opened.mapplic-sidebar-filterable .mapplic-search-toggle { background-color: #f4f4f4; } .mapplic-icon.mapplic-icon-cross { width: 8px; height: 8px; padding: 8px; } /* Search Disabled */ .mapplic-sidebar-nosearch .mapplic-list-container { top: 12px; } /* Tags */ .mapplic-filter-tags { white-space: nowrap; max-width: 100%; overflow: hidden; display: none; margin: 10px 0; } .mapplic-tag { background-color: #aaa; border-radius: 12px; border: none; color: rgba(255, 255, 255, 0.8); text-transform: uppercase; cursor: pointer; font-size: 9px; line-height: 20px; font-weight: 600; margin-right: 6px; padding: 0 8px; display: inline-block; } .mapplic-tag > span { background-image: url(/images/cross.svg); background-position: center; background-repeat: no-repeat; background-size: 6px 6px; display: inline-block; margin-left: 6px; width: 8px; height: 6px; opacity: 0.4; } /* Sidebar list */ .mapplic-list-container { background-color: #fdfdfd; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.04); box-sizing: border-box; overflow-y: auto; position: absolute; bottom: 12px; top: 92px; right: 12px; left: 12px; padding: 0; margin: 0; transition: top 0.2s; -webkit-overflow-scrolling: touch; } .mapplic-list-container li { margin: 0 !important; } .mapplic-list-container h4 { font-size: 16px !important; font-weight: 400 !important; } .mapplic-list-container .mapplic-dir-item a { padding: 12px 20px 12px 18px; } /* Filters */ .mapplic-filter { margin: 10px -20px -6px -20px; overflow-y: auto; opacity: 0; transition: opacity 0.2s; } .mapplic-sidebar-header-opened.mapplic-sidebar-filterable .mapplic-filter { opacity: 1; } .mapplic-filter > ul { padding: 0 !important; margin: 0 !important; } .mapplic-filter h5 { color: #aaa; font-size: 10px; margin: 5px 20px; font-weight: 400; } .mapplic-list-category { margin: 0 !important; } .mapplic-list-category > a { border-radius: 4px; box-sizing: border-box; color: #2f3434 !important; display: block; margin: 6px 10px; margin-bottom: 0; padding: 10px; text-decoration: none; overflow: hidden; text-overflow: ellipsis; transition: background-color 0.2s; } .mapplic-list-category > a:hover, .mapplic-list-category > a:focus { background-color: #f8f8f8; } .mapplic-list-category h4 { display: inline-block; font-size: 14px; font-weight: bold; line-height: 22px; margin: 0; } .mapplic-list-category h4.mapplic-margin { margin-top: 9px; } .mapplic-about { color: #aaa; display: block; font-weight: normal; font-size: 13px; line-height: 16px; } /* Thumbnail */ .mapplic-list-category .mapplic-thumbnail { background-color: #aaa; border: 2px solid transparent; border-radius: 50%; box-sizing: border-box; width: 40px; height: 40px; } .mapplic-list-category .mapplic-thumbnail-placeholder { color: rgba(255, 255, 255, 0.7); font-size: 18px; font-weight: bold; line-height: 22px; } .mapplic-thumbnail { border-radius: 0px; box-shadow: none !important; margin-right: 10px; float: left; width: 50px; height: 50px; object-fit: cover; } .mapplic-thumbnail-placeholder { background-color: #eee; box-sizing: border-box; color: #fff; font-size: 20px; font-weight: 600; line-height: 34px; padding: 8px 4px; width: 50px; height: 50px; text-align: center; } .mapplic-list-category > a .mapplic-list-count { color: #aaa; font-size: 12px; font-weight: normal; margin-left: 4px; opacity: 0.5; } .mapplic-dir-item[data-location=init] { display: none !important; } .mapplic-dir-item > a { border-left: 2px solid transparent; padding: 10px 20px 10px 18px; text-decoration: none; transition: border, background-color 0.1s; } .mapplic-sidebar .mapplic-dir-item:hover > a, .mapplic-sidebar .mapplic-dir-item > a:focus, .mapplic-sidebar .mapplic-dir-item.mapplic-active > a { background-color: #f4f4f4; padding: 12px 20px; } /* Directory */ .mapplic-dir > h3 { border-bottom: 2px solid #fafafa; font-size: 32px; line-height: 60px; font-weight: 300; margin: 20px 0; padding-bottom: 0; } .mapplic-dir > h3 > span { border-bottom: 2px solid #888; display: inline-block; font-weight: 600; margin-bottom: -2px; } .mapplic-dir ul { padding-left: 0; list-style: none; } .mapplic-dir.mapplic-dir-results { margin-top: 40px; display: none; } .mapplic-dir-results-clear { background-color: #fafafa; border: none; border-radius: 4px; color: #333; cursor: pointer; font-weight: bold; font-size: 12px; margin-left: 20px; padding: 10px 12px; outline: none; vertical-align: middle; transition: background-color 0.2s; } .mapplic-dir-results-clear .mapplic-icon-cross { padding: 0; margin: 0 0 0 6px; position: static; transition: transform 0.4s; } .mapplic-dir-results-clear:hover .mapplic-icon-cross { transform: rotate(180deg); } .mapplic-dir-results-clear:hover, .mapplic-dir-results-clear:active { background-color: #eee; } .mapplic-dir.mapplic-dir-horizontal ul { max-width: 100%; white-space: nowrap; overflow-x: auto; margin-bottom: 40px; } .mapplic-dir.mapplic-dir-horizontal .mapplic-dir-item { white-space: normal; display: inline-block; } .mapplic-dir-item { border-color: #888; position: relative; overflow: hidden; } .mapplic-dir-item a { display: block; padding: 12px 0; transition: background-color 0.2s, padding 0.2s; box-sizing: border-box; text-decoration: none !important; line-height: 0 !important; } .mapplic-dir-item a:focus { outline: none; } .mapplic-dir-item a::after { content: ""; clear: both; display: table; overflow: auto; } .mapplic-dir-item:hover a, .mapplic-dir-item a:focus, .mapplic-dir-item.mapplic-active > a { background-color: #fafafa; padding: 12px; } .mapplic-dir-item.mapplic-active > a { border-color: inherit; } .mapplic-dir-item h4 { color: #222; font-size: 14px; margin: 4px 0 !important; font-weight: 600; line-height: 20px !important; display: inline-block; } .mapplic-dir-grid ul { margin: 0 -20px; } .mapplic-dir-grid .mapplic-dir-item { margin-bottom: 20px; text-align: center; } .mapplic-dir-grid.mapplic-dir-columns .mapplic-dir-item { display: inline-block; width: 25%; vertical-align: top; } .mapplic-dir-grid .mapplic-dir-item h4 { font-size: 16px; margin-bottom: 10px; } .mapplic-dir-grid .mapplic-dir-item a { padding: 20px; } .mapplic-dir-grid .mapplic-thumbnail { margin-bottom: 12px; float: none; width: 100%; min-height: 180px; } .mapplic-dir-grid .mapplic-thumbnail-placeholder { line-height: 160px; font-weight: bold; font-size: 42px; } @media screen and (max-width: 992px) { .mapplic-dir-grid.mapplic-dir-columns .mapplic-dir-item { width: 33%; } } @media screen and (max-width: 600px) { .mapplic-dir-grid.mapplic-dir-columns .mapplic-dir-item { width: 50%; } } /* dir view */ .mapplic-dir-view { position: relative; } .mapplic-dir-view button { position: absolute; right: 30px; top: 0; } /* dir search */ .mapplic-dir-search { border: none; box-sizing: border-box; width: 100%; font-size: 36px; outline: none; padding: 12px 0; transition: padding 0.2s; } .mapplic-dir-search::placeholder { color: #ccc; font-weight: normal !important; } .mapplic-dir-search:focus { background-color: #fafafa; padding: 12px 20px; } .mapplic-dir-filter { border: none; box-sizing: border-box; width: 100%; font-size: 16px; font-weight: bold; outline: none; padding: 22px 0; transition: padding 0.2s; -moz-appearance: none; -webkit-appearance: none; } .mapplic-dir-filter:focus { background-color: #fafafa; padding: 22px 20px; } /* Tooltip */ .mapplic-tooltip { display: none; position: absolute; transform-origin: 0 0; padding-bottom: 30px; pointer-events: none; } .mapplic-tooltip:after { content: ''; border-color: #fff transparent transparent transparent !important; border-style: solid; border-width: 8px 7px 0 7px; width: 0; height: 0; position: absolute; top: 0; left: 0; margin-left: -7px; margin-top: -33px; /* SHIFT */ } .mapplic-tooltip-wrap { background-color: #fff; box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); max-width: 300px; min-width: 120px; pointer-events: auto; transform: translate(-50%, -100%); margin-top: -32px; /* SHIFT */ transition: transform 0.1s; } .mapplic-tooltip-bottom .mapplic-tooltip-wrap { transform: translate(-50%, 0); margin-top: 17px; /* SHIFT */ } .mapplic-tooltip-bottom.mapplic-tooltip:after { border-color: transparent transparent #fff transparent !important; border-width: 0 7px 8px 7px; margin-top: 10px; } .mapplic-tooltip-body { padding: 16px; } .mapplic-tooltip-body:focus { outline: none; } .mapplic-tooltip-body::after { content: ''; clear: both; display: table; } .mapplic-tooltip img { max-width: 100%; } .mapplic-tooltip-title { color: #333; display: inline-block; font-size: 16px; font-weight: bold; line-height: 20px; margin: 0 12px 0 0 !important; } .mapplic-hovertip, .mapplic-hovertip > .mapplic-tooltip-wrap { pointer-events: none; } .mapplic-hovertip > .mapplic-tooltip-wrap { min-width: 20px; padding: 6px 14px; } .mapplic-hovertip .mapplic-tooltip-title { margin: 0 !important; font-size: 16px; line-height: 24px; text-align: center; } .mapplic-tooltip-content { margin-top: 10px; margin-bottom: 6px; max-height: 160px; overflow-y: auto; -webkit-overflow-scrolling: touch; } .mapplic-tooltip .mapplic-thumbnail { border-radius: 50% !important; width: 48px; height: 48px; margin-right: 12px; } .mapplic-tooltip-description, .mapplic-tooltip p { font-size: 13px; line-height: 22px; margin: 0; } .mapplic-tooltip p { margin-top: 0; margin-bottom: 6px !important; } .mapplic-tooltip-description p:last-child { margin: 0; } .mapplic-popup-link { background-color: #888; border-radius: 4px; box-shadow: 0 0 6px rgba(0, 0, 0, 0.1) !important; color: #fff !important; font-size: 14px; line-height: 20px; font-weight: 600; display: inline-block; float: right; margin-top: 4px; padding: 4px 8px; text-decoration: none; transition: background-color 0.2s, box-shadow 0.2s; } .mapplic-popup-link:hover { background-color: #666; box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2) !important; } .mapplic-tooltip-close { background-position: center; background-repeat: no-repeat; background-size: 8px 8px; border: none; cursor: pointer; position: absolute; right: 36px; top: 0; padding: 0; margin: 0; opacity: 0.5; z-index: 100; transition: opacity 0.2s; } .mapplic-tooltip-close:hover { opacity: 1.0; } .mapplic-tooltip-close .mapplic-icon { background-color: #fff; border-radius: 50%; } /* Lightbox */ .mapplic-lightbox-title { color: #333; font-weight: bold; margin-top: 0; margin-bottom: 20px; } .mapplic-lightbox { background-color: #fff; position: relative; padding: 20px; width: auto; max-width: 500px; margin: 20px auto; } .mapplic-lightbox:after { content: ''; display: block; clear: both; } .mapplic-lightbox-description, .mapplic-lightbox p { font-size: 18px; line-height: 28px; } .mapplic-popup-image { outline: none; } .mfp-bg { z-index: 99981 !important; } .mfp-wrap { z-index: 99982 !important; } .mfp-content { z-index: 99983 !important; } /* Lightbox animation */ .mfp-fade.mfp-bg { opacity: 0; -webkit-transition: all 0.15s ease-out; -moz-transition: all 0.15s ease-out; transition: all 0.15s ease-out; } .mfp-fade.mfp-bg.mfp-ready { opacity: 0.8; } .mfp-fade.mfp-bg.mfp-removing { opacity: 0; } .mfp-fade.mfp-wrap .mfp-content { opacity: 0; -webkit-transition: all 0.15s ease-out; -moz-transition: all 0.15s ease-out; transition: all 0.15s ease-out; } .mfp-fade.mfp-wrap.mfp-ready .mfp-content { opacity: 1; } .mfp-fade.mfp-wrap.mfp-removing .mfp-content { opacity: 0; } /* Toggle */ .mapplic-toggle { display: block; cursor: pointer; font-size: 14px; position: relative; margin: 6px 0; min-width: 20px; min-height: 20px; } .mapplic-toggle > .mapplic-toggle-circle { background-color: #aaa; border-radius: 50%; position: absolute; left: 1px; top: 1px; width: 18px; height: 18px; transform-origin: center; transform: scale(0); transition: 0.2s; } .mapplic-toggle:before { background-color: #fff; border: 1px solid #e4e4e4; border-radius: 50%; box-sizing: content-box; content: ''; display: block; position: absolute; left: 0; top: 0; width: 18px; height: 18px; } .mapplic-toggle > input { display: none; } .mapplic-toggle > input:checked + span { transform: scale(0.7); } .mapplic-list-category { position: relative; } .mapplic-list-category .mapplic-toggle { position: absolute; right: 20px; top: 50%; margin-top: -10px; box-sizing: border-box; } /* Legend */ .mapplic-legend { background-color: rgba(255,255,255, 0.9); margin: 12px; padding: 0 8px; position: absolute; left: 0; bottom: 0; } .mapplic-legend-label { display: block; font-size: 14px; font-weight: normal; margin: 6px 0; padding-left: 28px; white-space: nowrap; -webkit-user-select: none; -moz-user-select: none; -khtml-user-select: none; -ms-user-select: none; } .mapplic-legend-key { background-color: #aaa; border: 2px solid #fff; border-radius: 50%; box-sizing: content-box; display: inline-block; height: 16px; width: 16px; position: absolute; left: 8px; } /* Reveal */ .mapplic-revealed { visibility: visible !important; } /* Portrait mode */ .mapplic-portrait.mapplic-element { height: auto !important; } .mapplic-portrait .mapplic-container, .mapplic-portrait .mapplic-sidebar { float: none; width: 100% !important; } .mapplic-portrait .mapplic-sidebar { min-height: 600px; max-height: 1000px; position: relative; } .mapplic-portrait .mapplic-tooltip { max-width: 240px; } .mapplic-portrait .mapplic-minimap-background { width: 100px !important; } /* Map */ .mapplic-map svg { width: 100%; height: 100%; } .mapplic-element svg a { cursor: pointer; } .mapplic-clickable:not(g), g.mapplic-clickable > * { cursor: pointer; -webkit-transition: opacity 0.2s; -moz-transition: opacity 0.2s; transition: opacity 0.2s; } .mapplic-map-image *[id^=MNOINT], .mapplic-map-image *[id^=nopointer] { pointer-events: none; } [id^=MLOC] .mapplic-clickable, [id^=landmark] .mapplic-clickable { cursor: pointer; } /* Developer tools */ .mapplic-coordinates { background-color: rgba(255, 255, 255, 0.9); color: #333; position: absolute; margin: 10px; margin-left: -80px; padding: 4px 6px; font-size: 14px; top: 0; left: 50%; pointer-events: none; } /* IE workaround */ @media all and (-ms-high-contrast:none) { .mapplic-zoomout-button { background: #fff url(/images/ie/minus.svg) no-repeat center !important; } .mapplic-zoomin-button { background: #fff url(/images/ie/plus.svg) no-repeat center !important; } .mapplic-clear-button { background: #fff url(/images/ie/reset.svg) no-repeat center !important; } .mapplic-fullscreen-button { background: #fff url(/images/ie/fullscreen.svg) no-repeat center !important; } .mapplic-fullscreen .mapplic-fullscreen-button { background: #fff url(/images/ie/fullscreen-exit.svg) no-repeat center !important; } .mapplic-levels .mapplic-levels-up { background: #fff url(/images/ie/arrow-up.svg) no-repeat center !important; } .mapplic-levels .mapplic-levels-down { background: #fff url(/images/ie/arrow-down.svg) no-repeat center !important; } .mapplic-search-clear { background: #fff url(/images/ie/cross.svg) no-repeat center !important; } } /* Accessibility */ .mapplic-accessible.mapplic-element input:focus, .mapplic-accessible.mapplic-element button:focus, .mapplic-accessible.mapplic-element a:focus, .mapplic-accessible.mapplic-element select:focus, .mapplic-accessible.mapplic-element *[aria-modal="true"] { z-index: 1000; outline: solid rgba(0, 115, 170, 0.15); outline-offset: 2px; } .mapplic-accessible.mapplic-element input.mapplic-search-input:focus { outline: solid rgba(0, 115, 170, 0.15); outline-offset: 6px; } .mapplic-accessible.mapplic-element input:focus { outline-offset: 6px; } .mapplic-accessible.mapplic-element select:focus { position: relative; } /* SKINS */ /* mapplic-booking */ .mapplic-booking .mapplic-active, .mapplic-booking .mapplic-active > * { fill: #A8D865; } .mapplic-booking .unavailable, .mapplic-booking .unavailable > * { fill: #F7B332; opacity: 1; cursor: default; } /* INTERACTIVE ELEMENTS */ /* clickable elements */ .mapplic-clickable:not(g), g.mapplic-clickable > * { transition: fill 0.2s; } /* hovered elements */ .mapplic-highlight:not(g), g.mapplic-highlight > *, .mapplic-clickable:not(g):hover, g.mapplic-clickable:hover > * { } /* active elements */ .mapplic-active:not(g), g.mapplic-active > * { } /* Default Style */ .defaultstyle.mapplic-clickable:not(g), g.defaultstyle.mapplic-clickable > * { fill: #70899C; } .defaultstyle.mapplic-highlight:not(g), g.defaultstyle.mapplic-highlight > *, .defaultstyle.mapplic-clickable:not(g):hover, g.defaultstyle.mapplic-clickable:hover > * { fill: #596D7E; } .defaultstyle.mapplic-active:not(g), g.defaultstyle.mapplic-active > * { fill: #4D5E6D !important; } /* Init shape */ [id^=MLOC] > #init, [id^=landmark] > #init, svg > #items > #init { visibility: hidden; } /* Highlight */ .mapplic-filtered .mapplic-pin { opacity: 0.4 !important; } .mapplic-filtered .mapplic-pin.mapplic-highlight { display: block !important; opacity: 1 !important; } .mapplic-filtered svg [id^=MLOC] > *, .mapplic-filtered svg [id^=landmark] > * { opacity: 0.4 !important; } .mapplic-filtered .mapplic-clickable.mapplic-highlight { opacity: 1 !important; } /* CUSTOM STYLES */ .mapplic-image, .mapplic-tooltip-wrap { max-width: 300px !important; } /* tooltip width */ .mapplic-tooltip-content { max-height: 160px; } /* tooltip height */ .mapplic-image { height: 160px !important; object-fit: cover; } /* example custom pin */ .mapplic-pin.my-new-pin { /* replace 'my-new-pin' with the name of your pin */ background-image: url(/images/my-new-pin.png); /* define the path to image file */ background-size: 20px 30px; width: 20px; height: 30px; margin-left: -10px; /* negative margins are used for */ margin-top: -15px; /* defining the pin's origin */ }

        Introduction
        Kane Studio (“Company” or “We”) respects your privacy and is committed to protecting it through our compliance with this policy.

        This policy describes the types of information we may collect from you or that you may provide when you visit the website www.kanestudio.com (our “Website“) and our practices for collecting, using, maintaining, protecting, and disclosing that information.

        This policy applies to information we collect:

        • On this Website.
        • In email, text, and other electronic messages between you and this Website.
        • When you interact with our advertising and applications on third-party websites and services, if those applications or advertising include links to this policy.

        It does not apply to information collected by:

        • us offline or through any other means, including on any other website operated by Company or any third; or
        • any third party including through any application or content (including advertising) that may link to or be accessible from or on the Website.

        Please read this policy carefully to understand our policies and practices regarding your information and how we will treat it. If you do not agree with our policies and practices, your choice is not to use our Website. By accessing or using this Website, you agree to this privacy policy. This policy may change from time to time (see Changes to Our Privacy Policy). Your continued use of this Website after we make changes is deemed to be acceptance of those changes, so please check the policy periodically for updates.

        Children Under the Age of 13
        Our Website is not intended for children under 13 years of age. No one under age 13 may provide any information to or on the Website. We do not knowingly collect personal information from children under 13. If you are under 13, do not use or provide any information on this Website or on or through any of its features/register on the Website, make any purchases through the Website, use any of the interactive or public comment features of this Website or provide any information about yourself to us, including your name, address, telephone number, email address, or any screen name or user name you may use. If we learn we have collected or received personal information from a child under 13 without verification of parental consent, we will delete that information. If you believe we might have any information from or about a child under 13, please contact us at This email address is being protected from spambots. You need JavaScript enabled to view it..

        Information We Collect About You and How We Collect It
        We may collect several types of information from and about users of our Website, including information:

        • by which you may be personally identified, such as name, postal address, e-mail address, telephone number /any other identifier by which you may be contacted online or offline (“personal information“);
        • that is about you but individually does not identify you; and/or
        • about your internet connection, the equipment you use to access our Website and usage details.

        We collect this information:

        • Directly from you when you provide it to us.
        • Automatically as you navigate through the site. Information collected automatically may include usage details, IP addresses, and information collected through cookies, web beacons, and other tracking technologies.
        • From third parties, for example, our business partners.

        Information You Provide to Us.
        The information we collect on or through our Website may include:

        • Information that you provide by filling in forms on our Website. This includes information provided at the time of registering to use our Website. We may also ask you for information when you report a problem with our Website.
        • Records and copies of your correspondence (including email addresses), if you contact us.

        Information We Collect Through Automatic Data Collection Technologies.
        As you navigate through and interact with our Website, we may use automatic data collection technologies to collect certain information about your equipment, browsing actions, and patterns, including:

        • Details of your visits to our Website, including traffic data, location data, logs, and other communication data and the resources that you access and use on the Website.
        • Information about your computer and internet connection, including your IP address, operating system, and browser type.

        Cookies and Beacons
        We may use cookies, beacons and similar technologies, now or in the future, to support the functionality of our Platform. This provides a better experience when you visit our Platform and allows us to improve our Services and Platform.

        • Browser Cookies. A browser cookie is a small file placed on the hard drive of your computer. That cookie then communicates with servers, ours or those of other companies that we authorize to collect data for us, and allows recognition of your personal computer.  We do not otherwise collect Personally Identifiable Information from browser cookies and we do not associate browser cookies with your Personally Identifiable Information.

        You may use the tools available on your computer or other device to set your browser to refuse or disable all or some browser cookies, or to alert you when cookies are being set.  However, if you refuse or disable all browser cookies, you may be unable to access certain parts or use certain features or functionality of our Platform.

        Unless you have adjusted your browser settings so that it refuses all cookies, we may use cookies when you direct your browser to our Platform.

        • Flash Cookies. Certain features of our Platform may use local stored objects called flash cookies to collect and store information about your preferences and navigation to, from and on our Platform.  We also include cookies in our third party hosted video players to count the number of unique viewers who see a video and to provide aggregate reporting.  The cookies do not identify you as an individual or track your online behavior. We do not collect Personally Identifiable Information from flash cookies and we will not associate them with your Personally Identifiable Information.
        • Beacons. Our Platform and e-mails may contain small electronic files known as beacons (also referred to as web beacons, clear GIFs, pixel tags and single-pixel GIFs) that permit us to, for example, count Users who have visited those pages or opened an e-mail and for other website-related statistics. beacons in e-mail marketing campaigns allow us to track your responses and your interests in our content, offerings and web pages. You may use the tools in your device to disable these technologies as well.

        Your Choices
        You may have the opportunity to receive certain communications from us related to our Platform. If you provide us with your e-mail address in order to receive communications, you can opt out of marketing e-mails at any time by following the instructions at the bottom of our e-mails and adjusting your e-mail preferences. Please note that certain e-mails may be necessary for the operation of our Platform. You will continue to receive these e-mails, if appropriate, even if you unsubscribe from our optional communications.

        Certain websites you visit may provide options regarding advertisements you receive.  For more information or to opt out of certain online behavioral advertising, please visit http://www.aboutads.info.

        Some browsers support a “Do Not Track” feature, which is intended to be a signal to websites that you do not wish to be tracked across different websites you visit. Our Platform does not currently change the way they operate based upon detection of a Do Not Track or similar signal.

        Please note that we cannot control how third party websites or online services you visit through our Platform respond to Do Not Track signals. Check the privacy policies of those third parties for information on their privacy practices.

        How We Use Your Information
        We use information that we collect about you or that you provide to us, including any personal information:

        • To present our Website and its contents to you;
        • To provide you with information, products, or services that you request from us;
        • To fulfill any other purpose for which you provide it;
        • To carry out our obligations and enforce our rights arising from any contracts entered into between you and us, including for billing and collection;
        • To notify you about changes to our Website or any products or services we offer or provide though it;
        • In any other way we may describe when you provide the information; and
        • For any other purpose with your consent.

        We may use the information we have collected from you to enable us to display advertisements to our advertisers’ target audiences. Even though we do not disclose your personal information for these purposes without your consent, if you click on or otherwise interact with an advertisement, the advertiser may assume that you meet its target criteria.

        Disclosure of Your Information
        We may disclose aggregated information about our users, and information that does not identify any individual, without restriction.

        We may disclose personal information that we collect or you provide as described in this privacy policy:

        • To our subsidiaries and affiliates.
        • To contractors, service providers, and other third parties we use to support our business.
        • To a buyer or other successor in the event of a merger, divestiture, restructuring, reorganization, dissolution, or other sale or transfer of some or all of the Company’s assets, whether as a going concern or as part of bankruptcy, liquidation, or similar proceeding, in which personal information held by the Company about our Website users is among the assets transferred.
        • To fulfill the purpose for which you provide it.
        • For any other purpose disclosed by us when you provide the information.
        • With your consent.

        We may also disclose your personal information:

        • To comply with any court order, law, or legal process, including to respond to any government or regulatory request.
        • To enforce or apply our terms of use and other agreements, including for billing and collection purposes.
        • If we believe disclosure is necessary or appropriate to protect the rights, property, or safety of the Company, our customers, or others. This includes exchanging information with other companies and organizations for the purposes of fraud protection and credit risk reduction.

        Your California Privacy Rights
        California Civil Code Section § 1798.83 permits users of our Website that are California residents to request certain information regarding our disclosure of personal information to third parties for their direct marketing purposes. To make such a request, please send an email to This email address is being protected from spambots. You need JavaScript enabled to view it. or write us at: Kane Studio 925B Peachtree NE, Suite 640, Atlanta, GA 30309

        Data Security
        We have implemented measures designed to secure your personal information from accidental loss and from unauthorized access, use, alteration, and disclosure

        The safety and security of your information also depends on you. Where we have given you (or where you have chosen) a password for access to certain parts of our Website, you are responsible for keeping this password confidential. We ask you not to share your password with anyone.

        Unfortunately, the transmission of information via the internet is not completely secure. Although we do our best to protect your personal information, we cannot guarantee the security of your personal information transmitted to our Website. Any transmission of personal information is at your own risk. We are not responsible for circumvention of any privacy settings or security measures contained on the Website.

        Changes to Our Privacy Policy
        It is our policy to post any changes we make to our privacy policy on this page. If we make material changes to how we treat our users’ personal information, we will notify you  through a notice on the Website home page. The date the privacy policy was last revised is identified at the top of the page. You are responsible for ensuring we have an up-to-date active and deliverable email address for you, and for periodically visiting our Website and this privacy policy to check for any changes.

        Contact Information
        To ask questions or comment about this privacy policy and our privacy practices, contact us at:

        This email address is being protected from spambots. You need JavaScript enabled to view it.

        or

        Kane Studio
        Attn: Legal
        925B Peachtree NE
        Suite 640
        Atlanta, GA 30309