├── car
├── car.css
├── index.html
└── car.js
└── README.md
/car/car.css:
--------------------------------------------------------------------------------
1 | .b-car { width: 54px; height: 54px; margin-left:-27px; margin-top:-27px; }
2 | .b-car.b-car_blue { background: url(http://ymlib.narod.ru/1.1/src/i/cars-blue.png) no-repeat 0 0; }
3 | .b-car.b-car-direction-e {background-position:-324px 0}
4 | .b-car.b-car-direction-ne {background-position:-378px 0}
5 | .b-car.b-car-direction-n {background-position:0 0}
6 | .b-car.b-car-direction-nw {background-position:-54px 0}
7 | .b-car.b-car-direction-w {background-position:-108px 0}
8 | .b-car.b-car-direction-sw {background-position:-162px 0}
9 | .b-car.b-car-direction-s {background-position:-216px 0}
10 | .b-car.b-car-direction-se {background-position:-270px 0}
11 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ymaps
2 | =====
3 |
4 | ymaps related things
5 |
6 | Examples: http://zxqfox.github.io/ymaps/examples/
7 |
8 | Published under MIT License
9 |
10 | Car
11 | ---
12 |
13 | Simple javascript object for animating some route on yandex.maps (http://api.yandex.ru/maps/doc/jsapi/2.x/ref/)
14 |
15 | Examples: http://zxqfox.github.io/ymaps/examples/car/
16 |
17 | ### Simple example usage
18 | ```js
19 | $.getScript('car.js', function () {
20 | car = new Car();
21 | ymaps.route([
22 | 'Москва, метро Смоленская', // from Smolenskaya subway station
23 | [55.740532, 37.625693] // to Tretyakovkaya subway station
24 | ]).then(function (route) {
25 | car.moveTo(route.getWayPoints().getPaths().get(0).getSegments());
26 | });
27 | });
28 | ```
29 |
30 | ### More complex
31 | ```js
32 | $.getScript('car.js', function () {
33 | car = new Car({
34 | // geoObject options
35 | iconLayout: ymaps.templateLayoutFactory.createClass(
36 | '
'
37 | )
38 | });
39 | ymaps.route([
40 | 'Москва, метро Смоленская', // from Smolenskaya subway station
41 | {
42 | type: 'viaPoint', // via Tretyakovskaya gallery
43 | point: 'Россия, Москва, Лаврушинский переулок, 10'
44 | },
45 | [55.740532, 37.625693] // to Tretyakovkaya subway station
46 | ], {
47 | // Router options
48 | mapStateAutoApply: true
49 | }).then(function (route) {
50 | // Setting custom label for routing points
51 | var points = route.getWayPoints();
52 | points.get(0).properties.set("iconContent", "A");
53 | points.get(1).properties.set("iconContent", "B");
54 |
55 | // Add route and car to map
56 | map.geoObjects.add(route);
57 | map.geoObjects.add(car);
58 |
59 | // Send car with specific move speed and directions count
60 | car.moveTo(route.getPaths().get(0).getSegments(), {
61 | speed: 10,
62 | directions: 8
63 | }, function (geoObject, coords, direction) { // тик движения
64 | // перемещаем машинку
65 | geoObject.geometry.setCoordinates(coords);
66 | // ставим машинке правильное направление - в данном случае меняем ей текст
67 | geoObject.properties.set('direction', direction.t);
68 |
69 | }, function (geoObject) { // приехали
70 | geoObject.properties.set('balloonContent', "Приехали!");
71 | geoObject.balloon.open();
72 | });
73 | });
74 | });
75 | ```
76 |
--------------------------------------------------------------------------------
/car/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Пример анимации иконки автомобиля по маршруту
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
82 |
83 |
84 |
85 |
Пример анимации иконки автомобиля по маршруту
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
100 |
101 |
102 |
103 |
104 |
--------------------------------------------------------------------------------
/car/car.js:
--------------------------------------------------------------------------------
1 | /**
2 | * fileOverview Класс анимированной машинки
3 | * @see http://ymlib.narod.ru/1.1/demos/animate.html
4 | * Версия для АПИ 2.0
5 | * @author Alex Yaroshevich
6 | */
7 |
8 | var Car = (function () {
9 | "use strict";
10 |
11 | // делаем заготовку для кол-ва направлений. 4, 8 или 16 (+, x, *)
12 | var directionsVariants = {
13 | classes: {
14 | 16: ['w', 'sww', 'sw', 'ssw', 's', 'sse', 'se', 'see', 'e', 'nee', 'ne', 'nne', 'n', 'nnw', 'nw', 'nww'],
15 | 8: ['w', 'sw', 's', 'se', 'e', 'ne', 'n', 'nw'],
16 | 4: ['w', 's', 'e', 'n']
17 | },
18 | n: function (x,y,n) {
19 | n = n || 8;
20 | var n2 = n>>1; // half of n
21 | var number = (Math.floor(Math.atan2(x,y)/Math.PI*n2+1/n)+n2) % n; // seems like there is a little bug here
22 | return {n: number, t: directionsVariants.classes[n][ number ]};
23 | },
24 | 16: function (x,y) { // -> values in range [0, 16]
25 | return directionsVariants.n(x,y,16);
26 | },
27 | 8: function (x,y) { // -> values in range [0, 8]
28 | return directionsVariants.n(x,y,8);
29 | },
30 | 4: function (x,y) { // -> values in range [0, 4]
31 | return directionsVariants.n(x,y,4);
32 | }
33 | };
34 |
35 | var defaultMovingCallback = function (geoObject, coords, direction) { // действие по умолчанию
36 | // перемещаем машинку
37 | geoObject.geometry.setCoordinates(coords);
38 | // ставим машинке правильное направление - в данном случае меняем ей текст
39 | geoObject.properties.set('iconContent', direction.t);
40 | },
41 | defaultCompleteCallback = function (geoObject) { // действие по умолчанию
42 | // приехали
43 | geoObject.properties.set('iconContent', "Приехали!");
44 | };
45 |
46 | // нормализуем в один массив точек сегметны из ymaps
47 | var makeWayPointsFromSegments = function (segments, options) {
48 | options = options || {};
49 | options.directions = [4, 8, 16].indexOf(options.directions) >= 0 ? options.directions : 8; // must be 4, 8, or 16
50 | options.speed = options.speed || 6;
51 |
52 | var points, street,
53 | wayList = [],
54 | // вспомогательные
55 | i, j, k, l, prev, cur, direction,
56 | getDirection = directionsVariants[options.directions],
57 | coordSystem = options.coordSystem;
58 |
59 | // открываю массив с точками
60 | points = [];
61 | // выполняю операцию для всех сегментов
62 | for (i = 0, l = segments.length; i < l; i++) {
63 | // беру координаты начала и конца сегмента
64 | street = segments[i].getCoordinates();
65 | // и добавляю КАЖДУЮ ИЗ НИХ в массив, чтобы получить полный список точек
66 | for (j = 0, k = street.length; j < k; j++) {
67 | cur = street[j];
68 | // пропускаем дубли
69 | if (prev && prev[0].toPrecision(10) === cur[0].toPrecision(10) && prev[1].toPrecision(10) === cur[1].toPrecision(10)) {
70 | continue;
71 | }
72 | points.push(cur);
73 | prev = cur;
74 | }
75 | }
76 |
77 | // строим путь. берем 1 единицу расстояния, возвращаемого distance, за пройденный путь в единицу времени. в 1 единица времени - будет 1 смещение геоточки. ни разу не оптимальный, но наглядный алгоритм
78 | for (i = 0, l = points.length - 1; l; --l, ++i) {
79 | var from = points[i], to = points[i+1], diff = [to[0]-from[0], to[1]-from[1]];
80 | direction = getDirection(diff[0], diff[1]);
81 | // каждую шестую, а то слишком медленно двигается. чрезмерно большая точность
82 | for (j = 0, k = Math.round(coordSystem.distance(from, to)); j < k; j += options.speed) {
83 | wayList.push({coords: [from[0]+(diff[0]*j/k), from[1]+(diff[1]*j/k)], direction: direction, vector: diff});
84 | }
85 | }
86 |
87 | return wayList;
88 | };
89 |
90 | /**
91 | * Класс машинки.
92 | * TODO: make it a geoObject with right interface.
93 | * @class
94 | * @name Car
95 | * @param {Object} [options] Опции машики.
96 | */
97 | var Car = function (options) {
98 | var properties = {
99 | // Описываем геометрию типа "Точка".
100 | geometry: {
101 | type: "Point",
102 | coordinates: [55.75062, 37.62561]
103 | }
104 | };
105 | options = options || {};
106 | options.preset = options.preset || 'twirl#greenStretchyIcon';
107 | var result = new ymaps.GeoObject(properties, options);
108 | result.coordSystem = options.coordSystem;
109 | result.waypoints = [];
110 |
111 | result.stop = function () {
112 | // чистим старый маршрут
113 | this.waypoints.length = 0;
114 | };
115 | /**
116 | * Метод анимации движения машики по марщруту.
117 | * @function
118 | * @name Car.moveTo
119 | * @param {Array} segments Массив сегментов маршрута.
120 | * @param {Object} [options] Опции анимации.
121 | * @param {Function} movingCallback Функция обратного вызова по-сегментам маршрута.
122 | * @param {Function} completeCallback Функция обратного вызова завершения анимации.
123 | */
124 | result.moveTo = function (segments, options, movingCallback, completeCallback) {
125 | if (!segments) return;
126 | options = options || {};
127 | // ищем систему координат
128 | options.coordSystem = options.coordSystem || this.coordSystem || this.getMap().options.get('projection').getCoordSystem();
129 | // считаем скорость базируясь на текущем зуме: very dirty but works pretty cute
130 | options.speed = options.speed || Math.round(80 / this.getMap().getZoom());
131 | // Получаем точечки
132 | this.waypoints = makeWayPointsFromSegments(segments, options);
133 | // Запуск анимации
134 | var that = this,
135 | timer = setInterval(function () {
136 | // если точек больше нет - значит приехали
137 | if (that.waypoints.length === 0) {
138 | (completeCallback || defaultCompleteCallback)(that);
139 | return clearTimeout(timer);
140 | }
141 | // берем следующую точку
142 | var nextPoint = that.waypoints.shift();
143 | // и отправляем в пользовательский callback
144 | (movingCallback || defaultMovingCallback)(that, nextPoint.coords, nextPoint.direction);
145 | }, 42);
146 | };
147 |
148 | return result;
149 | };
150 |
151 | return Car;
152 | }());
153 |
154 |
--------------------------------------------------------------------------------