Created
February 4, 2017 11:48
-
-
Save 7iomka/16673e3c176d1a2720e09d1b98c216b7 to your computer and use it in GitHub Desktop.
Yandex map list adress with click and focus
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Start:"a:4:{s:4:"full";s:60:"https://kankan.ru/local/js/controllers/partials/yandex-map.js?148514742316146";s:6:"source";s:44:"/local/js/controllers/partials/yandex-map.js";s:3:"min";s:0:"";s:3:"map";s:0:"";}"*/ | |
(function($, APP) { | |
'use strict'; | |
/** | |
* Контроллер Яндекс Карты | |
**/ | |
APP.Controls.YandexMap = can.Control.extend({ | |
defaults: { | |
coords: [55.76, 37.64], | |
address: null, | |
map: '.js-map', | |
pinList: '.js-map-pin-list', | |
pinMapPointBtn: '.js-point-map', | |
toggleStarter: '.js-schedule-toggle-starter', | |
toggleBlock: '.js-schedule-button-toggle', | |
pinListItem: '.js-pin-list-item', | |
mapToggleItem: '.js-map-toggle-item', | |
mapToggle: '.js-map-toggle-list', | |
metroMap: '.js-map-metro', | |
metroStation: '.js-station' | |
} | |
}, { | |
init: function() { | |
ymaps.ready(function() { | |
this.initMap(this.options.coords); | |
} | |
.bind(this)); | |
}, | |
initMap: function(coords) { | |
var elementId = this.element.find(this.options.map).get(0); | |
this.metroInited = false; | |
if (typeof this.options.metro == "object" && typeof this.options.metro.SCHEME != 'undefined' && this.options.metro.SCHEME != 'undefined') { | |
this.options.metro.SCHEME = decodeURIComponent(this.options.metro.SCHEME); | |
this.initMapToggle(); | |
} else { | |
this.removeMapToggle(); | |
} | |
this.contactsMap = new ymaps.Map(elementId,{ | |
center: coords, | |
zoom: 12, | |
controls: ['zoomControl', 'searchControl', 'trafficControl'] | |
}); | |
this.addPlacemark(this.options.points, this.contactsMap); | |
this.createPinList(this.options.points, this.contactsMap); | |
}, | |
addPlacemark: function(points, map) { | |
if (points == undefined) { | |
return false; | |
} | |
var myCollection = new ymaps.GeoObjectCollection(); | |
var self = this; | |
$.each(points, function(i, val) { | |
var myPlacemark = new ymaps.Placemark([val.LAT, val.LON],{ | |
id: val.CODE, | |
name: val.NAME, | |
address: val.ADDRESS, | |
schedule: val.SCHEDULE, | |
lat: val.LAT, | |
lon: val.LON, | |
metro: val.METRO_STATION, | |
metroTrim: val.METRO_STATION_TRIM, | |
button: 'Выбрать метку' | |
},{ | |
iconLayout: 'default#image', | |
iconImageHref: '/local/images/pin.png', | |
iconImageSize: [40, 52], | |
iconImageOffset: [-20, -52], | |
hasBalloon: false //balloonContentLayout: BalloonContentLayout | |
}); | |
myCollection.add(myPlacemark); | |
myPlacemark.events.add('click', self.onClickListener.bind(self)); | |
}); | |
map.geoObjects.add(myCollection); | |
map.setBounds(myCollection.getBounds(), { | |
checkZoomRange: true | |
}); | |
}, | |
'{pinMapPointBtn} click': function($el) { | |
this.options.parent.selectPoint($el); | |
}, | |
createSchedule: function(data) { | |
var days = { | |
1: 'Пн.', | |
2: 'Вт.', | |
3: 'Ср.', | |
4: 'Чт.', | |
5: 'Пт', | |
6: 'Сб.', | |
7: 'Вс.' | |
}; | |
var result = []; | |
var iTmp = 0; | |
//debugger; | |
for (var i in days) { | |
if (i == 7) { | |
iTmp = 0; | |
} else { | |
iTmp = i; | |
} | |
if (data[iTmp] == undefined) { | |
//выходной | |
result[days[i]] = 'Выходной'; | |
} else { | |
result[days[i]] = data[iTmp].Time; | |
} | |
} | |
return result; | |
}, | |
onClickListener: function(e) { | |
var point = e.get('target'); | |
//текущую иконку меняем на активную остальные на обычные | |
var pointId = point.properties.get('id'); | |
if (pointId != undefined) { | |
var el = this.$pinList.find(this.options.pinListItem).filter('[data-id="' + pointId + '"]'); | |
el.click(); | |
this.$pinList.mCustomScrollbar("scrollTo", el); | |
} | |
}, | |
createPinList: function(points, map) { | |
this.$pinList = this.element.find(this.options.pinList); | |
var resultItems = ''; | |
var self = this; | |
this.contactsMap.geoObjects.get(0).each(function(val, i) { | |
var prop = val.properties.getAll(); | |
var schedule = self.createSchedule(prop.schedule); | |
var scheduleResult = ''; | |
for (var name in schedule) { | |
scheduleResult += '<div class="day-wrapper"><div class="day">' + name + '</div><div class="time">' + schedule[name] + '</div></div>'; | |
} | |
prop.metroTrim = (typeof prop.metroTrim != "undefined" && prop.metroTrim != '') ? prop.metroTrim : null; | |
resultItems += '<div class="pin-list-item js-pin-list-item" data-geo-index="' + i + '" data-id="' + prop.id + '" data-metro="' + prop.metroTrim + '">' + '<div class="name js-schedule-toggle-starter"><span>' + prop.name + '</span><i class="name-arrow"></i></div>' + '<div class="address">' + prop.address + '</div>' + '<div class="schedule-button-toggle js-schedule-button-toggle">' + '<div class="schedule">' + scheduleResult + '</div>' + '<div class="button-wrapper"><button class="point-map-btn js-point-map"' + 'data-address="' + prop.address + '"' + 'data-id="' + prop.id + '"' + '>Заберу отсюда</button></div>' + '</div>' + '</div>' | |
}); | |
this.$pinList.html(resultItems); | |
this.$pinList.mCustomScrollbar({ | |
scrollbarPosition: 'outside', | |
scrollInertia: 0 | |
}); | |
if (this.options.selectedPoint != undefined && this.options.selectedPoint.val() != '') { | |
var el = this.$pinList.find(this.options.pinListItem).filter('[data-id="' + this.options.selectedPoint.val() + '"]'); | |
if (el != undefined) { | |
el.click(); | |
this.$pinList.mCustomScrollbar("scrollTo", el); | |
} | |
} | |
}, | |
setDefaultIcon: function() { | |
var indexOld = this.$pinList.find(this.options.pinListItem).filter('.active').data('geo-index'); | |
if (indexOld != undefined) { | |
var optionOld = { | |
iconImageHref: '/local/images/pin.png', | |
iconImageSize: [40, 52], | |
iconImageOffset: [-20, -52], | |
zIndex: 0 | |
}; | |
var point = this.contactsMap.geoObjects.get(0).get(indexOld); | |
point.options.set(optionOld); | |
} | |
}, | |
'{pinListItem} click': function($el) { | |
this.setDefaultIcon(); | |
this.$pinList.find(this.options.pinListItem).removeClass('active'); | |
$el.addClass('active'); | |
var point = this.contactsMap.geoObjects.get(0).get($el.data('geo-index')); | |
if (point != undefined) { | |
this.contactsMap.setCenter([point.properties.get('lat'), point.properties.get('lon')]); | |
point.options.set({ | |
iconImageHref: '/local/images/pin-active.png', | |
iconImageSize: [57, 71], | |
iconImageOffset: [-28, -71], | |
zIndex: 999 | |
}); | |
} | |
}, | |
initMapToggle: function() { | |
var toggleItem = '<a href="javascript:void(0);" class="js-map-toggle-item map-toggle-item toggle-icon-map active" data-type="map"><span>На карте</span></a><a href="javascript:void(0);" class="js-map-toggle-item map-toggle-item toggle-icon-metro" data-type="metro"><span>На карте метро</span></a>'; | |
this.element.find(this.options.mapToggle).html(toggleItem); | |
}, | |
removeMapToggle: function() { | |
this.element.find(this.options.mapToggle).html(''); | |
}, | |
'{mapToggleItem} click': function($el, ev) { | |
this.element.find(this.options.mapToggleItem).removeClass('active'); | |
$el.addClass('active'); | |
var type = $el.data('type'); | |
switch (type) { | |
case 'metro': | |
//show metro map | |
this.initMetroMap(); | |
this.showMetroMap(); | |
this.showPointWithStation(); | |
this.scrollToActive(); | |
break; | |
case 'map': | |
this.clearPointStation(); | |
this.hideMetroMap(); | |
this.scrollToActive(); | |
break; | |
} | |
}, | |
'{metroStation} click': function($el, ev) { | |
this.clearPointStation(); | |
this.showPointStation($el.data('station')); | |
}, | |
initMetroMap: function() { | |
var metroMap = this.element.find(this.options.metroMap); | |
if (metroMap.hasClass('js-inited')) { | |
return false; | |
} | |
metroMap.addClass('show-metro'); | |
this._renderMetroStation(metroMap, this.options.metro); | |
if (this.element.find('.js-map-inner svg').length) { | |
this.initScaleDragMap(); | |
} | |
}, | |
initScaleDragMap: function() { | |
if (this.metroInited) { | |
return false; | |
} | |
this.resetScale(); | |
this.setZoom(1); | |
this.setPostion((this.map.width() - this.svgWidth * this.currentScale) / 2, (this.map.height() - this.svgHeight * this.currentScale) / 2); | |
interact('.js-mapsvg').draggable({ | |
// enable inertial throwing | |
inertia: false, | |
// call this function on every dragmove event | |
onmove: this.dragMoveListener.bind(this), | |
// call this function on every dragend event | |
onend: function(event) {} | |
}).resizable({ | |
preserveAspectRatio: true, | |
edges: { | |
left: true, | |
right: true, | |
bottom: true, | |
top: true | |
} | |
}).on('tap', function(event) { | |
$(event.target).closest('.js-station').click(); | |
event.preventDefault(); | |
}); | |
this.metroInited = true; | |
}, | |
resetScale: function() { | |
this.map = this.element.find(this.options.metroMap); | |
this.mapDrag = this.element.find('.js-mapsvg'); | |
this.svg = this.element.find('.js-map-inner svg'); | |
this.scaleElement = this.svg.find('#transform-wrapper'); | |
this.svg.get(0).setAttribute('width', '100%'); | |
this.svg.get(0).setAttribute('height', '100%'); | |
this.svgWidth = this.scaleElement.get(0).getBBox().width; | |
this.svgHeight = this.scaleElement.get(0).getBBox().height; | |
var initScaleParam = this.svg.height() < this.svg.width() ? this.svgHeight : this.svgWidth; | |
var initScaleDiv = this.map.height() < this.map.width() ? this.map.height() : this.map.width(); | |
if (initScaleParam > initScaleDiv) { | |
this.currentScale = initScaleDiv / (initScaleParam + 80); | |
} else { | |
this.currentScale = initScaleParam / (initScaleDiv + 80); | |
} | |
}, | |
setZoom: function(scale) { | |
this.currentScale *= scale; | |
this.setPostion((this.map.width() - this.svgWidth * this.currentScale) / 2, (this.map.height() - this.svgHeight * this.currentScale) / 2); | |
var newMatrix = "scale(" + this.currentScale + ", " + this.currentScale + ")"; | |
this.scaleElement.get(0).setAttributeNS(null, "transform", newMatrix); | |
}, | |
dragMoveListener: function(event) { | |
var target = event.target; | |
this.setPostion((parseFloat(target.getAttribute('data-x')) || 0) + event.dx, (parseFloat(target.getAttribute('data-y')) || 0) + event.dy); | |
}, | |
_renderMetroStation: function(obj, metro) { | |
//получить список станций у которых есть метро | |
obj.append('<div class="map-metro-inner js-map-inner">' + '<div class="js-mapsvg map-drag">' + metro.SCHEME + '</div>' + '<div class="zoom-button"><div class="button-plus button js-zoom-plus">+</div><div class="button-minis button js-zoom-minus">-</div></div>' + '</div>'); | |
}, | |
showMetroMap: function() { | |
this.element.find(this.options.metroMap).addClass('show-metro'); | |
}, | |
hideMetroMap: function() { | |
this.element.find(this.options.metroMap).removeClass('show-metro'); | |
}, | |
showPointWithStation: function() { | |
this.$pinList.find(this.options.pinListItem).filter('[data-metro="null"]').hide(); | |
}, | |
showPointStation: function(station) { | |
this.$pinList.find(this.options.pinListItem).filter('[data-metro!="' + station + '"]').hide(); | |
}, | |
clearPointStation: function() { | |
this.$pinList.find(this.options.pinListItem).show(); | |
}, | |
scrollToActive: function() { | |
var el = this.$pinList.find(this.options.pinListItem).filter('.active'); | |
this.$pinList.mCustomScrollbar("scrollTo", el); | |
}, | |
'.js-zoom-plus click': function() { | |
this.setZoom(1.25); | |
}, | |
'.js-zoom-minus click': function() { | |
this.setZoom(0.8); | |
}, | |
'{window} resize': function() { | |
if (typeof this.mapDrag != "undefined") { | |
setTimeout(function() { | |
this.resetScale(); | |
this.setZoom(1); | |
this.setPostion((this.map.width() - this.scaleElement.get(0).getBBox().width * this.currentScale) / 2, (this.map.height() - this.scaleElement.get(0).getBBox().height * this.currentScale) / 2); | |
} | |
.bind(this), 100); | |
} | |
}, | |
setPostion: function(dx, dy) { | |
var target = this.mapDrag.get(0) | |
, // keep the dragged position in the data-x/data-y attributes | |
x = dx | |
, y = dy; | |
// translate the element | |
target.style.webkitTransform = target.style.transform = 'translate(' + x + 'px, ' + y + 'px)'; | |
// update the posiion attributes | |
target.setAttribute('data-x', x); | |
target.setAttribute('data-y', y); | |
} | |
}); | |
})(jQuery, window.APP); | |
/* End */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment