├── src
├── controllers
│ ├── index.js
│ ├── MapController.js
│ ├── PanoramaController.js
│ ├── ImportObjectController.js
│ ├── MarkerController.js
│ └── layouts.js
├── constants
│ └── index.js
├── utils
│ ├── .DS_Store
│ ├── loaders
│ │ ├── fetchScript.js
│ │ └── loadApi.js
│ ├── decorators.js
│ └── eventsHandler.js
├── configs
│ └── index.js
├── BalloonLayout.jsx
├── index.js
├── PanoramaElement.jsx
├── MapElement.jsx
├── MarkerLayout.jsx
├── apiEventsLists
│ ├── map.js
│ └── geoObject.js
├── api.js
├── ConstructorJSONImport.js
├── MapMarker.jsx
├── PanoramaContainer.jsx
└── MapContainer.jsx
├── lib
├── controllers
│ ├── index.js
│ ├── MapController.js
│ ├── PanoramaController.js
│ ├── ImportObjectController.js
│ ├── layouts.js
│ └── MarkerController.js
├── constants
│ └── index.js
├── configs
│ └── index.js
├── apiEventsLists
│ ├── map.js
│ └── geoObject.js
├── utils
│ ├── loaders
│ │ ├── fetchScript.js
│ │ └── loadApi.js
│ ├── decorators.js
│ └── eventsHandler.js
├── index.js
├── api.js
├── BalloonLayout.js
├── MapElement.js
├── PanoramaElement.js
├── MarkerLayout.js
├── ConstructorJSONImport.js
├── MapMarker.js
├── MapContainer.js
└── PanoramaContainer.js
├── .gitignore
├── .babelrc
├── .editorconfig
├── webpack.config.dev.js
├── .eslintrc
├── webpack.config.js
├── package.json
└── README.md
/src/controllers/index.js:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/lib/controllers/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
--------------------------------------------------------------------------------
/src/constants/index.js:
--------------------------------------------------------------------------------
1 |
2 | export const types = {
3 | MARKER_LAYOUT: 1
4 | };
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | .DS_Store
3 | .DS_Store?
4 | .idea/
5 | Thumbs.db
6 | *.log
7 |
--------------------------------------------------------------------------------
/src/utils/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/effrenus/yandex-map-react/HEAD/src/utils/.DS_Store
--------------------------------------------------------------------------------
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": ["es2015", "stage-0", "react"],
3 | "plugins": ["syntax-decorators"]
4 | }
5 |
--------------------------------------------------------------------------------
/src/configs/index.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Yandex API config
3 | */
4 | export const apiConfig = {
5 | host: 'api-maps.yandex.ru',
6 | version: '2.1'
7 | };
8 |
--------------------------------------------------------------------------------
/lib/constants/index.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | var types = exports.types = {
7 | MARKER_LAYOUT: 1
8 | };
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_style = space
5 | indent_size = 4
6 | end_of_line = lf
7 | charset = utf-8
8 | trim_trailing_whitespace = true
9 | insert_final_newline = true
10 |
11 | [*.{json,yml}]
12 | indent_size = 2
--------------------------------------------------------------------------------
/lib/configs/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | /**
7 | * Yandex API config
8 | */
9 | var apiConfig = exports.apiConfig = {
10 | host: 'api-maps.yandex.ru',
11 | version: '2.1'
12 | };
--------------------------------------------------------------------------------
/src/BalloonLayout.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 |
4 | class BalloonLayout extends Component {
5 | render () {
6 | return (
7 |
8 | {this.props.children}
9 |
10 | );
11 | }
12 | }
13 |
14 | export default BalloonLayout;
15 |
--------------------------------------------------------------------------------
/webpack.config.dev.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 | var baseConfig = require('./webpack.config');
3 |
4 | module.exports = Object.assign({}, baseConfig, {
5 | plugins: [
6 | new webpack.optimize.OccurenceOrderPlugin(),
7 | new webpack.DefinePlugin({
8 | 'process.env.NODE_ENV': JSON.stringify('development')
9 | })
10 | ]
11 | });
12 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import Map from './MapContainer';
2 | import Marker from './MapMarker';
3 | import MarkerLayout from './MarkerLayout';
4 | import BalloonLayout from './BalloonLayout';
5 | import ConstructorJSONImport from './ConstructorJSONImport'
6 | import Panorama from './PanoramaContainer';
7 |
8 | export {
9 | Map,
10 | Marker,
11 | MarkerLayout,
12 | BalloonLayout,
13 | ConstructorJSONImport,
14 | Panorama
15 | };
16 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | extends: 'loris/es6',
3 | env: {
4 | es6: true,
5 | browser: true
6 | },
7 | ecmaFeatures: {
8 | sourceType: 'module'
9 | },
10 | parserOptions: {
11 | sourceType: 'module',
12 | ecmaFeatures: {
13 | jsx: true,
14 | experimentalObjectRestSpread: true
15 | }
16 | },
17 | rules: {
18 | space-before-function-paren: 0
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/utils/loaders/fetchScript.js:
--------------------------------------------------------------------------------
1 | export default function fetchScript (url) {
2 | return new Promise((resolve, reject) => {
3 | const script = document.createElement('script');
4 | script.onload = resolve;
5 | script.onerror = reject;
6 | script.src = url;
7 |
8 | const beforeScript = document.getElementsByTagName('script')[0];
9 | beforeScript.parentNode.insertBefore(script, beforeScript);
10 | });
11 | }
12 |
--------------------------------------------------------------------------------
/src/utils/decorators.js:
--------------------------------------------------------------------------------
1 | import {register as registerEvents} from './eventsHandler';
2 |
3 | export function eventsDecorator (Component, {supportEvents}) {
4 | Object.defineProperty(Component.prototype, '_setupEvents', {
5 | enumerable: false,
6 | configurable: true,
7 | writable: true,
8 | value() {
9 | registerEvents(this.getController(), this.props, supportEvents);
10 | }
11 | });
12 |
13 | return Component;
14 | }
15 |
--------------------------------------------------------------------------------
/lib/apiEventsLists/map.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = ['actionbegin', 'actionbreak', 'actionend', 'actiontick', 'actiontickcomplete', 'balloonclose', 'balloonopen', 'boundschange', 'click', 'contextmenu', 'dblclick', 'destroy', 'hintclose', 'hintopen', 'marginchange', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'mouseup', 'multitouchend', 'multitouchmove', 'multitouchstart', 'optionschange', 'sizechange', 'typechange', 'wheel'];
--------------------------------------------------------------------------------
/src/PanoramaElement.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | const style = {
4 | position: 'absolute',
5 | width: '100%',
6 | height: '100%',
7 | margin: 0,
8 | padding: 0
9 | };
10 |
11 | class PanoramaElement extends Component {
12 | render () {
13 | if (this.props.show) {
14 | return (
15 |
16 | );
17 | } else {
18 | return null;
19 | }
20 | }
21 | }
22 |
23 | export default PanoramaElement;
24 |
--------------------------------------------------------------------------------
/lib/apiEventsLists/geoObject.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = ['balloonclose', 'balloonopen', 'beforedrag', 'beforedragstart', 'click', 'contextmenu', 'dblclick', 'geometrychange', 'hintclose', 'hintopen', 'mapchange', 'mousedown', 'mouseenter', 'mouseleave', 'mousemove', 'mouseup', 'multitouchend', 'multitouchmove', 'multitouchstart', 'optionschange', 'overlaychange', 'parentchange', 'propertieschange', 'wheel', 'drag', 'dragend', 'dragstart', 'editorstatechange'];
--------------------------------------------------------------------------------
/src/MapElement.jsx:
--------------------------------------------------------------------------------
1 | import React, { Component } from 'react';
2 |
3 | const style = {
4 | position: 'absolute',
5 | width: '100%',
6 | height: '100%',
7 | margin: 0,
8 | padding: 0
9 | };
10 |
11 | class MapElement extends Component {
12 | constructor (props) {
13 | super(props);
14 | }
15 |
16 | shouldComponentUpdate () {
17 | return false;
18 | }
19 |
20 | render () {
21 | return (
22 |
23 | );
24 | }
25 | }
26 |
27 | export default MapElement;
28 |
--------------------------------------------------------------------------------
/lib/utils/loaders/fetchScript.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = fetchScript;
7 | function fetchScript(url) {
8 | return new Promise(function (resolve, reject) {
9 | var script = document.createElement('script');
10 | script.onload = resolve;
11 | script.onerror = reject;
12 | script.src = url;
13 |
14 | var beforeScript = document.getElementsByTagName('script')[0];
15 | beforeScript.parentNode.insertBefore(script, beforeScript);
16 | });
17 | }
--------------------------------------------------------------------------------
/src/MarkerLayout.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import { types } from './constants';
4 |
5 | /**
6 | * @class MarkerLayout
7 | */
8 | class MarkerLayout extends Component {
9 | static propTypes = {
10 | marker: PropTypes.object
11 | }
12 |
13 | componentWillUnmount () {
14 | if (this._marker) {
15 | this._marker.destroy();
16 | }
17 | }
18 |
19 | render () {
20 | return {this.props.children}
;
21 | }
22 | }
23 |
24 | export default MarkerLayout;
25 |
--------------------------------------------------------------------------------
/src/apiEventsLists/map.js:
--------------------------------------------------------------------------------
1 | export default [
2 | 'actionbegin',
3 | 'actionbreak',
4 | 'actionend',
5 | 'actiontick',
6 | 'actiontickcomplete',
7 | 'balloonclose',
8 | 'balloonopen',
9 | 'boundschange',
10 | 'click',
11 | 'contextmenu',
12 | 'dblclick',
13 | 'destroy',
14 | 'hintclose',
15 | 'hintopen',
16 | 'marginchange',
17 | 'mousedown',
18 | 'mouseenter',
19 | 'mouseleave',
20 | 'mousemove',
21 | 'mouseup',
22 | 'multitouchend',
23 | 'multitouchmove',
24 | 'multitouchstart',
25 | 'optionschange',
26 | 'sizechange',
27 | 'typechange',
28 | 'wheel'
29 | ];
30 |
--------------------------------------------------------------------------------
/lib/utils/decorators.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.eventsDecorator = eventsDecorator;
7 |
8 | var _eventsHandler = require('./eventsHandler');
9 |
10 | function eventsDecorator(Component, _ref) {
11 | var supportEvents = _ref.supportEvents;
12 |
13 | Object.defineProperty(Component.prototype, '_setupEvents', {
14 | enumerable: false,
15 | configurable: true,
16 | writable: true,
17 | value: function value() {
18 | (0, _eventsHandler.register)(this.getController(), this.props, supportEvents);
19 | }
20 | });
21 |
22 | return Component;
23 | }
--------------------------------------------------------------------------------
/src/apiEventsLists/geoObject.js:
--------------------------------------------------------------------------------
1 | export default [
2 | 'balloonclose',
3 | 'balloonopen',
4 | 'beforedrag',
5 | 'beforedragstart',
6 | 'click',
7 | 'contextmenu',
8 | 'dblclick',
9 | 'geometrychange',
10 | 'hintclose',
11 | 'hintopen',
12 | 'mapchange',
13 | 'mousedown',
14 | 'mouseenter',
15 | 'mouseleave',
16 | 'mousemove',
17 | 'mouseup',
18 | 'multitouchend',
19 | 'multitouchmove',
20 | 'multitouchstart',
21 | 'optionschange',
22 | 'overlaychange',
23 | 'parentchange',
24 | 'propertieschange',
25 | 'wheel',
26 | 'drag',
27 | 'dragend',
28 | 'dragstart',
29 | 'editorstatechange'
30 | ];
31 |
--------------------------------------------------------------------------------
/src/utils/eventsHandler.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | function toOnEventName (name) {
4 | return `on${name.substr(0, 1).toUpperCase()}${name.substr(1)}`;
5 | }
6 |
7 | /**
8 | * Register event callback on api instance
9 | * @param {Object} controller
10 | * @param {Object} props React component `props`
11 | * @param {Array} eventsList Events supported in API (specific for different objects)
12 | */
13 | export function register (controller, props, eventsList) {
14 | eventsList.forEach((eventName) => {
15 | const onEventName = toOnEventName(eventName);
16 | if (props.hasOwnProperty(onEventName)) {
17 | controller.events.add(eventName, props[onEventName]);
18 | }
19 | });
20 | }
21 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | var webpack = require('webpack');
2 |
3 | var reactExternal = {
4 | root: 'React',
5 | commonjs2: 'react',
6 | commonjs: 'react',
7 | amd: 'react'
8 | };
9 |
10 | var reactDomExternal = {
11 | root: 'ReactDOM',
12 | commonjs2: 'react-dom',
13 | commonjs: 'react-dom',
14 | amd: 'react-dom'
15 | };
16 |
17 | module.exports = {
18 | output: {
19 | library: 'YandexMapReact',
20 | libraryTarget: 'umd'
21 | },
22 | externals: {
23 | 'react': reactExternal,
24 | 'react-dom': reactDomExternal
25 | },
26 | module: {
27 | loaders: [
28 | {test: /\.jsx?/i, exclude: /node_modules/, loader: 'babel'}
29 | ]
30 | }
31 | };
32 |
--------------------------------------------------------------------------------
/src/api.js:
--------------------------------------------------------------------------------
1 | import loadApi from './utils/loaders/loadApi';
2 |
3 | class Api {
4 | constructor () {
5 | this.api = (typeof window != 'undefined' && window.ymaps) ? window.ymaps : null;
6 | }
7 |
8 | setAPI (instance) {
9 | this.api = instance;
10 |
11 | return this.api;
12 | }
13 |
14 | getAPI () {
15 | return this.api;
16 | }
17 |
18 | isAvailible () {
19 | return Boolean(this.api);
20 | }
21 |
22 | /**
23 | * Loading API
24 | * @return {Promise}
25 | */
26 | load (options={}) {
27 | return loadApi(options).then((instance) => {
28 | this.api = instance;
29 | return instance;
30 | });
31 | }
32 | }
33 |
34 | export default new Api();
35 |
--------------------------------------------------------------------------------
/lib/utils/eventsHandler.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.register = register;
7 |
8 |
9 | function toOnEventName(name) {
10 | return "on" + name.substr(0, 1).toUpperCase() + name.substr(1);
11 | }
12 |
13 | /**
14 | * Register event callback on api instance
15 | * @param {Object} controller
16 | * @param {Object} props React component `props`
17 | * @param {Array} eventsList Events supported in API (specific for different objects)
18 | */
19 | function register(controller, props, eventsList) {
20 | eventsList.forEach(function (eventName) {
21 | var onEventName = toOnEventName(eventName);
22 | if (props.hasOwnProperty(onEventName)) {
23 | controller.events.add(eventName, props[onEventName]);
24 | }
25 | });
26 | }
--------------------------------------------------------------------------------
/src/ConstructorJSONImport.js:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import ImportObjectController from './controllers/ImportObjectController';
4 |
5 | class ConstructorJSONImport extends Component {
6 | static propTypes = {
7 | userMapData: PropTypes.object.isRequired
8 | }
9 |
10 | static contextTypes = {
11 | mapController: PropTypes.object
12 | }
13 |
14 | componentDidMount () {
15 | const {map} = this.context.mapController;
16 | this._controller = new ImportObjectController(map, this.props.userMapData);
17 | }
18 |
19 | componentWillUnmount () {
20 | this._controller.destroy();
21 | }
22 |
23 | shouldComponentUpdate () {
24 | return false;
25 | }
26 |
27 | render () {
28 | return null;
29 | }
30 | }
31 |
32 | export default ConstructorJSONImport;
33 |
--------------------------------------------------------------------------------
/src/controllers/MapController.js:
--------------------------------------------------------------------------------
1 | import api from '../api';
2 |
3 | class MapController {
4 | constructor () {
5 |
6 | }
7 |
8 | createMap (container, state, options) {
9 | this._map = new (api.getAPI()).Map(container, state, options);
10 | this.events = this._map.events.group();
11 |
12 | this._setupCollection();
13 |
14 | return this;
15 | }
16 |
17 | appendMarker (marker) {
18 | this._geoCollection.add(marker.getAPIInstance());
19 | marker.setBalloonState(marker.balloonState);
20 | }
21 |
22 | get map () {
23 | return this._map;
24 | }
25 |
26 | setOptions (name, value) {
27 | this._map.options.set(name, value);
28 | }
29 |
30 | setCenter (coords) {
31 | this._map.setCenter(coords);
32 | }
33 |
34 | setZoom (zoom) {
35 | this._map.setZoom(zoom);
36 | }
37 | setBounds (bounds) {
38 | this._map.setBounds(bounds);
39 | }
40 |
41 | setState (name, value) {
42 | this._map.state.set(name, value);
43 | }
44 |
45 | destroy () {
46 | this.events.removeAll();
47 | this._map.destroy();
48 | }
49 |
50 | _setupCollection () {
51 | this._geoCollection = new (api.getAPI()).GeoObjectCollection();
52 | this._map.geoObjects.add(this._geoCollection);
53 | }
54 | }
55 |
56 | export default MapController;
57 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "yandex-map-react",
3 | "version": "1.0.0",
4 | "description": "Yandex map react",
5 | "main": "lib/index.js",
6 | "scripts": {
7 | "build:lib": "babel ./src -d lib",
8 | "build:umd": "webpack src/index.js dist/YandexMapReact.js --config webpack.config.dev.js",
9 | "watch": "babel --watch ./src -d lib",
10 | "lint": "eslint src/",
11 | "test": "echo \"Error: no test specified\" && exit 1"
12 | },
13 | "files": [
14 | "lib"
15 | ],
16 | "keywords": [
17 | "yandex",
18 | "map",
19 | "react"
20 | ],
21 | "author": "Alexey Sazonov",
22 | "license": "MIT",
23 | "bugs": {
24 | "url": "https://github.com/effrenus/yandex-map-react/issues"
25 | },
26 | "devDependencies": {
27 | "babel-cli": "^6.6.5",
28 | "babel-core": "^6.7.4",
29 | "babel-loader": "^6.2.4",
30 | "babel-plugin-syntax-decorators": "^6.8.0",
31 | "babel-preset-es2015": "^6.6.0",
32 | "babel-preset-react": "^6.5.0",
33 | "babel-preset-stage-0": "^6.5.0",
34 | "babel-plugin-syntax-decorators": "^6.8.0",
35 | "eslint": "^2.9.0",
36 | "eslint-config-loris": "^4.0.0",
37 | "webpack": "^1.12.14",
38 | "react": "^15.5.0",
39 | "react-dom": "^15.5.0",
40 | "prop-types": "^15.5.0"
41 | },
42 | "peerDependencies": {
43 | "prop-types": "^15.5.0",
44 | "react": "^0.14.8 || ^15.5.0 || ^16.0.0",
45 | "react-dom": "^0.14.8 || ^15.5.0 || ^16.0.0"
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/lib/index.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.Panorama = exports.ConstructorJSONImport = exports.BalloonLayout = exports.MarkerLayout = exports.Marker = exports.Map = undefined;
7 |
8 | var _MapContainer = require('./MapContainer');
9 |
10 | var _MapContainer2 = _interopRequireDefault(_MapContainer);
11 |
12 | var _MapMarker = require('./MapMarker');
13 |
14 | var _MapMarker2 = _interopRequireDefault(_MapMarker);
15 |
16 | var _MarkerLayout = require('./MarkerLayout');
17 |
18 | var _MarkerLayout2 = _interopRequireDefault(_MarkerLayout);
19 |
20 | var _BalloonLayout = require('./BalloonLayout');
21 |
22 | var _BalloonLayout2 = _interopRequireDefault(_BalloonLayout);
23 |
24 | var _ConstructorJSONImport = require('./ConstructorJSONImport');
25 |
26 | var _ConstructorJSONImport2 = _interopRequireDefault(_ConstructorJSONImport);
27 |
28 | var _PanoramaContainer = require('./PanoramaContainer');
29 |
30 | var _PanoramaContainer2 = _interopRequireDefault(_PanoramaContainer);
31 |
32 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
33 |
34 | exports.Map = _MapContainer2.default;
35 | exports.Marker = _MapMarker2.default;
36 | exports.MarkerLayout = _MarkerLayout2.default;
37 | exports.BalloonLayout = _BalloonLayout2.default;
38 | exports.ConstructorJSONImport = _ConstructorJSONImport2.default;
39 | exports.Panorama = _PanoramaContainer2.default;
--------------------------------------------------------------------------------
/src/utils/loaders/loadApi.js:
--------------------------------------------------------------------------------
1 | import fetchScript from './fetchScript';
2 | import {apiConfig} from '../../configs';
3 |
4 | let loadPromise;
5 |
6 | const enabledAPIParams = ['lang', 'apikey', 'coordorder', 'load', 'mode'];
7 | const successCallbackName = '_$_api_success';
8 | const errorCallbackName = '_$_api_error';
9 |
10 | const defaultOptions = {
11 | lang: 'ru_RU',
12 | coordorder: 'latlong',
13 | load: 'package.full',
14 | mode: 'release',
15 | ns: '',
16 | onload: successCallbackName,
17 | onerror: errorCallbackName
18 | };
19 |
20 | function generateURL (options) {
21 | const params = Object.assign({}, defaultOptions);
22 | Object.keys(options)
23 | .filter((key) => enabledAPIParams.indexOf(key) !== -1)
24 | .forEach((key) => {
25 | params[key] = options[key];
26 | });
27 |
28 | const queryString = Object.keys(params).map((key) => `${key}=${params[key]}`).join('&');
29 |
30 | return `https://${apiConfig.host}/${options.version || apiConfig.version}/?${queryString}`;
31 | }
32 |
33 | export default function loadApi (options) {
34 | if (loadPromise) {
35 | return loadPromise;
36 | }
37 |
38 | loadPromise = new Promise((resolve, reject) => {
39 |
40 | window[successCallbackName] = (ymaps) => {
41 | resolve(ymaps);
42 | window[successCallbackName] = null;
43 | };
44 |
45 | window[errorCallbackName] = (error) => {
46 | reject(error);
47 | window[errorCallbackName] = null;
48 | };
49 |
50 | fetchScript(generateURL(options));
51 | });
52 |
53 | return loadPromise;
54 | }
55 |
--------------------------------------------------------------------------------
/src/controllers/PanoramaController.js:
--------------------------------------------------------------------------------
1 | import api from '../api';
2 |
3 | class PanoramaController {
4 | constructor (func) {
5 | this._isPanoramas = func;
6 | }
7 |
8 | createPanorama (container, state, options) {
9 |
10 | this._container = container;
11 | this._coordinates = state.center;
12 | this._options = options;
13 | this._panorama = api.getAPI().panorama;
14 |
15 | return this;
16 | }
17 |
18 | locate (showService) {
19 |
20 | if (this.isSupported()) {
21 | this._panorama.locate(this._coordinates).done(
22 | (panoramas) => {
23 |
24 | this._isPanoramas(Boolean(panoramas.length));
25 |
26 | if (showService) {
27 | this.show(panoramas);
28 | }
29 | },
30 | (error) => this.error(error)
31 | );
32 | } else {
33 | this.error ({
34 | message: 'Браузер не поддерживается плеером.'
35 | });
36 | }
37 | }
38 |
39 | show (panoramas) {
40 | if (panoramas.length > 0) {
41 | const player = new this._panorama.Player(
42 | this._container,
43 | panoramas[0],
44 | this._options
45 | );
46 |
47 | player.events.add('destroy', this.destroy.bind(this));
48 | }
49 | }
50 |
51 | error (error) {
52 | console.error(error.message);
53 | }
54 |
55 | isSupported () {
56 | return this._panorama.isSupported();
57 | }
58 |
59 | destroy () {
60 | this._panorama = null;
61 |
62 | if (this._options.parentFunct) {
63 | this._options.parentFunct();
64 | }
65 | }
66 | }
67 |
68 | export default PanoramaController;
69 |
--------------------------------------------------------------------------------
/src/controllers/ImportObjectController.js:
--------------------------------------------------------------------------------
1 | import api from '../api';
2 |
3 | class ImportObjectController {
4 | constructor (map, data) {
5 | this._map = map;
6 | this._data = data;
7 |
8 | this._setupPresets();
9 | this._setupGeoObjects();
10 | }
11 |
12 | destroy () {
13 | this._clearPresets();
14 | this._geoObject.removeFromMap(this._map);
15 | this._geoObject = null;
16 | this._map = null;
17 | }
18 |
19 | _setupGeoObjects () {
20 | const {geoObjects} = this._data;
21 | const ymaps = api.getAPI();
22 |
23 | if (!geoObjects) {
24 | return;
25 | }
26 |
27 | this._geoObject = ymaps.geoQuery(this._prepare(geoObjects)).addToMap(this._map);
28 | }
29 |
30 | _prepare (collection) {
31 | const updatedCollection = {...collection};
32 |
33 | updatedCollection.features.forEach((feature) => {
34 | const props = feature.properties;
35 | if (!props) {
36 | return feature;
37 | }
38 | if (props.name) {
39 | props.balloonContentHeader = props.name;
40 | }
41 | if (props.description) {
42 | props.balloonContentBody = props.description;
43 | }
44 | });
45 |
46 | return updatedCollection;
47 | }
48 |
49 | _setupPresets () {
50 | const {presetStorage} = this._data;
51 | const ymaps = api.getAPI();
52 |
53 | if (!presetStorage) {
54 | return;
55 | }
56 |
57 | this._presetKeys = Object.keys(presetStorage);
58 | this._presetKeys.forEach((key) => {
59 | ymaps.option.presetStorage.add(key, presetStorage[key]);
60 | });
61 | }
62 |
63 | _clearPresets () {
64 | const ymaps = api.getAPI();
65 | this._presetKeys.forEach((key) => {
66 | ymaps.option.presetStorage.remove(key);
67 | });
68 | }
69 | }
70 |
71 | export default ImportObjectController;
72 |
--------------------------------------------------------------------------------
/lib/utils/loaders/loadApi.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 | exports.default = loadApi;
7 |
8 | var _fetchScript = require('./fetchScript');
9 |
10 | var _fetchScript2 = _interopRequireDefault(_fetchScript);
11 |
12 | var _configs = require('../../configs');
13 |
14 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15 |
16 | var loadPromise = void 0;
17 |
18 | var enabledAPIParams = ['lang', 'apikey', 'coordorder', 'load', 'mode'];
19 | var successCallbackName = '_$_api_success';
20 | var errorCallbackName = '_$_api_error';
21 |
22 | var defaultOptions = {
23 | lang: 'ru_RU',
24 | coordorder: 'latlong',
25 | load: 'package.full',
26 | mode: 'release',
27 | ns: '',
28 | onload: successCallbackName,
29 | onerror: errorCallbackName
30 | };
31 |
32 | function generateURL(options) {
33 | var params = Object.assign({}, defaultOptions);
34 | Object.keys(options).filter(function (key) {
35 | return enabledAPIParams.indexOf(key) !== -1;
36 | }).forEach(function (key) {
37 | params[key] = options[key];
38 | });
39 |
40 | var queryString = Object.keys(params).map(function (key) {
41 | return key + '=' + params[key];
42 | }).join('&');
43 |
44 | return 'https://' + _configs.apiConfig.host + '/' + (options.version || _configs.apiConfig.version) + '/?' + queryString;
45 | }
46 |
47 | function loadApi(options) {
48 | if (loadPromise) {
49 | return loadPromise;
50 | }
51 |
52 | loadPromise = new Promise(function (resolve, reject) {
53 |
54 | window[successCallbackName] = function (ymaps) {
55 | resolve(ymaps);
56 | window[successCallbackName] = null;
57 | };
58 |
59 | window[errorCallbackName] = function (error) {
60 | reject(error);
61 | window[errorCallbackName] = null;
62 | };
63 |
64 | (0, _fetchScript2.default)(generateURL(options));
65 | });
66 |
67 | return loadPromise;
68 | }
--------------------------------------------------------------------------------
/lib/api.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _loadApi = require('./utils/loaders/loadApi');
10 |
11 | var _loadApi2 = _interopRequireDefault(_loadApi);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16 |
17 | var Api = function () {
18 | function Api() {
19 | _classCallCheck(this, Api);
20 |
21 | this.api = typeof window != 'undefined' && window.ymaps ? window.ymaps : null;
22 | }
23 |
24 | _createClass(Api, [{
25 | key: 'setAPI',
26 | value: function setAPI(instance) {
27 | this.api = instance;
28 |
29 | return this.api;
30 | }
31 | }, {
32 | key: 'getAPI',
33 | value: function getAPI() {
34 | return this.api;
35 | }
36 | }, {
37 | key: 'isAvailible',
38 | value: function isAvailible() {
39 | return Boolean(this.api);
40 | }
41 |
42 | /**
43 | * Loading API
44 | * @return {Promise}
45 | */
46 |
47 | }, {
48 | key: 'load',
49 | value: function load() {
50 | var _this = this;
51 |
52 | var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
53 |
54 | return (0, _loadApi2.default)(options).then(function (instance) {
55 | _this.api = instance;
56 | return instance;
57 | });
58 | }
59 | }]);
60 |
61 | return Api;
62 | }();
63 |
64 | exports.default = new Api();
--------------------------------------------------------------------------------
/lib/BalloonLayout.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _propTypes = require('prop-types');
10 |
11 | var _propTypes2 = _interopRequireDefault(_propTypes);
12 |
13 | var _react = require('react');
14 |
15 | var _react2 = _interopRequireDefault(_react);
16 |
17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18 |
19 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20 |
21 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
22 |
23 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
24 |
25 | var BalloonLayout = function (_Component) {
26 | _inherits(BalloonLayout, _Component);
27 |
28 | function BalloonLayout() {
29 | _classCallCheck(this, BalloonLayout);
30 |
31 | return _possibleConstructorReturn(this, (BalloonLayout.__proto__ || Object.getPrototypeOf(BalloonLayout)).apply(this, arguments));
32 | }
33 |
34 | _createClass(BalloonLayout, [{
35 | key: 'render',
36 | value: function render() {
37 | return _react2.default.createElement(
38 | 'div',
39 | null,
40 | this.props.children
41 | );
42 | }
43 | }]);
44 |
45 | return BalloonLayout;
46 | }(_react.Component);
47 |
48 | exports.default = BalloonLayout;
--------------------------------------------------------------------------------
/lib/MapElement.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16 |
17 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18 |
19 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
20 |
21 | var style = {
22 | position: 'absolute',
23 | width: '100%',
24 | height: '100%',
25 | margin: 0,
26 | padding: 0
27 | };
28 |
29 | var MapElement = function (_Component) {
30 | _inherits(MapElement, _Component);
31 |
32 | function MapElement(props) {
33 | _classCallCheck(this, MapElement);
34 |
35 | return _possibleConstructorReturn(this, (MapElement.__proto__ || Object.getPrototypeOf(MapElement)).call(this, props));
36 | }
37 |
38 | _createClass(MapElement, [{
39 | key: 'shouldComponentUpdate',
40 | value: function shouldComponentUpdate() {
41 | return false;
42 | }
43 | }, {
44 | key: 'render',
45 | value: function render() {
46 | return _react2.default.createElement('div', { style: style });
47 | }
48 | }]);
49 |
50 | return MapElement;
51 | }(_react.Component);
52 |
53 | exports.default = MapElement;
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # yandex-map-react
2 |
3 | ## Quick start
4 |
5 | ```js
6 | import React from 'react';
7 | import ReactDOM from 'react-dom';
8 | import { Map, Marker, MarkerLayout } from 'yandex-map-react';
9 |
10 | export default function ContactMap (props) {
11 | render () {
12 | return (
13 |
16 | );
17 | }
18 | }
19 | ```
20 |
21 | ## Installation
22 |
23 | `yandex-map-react` requires React >= 0.14
24 |
25 | ### npm
26 |
27 | ```
28 | npm install --save yandex-map-react
29 | ```
30 |
31 | ## Parameters
32 |
33 | | Parameter | Default value | Type | Decription |
34 | |---------|-----------------------|---------|----------|
35 | | `width` | 600 | Number | container width |
36 | | `height` | 600 | Number | container height |
37 | | `style` | {} | Object | styles that will be applied to container element |
38 | | `loadOptions` | {lang: 'ru_RU', coordorder: 'latlong', load: 'package.full', mode: 'release'} | Object | API loading [params](https://tech.yandex.ru/maps/doc/jsapi/2.1/dg/concepts/load-docpage/). Enabled params: `lang`, `apikey`, `coordorder`, `load`, `mode` |
39 | | [Supported YandexMap API params](https://tech.yandex.com/maps/doc/jsapi/2.1/ref/reference/Map-docpage/) |
40 | | `center` | [55, 45] | Array[Number] | coordinates of map center |
41 | | `zoom` | 10 | Number | zoom level |
42 | | `state` | {controls: []} | Object | describe map state (ex. [controls](https://tech.yandex.com/maps/doc/jsapi/2.1/ref/reference/Map-docpage/#param-state.controls)) |
43 | | Callbacks |
44 | | `onAPIAvailable` | - | Function | callback will be invoked as soon as YandexMAP API available |
45 |
46 | ## Events
47 |
48 | Components support API events, to handle convert first letter of event name to uppercase and add `on` to begin. Example: `mousemove` -> `onMousemove` ([description](https://tech.yandex.com/maps/doc/jsapi/2.1/ref/reference/IDomEventEmitter-docpage/#event-mousemove)).
49 |
50 | ## Features
51 |
52 | Custom Geoobject marker [layout](https://tech.yandex.com/maps/doc/jsapi/2.1/ref/reference/GeoObject-docpage/#param-options.iconLayout). Custom balloon layout - soon.
53 |
54 | ```js
55 |
56 |
57 |
58 |

59 |
60 |
61 |
62 | ```
63 |
64 | ## Examples
65 |
66 | https://github.com/effrenus/yandex-map-react-examples/
67 |
68 | ## License
69 |
70 | MIT (http://www.opensource.org/licenses/mit-license.php)
71 |
--------------------------------------------------------------------------------
/lib/PanoramaElement.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _react = require('react');
10 |
11 | var _react2 = _interopRequireDefault(_react);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16 |
17 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
18 |
19 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
20 |
21 | var style = {
22 | position: 'absolute',
23 | width: '100%',
24 | height: '100%',
25 | margin: 0,
26 | padding: 0
27 | };
28 |
29 | var PanoramaElement = function (_Component) {
30 | _inherits(PanoramaElement, _Component);
31 |
32 | function PanoramaElement() {
33 | _classCallCheck(this, PanoramaElement);
34 |
35 | return _possibleConstructorReturn(this, (PanoramaElement.__proto__ || Object.getPrototypeOf(PanoramaElement)).apply(this, arguments));
36 | }
37 |
38 | _createClass(PanoramaElement, [{
39 | key: 'render',
40 | value: function render() {
41 | if (this.props.show) {
42 | return _react2.default.createElement(
43 | 'div',
44 | { style: style },
45 | ' '
46 | );
47 | } else {
48 | return null;
49 | }
50 | }
51 | }]);
52 |
53 | return PanoramaElement;
54 | }(_react.Component);
55 |
56 | exports.default = PanoramaElement;
--------------------------------------------------------------------------------
/lib/MarkerLayout.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _propTypes = require('prop-types');
10 |
11 | var _propTypes2 = _interopRequireDefault(_propTypes);
12 |
13 | var _react = require('react');
14 |
15 | var _react2 = _interopRequireDefault(_react);
16 |
17 | var _constants = require('./constants');
18 |
19 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
20 |
21 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
22 |
23 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
24 |
25 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
26 |
27 | /**
28 | * @class MarkerLayout
29 | */
30 | var MarkerLayout = function (_Component) {
31 | _inherits(MarkerLayout, _Component);
32 |
33 | function MarkerLayout() {
34 | _classCallCheck(this, MarkerLayout);
35 |
36 | return _possibleConstructorReturn(this, (MarkerLayout.__proto__ || Object.getPrototypeOf(MarkerLayout)).apply(this, arguments));
37 | }
38 |
39 | _createClass(MarkerLayout, [{
40 | key: 'componentWillUnmount',
41 | value: function componentWillUnmount() {
42 | if (this._marker) {
43 | this._marker.destroy();
44 | }
45 | }
46 | }, {
47 | key: 'render',
48 | value: function render() {
49 | return _react2.default.createElement(
50 | 'div',
51 | null,
52 | this.props.children
53 | );
54 | }
55 | }]);
56 |
57 | return MarkerLayout;
58 | }(_react.Component);
59 |
60 | MarkerLayout.propTypes = {
61 | marker: _propTypes2.default.object
62 | };
63 | exports.default = MarkerLayout;
--------------------------------------------------------------------------------
/src/controllers/MarkerController.js:
--------------------------------------------------------------------------------
1 | import api from '../api';
2 | import layouts from './layouts';
3 |
4 | /**
5 | * @class MarkerController
6 | */
7 | class MarkerController {
8 | /**
9 | * @constructor
10 | * @param {Number[]} coordinates Marker coordinate
11 | * @param {Object} properties
12 | * @param {Object} options
13 | * @param {HTMLElement} options.markerDOM Marker layout
14 | */
15 | constructor (coordinates, properties = {}, options = {}, balloonState) {
16 | this.options = options;
17 | this.properties = properties;
18 | this.balloonState = balloonState;
19 | this._coordinates = coordinates;
20 | this._marker = new (api.getAPI()).Placemark(coordinates, null, null);
21 | this._setupMarkerProperties();
22 | this._setupMarkerOptions();
23 | this.events = this._marker.events.group();
24 | }
25 |
26 | /**
27 | * @return {Object} Return marker instance (specific for MAPAPI)
28 | */
29 | getAPIInstance () {
30 | return this._marker;
31 | }
32 |
33 | /**
34 | * @return {Number[]} Marker coordinates
35 | */
36 | getCoordinates () {
37 | return this._coordinates;
38 | }
39 |
40 | setPosition (coordinates) {
41 | this._marker.geometry.setCoordinates(coordinates);
42 | }
43 |
44 | setProperty (propName, value) {
45 | this._marker.properties.set(propName, value);
46 | }
47 |
48 | setOption (optName, value) {
49 | this._marker.options.set(optName, value);
50 | }
51 |
52 | setBalloonState(state) {
53 | if (state === 'opened') {
54 | if (!this._marker.balloon.isOpen()) {
55 | this._marker.balloon.open();
56 | }
57 | } else {
58 | if (this._marker.balloon.isOpen()) {
59 | this._marker.balloon.close();
60 | }
61 | }
62 | }
63 |
64 | /**
65 | *
66 | * @param {String} name
67 | * @param {HTMLElement} element
68 | */
69 | setLayout (name, element) {
70 | let layout;
71 |
72 | if (name === 'iconLayout') {
73 | layout = layouts.createIconLayoutClass(element);
74 | } else if (name === 'balloonLayout') {
75 | layout = layouts.createBalloonLayoutClass(element);
76 | }
77 |
78 | this._marker.options.set(name, layout);
79 | }
80 |
81 | /**
82 | * Destroy marker
83 | */
84 | destroy () {
85 | this.events.removeAll();
86 | this._marker.setParent(null);
87 | this._marker = null;
88 | }
89 |
90 | _setupMarkerProperties () {
91 | const {properties} = this;
92 | Object.keys(properties).forEach(propName => {
93 | this.setProperty(propName, properties[propName]);
94 | });
95 | }
96 |
97 | _setupMarkerOptions () {
98 | const {options} = this;
99 | Object.keys(options).forEach(optName => {
100 | this.setOption(optName, options[optName]);
101 | });
102 | }
103 | }
104 |
105 | export default MarkerController;
106 |
--------------------------------------------------------------------------------
/lib/controllers/MapController.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _api = require('../api');
10 |
11 | var _api2 = _interopRequireDefault(_api);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16 |
17 | var MapController = function () {
18 | function MapController() {
19 | _classCallCheck(this, MapController);
20 | }
21 |
22 | _createClass(MapController, [{
23 | key: 'createMap',
24 | value: function createMap(container, state, options) {
25 | this._map = new (_api2.default.getAPI().Map)(container, state, options);
26 | this.events = this._map.events.group();
27 |
28 | this._setupCollection();
29 |
30 | return this;
31 | }
32 | }, {
33 | key: 'appendMarker',
34 | value: function appendMarker(marker) {
35 | this._geoCollection.add(marker.getAPIInstance());
36 | marker.setBalloonState(marker.balloonState);
37 | }
38 | }, {
39 | key: 'setOptions',
40 | value: function setOptions(name, value) {
41 | this._map.options.set(name, value);
42 | }
43 | }, {
44 | key: 'setCenter',
45 | value: function setCenter(coords) {
46 | this._map.setCenter(coords);
47 | }
48 | }, {
49 | key: 'setZoom',
50 | value: function setZoom(zoom) {
51 | this._map.setZoom(zoom);
52 | }
53 | }, {
54 | key: 'setBounds',
55 | value: function setBounds(bounds) {
56 | this._map.setBounds(bounds);
57 | }
58 | }, {
59 | key: 'setState',
60 | value: function setState(name, value) {
61 | this._map.state.set(name, value);
62 | }
63 | }, {
64 | key: 'destroy',
65 | value: function destroy() {
66 | this.events.removeAll();
67 | this._map.destroy();
68 | }
69 | }, {
70 | key: '_setupCollection',
71 | value: function _setupCollection() {
72 | this._geoCollection = new (_api2.default.getAPI().GeoObjectCollection)();
73 | this._map.geoObjects.add(this._geoCollection);
74 | }
75 | }, {
76 | key: 'map',
77 | get: function get() {
78 | return this._map;
79 | }
80 | }]);
81 |
82 | return MapController;
83 | }();
84 |
85 | exports.default = MapController;
--------------------------------------------------------------------------------
/lib/controllers/PanoramaController.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _api = require('../api');
10 |
11 | var _api2 = _interopRequireDefault(_api);
12 |
13 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
14 |
15 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
16 |
17 | var PanoramaController = function () {
18 | function PanoramaController(func) {
19 | _classCallCheck(this, PanoramaController);
20 |
21 | this._isPanoramas = func;
22 | }
23 |
24 | _createClass(PanoramaController, [{
25 | key: 'createPanorama',
26 | value: function createPanorama(container, state, options) {
27 |
28 | this._container = container;
29 | this._coordinates = state.center;
30 | this._options = options;
31 | this._panorama = _api2.default.getAPI().panorama;
32 |
33 | return this;
34 | }
35 | }, {
36 | key: 'locate',
37 | value: function locate(showService) {
38 | var _this = this;
39 |
40 | if (this.isSupported()) {
41 | this._panorama.locate(this._coordinates).done(function (panoramas) {
42 |
43 | _this._isPanoramas(Boolean(panoramas.length));
44 |
45 | if (showService) {
46 | _this.show(panoramas);
47 | }
48 | }, function (error) {
49 | return _this.error(error);
50 | });
51 | } else {
52 | this.error({
53 | message: 'Браузер не поддерживается плеером.'
54 | });
55 | }
56 | }
57 | }, {
58 | key: 'show',
59 | value: function show(panoramas) {
60 | if (panoramas.length > 0) {
61 | var player = new this._panorama.Player(this._container, panoramas[0], this._options);
62 |
63 | player.events.add('destroy', this.destroy.bind(this));
64 | }
65 | }
66 | }, {
67 | key: 'error',
68 | value: function error(_error) {
69 | console.error(_error.message);
70 | }
71 | }, {
72 | key: 'isSupported',
73 | value: function isSupported() {
74 | return this._panorama.isSupported();
75 | }
76 | }, {
77 | key: 'destroy',
78 | value: function destroy() {
79 | this._panorama = null;
80 |
81 | if (this._options.parentFunct) {
82 | this._options.parentFunct();
83 | }
84 | }
85 | }]);
86 |
87 | return PanoramaController;
88 | }();
89 |
90 | exports.default = PanoramaController;
--------------------------------------------------------------------------------
/lib/ConstructorJSONImport.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _propTypes = require('prop-types');
10 |
11 | var _propTypes2 = _interopRequireDefault(_propTypes);
12 |
13 | var _react = require('react');
14 |
15 | var _react2 = _interopRequireDefault(_react);
16 |
17 | var _ImportObjectController = require('./controllers/ImportObjectController');
18 |
19 | var _ImportObjectController2 = _interopRequireDefault(_ImportObjectController);
20 |
21 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
22 |
23 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
24 |
25 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
26 |
27 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
28 |
29 | var ConstructorJSONImport = function (_Component) {
30 | _inherits(ConstructorJSONImport, _Component);
31 |
32 | function ConstructorJSONImport() {
33 | _classCallCheck(this, ConstructorJSONImport);
34 |
35 | return _possibleConstructorReturn(this, (ConstructorJSONImport.__proto__ || Object.getPrototypeOf(ConstructorJSONImport)).apply(this, arguments));
36 | }
37 |
38 | _createClass(ConstructorJSONImport, [{
39 | key: 'componentDidMount',
40 | value: function componentDidMount() {
41 | var map = this.context.mapController.map;
42 |
43 | this._controller = new _ImportObjectController2.default(map, this.props.userMapData);
44 | }
45 | }, {
46 | key: 'componentWillUnmount',
47 | value: function componentWillUnmount() {
48 | this._controller.destroy();
49 | }
50 | }, {
51 | key: 'shouldComponentUpdate',
52 | value: function shouldComponentUpdate() {
53 | return false;
54 | }
55 | }, {
56 | key: 'render',
57 | value: function render() {
58 | return null;
59 | }
60 | }]);
61 |
62 | return ConstructorJSONImport;
63 | }(_react.Component);
64 |
65 | ConstructorJSONImport.propTypes = {
66 | userMapData: _propTypes2.default.object.isRequired
67 | };
68 | ConstructorJSONImport.contextTypes = {
69 | mapController: _propTypes2.default.object
70 | };
71 | exports.default = ConstructorJSONImport;
--------------------------------------------------------------------------------
/src/controllers/layouts.js:
--------------------------------------------------------------------------------
1 | import api from '../api';
2 |
3 | function detectImagesLoaded (element) {
4 | const images = Array.from(element.querySelectorAll('img') || []);
5 |
6 | if (images.length === 0) {
7 | return Promise.resolve();
8 | }
9 |
10 | return Promise.all(images.map((image) => {
11 | return new Promise((resolve) => {
12 | if (image.complete) {
13 | resolve();
14 | return;
15 | }
16 | image.onload = image.onerror = resolve;
17 | });
18 | }));
19 | }
20 |
21 | function createLayout ({domElement, extendMethods = {}}) {
22 | const LayoutClass = (api.getAPI()).templateLayoutFactory.createClass('', Object.assign({
23 | build: function () {
24 | LayoutClass.superclass.build.call(this);
25 |
26 | this.options = this.getData().options;
27 |
28 | this._setupContent(domElement);
29 | this._updateSize();
30 |
31 | detectImagesLoaded(this.getElement()).then(this._updateMarkerShape.bind(this));
32 | },
33 |
34 | getShape: function () {
35 | return new (api.getAPI()).shape.Rectangle(
36 | new (api.getAPI()).geometry.pixel.Rectangle(
37 | [
38 | [0, 0],
39 | [this._size[0], this._size[1]]
40 | ]
41 | )
42 | );
43 | },
44 |
45 | _updateMarkerShape: function () {
46 | this._updateSize();
47 | this.events.fire('shapechange');
48 | },
49 |
50 | _setupContent: function (domElement) {
51 | const element = this.getElement();
52 | element.appendChild(domElement);
53 | },
54 |
55 | _updateSize: function () {
56 | this._size = this._getSize();
57 | },
58 |
59 | _getSize: function () {
60 | let elementSize = [];
61 |
62 | if (this.getElement()) {
63 | const element = this.getElement().querySelector('.icon-content');
64 |
65 | if (element) {
66 | elementSize = [element.offsetWidth, element.offsetHeight];
67 | }
68 | }
69 |
70 | return elementSize;
71 | }
72 | }, extendMethods));
73 |
74 | return LayoutClass;
75 | }
76 |
77 | export default {
78 | createIconLayoutClass: function (domElement) {
79 | return createLayout({
80 | domElement,
81 | extendMethods: {
82 | _updateSize: function () {
83 | let geoObject;
84 | const oldSize = this._size;
85 |
86 | this._size = this._getSize();
87 |
88 | // Update layout offset.
89 | if (this._size.length) {
90 | if (!oldSize || (oldSize[0] !== this._size[0] || oldSize[1] !== this._size[1])) {
91 | geoObject = this.getData().geoObject;
92 |
93 | if (geoObject.getOverlaySync()) {
94 | geoObject.options.set('iconOffset', [-this._size[0] / 2, -this._size[1]]);
95 | } else {
96 | geoObject.getOverlay().then(() => {
97 | geoObject.options.set('iconOffset', [-this._size[0] / 2, -this._size[1]]);
98 | });
99 | }
100 | }
101 | }
102 | }
103 | }
104 | });
105 | },
106 |
107 | createBalloonLayoutClass: function (domElement) {
108 | return createLayout({domElement});
109 | }
110 | };
111 |
--------------------------------------------------------------------------------
/lib/controllers/ImportObjectController.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8 |
9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10 |
11 | var _api = require('../api');
12 |
13 | var _api2 = _interopRequireDefault(_api);
14 |
15 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
16 |
17 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
18 |
19 | var ImportObjectController = function () {
20 | function ImportObjectController(map, data) {
21 | _classCallCheck(this, ImportObjectController);
22 |
23 | this._map = map;
24 | this._data = data;
25 |
26 | this._setupPresets();
27 | this._setupGeoObjects();
28 | }
29 |
30 | _createClass(ImportObjectController, [{
31 | key: 'destroy',
32 | value: function destroy() {
33 | this._clearPresets();
34 | this._geoObject.removeFromMap(this._map);
35 | this._geoObject = null;
36 | this._map = null;
37 | }
38 | }, {
39 | key: '_setupGeoObjects',
40 | value: function _setupGeoObjects() {
41 | var geoObjects = this._data.geoObjects;
42 |
43 | var ymaps = _api2.default.getAPI();
44 |
45 | if (!geoObjects) {
46 | return;
47 | }
48 |
49 | this._geoObject = ymaps.geoQuery(this._prepare(geoObjects)).addToMap(this._map);
50 | }
51 | }, {
52 | key: '_prepare',
53 | value: function _prepare(collection) {
54 | var updatedCollection = _extends({}, collection);
55 |
56 | updatedCollection.features.forEach(function (feature) {
57 | var props = feature.properties;
58 | if (!props) {
59 | return feature;
60 | }
61 | if (props.name) {
62 | props.balloonContentHeader = props.name;
63 | }
64 | if (props.description) {
65 | props.balloonContentBody = props.description;
66 | }
67 | });
68 |
69 | return updatedCollection;
70 | }
71 | }, {
72 | key: '_setupPresets',
73 | value: function _setupPresets() {
74 | var presetStorage = this._data.presetStorage;
75 |
76 | var ymaps = _api2.default.getAPI();
77 |
78 | if (!presetStorage) {
79 | return;
80 | }
81 |
82 | this._presetKeys = Object.keys(presetStorage);
83 | this._presetKeys.forEach(function (key) {
84 | ymaps.option.presetStorage.add(key, presetStorage[key]);
85 | });
86 | }
87 | }, {
88 | key: '_clearPresets',
89 | value: function _clearPresets() {
90 | var ymaps = _api2.default.getAPI();
91 | this._presetKeys.forEach(function (key) {
92 | ymaps.option.presetStorage.remove(key);
93 | });
94 | }
95 | }]);
96 |
97 | return ImportObjectController;
98 | }();
99 |
100 | exports.default = ImportObjectController;
--------------------------------------------------------------------------------
/lib/controllers/layouts.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _api = require('../api');
8 |
9 | var _api2 = _interopRequireDefault(_api);
10 |
11 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
12 |
13 | function detectImagesLoaded(element) {
14 | var images = Array.from(element.querySelectorAll('img') || []);
15 |
16 | if (images.length === 0) {
17 | return Promise.resolve();
18 | }
19 |
20 | return Promise.all(images.map(function (image) {
21 | return new Promise(function (resolve) {
22 | if (image.complete) {
23 | resolve();
24 | return;
25 | }
26 | image.onload = image.onerror = resolve;
27 | });
28 | }));
29 | }
30 |
31 | function createLayout(_ref) {
32 | var domElement = _ref.domElement,
33 | _ref$extendMethods = _ref.extendMethods,
34 | extendMethods = _ref$extendMethods === undefined ? {} : _ref$extendMethods;
35 |
36 | var LayoutClass = _api2.default.getAPI().templateLayoutFactory.createClass('', Object.assign({
37 | build: function build() {
38 | LayoutClass.superclass.build.call(this);
39 |
40 | this.options = this.getData().options;
41 |
42 | this._setupContent(domElement);
43 | this._updateSize();
44 |
45 | detectImagesLoaded(this.getElement()).then(this._updateMarkerShape.bind(this));
46 | },
47 |
48 | getShape: function getShape() {
49 | return new (_api2.default.getAPI().shape.Rectangle)(new (_api2.default.getAPI().geometry.pixel.Rectangle)([[0, 0], [this._size[0], this._size[1]]]));
50 | },
51 |
52 | _updateMarkerShape: function _updateMarkerShape() {
53 | this._updateSize();
54 | this.events.fire('shapechange');
55 | },
56 |
57 | _setupContent: function _setupContent(domElement) {
58 | var element = this.getElement();
59 | element.appendChild(domElement);
60 | },
61 |
62 | _updateSize: function _updateSize() {
63 | this._size = this._getSize();
64 | },
65 |
66 | _getSize: function _getSize() {
67 | var elementSize = [];
68 |
69 | if (this.getElement()) {
70 | var element = this.getElement().querySelector('.icon-content');
71 |
72 | if (element) {
73 | elementSize = [element.offsetWidth, element.offsetHeight];
74 | }
75 | }
76 |
77 | return elementSize;
78 | }
79 | }, extendMethods));
80 |
81 | return LayoutClass;
82 | }
83 |
84 | exports.default = {
85 | createIconLayoutClass: function createIconLayoutClass(domElement) {
86 | return createLayout({
87 | domElement: domElement,
88 | extendMethods: {
89 | _updateSize: function _updateSize() {
90 | var _this = this;
91 |
92 | var geoObject = void 0;
93 | var oldSize = this._size;
94 |
95 | this._size = this._getSize();
96 |
97 | // Update layout offset.
98 | if (this._size.length) {
99 | if (!oldSize || oldSize[0] !== this._size[0] || oldSize[1] !== this._size[1]) {
100 | geoObject = this.getData().geoObject;
101 |
102 | if (geoObject.getOverlaySync()) {
103 | geoObject.options.set('iconOffset', [-this._size[0] / 2, -this._size[1]]);
104 | } else {
105 | geoObject.getOverlay().then(function () {
106 | geoObject.options.set('iconOffset', [-_this._size[0] / 2, -_this._size[1]]);
107 | });
108 | }
109 | }
110 | }
111 | }
112 | }
113 | });
114 | },
115 |
116 | createBalloonLayoutClass: function createBalloonLayoutClass(domElement) {
117 | return createLayout({ domElement: domElement });
118 | }
119 | };
--------------------------------------------------------------------------------
/src/MapMarker.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import ReactDOM from 'react-dom';
4 | import BalloonLayout from './BalloonLayout'
5 | import MarkerLayout from './MarkerLayout'
6 | import MarkerController from './controllers/MarkerController';
7 | import supportEvents from './apiEventsLists/geoObject';
8 | import {eventsDecorator} from './utils/decorators';
9 |
10 | class MapMarker extends Component {
11 | static propTypes = {
12 | lat: PropTypes.number.isRequired,
13 | lon: PropTypes.number.isRequired,
14 | properties: PropTypes.object,
15 | options: PropTypes.object,
16 | balloonState: PropTypes.oneOf(['opened', 'closed']),
17 | }
18 |
19 | static defaultProps = {
20 | balloonState: 'closed'
21 | }
22 |
23 | static contextTypes = {
24 | mapController: PropTypes.object,
25 | coordorder: PropTypes.oneOf(['latlong', 'longlat'])
26 | }
27 |
28 | constructor (props) {
29 | super(props);
30 | this.options = {};
31 | }
32 |
33 | componentDidUpdate (prevProps) {
34 | const {lat, lon, children, properties, options, balloonState} = this.props;
35 |
36 | if (lat !== prevProps.lat || lon !== prevProps.lon) {
37 | this._controller.setPosition((this.context.coordorder === 'longlat') ? [lon, lat] : [lat, lon]);
38 | }
39 |
40 | Object.keys(properties || {}).forEach(propName => {
41 | if (!prevProps.properties || properties[propName] !== prevProps.properties[propName]) {
42 | this._controller.setProperty(propName, properties[propName]);
43 | }
44 | });
45 |
46 | Object.keys(options || {}).forEach(optName => {
47 | if (!prevProps.options || options[optName] !== prevProps.options[optName]) {
48 | this._controller.setOption(optName, options[optName]);
49 | }
50 | });
51 |
52 | this._controller.setBalloonState(balloonState);
53 |
54 | if (children != prevProps.children) {
55 | this._clearLayouts();
56 | this._setupLayouts();
57 | }
58 | }
59 |
60 | componentDidMount () {
61 | const {lat, lon, properties, options, balloonState} = this.props;
62 | const coords = (this.context.coordorder === 'longlat') ? [lon, lat] : [lat, lon];
63 |
64 | this._controller = new MarkerController(coords, properties, options, balloonState);
65 |
66 | this._setupLayouts();
67 | this._setupEvents();
68 |
69 | this.context.mapController.appendMarker(this._controller);
70 | }
71 |
72 | componentWillUnmount () {
73 | this._clearLayouts();
74 | this._controller.destroy();
75 | }
76 |
77 | getController () {
78 | return this._controller ? this._controller : null;
79 | }
80 |
81 | _setupLayouts () {
82 | React.Children
83 | .toArray(this.props.children)
84 | .forEach(component => {
85 | if (component.type === BalloonLayout) {
86 | this._setupBalloonLayout(component);
87 | }
88 | if (component.type === MarkerLayout) {
89 | this._setupMarkerLayout(component);
90 | }
91 | });
92 | }
93 |
94 | _setupMarkerLayout (component) {
95 | this._markerElement = document.createElement('div');
96 | this._markerElement.className = 'icon-content';
97 | this._markerElement.style.display = 'inline-block';
98 |
99 | ReactDOM.render(component, this._markerElement);
100 | this._controller.setLayout('iconLayout', this._markerElement);
101 | }
102 |
103 | _setupBalloonLayout (component) {
104 | this._balloonElement = document.createElement('div');
105 |
106 | ReactDOM.render(component, this._balloonElement);
107 | this._controller.setLayout('balloonLayout', this._balloonElement);
108 | }
109 |
110 | _clearLayouts () {
111 | if (this._markerElement) {
112 | ReactDOM.unmountComponentAtNode(this._markerElement);
113 | this._markerElement = null;
114 | }
115 |
116 | if (this._balloonElement) {
117 | ReactDOM.unmountComponentAtNode(this._balloonElement);
118 | this._balloonElement = null;
119 | }
120 | }
121 |
122 | render () {
123 | return null;
124 | }
125 | }
126 |
127 | export default eventsDecorator(MapMarker, {supportEvents});
128 |
--------------------------------------------------------------------------------
/src/PanoramaContainer.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import ReactDOM from 'react-dom';
4 | import PanoramaElement from './PanoramaElement';
5 | import PanoramaController from './controllers/PanoramaController';
6 | import supportEvents from './apiEventsLists/map';
7 | import {eventsDecorator} from './utils/decorators';
8 | import api from './api';
9 |
10 | class YandexPanorama extends Component {
11 | static propTypes = {
12 | apiKey: PropTypes.string,
13 | onAPIAvailable: PropTypes.func,
14 | width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
15 | height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
16 | zoom: PropTypes.number,
17 | state: PropTypes.object,
18 | options: PropTypes.object,
19 | loadOptions: PropTypes.object,
20 | bounds: PropTypes.array
21 | }
22 |
23 | static defaultProps = {
24 | zoom: 10,
25 | center: [55, 45],
26 | width: 600,
27 | height: 600,
28 | bounds: undefined,
29 | state: {
30 | controls: []
31 | },
32 | options: {},
33 | loadOptions: {},
34 | style: {
35 | position: 'relative'
36 | }
37 | }
38 |
39 | static childContextTypes = {
40 | mapController: PropTypes.object,
41 | coordorder: PropTypes.oneOf(['latlong', 'longlat'])
42 | }
43 |
44 | constructor (props) {
45 | super(props);
46 | this.state = {
47 | isAPILoaded: false,
48 | showService: false,
49 | isPanoramas: false
50 | };
51 | }
52 |
53 | getChildContext () {
54 | return {
55 | mapController: this._controller,
56 | coordorder: this.props.loadOptions.coordorder || 'latlong'
57 | };
58 | }
59 |
60 | getController () {
61 | return this._controller ? this._controller : null;
62 | }
63 |
64 | componentWillReceiveProps (nextProps) {
65 | this._controller && Object.keys(nextProps).forEach(key => {
66 | switch (key) {
67 | case 'showService':
68 | if (this.state.showService !== nextProps.showService) {
69 | this.setState({
70 | showService: nextProps.showService
71 | }, () => this.state.showService && this.init());
72 | }
73 | break;
74 | default:
75 | break;
76 | }
77 | });
78 | }
79 |
80 | componentDidMount () {
81 | this.init();
82 | }
83 |
84 | init () {
85 | if (api.isAvailible()) {
86 | this._onAPILoad(api.getAPI());
87 | } else {
88 | api.load(this.props.loadOptions)
89 | .then(this._onAPILoad.bind(this))
90 | .catch((error) => console.log('Error occured: %s', error));
91 | }
92 | }
93 |
94 | isPanoramas = (isPanoramas) => {
95 | this.setState({
96 | isPanoramas
97 | })
98 | }
99 |
100 | render () {
101 |
102 | let style = {};
103 | if (this.state.showService) {
104 | style = this._getStyle();
105 | }
106 |
107 | return (
108 |
109 |
112 |
113 | {
114 | !this.state.showService && this.state.isPanoramas && this.props.children
115 | }
116 |
117 | );
118 | }
119 |
120 | _getStyle () {
121 | return {
122 | ...this.props.style,
123 | width: typeof this.props.width == 'string' ? this.props.width : `${this.props.width}px`,
124 | height: typeof this.props.height == 'string' ? this.props.height : `${this.props.height}px`
125 | };
126 | }
127 |
128 | _onAPILoad (namespace) {
129 | this.props.onAPIAvailable && this.props.onAPIAvailable(namespace);
130 |
131 | this._controller = new PanoramaController(this.isPanoramas);
132 | this._controller.createPanorama(
133 | ReactDOM.findDOMNode(this.refs.panoramaPlayer),
134 | {
135 | ...this.props.state,
136 | center: this.props.center,
137 | zoom: this.props.zoom,
138 | bounds: this.props.bounds
139 | },
140 | {...this.props.options}
141 | );
142 |
143 | this.setState({isAPILoaded: true}, () => this._controller.locate(this.state.showService));
144 | }
145 | }
146 |
147 | export default eventsDecorator(YandexPanorama, {supportEvents});
148 |
--------------------------------------------------------------------------------
/src/MapContainer.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from 'prop-types';
2 | import React, { Component } from 'react';
3 | import ReactDOM from 'react-dom';
4 | import MapElement from './MapElement';
5 | import MapController from './controllers/MapController';
6 | import supportEvents from './apiEventsLists/map';
7 | import {eventsDecorator} from './utils/decorators';
8 | import config from './configs';
9 | import api from './api';
10 |
11 | class YandexMap extends Component {
12 | static propTypes = {
13 | apiKey: PropTypes.string,
14 | onAPIAvailable: PropTypes.func,
15 | width: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
16 | height: PropTypes.oneOfType([PropTypes.string, PropTypes.number]),
17 | zoom: PropTypes.number,
18 | state: PropTypes.object,
19 | options: PropTypes.object,
20 | loadOptions: PropTypes.object,
21 | bounds: PropTypes.array
22 | }
23 |
24 | static defaultProps = {
25 | zoom: 10,
26 | center: [55, 45],
27 | width: 600,
28 | height: 600,
29 | bounds: undefined,
30 | state: {
31 | controls: []
32 | },
33 | options: {},
34 | loadOptions: {},
35 | style: {
36 | position: 'relative'
37 | }
38 | }
39 |
40 | static childContextTypes = {
41 | mapController: PropTypes.object,
42 | coordorder: PropTypes.oneOf(['latlong', 'longlat'])
43 | }
44 |
45 | constructor (props) {
46 | super(props);
47 | this.state = {
48 | isAPILoaded: false
49 | };
50 | }
51 |
52 | getChildContext () {
53 | return {
54 | mapController: this._controller,
55 | coordorder: this.props.loadOptions.coordorder || 'latlong'
56 | };
57 | }
58 |
59 | getController () {
60 | return this._controller ? this._controller : null;
61 | }
62 |
63 | componentWillReceiveProps (nextProps) {
64 | this._controller && Object.keys(nextProps).forEach(key => {
65 | switch (key) {
66 | case 'controls':
67 | this._controller.setState(key, nextProps[key]);
68 | break;
69 | case 'center':
70 | if (this.props.center[0] !== nextProps.center[0]
71 | || this.props.center[1] !== nextProps.center[1] ) {
72 | this._controller.setCenter(nextProps.center);
73 | }
74 |
75 | break;
76 | case 'zoom':
77 | if (this.props.zoom !== nextProps.zoom) {
78 | this._controller.setZoom(nextProps.zoom);
79 | }
80 |
81 | break;
82 | case 'bounds':
83 | if (this.props.bounds !== nextProps.bounds) {
84 | this._controller.setBounds(nextProps.bounds);
85 | }
86 |
87 | break;
88 | default:
89 | break;
90 | }
91 | });
92 | }
93 |
94 | componentDidMount () {
95 | if (api.isAvailible()) {
96 | this._onAPILoad(api.getAPI());
97 | } else {
98 | api.load(this.props.loadOptions)
99 | .then(this._onAPILoad.bind(this))
100 | .catch((error) => console.log('Error occured: %s', error));
101 | }
102 | }
103 |
104 | render () {
105 | return (
106 |
107 |
108 | {Boolean(this.state.isAPILoaded) ? this.props.children : null}
109 |
110 | );
111 | }
112 |
113 | _getStyle () {
114 | return {
115 | ...this.props.style,
116 | width: typeof this.props.width == 'string' ? this.props.width : `${this.props.width}px`,
117 | height: typeof this.props.height == 'string' ? this.props.height : `${this.props.height}px`
118 | };
119 | }
120 |
121 | _onAPILoad (namespace) {
122 | this.props.onAPIAvailable && this.props.onAPIAvailable(namespace);
123 |
124 | this._controller = new MapController();
125 | this._controller.createMap(
126 | ReactDOM.findDOMNode(this.refs.mapContainer),
127 | {
128 | ...this.props.state,
129 | center: this.props.center,
130 | zoom: this.props.zoom,
131 | bounds: this.props.bounds
132 | },
133 | {...this.props.options}
134 | );
135 |
136 | this._setupEvents();
137 | this.setState({isAPILoaded: true});
138 |
139 | if (this.props.onMapAvailable) {
140 | this.props.onMapAvailable(this._controller.map);
141 | }
142 | }
143 | }
144 |
145 | export default eventsDecorator(YandexMap, {supportEvents});
146 |
--------------------------------------------------------------------------------
/lib/controllers/MarkerController.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _api = require('../api');
10 |
11 | var _api2 = _interopRequireDefault(_api);
12 |
13 | var _layouts = require('./layouts');
14 |
15 | var _layouts2 = _interopRequireDefault(_layouts);
16 |
17 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
18 |
19 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
20 |
21 | /**
22 | * @class MarkerController
23 | */
24 | var MarkerController = function () {
25 | /**
26 | * @constructor
27 | * @param {Number[]} coordinates Marker coordinate
28 | * @param {Object} properties
29 | * @param {Object} options
30 | * @param {HTMLElement} options.markerDOM Marker layout
31 | */
32 | function MarkerController(coordinates) {
33 | var properties = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
34 | var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
35 | var balloonState = arguments[3];
36 |
37 | _classCallCheck(this, MarkerController);
38 |
39 | this.options = options;
40 | this.properties = properties;
41 | this.balloonState = balloonState;
42 | this._coordinates = coordinates;
43 | this._marker = new (_api2.default.getAPI().Placemark)(coordinates, null, null);
44 | this._setupMarkerProperties();
45 | this._setupMarkerOptions();
46 | this.events = this._marker.events.group();
47 | }
48 |
49 | /**
50 | * @return {Object} Return marker instance (specific for MAPAPI)
51 | */
52 |
53 |
54 | _createClass(MarkerController, [{
55 | key: 'getAPIInstance',
56 | value: function getAPIInstance() {
57 | return this._marker;
58 | }
59 |
60 | /**
61 | * @return {Number[]} Marker coordinates
62 | */
63 |
64 | }, {
65 | key: 'getCoordinates',
66 | value: function getCoordinates() {
67 | return this._coordinates;
68 | }
69 | }, {
70 | key: 'setPosition',
71 | value: function setPosition(coordinates) {
72 | this._marker.geometry.setCoordinates(coordinates);
73 | }
74 | }, {
75 | key: 'setProperty',
76 | value: function setProperty(propName, value) {
77 | this._marker.properties.set(propName, value);
78 | }
79 | }, {
80 | key: 'setOption',
81 | value: function setOption(optName, value) {
82 | this._marker.options.set(optName, value);
83 | }
84 | }, {
85 | key: 'setBalloonState',
86 | value: function setBalloonState(state) {
87 | if (state === 'opened') {
88 | if (!this._marker.balloon.isOpen()) {
89 | this._marker.balloon.open();
90 | }
91 | } else {
92 | if (this._marker.balloon.isOpen()) {
93 | this._marker.balloon.close();
94 | }
95 | }
96 | }
97 |
98 | /**
99 | *
100 | * @param {String} name
101 | * @param {HTMLElement} element
102 | */
103 |
104 | }, {
105 | key: 'setLayout',
106 | value: function setLayout(name, element) {
107 | var layout = void 0;
108 |
109 | if (name === 'iconLayout') {
110 | layout = _layouts2.default.createIconLayoutClass(element);
111 | } else if (name === 'balloonLayout') {
112 | layout = _layouts2.default.createBalloonLayoutClass(element);
113 | }
114 |
115 | this._marker.options.set(name, layout);
116 | }
117 |
118 | /**
119 | * Destroy marker
120 | */
121 |
122 | }, {
123 | key: 'destroy',
124 | value: function destroy() {
125 | this.events.removeAll();
126 | this._marker.setParent(null);
127 | this._marker = null;
128 | }
129 | }, {
130 | key: '_setupMarkerProperties',
131 | value: function _setupMarkerProperties() {
132 | var _this = this;
133 |
134 | var properties = this.properties;
135 |
136 | Object.keys(properties).forEach(function (propName) {
137 | _this.setProperty(propName, properties[propName]);
138 | });
139 | }
140 | }, {
141 | key: '_setupMarkerOptions',
142 | value: function _setupMarkerOptions() {
143 | var _this2 = this;
144 |
145 | var options = this.options;
146 |
147 | Object.keys(options).forEach(function (optName) {
148 | _this2.setOption(optName, options[optName]);
149 | });
150 | }
151 | }]);
152 |
153 | return MarkerController;
154 | }();
155 |
156 | exports.default = MarkerController;
--------------------------------------------------------------------------------
/lib/MapMarker.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8 |
9 | var _propTypes = require('prop-types');
10 |
11 | var _propTypes2 = _interopRequireDefault(_propTypes);
12 |
13 | var _react = require('react');
14 |
15 | var _react2 = _interopRequireDefault(_react);
16 |
17 | var _reactDom = require('react-dom');
18 |
19 | var _reactDom2 = _interopRequireDefault(_reactDom);
20 |
21 | var _BalloonLayout = require('./BalloonLayout');
22 |
23 | var _BalloonLayout2 = _interopRequireDefault(_BalloonLayout);
24 |
25 | var _MarkerLayout = require('./MarkerLayout');
26 |
27 | var _MarkerLayout2 = _interopRequireDefault(_MarkerLayout);
28 |
29 | var _MarkerController = require('./controllers/MarkerController');
30 |
31 | var _MarkerController2 = _interopRequireDefault(_MarkerController);
32 |
33 | var _geoObject = require('./apiEventsLists/geoObject');
34 |
35 | var _geoObject2 = _interopRequireDefault(_geoObject);
36 |
37 | var _decorators = require('./utils/decorators');
38 |
39 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
40 |
41 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
42 |
43 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
44 |
45 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
46 |
47 | var MapMarker = function (_Component) {
48 | _inherits(MapMarker, _Component);
49 |
50 | function MapMarker(props) {
51 | _classCallCheck(this, MapMarker);
52 |
53 | var _this = _possibleConstructorReturn(this, (MapMarker.__proto__ || Object.getPrototypeOf(MapMarker)).call(this, props));
54 |
55 | _this.options = {};
56 | return _this;
57 | }
58 |
59 | _createClass(MapMarker, [{
60 | key: 'componentDidUpdate',
61 | value: function componentDidUpdate(prevProps) {
62 | var _this2 = this;
63 |
64 | var _props = this.props,
65 | lat = _props.lat,
66 | lon = _props.lon,
67 | children = _props.children,
68 | properties = _props.properties,
69 | options = _props.options,
70 | balloonState = _props.balloonState;
71 |
72 |
73 | if (lat !== prevProps.lat || lon !== prevProps.lon) {
74 | this._controller.setPosition(this.context.coordorder === 'longlat' ? [lon, lat] : [lat, lon]);
75 | }
76 |
77 | Object.keys(properties || {}).forEach(function (propName) {
78 | if (!prevProps.properties || properties[propName] !== prevProps.properties[propName]) {
79 | _this2._controller.setProperty(propName, properties[propName]);
80 | }
81 | });
82 |
83 | Object.keys(options || {}).forEach(function (optName) {
84 | if (!prevProps.options || options[optName] !== prevProps.options[optName]) {
85 | _this2._controller.setOption(optName, options[optName]);
86 | }
87 | });
88 |
89 | this._controller.setBalloonState(balloonState);
90 |
91 | if (children != prevProps.children) {
92 | this._clearLayouts();
93 | this._setupLayouts();
94 | }
95 | }
96 | }, {
97 | key: 'componentDidMount',
98 | value: function componentDidMount() {
99 | var _props2 = this.props,
100 | lat = _props2.lat,
101 | lon = _props2.lon,
102 | properties = _props2.properties,
103 | options = _props2.options,
104 | balloonState = _props2.balloonState;
105 |
106 | var coords = this.context.coordorder === 'longlat' ? [lon, lat] : [lat, lon];
107 |
108 | this._controller = new _MarkerController2.default(coords, properties, options, balloonState);
109 |
110 | this._setupLayouts();
111 | this._setupEvents();
112 |
113 | this.context.mapController.appendMarker(this._controller);
114 | }
115 | }, {
116 | key: 'componentWillUnmount',
117 | value: function componentWillUnmount() {
118 | this._clearLayouts();
119 | this._controller.destroy();
120 | }
121 | }, {
122 | key: 'getController',
123 | value: function getController() {
124 | return this._controller ? this._controller : null;
125 | }
126 | }, {
127 | key: '_setupLayouts',
128 | value: function _setupLayouts() {
129 | var _this3 = this;
130 |
131 | _react2.default.Children.toArray(this.props.children).forEach(function (component) {
132 | if (component.type === _BalloonLayout2.default) {
133 | _this3._setupBalloonLayout(component);
134 | }
135 | if (component.type === _MarkerLayout2.default) {
136 | _this3._setupMarkerLayout(component);
137 | }
138 | });
139 | }
140 | }, {
141 | key: '_setupMarkerLayout',
142 | value: function _setupMarkerLayout(component) {
143 | this._markerElement = document.createElement('div');
144 | this._markerElement.className = 'icon-content';
145 | this._markerElement.style.display = 'inline-block';
146 |
147 | _reactDom2.default.render(component, this._markerElement);
148 | this._controller.setLayout('iconLayout', this._markerElement);
149 | }
150 | }, {
151 | key: '_setupBalloonLayout',
152 | value: function _setupBalloonLayout(component) {
153 | this._balloonElement = document.createElement('div');
154 |
155 | _reactDom2.default.render(component, this._balloonElement);
156 | this._controller.setLayout('balloonLayout', this._balloonElement);
157 | }
158 | }, {
159 | key: '_clearLayouts',
160 | value: function _clearLayouts() {
161 | if (this._markerElement) {
162 | _reactDom2.default.unmountComponentAtNode(this._markerElement);
163 | this._markerElement = null;
164 | }
165 |
166 | if (this._balloonElement) {
167 | _reactDom2.default.unmountComponentAtNode(this._balloonElement);
168 | this._balloonElement = null;
169 | }
170 | }
171 | }, {
172 | key: 'render',
173 | value: function render() {
174 | return null;
175 | }
176 | }]);
177 |
178 | return MapMarker;
179 | }(_react.Component);
180 |
181 | MapMarker.propTypes = {
182 | lat: _propTypes2.default.number.isRequired,
183 | lon: _propTypes2.default.number.isRequired,
184 | properties: _propTypes2.default.object,
185 | options: _propTypes2.default.object,
186 | balloonState: _propTypes2.default.oneOf(['opened', 'closed'])
187 | };
188 | MapMarker.defaultProps = {
189 | balloonState: 'closed'
190 | };
191 | MapMarker.contextTypes = {
192 | mapController: _propTypes2.default.object,
193 | coordorder: _propTypes2.default.oneOf(['latlong', 'longlat'])
194 | };
195 | exports.default = (0, _decorators.eventsDecorator)(MapMarker, { supportEvents: _geoObject2.default });
--------------------------------------------------------------------------------
/lib/MapContainer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8 |
9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10 |
11 | var _propTypes = require('prop-types');
12 |
13 | var _propTypes2 = _interopRequireDefault(_propTypes);
14 |
15 | var _react = require('react');
16 |
17 | var _react2 = _interopRequireDefault(_react);
18 |
19 | var _reactDom = require('react-dom');
20 |
21 | var _reactDom2 = _interopRequireDefault(_reactDom);
22 |
23 | var _MapElement = require('./MapElement');
24 |
25 | var _MapElement2 = _interopRequireDefault(_MapElement);
26 |
27 | var _MapController = require('./controllers/MapController');
28 |
29 | var _MapController2 = _interopRequireDefault(_MapController);
30 |
31 | var _map = require('./apiEventsLists/map');
32 |
33 | var _map2 = _interopRequireDefault(_map);
34 |
35 | var _decorators = require('./utils/decorators');
36 |
37 | var _configs = require('./configs');
38 |
39 | var _configs2 = _interopRequireDefault(_configs);
40 |
41 | var _api = require('./api');
42 |
43 | var _api2 = _interopRequireDefault(_api);
44 |
45 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
46 |
47 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
48 |
49 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
50 |
51 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
52 |
53 | var YandexMap = function (_Component) {
54 | _inherits(YandexMap, _Component);
55 |
56 | function YandexMap(props) {
57 | _classCallCheck(this, YandexMap);
58 |
59 | var _this = _possibleConstructorReturn(this, (YandexMap.__proto__ || Object.getPrototypeOf(YandexMap)).call(this, props));
60 |
61 | _this.state = {
62 | isAPILoaded: false
63 | };
64 | return _this;
65 | }
66 |
67 | _createClass(YandexMap, [{
68 | key: 'getChildContext',
69 | value: function getChildContext() {
70 | return {
71 | mapController: this._controller,
72 | coordorder: this.props.loadOptions.coordorder || 'latlong'
73 | };
74 | }
75 | }, {
76 | key: 'getController',
77 | value: function getController() {
78 | return this._controller ? this._controller : null;
79 | }
80 | }, {
81 | key: 'componentWillReceiveProps',
82 | value: function componentWillReceiveProps(nextProps) {
83 | var _this2 = this;
84 |
85 | this._controller && Object.keys(nextProps).forEach(function (key) {
86 | switch (key) {
87 | case 'controls':
88 | _this2._controller.setState(key, nextProps[key]);
89 | break;
90 | case 'center':
91 | if (_this2.props.center[0] !== nextProps.center[0] || _this2.props.center[1] !== nextProps.center[1]) {
92 | _this2._controller.setCenter(nextProps.center);
93 | }
94 |
95 | break;
96 | case 'zoom':
97 | if (_this2.props.zoom !== nextProps.zoom) {
98 | _this2._controller.setZoom(nextProps.zoom);
99 | }
100 |
101 | break;
102 | case 'bounds':
103 | if (_this2.props.bounds !== nextProps.bounds) {
104 | _this2._controller.setBounds(nextProps.bounds);
105 | }
106 |
107 | break;
108 | default:
109 | break;
110 | }
111 | });
112 | }
113 | }, {
114 | key: 'componentDidMount',
115 | value: function componentDidMount() {
116 | if (_api2.default.isAvailible()) {
117 | this._onAPILoad(_api2.default.getAPI());
118 | } else {
119 | _api2.default.load(this.props.loadOptions).then(this._onAPILoad.bind(this)).catch(function (error) {
120 | return console.log('Error occured: %s', error);
121 | });
122 | }
123 | }
124 | }, {
125 | key: 'render',
126 | value: function render() {
127 | return _react2.default.createElement(
128 | 'div',
129 | { style: this._getStyle() },
130 | _react2.default.createElement(_MapElement2.default, { ref: 'mapContainer' }),
131 | Boolean(this.state.isAPILoaded) ? this.props.children : null
132 | );
133 | }
134 | }, {
135 | key: '_getStyle',
136 | value: function _getStyle() {
137 | return _extends({}, this.props.style, {
138 | width: typeof this.props.width == 'string' ? this.props.width : this.props.width + 'px',
139 | height: typeof this.props.height == 'string' ? this.props.height : this.props.height + 'px'
140 | });
141 | }
142 | }, {
143 | key: '_onAPILoad',
144 | value: function _onAPILoad(namespace) {
145 | this.props.onAPIAvailable && this.props.onAPIAvailable(namespace);
146 |
147 | this._controller = new _MapController2.default();
148 | this._controller.createMap(_reactDom2.default.findDOMNode(this.refs.mapContainer), _extends({}, this.props.state, {
149 | center: this.props.center,
150 | zoom: this.props.zoom,
151 | bounds: this.props.bounds
152 | }), _extends({}, this.props.options));
153 |
154 | this._setupEvents();
155 | this.setState({ isAPILoaded: true });
156 |
157 | if (this.props.onMapAvailable) {
158 | this.props.onMapAvailable(this._controller.map);
159 | }
160 | }
161 | }]);
162 |
163 | return YandexMap;
164 | }(_react.Component);
165 |
166 | YandexMap.propTypes = {
167 | apiKey: _propTypes2.default.string,
168 | onAPIAvailable: _propTypes2.default.func,
169 | width: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
170 | height: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
171 | zoom: _propTypes2.default.number,
172 | state: _propTypes2.default.object,
173 | options: _propTypes2.default.object,
174 | loadOptions: _propTypes2.default.object,
175 | bounds: _propTypes2.default.array
176 | };
177 | YandexMap.defaultProps = {
178 | zoom: 10,
179 | center: [55, 45],
180 | width: 600,
181 | height: 600,
182 | bounds: undefined,
183 | state: {
184 | controls: []
185 | },
186 | options: {},
187 | loadOptions: {},
188 | style: {
189 | position: 'relative'
190 | }
191 | };
192 | YandexMap.childContextTypes = {
193 | mapController: _propTypes2.default.object,
194 | coordorder: _propTypes2.default.oneOf(['latlong', 'longlat'])
195 | };
196 | exports.default = (0, _decorators.eventsDecorator)(YandexMap, { supportEvents: _map2.default });
--------------------------------------------------------------------------------
/lib/PanoramaContainer.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | Object.defineProperty(exports, "__esModule", {
4 | value: true
5 | });
6 |
7 | var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
8 |
9 | var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
10 |
11 | var _propTypes = require('prop-types');
12 |
13 | var _propTypes2 = _interopRequireDefault(_propTypes);
14 |
15 | var _react = require('react');
16 |
17 | var _react2 = _interopRequireDefault(_react);
18 |
19 | var _reactDom = require('react-dom');
20 |
21 | var _reactDom2 = _interopRequireDefault(_reactDom);
22 |
23 | var _PanoramaElement = require('./PanoramaElement');
24 |
25 | var _PanoramaElement2 = _interopRequireDefault(_PanoramaElement);
26 |
27 | var _PanoramaController = require('./controllers/PanoramaController');
28 |
29 | var _PanoramaController2 = _interopRequireDefault(_PanoramaController);
30 |
31 | var _map = require('./apiEventsLists/map');
32 |
33 | var _map2 = _interopRequireDefault(_map);
34 |
35 | var _decorators = require('./utils/decorators');
36 |
37 | var _api = require('./api');
38 |
39 | var _api2 = _interopRequireDefault(_api);
40 |
41 | function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
42 |
43 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
44 |
45 | function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
46 |
47 | function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
48 |
49 | var YandexPanorama = function (_Component) {
50 | _inherits(YandexPanorama, _Component);
51 |
52 | function YandexPanorama(props) {
53 | _classCallCheck(this, YandexPanorama);
54 |
55 | var _this = _possibleConstructorReturn(this, (YandexPanorama.__proto__ || Object.getPrototypeOf(YandexPanorama)).call(this, props));
56 |
57 | _this.isPanoramas = function (isPanoramas) {
58 | _this.setState({
59 | isPanoramas: isPanoramas
60 | });
61 | };
62 |
63 | _this.state = {
64 | isAPILoaded: false,
65 | showService: false,
66 | isPanoramas: false
67 | };
68 | return _this;
69 | }
70 |
71 | _createClass(YandexPanorama, [{
72 | key: 'getChildContext',
73 | value: function getChildContext() {
74 | return {
75 | mapController: this._controller,
76 | coordorder: this.props.loadOptions.coordorder || 'latlong'
77 | };
78 | }
79 | }, {
80 | key: 'getController',
81 | value: function getController() {
82 | return this._controller ? this._controller : null;
83 | }
84 | }, {
85 | key: 'componentWillReceiveProps',
86 | value: function componentWillReceiveProps(nextProps) {
87 | var _this2 = this;
88 |
89 | this._controller && Object.keys(nextProps).forEach(function (key) {
90 | switch (key) {
91 | case 'showService':
92 | if (_this2.state.showService !== nextProps.showService) {
93 | _this2.setState({
94 | showService: nextProps.showService
95 | }, function () {
96 | return _this2.state.showService && _this2.init();
97 | });
98 | }
99 | break;
100 | default:
101 | break;
102 | }
103 | });
104 | }
105 | }, {
106 | key: 'componentDidMount',
107 | value: function componentDidMount() {
108 | this.init();
109 | }
110 | }, {
111 | key: 'init',
112 | value: function init() {
113 | if (_api2.default.isAvailible()) {
114 | this._onAPILoad(_api2.default.getAPI());
115 | } else {
116 | _api2.default.load(this.props.loadOptions).then(this._onAPILoad.bind(this)).catch(function (error) {
117 | return console.log('Error occured: %s', error);
118 | });
119 | }
120 | }
121 | }, {
122 | key: 'render',
123 | value: function render() {
124 |
125 | var style = {};
126 | if (this.state.showService) {
127 | style = this._getStyle();
128 | }
129 |
130 | return _react2.default.createElement(
131 | 'div',
132 | null,
133 | _react2.default.createElement(
134 | 'div',
135 | { style: style },
136 | _react2.default.createElement(_PanoramaElement2.default, { ref: 'panoramaPlayer', show: this.state.showService })
137 | ),
138 | !this.state.showService && this.state.isPanoramas && this.props.children
139 | );
140 | }
141 | }, {
142 | key: '_getStyle',
143 | value: function _getStyle() {
144 | return _extends({}, this.props.style, {
145 | width: typeof this.props.width == 'string' ? this.props.width : this.props.width + 'px',
146 | height: typeof this.props.height == 'string' ? this.props.height : this.props.height + 'px'
147 | });
148 | }
149 | }, {
150 | key: '_onAPILoad',
151 | value: function _onAPILoad(namespace) {
152 | var _this3 = this;
153 |
154 | this.props.onAPIAvailable && this.props.onAPIAvailable(namespace);
155 |
156 | this._controller = new _PanoramaController2.default(this.isPanoramas);
157 | this._controller.createPanorama(_reactDom2.default.findDOMNode(this.refs.panoramaPlayer), _extends({}, this.props.state, {
158 | center: this.props.center,
159 | zoom: this.props.zoom,
160 | bounds: this.props.bounds
161 | }), _extends({}, this.props.options));
162 |
163 | this.setState({ isAPILoaded: true }, function () {
164 | return _this3._controller.locate(_this3.state.showService);
165 | });
166 | }
167 | }]);
168 |
169 | return YandexPanorama;
170 | }(_react.Component);
171 |
172 | YandexPanorama.propTypes = {
173 | apiKey: _propTypes2.default.string,
174 | onAPIAvailable: _propTypes2.default.func,
175 | width: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
176 | height: _propTypes2.default.oneOfType([_propTypes2.default.string, _propTypes2.default.number]),
177 | zoom: _propTypes2.default.number,
178 | state: _propTypes2.default.object,
179 | options: _propTypes2.default.object,
180 | loadOptions: _propTypes2.default.object,
181 | bounds: _propTypes2.default.array
182 | };
183 | YandexPanorama.defaultProps = {
184 | zoom: 10,
185 | center: [55, 45],
186 | width: 600,
187 | height: 600,
188 | bounds: undefined,
189 | state: {
190 | controls: []
191 | },
192 | options: {},
193 | loadOptions: {},
194 | style: {
195 | position: 'relative'
196 | }
197 | };
198 | YandexPanorama.childContextTypes = {
199 | mapController: _propTypes2.default.object,
200 | coordorder: _propTypes2.default.oneOf(['latlong', 'longlat'])
201 | };
202 | exports.default = (0, _decorators.eventsDecorator)(YandexPanorama, { supportEvents: _map2.default });
--------------------------------------------------------------------------------