c80_map 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +10 -0
- data/.travis.yml +3 -0
- data/CODE_OF_CONDUCT.md +13 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +51 -0
- data/Rakefile +1 -0
- data/app/admin/c80_map/settings.rb +32 -0
- data/app/assets/javascripts/buttons/admin_buttons/button_back_to_map.js +48 -0
- data/app/assets/javascripts/buttons/admin_buttons/button_cancel_create.js +21 -0
- data/app/assets/javascripts/buttons/admin_buttons/button_complete_create.js +22 -0
- data/app/assets/javascripts/buttons/admin_buttons/button_edit.js +80 -0
- data/app/assets/javascripts/buttons/admin_buttons/button_new.js +46 -0
- data/app/assets/javascripts/buttons/admin_buttons/button_save.js +83 -0
- data/app/assets/javascripts/buttons/zoom_buttons.js +61 -0
- data/app/assets/javascripts/c80_map.js.coffee +11 -0
- data/app/assets/javascripts/events/app_event.js +15 -0
- data/app/assets/javascripts/map_objects/area.js +221 -0
- data/app/assets/javascripts/map_objects/building.js +309 -0
- data/app/assets/javascripts/map_objects/dot.js +14 -0
- data/app/assets/javascripts/src/main.js +992 -0
- data/app/assets/javascripts/src/state_controller.js +220 -0
- data/app/assets/javascripts/src/utils.js +127 -0
- data/app/assets/javascripts/svg_elements/helper.js +36 -0
- data/app/assets/javascripts/svg_elements/polygon.js +192 -0
- data/app/assets/javascripts/view/save_preloader.js +30 -0
- data/app/assets/stylesheets/c80_map.scss +2 -0
- data/app/assets/stylesheets/map.scss +1435 -0
- data/app/assets/stylesheets/view/save_preloader.scss +206 -0
- data/app/controllers/c80_map/application_controller.rb +6 -0
- data/app/controllers/c80_map/map_ajax_controller.rb +54 -0
- data/app/helpers/c80_map/application_helper.rb +33 -0
- data/app/models/c80_map/area.rb +5 -0
- data/app/models/c80_map/building.rb +73 -0
- data/app/models/c80_map/setting.rb +30 -0
- data/app/uploaders/c80_map/map_image_uploader.rb +31 -0
- data/app/views/c80_map/_map_row.html.erb +15 -0
- data/app/views/c80_map/_map_row_index.html.erb +39 -0
- data/app/views/c80_map/shared/_save_preloader.html.erb +3 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/c80_map.gemspec +25 -0
- data/config/routes.rb +3 -0
- data/db/migrate/20160617130000_create_c80_map_settings.rb +8 -0
- data/db/migrate/20160620040202_create_c80_map_areas.rb +9 -0
- data/db/migrate/20160620040204_create_c80_map_buildings.rb +8 -0
- data/db/seeds/801_fill_map_settings.rb +6 -0
- data/lib/c80_map/engine.rb +23 -0
- data/lib/c80_map/version.rb +3 -0
- data/lib/c80_map.rb +8 -0
- metadata +136 -0
@@ -0,0 +1,992 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var InitMap = function () {
|
4
|
+
|
5
|
+
// - to delete start -----------------------------------------------------------------------------------------------------------------------
|
6
|
+
var scale = 0.599999;
|
7
|
+
|
8
|
+
var window_height = $(window).height() - 200;
|
9
|
+
if (window_height < 400) window_height = 400;
|
10
|
+
|
11
|
+
var window_width = $(window).width();
|
12
|
+
var image_width = MAP_WIDTH * scale;
|
13
|
+
var image_height = MAP_HEIGHT * scale;
|
14
|
+
|
15
|
+
var x = (window_width - image_width)/2;
|
16
|
+
var y = (window_height - image_height)/2;
|
17
|
+
// - to delete end -----------------------------------------------------------------------------------------------------------------------
|
18
|
+
|
19
|
+
$('#map_wrapper').beMap(
|
20
|
+
{
|
21
|
+
source:LOCS_HASH,
|
22
|
+
scale: scale,
|
23
|
+
x: x,
|
24
|
+
y: y,
|
25
|
+
mapwidth: MAP_WIDTH,
|
26
|
+
mapheight: MAP_HEIGHT,
|
27
|
+
height: window_height
|
28
|
+
}
|
29
|
+
);
|
30
|
+
|
31
|
+
};
|
32
|
+
|
33
|
+
var clog = function () {
|
34
|
+
console.log(arguments[0]);
|
35
|
+
};
|
36
|
+
|
37
|
+
(function () {
|
38
|
+
|
39
|
+
var Map = function () {
|
40
|
+
var self = this;
|
41
|
+
|
42
|
+
self.debug = true;
|
43
|
+
self.o = {
|
44
|
+
source: 'locations.json', // data
|
45
|
+
height: 400, // viewbox height, pixels
|
46
|
+
mapwidth: 100, // actual image size, in pixels
|
47
|
+
mapheight: 100,
|
48
|
+
mapfill: true,
|
49
|
+
zoom: true,
|
50
|
+
zoombuttons: true,
|
51
|
+
maxscale: 1,
|
52
|
+
fitscale: 0.51,
|
53
|
+
skin: '', // css class name
|
54
|
+
scale: 1,
|
55
|
+
x: 0,
|
56
|
+
y: 0
|
57
|
+
};
|
58
|
+
self.svg = null;
|
59
|
+
self.svg_overlay = null;
|
60
|
+
self.container = null;
|
61
|
+
self.mode = 'viewing';
|
62
|
+
self.prev_mode = null;
|
63
|
+
self.setMode = null;
|
64
|
+
self.selected_area = null;
|
65
|
+
self.drawing_poligon = null;
|
66
|
+
self.events = [];
|
67
|
+
self.edit_type = null;
|
68
|
+
self.new_button_klass = null;
|
69
|
+
self.edit_button_klass = null;
|
70
|
+
self.complete_creating_button_klass = null;
|
71
|
+
self.back_to_map_button_klass = null;
|
72
|
+
self.current_building = null;
|
73
|
+
self.current_area = null;
|
74
|
+
self.is_draw = false;
|
75
|
+
self.save_button_klass = null;
|
76
|
+
self.drawn_areas = []; // если имеются нарисованные но несохранённые Площади - они хранятся тут
|
77
|
+
self.drawn_buildings = []; // если имеются нарисованные но несохранённые Здания - они хранятся тут
|
78
|
+
self.save_preloader_klass = null;
|
79
|
+
|
80
|
+
// true, если:
|
81
|
+
//- юзер не кликал по кнопкам zoom
|
82
|
+
//- юзер не делал drag-n-drop
|
83
|
+
//- юзер не в здании и не в площади
|
84
|
+
self.mark_virgin = true;
|
85
|
+
|
86
|
+
self.init = function (el, params) {
|
87
|
+
// extend options
|
88
|
+
self.o = $.extend(self.o, params);
|
89
|
+
|
90
|
+
self.x = self.o.x;
|
91
|
+
self.y = self.o.y;
|
92
|
+
self.scale = self.o.scale;
|
93
|
+
|
94
|
+
self.el = el.addClass('melem mloading').addClass(self.o.skin).height(self.o.height);
|
95
|
+
|
96
|
+
// Disable modules when landmark mode is active
|
97
|
+
/*if (self.o.landmark) {
|
98
|
+
self.o.sidebar = false;
|
99
|
+
self.o.zoombuttons = false;
|
100
|
+
self.o.deeplinking = false;
|
101
|
+
}*/
|
102
|
+
|
103
|
+
if (typeof self.o.source === 'string') {
|
104
|
+
// Loading .json file with AJAX
|
105
|
+
$.getJSON(self.o.source, function (data) { // Success
|
106
|
+
initProcessData(data);
|
107
|
+
self.el.removeClass('mloading');
|
108
|
+
//setTimeout(invalidateZoom,1000);
|
109
|
+
|
110
|
+
}).fail(function () { // Failure: couldn't load JSON file, or it is invalid.
|
111
|
+
console.error('Couldn\'t load map data. (Make sure you are running the script through a server and not just opening the html file with your browser)');
|
112
|
+
self.el.removeClass('mloading').addClass('merror');
|
113
|
+
alert('Data file missing or invalid!');
|
114
|
+
});
|
115
|
+
}
|
116
|
+
else {
|
117
|
+
// Inline json object
|
118
|
+
initProcessData(self.o.source);
|
119
|
+
self.el.removeClass('mloading');
|
120
|
+
}
|
121
|
+
|
122
|
+
|
123
|
+
return self;
|
124
|
+
|
125
|
+
|
126
|
+
};
|
127
|
+
|
128
|
+
var initProcessData = function (data) {
|
129
|
+
|
130
|
+
self.data = data;
|
131
|
+
|
132
|
+
//var nrlevels = 0;
|
133
|
+
//var shownLevel;
|
134
|
+
|
135
|
+
self.container = $('.mcontainer'); //$('<div></div>').addClass('mcontainer').appendTo(self.el);
|
136
|
+
self.map = self.container.find('.mmap'); //$('<div></div>').addClass('mmap').appendTo(self.container);
|
137
|
+
if (self.o.zoom) self.map.addClass('mapplic-zoomable');
|
138
|
+
self.map_layers = self.map.find('.layers');
|
139
|
+
self.map_overlay_layers = self.map.find('.overlay_layers');
|
140
|
+
|
141
|
+
self.svg = $("#svg");
|
142
|
+
self.svg_overlay = $('#svg_overlay');
|
143
|
+
//$('<svg></svg>')
|
144
|
+
//.attr('xmlns','http://www.w3.org/2000/svg')
|
145
|
+
//.attr('version','1.2')
|
146
|
+
//.attr('baseProfile','tiny')
|
147
|
+
//.attr('id','svg')
|
148
|
+
//.appendTo(self.map);
|
149
|
+
|
150
|
+
self.levelselect = $('<select></select>').addClass('mlevels_select');
|
151
|
+
|
152
|
+
self.container.css('width', '100%'); // if (!self.o.sidebar)
|
153
|
+
|
154
|
+
self.contentWidth = parseInt(data.mapwidth);
|
155
|
+
self.contentHeight = parseInt(data.mapheight);
|
156
|
+
|
157
|
+
self.hw_ratio = data.mapheight / data.mapwidth;
|
158
|
+
|
159
|
+
self.map.css({
|
160
|
+
'width': data.mapwidth,
|
161
|
+
'height': data.mapheight
|
162
|
+
});
|
163
|
+
|
164
|
+
// Create new map layer
|
165
|
+
var layer = $('<div></div>').addClass('mlayer').addClass(data["object_type"]).appendTo(self.map_layers); // .hide()
|
166
|
+
$('<img>').attr('src', data["img"]).addClass('mmap-image').appendTo(layer);
|
167
|
+
|
168
|
+
// Zoom buttons
|
169
|
+
if (self.o.zoombuttons) {
|
170
|
+
self.zoombuttons = new ZoomButtons();
|
171
|
+
self.zoombuttons.init({height: self.o.height}, self);
|
172
|
+
//if (!self.o.clearbutton) self.zoombuttons.el.css('bottom', '0');
|
173
|
+
}
|
174
|
+
|
175
|
+
var sc = new StateController();
|
176
|
+
sc.init(self);
|
177
|
+
self.setMode = sc.setMode;
|
178
|
+
|
179
|
+
// Admin buttons
|
180
|
+
$.ajax({
|
181
|
+
url: '/ajax/map_edit_buttons',
|
182
|
+
type: 'POST',
|
183
|
+
dataType: 'script',
|
184
|
+
data: {
|
185
|
+
div_css_selector: '#container_buttons .mzoom_buttons'
|
186
|
+
}
|
187
|
+
}).done(function () {
|
188
|
+
clog('<ajax.done>');
|
189
|
+
|
190
|
+
self.edit_button_klass = new EditButton();
|
191
|
+
self.edit_button_klass.init('.mapplic-edit-button', self);
|
192
|
+
|
193
|
+
var e = new NewButton();
|
194
|
+
e.init('.mapplic-new-button', self);
|
195
|
+
self.new_button_klass = e;
|
196
|
+
|
197
|
+
e = new CancelCreatingButton();
|
198
|
+
e.init("#cancelCreating", self);
|
199
|
+
|
200
|
+
e = new CompleteCreatingButton();
|
201
|
+
e.init("#completeCreating", self);
|
202
|
+
|
203
|
+
self.save_button_klass = new SaveChangesButton();
|
204
|
+
self.save_button_klass.init('.mapplic-save-button', self);
|
205
|
+
|
206
|
+
});
|
207
|
+
|
208
|
+
// Controls
|
209
|
+
initAddControls();
|
210
|
+
|
211
|
+
self.draw_childs(data["childs"]);
|
212
|
+
|
213
|
+
self.ivalidateViewArea();
|
214
|
+
|
215
|
+
// Browser resize
|
216
|
+
$(window).resize(function () {
|
217
|
+
|
218
|
+
// Mobile
|
219
|
+
//if ($(window).width() < 668) {
|
220
|
+
// self.container.height($(window).height() - 66);
|
221
|
+
//}
|
222
|
+
//else self.container.height('100%');
|
223
|
+
|
224
|
+
// Контейнер с картой должен слушать изменения габаритов окна и подгоняться по высоте
|
225
|
+
var window_height = $(window).height() - 200;
|
226
|
+
if (window_height < 400) window_height = 400;
|
227
|
+
self.el.height(window_height + "px");
|
228
|
+
|
229
|
+
// ------------------------------------------------------------------------------------------------------------------------
|
230
|
+
|
231
|
+
// если пользователь еще не взаимодействовал с картой или вне здания\площади
|
232
|
+
// вписываем картинку карты в главный прямоугольник карты
|
233
|
+
// т.е. меняем масштаб
|
234
|
+
if (self.mark_virgin) {
|
235
|
+
// рассчитаем масштаб, при котором можно вписать главный прямоугольник карты в прямоугольник рабочей области
|
236
|
+
var scaleX = self.calcScale(self.o.mapwidth*0.05, self.o.mapwidth *.95, self.X10, self.X20);
|
237
|
+
var scaleY = self.calcScale(self.o.mapheight*0.05, self.o.mapheight *.95, self.Y10, self.Y20);
|
238
|
+
var scale = (scaleX < scaleY) ? scaleX : scaleY;
|
239
|
+
self.scale = scale;
|
240
|
+
}
|
241
|
+
|
242
|
+
// совмещаем точку на экране, в которую надо центрировать карту,
|
243
|
+
// с центром карты (или с центром здания\площади, в котором находится юзер),
|
244
|
+
// с учётом рассчитанного масштаба
|
245
|
+
|
246
|
+
// если пользователь еще не взаимодействовал с картой или вне здания\площади,
|
247
|
+
// то фокусируемся на центр карты,
|
248
|
+
// иначе - фокусируемся на центр здания\площади, в котором находится пользователь и
|
249
|
+
// фокус сдвигаем, с учётом того, что сбоку открыта панель с информацией о здании
|
250
|
+
|
251
|
+
// NOTE-25::хардкод
|
252
|
+
// логические координаты - геометрический центр картинки
|
253
|
+
var cx = self.o.mapwidth/2;
|
254
|
+
var cy = self.o.mapheight/2;
|
255
|
+
var mark_do_moving = false;
|
256
|
+
|
257
|
+
if (self.current_building) {
|
258
|
+
cx = self.current_building.cx();
|
259
|
+
cy = self.current_building.cy();
|
260
|
+
mark_do_moving = true;
|
261
|
+
} else if (self.current_area) {
|
262
|
+
cx = self.current_area.cx();
|
263
|
+
cy = self.current_area.cy();
|
264
|
+
mark_do_moving = true;
|
265
|
+
} else if (self.mark_virgin) {
|
266
|
+
mark_do_moving = true;
|
267
|
+
}
|
268
|
+
|
269
|
+
if (mark_do_moving) {
|
270
|
+
self.x = self.normalizeX(self.CX - self.scale * cx - self.container.offset().left);
|
271
|
+
self.y = self.normalizeY(self.CY - self.scale * cy - self.container.offset().top);
|
272
|
+
clog("<Map.initProcessData> call moveTo");
|
273
|
+
self.moveTo(self.x, self.y, self.scale, 100);
|
274
|
+
}
|
275
|
+
|
276
|
+
// ------------------------------------------------------------------------------------------------------------------------
|
277
|
+
|
278
|
+
|
279
|
+
self.ivalidateViewArea();
|
280
|
+
|
281
|
+
}).resize();
|
282
|
+
|
283
|
+
};
|
284
|
+
|
285
|
+
var initAddControls = function () {
|
286
|
+
var map = self.map,
|
287
|
+
mapbody = $('.mmap-image', self.map);
|
288
|
+
|
289
|
+
document.ondragstart = function () {
|
290
|
+
return false;
|
291
|
+
}; // IE drag fix
|
292
|
+
|
293
|
+
function onSvgMousedown(e) {
|
294
|
+
clog("<onSvgMousedown> self.mode = " + self.mode);
|
295
|
+
|
296
|
+
if (self.mode === 'editing' || self.mode === "edit_building" || self.mode === 'edit_area') {
|
297
|
+
if (e.target.parentNode.tagName === 'g') {
|
298
|
+
clog("<onSvgMousedown> e = ");
|
299
|
+
//clog(e.pageX);
|
300
|
+
//clog("<mouseDown> e.target.parentNode.tagName = " + e.target.parentNode.tagName);
|
301
|
+
//clog(e.target);
|
302
|
+
//info.unload();
|
303
|
+
|
304
|
+
// запомним ссылку на "выбранную" область
|
305
|
+
self.selected_area = e.target.parentNode.obj;
|
306
|
+
|
307
|
+
//app.deselectAll();
|
308
|
+
|
309
|
+
// поменяем внешний вид - добавим класс .selected
|
310
|
+
self.selected_area.select();
|
311
|
+
|
312
|
+
// запомним начальные координаты кликаы
|
313
|
+
self.selected_area.delta = {
|
314
|
+
'x': e.pageX,
|
315
|
+
'y': e.pageY
|
316
|
+
};
|
317
|
+
|
318
|
+
// если взаимодействуем с вершиной
|
319
|
+
if (utils.hasClass(e.target, 'helper')) {
|
320
|
+
var helper = e.target;
|
321
|
+
//clog("<mouseDown> helper.action = ");
|
322
|
+
//clog(helper.action);
|
323
|
+
self.edit_type = helper.action; // pointMove
|
324
|
+
|
325
|
+
if (helper.n >= 0) { // if typeof selected_area == polygon
|
326
|
+
self.selected_area.selected_point = helper.n;
|
327
|
+
}
|
328
|
+
|
329
|
+
self.addEvent(self.el[0], 'mousemove', self.onEdit)
|
330
|
+
//self.addEvent(self.el[0], 'mousemove', self.selected_area.onEdit)
|
331
|
+
.addEvent(self.el[0], 'mouseup', self.onEditStop);
|
332
|
+
}
|
333
|
+
|
334
|
+
else if (e.target.tagName === 'rect' || e.target.tagName === 'circle' || e.target.tagName === 'polygon') {
|
335
|
+
self.edit_type = 'move';
|
336
|
+
self.addEvent(self.el[0], 'mousemove', self.onEdit)
|
337
|
+
.addEvent(self.el[0], 'mouseup', self.onEditStop);
|
338
|
+
}
|
339
|
+
} else {
|
340
|
+
//app.deselectAll();
|
341
|
+
//info.unload();
|
342
|
+
}
|
343
|
+
}
|
344
|
+
}
|
345
|
+
|
346
|
+
self.svg.on('mousedown', onSvgMousedown);
|
347
|
+
//self.el[0].addEventListener('mousedown', onSvgMousedown, false);
|
348
|
+
|
349
|
+
|
350
|
+
// Drag & drop
|
351
|
+
function onDragNdrop(event) {
|
352
|
+
//clog("<mousedown> edit_type = " + self.edit_type);
|
353
|
+
clog("<mousedown> mode = " + self.mode);
|
354
|
+
//clog(event);
|
355
|
+
|
356
|
+
// если в данный момент не редактируем фигуру (т.е. не двигаем вершину фигуры)
|
357
|
+
if (self.edit_type == null) {
|
358
|
+
self.dragging = false;
|
359
|
+
map.stop();
|
360
|
+
|
361
|
+
map.data('mouseX', event.pageX);
|
362
|
+
map.data('mouseY', event.pageY);
|
363
|
+
map.data('lastX', self.x);
|
364
|
+
map.data('lastY', self.y);
|
365
|
+
map.data('startX', self.x);
|
366
|
+
map.data('startY', self.y);
|
367
|
+
|
368
|
+
map.addClass('mdragging');
|
369
|
+
|
370
|
+
self.map.on('mousemove', function (event) {
|
371
|
+
self.dragging = true;
|
372
|
+
|
373
|
+
var x = event.pageX - map.data('mouseX') + self.x;
|
374
|
+
var y = event.pageY - map.data('mouseY') + self.y;
|
375
|
+
|
376
|
+
x = self.normalizeX(x);
|
377
|
+
y = self.normalizeY(y);
|
378
|
+
|
379
|
+
clog("<Map.mousemove> x = " + x + "; y = " + y);
|
380
|
+
clog("<Map.mousemove> Call moveTo.");
|
381
|
+
self.moveTo(x, y);
|
382
|
+
map.data('lastX', x);
|
383
|
+
map.data('lastY', y);
|
384
|
+
});
|
385
|
+
|
386
|
+
$(document).on('mouseup', function (event) {
|
387
|
+
//clog("<mouseup> dragging = " + self.dragging + ", mode = " + self.mode + "; is_draw = " + self.is_draw + "; scale = " + self.scale);
|
388
|
+
//clog("<mouseup> event = ");
|
389
|
+
//clog(event);
|
390
|
+
//clog("<mouseup> event.target = ");
|
391
|
+
//clog($(event.target).parent()[0].obj);
|
392
|
+
|
393
|
+
//clog("<mouseup> [qq] screen: " + event.pageX + ", " + event.pageY +
|
394
|
+
//"; logic: " + self.rightX(event.pageX) + ", " + self.rightY(event.pageY));
|
395
|
+
|
396
|
+
clog("<mouseup> self.mode = " + self.mode);
|
397
|
+
|
398
|
+
// исключаем случайный dnd дрожащей рукой
|
399
|
+
var dx = map.data('startX') - map.data('lastX');
|
400
|
+
var dy = map.data('startY') - map.data('lastY');
|
401
|
+
var delta = Math.sqrt(dx*dx + dy*dy);
|
402
|
+
var is_real_dragging = delta > 10;
|
403
|
+
|
404
|
+
// если это в самом деле был drag\n\drop
|
405
|
+
if (self.dragging && is_real_dragging) {
|
406
|
+
|
407
|
+
self.x = map.data('lastX');
|
408
|
+
self.y = map.data('lastY');
|
409
|
+
}
|
410
|
+
|
411
|
+
// иначе - пытаемся выяснить, в каком режиме находимся
|
412
|
+
else {
|
413
|
+
|
414
|
+
var p;
|
415
|
+
|
416
|
+
/* если находимся в режиме просмотра всей карты - входим в здание */
|
417
|
+
if (self.mode == 'viewing') {
|
418
|
+
//clog($(event.target).parent()[0].obj.building);
|
419
|
+
|
420
|
+
// добираемся до объекта класса Здание, который обслуживает полигон
|
421
|
+
p = $(event.target).parent()[0];
|
422
|
+
if (p.obj && p.obj.building) {
|
423
|
+
var building = p.obj.building;
|
424
|
+
clog("<mouseup> Входим в здание.");
|
425
|
+
building.enter();
|
426
|
+
}
|
427
|
+
|
428
|
+
}
|
429
|
+
|
430
|
+
/* если находимся в режиме рисования - рисуем */
|
431
|
+
else if (self.mode == 'creating') {
|
432
|
+
|
433
|
+
// и если ещё пока не начали рисовать (т.е. если это первый клик)
|
434
|
+
if (!self.is_draw) {
|
435
|
+
|
436
|
+
var xx = self.rightX(event.pageX);
|
437
|
+
var yy = self.rightY(event.pageY);
|
438
|
+
//clog("<mouseup> " + xx + "; " + yy);
|
439
|
+
|
440
|
+
self.drawing_poligon = new Polygon(xx, yy, false, self);
|
441
|
+
|
442
|
+
//self.addEvent(self.el[0], 'mousemove', self.drawing_poligon.onDraw)
|
443
|
+
self.addEvent(self.el[0], 'mousemove', function (e) {
|
444
|
+
var _n_f = self.drawing_poligon;
|
445
|
+
var right_angle = !!e.shiftKey; //e.shiftKey ? true : false;
|
446
|
+
|
447
|
+
_n_f.dynamicDraw(self.rightX(e.pageX), self.rightY(e.pageY), right_angle);
|
448
|
+
})
|
449
|
+
//.addEvent(self.drawing_poligon.helpers[0].helper, 'click', self.drawing_poligon.onDrawStop)
|
450
|
+
//.addEvent(self.el[0], 'click', self.drawing_poligon.onDrawAddPoint);
|
451
|
+
.addEvent(self.el[0], 'click', function (e) {
|
452
|
+
|
453
|
+
// если кликнули в первую точку фигуры - заканчиваем рисование
|
454
|
+
var $et = $(e.target);
|
455
|
+
var $h = $(self.drawing_poligon.helpers[0].helper);
|
456
|
+
if ($et.attr('x') == $h.attr('x') && $et.attr('y') == $h.attr('y')) {
|
457
|
+
//self.drawing_poligon.onDrawStop();
|
458
|
+
self.onDrawStop();
|
459
|
+
return;
|
460
|
+
}
|
461
|
+
|
462
|
+
var x = self.rightX(e.pageX),
|
463
|
+
y = self.rightY(e.pageY),
|
464
|
+
_n_f = self.drawing_poligon;
|
465
|
+
|
466
|
+
if (e.shiftKey) {
|
467
|
+
var right_coords = _n_f.right_angle(x, y);
|
468
|
+
x = right_coords.x;
|
469
|
+
y = right_coords.y;
|
470
|
+
}
|
471
|
+
_n_f.addPoint(x, y);
|
472
|
+
})
|
473
|
+
.addEvent(document, 'keydown', self.onDrawStop);
|
474
|
+
}
|
475
|
+
}
|
476
|
+
|
477
|
+
/* если находимся в режиме просмотра здания - входим в площадь*/
|
478
|
+
else if (self.mode == 'view_building') {
|
479
|
+
|
480
|
+
// добираемся до объекта класса Area, который обслуживает полигон
|
481
|
+
p = $(event.target).parent()[0];
|
482
|
+
//clog($(event.target).parent()[0].obj.area_hash);
|
483
|
+
|
484
|
+
if (p.obj && p.obj.area) {
|
485
|
+
var area = p.obj.area;
|
486
|
+
clog("<mouseup> Входим в площадь.");
|
487
|
+
area.enter();
|
488
|
+
}
|
489
|
+
|
490
|
+
}
|
491
|
+
}
|
492
|
+
|
493
|
+
self.map.off('mousemove');
|
494
|
+
$(document).off('mouseup');
|
495
|
+
|
496
|
+
map.removeClass('mdragging');
|
497
|
+
});
|
498
|
+
}
|
499
|
+
}
|
500
|
+
|
501
|
+
self.svg.on('mousedown', onDragNdrop);
|
502
|
+
self.svg_overlay.on('mousedown', onDragNdrop);
|
503
|
+
|
504
|
+
self.el[0].addEventListener('mousemove', function (e) {
|
505
|
+
//coords_info.innerHTML = 'x: ' + rightX(e.pageX) + ', ' + 'y: ' + rightY(e.pageY);
|
506
|
+
}, false);
|
507
|
+
|
508
|
+
self.el[0].addEventListener('mouseleave', function () {
|
509
|
+
//coords_info.innerHTML = '';
|
510
|
+
}, false);
|
511
|
+
|
512
|
+
/* Disable selection */
|
513
|
+
//self.el[0].addEventListener('mousedown', function(e) { e.preventDefault(); }, false);
|
514
|
+
|
515
|
+
/* Disable image dragging */
|
516
|
+
self.el[0].addEventListener('dragstart', function (e) {
|
517
|
+
e.preventDefault();
|
518
|
+
}, false);
|
519
|
+
|
520
|
+
self.back_to_map_button_klass = new BackToMapButton();
|
521
|
+
self.back_to_map_button_klass.init("#container_buttons", self);
|
522
|
+
|
523
|
+
self.save_preloader_klass = new SavePreloader();
|
524
|
+
self.save_preloader_klass.init();
|
525
|
+
|
526
|
+
};
|
527
|
+
|
528
|
+
// какой должен быть минимальный масштаб, чтобы вписать отрезок [min,max] в отрезок [p1,p2]
|
529
|
+
self.calcScale = function (min, max, p1, p2) {
|
530
|
+
clog("<calcScale> [" + min + "," + max + '] to [' + p1 + "," + p2 + "]");
|
531
|
+
return (p2 - p1) / (max - min);
|
532
|
+
};
|
533
|
+
|
534
|
+
self.calcCoord = function (scale, pageC, logicC) {
|
535
|
+
return pageC - scale * logicC;
|
536
|
+
};
|
537
|
+
|
538
|
+
/* --- ivalidateViewArea BEGIN --------------------------------------------------------------------------------- */
|
539
|
+
|
540
|
+
var _$m = $("#map_wrapper");
|
541
|
+
var _$b = $('footer .container');
|
542
|
+
var $building_info = $('.building_info');
|
543
|
+
var $area_order_button = $('.area_order_button');
|
544
|
+
var $container_buttons = $('#container_buttons');
|
545
|
+
var _is_debug_drawn = false;
|
546
|
+
|
547
|
+
self.ivalidateViewArea = function () {
|
548
|
+
//clog('<init> _$b.offset().left = ' + _$b.offset().left);
|
549
|
+
|
550
|
+
// рассчитаем "константы" - прямоугольник, в который надо вписывать картинки зданий при входе в них
|
551
|
+
self.X1 = _$b.offset().left + 100;
|
552
|
+
self.X1S = _$b.offset().left + 200;
|
553
|
+
self.Y1 = 73;
|
554
|
+
self.Y1S = 140;
|
555
|
+
self.X2 = self.X1 + _$b.width() * .5;
|
556
|
+
self.X2S = self.X1 + _$b.width() * .4;
|
557
|
+
self.X3 = self.X1 + _$b.width() - 100;
|
558
|
+
self.Y2 = _$m.height() - 20;
|
559
|
+
self.Y2S = _$m.height() - 80;
|
560
|
+
self.CX = (self.X2 - self.X1) / 2 - 2 + self.X1;
|
561
|
+
self.CY = (self.Y2 - self.Y1) / 2 - 2 + self.Y1;
|
562
|
+
|
563
|
+
self.X10 = _$b.offset().left + 15;
|
564
|
+
self.X20 = self.X10 + _$b.width();
|
565
|
+
self.Y10 = 73;
|
566
|
+
self.Y20 = _$m.height();
|
567
|
+
|
568
|
+
// позиционируем элементы
|
569
|
+
$building_info.css("left", self.X2 + "px");
|
570
|
+
$area_order_button.css("left", self.X2 + "px");
|
571
|
+
if (self.container) $container_buttons.css("margin-top", (self.container.height() -10) + "px");
|
572
|
+
|
573
|
+
// DEBUG
|
574
|
+
if (self.debug) {
|
575
|
+
|
576
|
+
if (!_is_debug_drawn) {
|
577
|
+
_is_debug_drawn = true;
|
578
|
+
|
579
|
+
var style = "display:block;position:absolute;background-color:#00ff00;opacity:0.4;";
|
580
|
+
var style_x = style + "width:1px;height:800px;top:0;left:{X}px;";
|
581
|
+
var style_y = style + "width:3000px;height:1px;left:0;top:{Y}px;";
|
582
|
+
var style_dot = style + 'width:4px;height:4px;left:{X}px;top:{Y}px;';
|
583
|
+
|
584
|
+
var to_draw = [
|
585
|
+
{x: self.X10},
|
586
|
+
{x: self.X20},
|
587
|
+
{y: self.Y10},
|
588
|
+
{y: self.Y20},
|
589
|
+
{x: self.CX},
|
590
|
+
{y: self.CY},
|
591
|
+
];
|
592
|
+
|
593
|
+
|
594
|
+
var i, istyle, xx, yy, ip;
|
595
|
+
for (i = 0; i < to_draw.length; i++) {
|
596
|
+
ip = to_draw[i];
|
597
|
+
|
598
|
+
if (ip.x != undefined) {
|
599
|
+
istyle = style_x.split("{X}").join(ip.x);
|
600
|
+
} else if (ip.y != undefined) {
|
601
|
+
istyle = style_y.split("{Y}").join(ip.y);
|
602
|
+
}
|
603
|
+
|
604
|
+
_$m.append($("<div style=" + istyle + "></div>"));
|
605
|
+
}
|
606
|
+
|
607
|
+
}
|
608
|
+
|
609
|
+
}
|
610
|
+
|
611
|
+
};
|
612
|
+
|
613
|
+
/* --- ivalidateViewArea END ----------------------------------------------------------------------------------- */
|
614
|
+
|
615
|
+
self.addEvent = function (target, eventType, func) {
|
616
|
+
self.events.push(new AppEvent(target, eventType, func));
|
617
|
+
return self;
|
618
|
+
};
|
619
|
+
|
620
|
+
self.removeAllEvents = function () {
|
621
|
+
utils.foreach(self.events, function (x) {
|
622
|
+
x.remove();
|
623
|
+
});
|
624
|
+
self.events.length = 0;
|
625
|
+
self.edit_type = null;
|
626
|
+
return this;
|
627
|
+
};
|
628
|
+
|
629
|
+
self.addNodeToSvg = function (node, is_overlay) {
|
630
|
+
if (is_overlay) {
|
631
|
+
self.svg_overlay[0].appendChild(node);
|
632
|
+
} else {
|
633
|
+
self.svg[0].appendChild(node);
|
634
|
+
}
|
635
|
+
return self;
|
636
|
+
};
|
637
|
+
|
638
|
+
self.removeNodeFromSvg = function(node, is_overlay) {
|
639
|
+
if (is_overlay) {
|
640
|
+
self.svg_overlay[0].removeChild(node);
|
641
|
+
} else {
|
642
|
+
self.svg[0].removeChild(node);
|
643
|
+
}
|
644
|
+
return this;
|
645
|
+
};
|
646
|
+
|
647
|
+
self.svgRemoveAllNodes = function () {
|
648
|
+
self.svg.empty();
|
649
|
+
};
|
650
|
+
|
651
|
+
self.draw_childs = function (childs, parent_hash) {
|
652
|
+
//clog("<Map.draw_childs>");
|
653
|
+
|
654
|
+
//var ip;
|
655
|
+
var iobj;
|
656
|
+
var ib, id, ia;
|
657
|
+
for (var i = 0; i < childs.length; i++) {
|
658
|
+
iobj = childs[i];
|
659
|
+
|
660
|
+
switch (iobj["object_type"]) {
|
661
|
+
case 'building':
|
662
|
+
ib = new Building();
|
663
|
+
ib.init(iobj,self);
|
664
|
+
break;
|
665
|
+
case 'dot':
|
666
|
+
id = new Dot();
|
667
|
+
id.init(iobj,self);
|
668
|
+
break;
|
669
|
+
case 'area':
|
670
|
+
ia = new Area();
|
671
|
+
ia.init(iobj, parent_hash, self);
|
672
|
+
break;
|
673
|
+
}
|
674
|
+
//ip = Polygon.createFromSaved(iobj);
|
675
|
+
//utils.id('svg').appendChild(ip.g);
|
676
|
+
}
|
677
|
+
};
|
678
|
+
|
679
|
+
//
|
680
|
+
self.draw_child_bg_image = function (img_src, obj_type, is_overlay) {
|
681
|
+
var t;
|
682
|
+
if (is_overlay == true) {
|
683
|
+
t = self.map_overlay_layers;
|
684
|
+
} else {
|
685
|
+
t = self.map_layers;
|
686
|
+
}
|
687
|
+
// Create new map layer
|
688
|
+
var layer = $('<div></div>').addClass('mlayer').addClass(obj_type).appendTo(t); // .hide()
|
689
|
+
$('<img>').attr('src', img_src).addClass('mmap-image').appendTo(layer);
|
690
|
+
|
691
|
+
return layer;
|
692
|
+
};
|
693
|
+
|
694
|
+
self.onEdit = function (e) {
|
695
|
+
|
696
|
+
//clog("<Polygon.prototype.onEdit> _s_f = " + _s_f);
|
697
|
+
//clog("<Polygon.prototype.onEdit> e = ");
|
698
|
+
//clog(_s_f);
|
699
|
+
//clog(e.pageX);
|
700
|
+
|
701
|
+
var selected_area = self.selected_area;
|
702
|
+
var edit_type = self.edit_type;
|
703
|
+
//clog("<Polygon.prototype.onEdit> edit_type = " + edit_type);
|
704
|
+
|
705
|
+
selected_area.dynamicEdit(selected_area[edit_type](e.pageX - selected_area.delta.x, e.pageY - selected_area.delta.y));
|
706
|
+
selected_area.delta.x = e.pageX;
|
707
|
+
selected_area.delta.y = e.pageY;
|
708
|
+
};
|
709
|
+
|
710
|
+
self.onDrawStop = function (e) {
|
711
|
+
clog("<Map.onDrawStop>");
|
712
|
+
|
713
|
+
if (e != undefined) {
|
714
|
+
if (e.type == 'keydown' && e.keyCode == 13) {
|
715
|
+
// its ok, continue execution..
|
716
|
+
} else {
|
717
|
+
return
|
718
|
+
}
|
719
|
+
}
|
720
|
+
|
721
|
+
var _n_f = self.drawing_poligon;
|
722
|
+
if (_n_f.params.length >= 6) { //>= 3 points for polygon
|
723
|
+
_n_f.polyline = _n_f.polygon;
|
724
|
+
_n_f.polygon = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
|
725
|
+
_n_f.g.replaceChild(_n_f.polygon, _n_f.polyline);
|
726
|
+
_n_f.setCoords(_n_f.params).deselect();
|
727
|
+
delete(_n_f.polyline);
|
728
|
+
|
729
|
+
// в зависимости от предыдущего состояния, создадим либо Здание, либо Площадь
|
730
|
+
if (self.prev_mode == "edit_building") {
|
731
|
+
var bo = self.current_building.options;
|
732
|
+
var a = new Area();
|
733
|
+
a.init({ coords:_n_f.params }, bo, self);
|
734
|
+
//a.is_new = true;
|
735
|
+
_n_f.remove(); // удаляем нарисованный полигон, т.к. его уже заменили полигоном Area
|
736
|
+
self.registerJustDrownArea(a);
|
737
|
+
}
|
738
|
+
else if (self.prev_mode == 'editing') {
|
739
|
+
var b = new Building();
|
740
|
+
b.init({ coords:_n_f.params }, self);
|
741
|
+
//b.is_new = true;
|
742
|
+
_n_f.remove(); // удаляем нарисованный полигон, т.к. его уже заменили полигоном Building
|
743
|
+
self.registerJustDrownBuilding(b);
|
744
|
+
}
|
745
|
+
|
746
|
+
self.removeAllEvents();
|
747
|
+
self.drawing_poligon = null;
|
748
|
+
self.is_draw = false;
|
749
|
+
}
|
750
|
+
|
751
|
+
self.setMode('editing');
|
752
|
+
};
|
753
|
+
|
754
|
+
self.onEditStop = function (e) {
|
755
|
+
//clog("<Polygon.prototype.onEditStop>");
|
756
|
+
var _s_f = self.selected_area,
|
757
|
+
edit_type = self.edit_type;
|
758
|
+
|
759
|
+
_s_f.setParams(_s_f.dynamicEdit(_s_f[edit_type](e.pageX - _s_f.delta.x, e.pageY - _s_f.delta.y)));
|
760
|
+
|
761
|
+
self.removeAllEvents();
|
762
|
+
};
|
763
|
+
|
764
|
+
self.registerJustDrownArea = function (area) {
|
765
|
+
self.drawn_areas.push(area);
|
766
|
+
};
|
767
|
+
|
768
|
+
self.registerJustDrownBuilding = function (building) {
|
769
|
+
self.drawn_buildings.push(building);
|
770
|
+
};
|
771
|
+
|
772
|
+
self.normalizeX = function (x) {
|
773
|
+
var minX = self.container.width() - self.contentWidth * self.scale;
|
774
|
+
|
775
|
+
if (minX < 0) {
|
776
|
+
if (x > 0) x = 0;
|
777
|
+
else if (x < minX) x = minX;
|
778
|
+
}
|
779
|
+
else x = minX / 2;
|
780
|
+
|
781
|
+
return x;
|
782
|
+
};
|
783
|
+
|
784
|
+
self.normalizeY = function (y) {
|
785
|
+
var minY = self.container.height() - self.contentHeight * self.scale;
|
786
|
+
|
787
|
+
if (minY < 0) {
|
788
|
+
if (y >= 0) y = 0;
|
789
|
+
else if (y < minY) y = minY;
|
790
|
+
}
|
791
|
+
else y = minY / 2;
|
792
|
+
|
793
|
+
return y;
|
794
|
+
};
|
795
|
+
|
796
|
+
self.normalizeScale = function (scale) {
|
797
|
+
clog('<self.normalizeScale>' + self.o.fitscale);
|
798
|
+
if (scale < self.o.fitscale) scale = self.o.fitscale;
|
799
|
+
else if (scale > self.o.maxscale) scale = self.o.maxscale;
|
800
|
+
|
801
|
+
if (self.zoombuttons) self.zoombuttons.update(scale);
|
802
|
+
|
803
|
+
return scale;
|
804
|
+
};
|
805
|
+
|
806
|
+
self.zoomTo = function (x, y, s, duration, easing, ry) {
|
807
|
+
duration = typeof duration !== 'undefined' ? duration : 400;
|
808
|
+
ry = typeof ry !== 'undefined' ? ry : 0.5;
|
809
|
+
|
810
|
+
self.scale = self.normalizeScale(self.o.fitscale * s);
|
811
|
+
|
812
|
+
self.x = self.normalizeX(self.container.width() * 0.5 - self.scale * self.contentWidth * x);
|
813
|
+
self.y = self.normalizeY(self.container.height() * ry - self.scale * self.contentHeight * y);
|
814
|
+
|
815
|
+
clog("<Map.zoomTo> Call moveTo.");
|
816
|
+
self.moveTo(self.x, self.y, self.scale, duration, easing);
|
817
|
+
};
|
818
|
+
|
819
|
+
// optimisation
|
820
|
+
var __moveToStep = function () {
|
821
|
+
//clog(self.map.attr('style'));
|
822
|
+
// left: -69.9985px; top: -299.999px;
|
823
|
+
// left: [-]{0,1}(\d+\.\d+px);
|
824
|
+
|
825
|
+
var str = self.map.attr('style');
|
826
|
+
var rx_left = /left: [-]{0,1}(\d+\.\d+)px;/;
|
827
|
+
var rx_top = /top: ([-]{0,1}\d+\.\d+)px;/;
|
828
|
+
var match_left = str.match(rx_left);
|
829
|
+
var match_right = str.match(rx_top);
|
830
|
+
|
831
|
+
if (match_left != null && match_right != null) {
|
832
|
+
var x = -1 * Number(match_left[1]); // ["left: -69.9985px;", "69.9985"]
|
833
|
+
var y = -1 * Number(match_right[1]); // ["left: -69.9985px;", "69.9985"]
|
834
|
+
var att = x + " " + y + " " + self.contentWidth + " " + self.contentHeight;
|
835
|
+
//clog(x + "; y = " + y);
|
836
|
+
self.svg.attr('viewBox', att);
|
837
|
+
self.svg_overlay.attr('viewBox', att);
|
838
|
+
}
|
839
|
+
|
840
|
+
};
|
841
|
+
var __moveToTimeout = function () {
|
842
|
+
$("#masked").removeClass('hiddn');
|
843
|
+
};
|
844
|
+
var __moveToAnimate = function () {
|
845
|
+
if (self.tooltip) self.tooltip.position();
|
846
|
+
};
|
847
|
+
|
848
|
+
// x,y - экранные координаты
|
849
|
+
self.moveTo = function (x, y, scale, d, easing) {
|
850
|
+
clog("<self.moveTo> x = " + x + "; y = " + y + "; scale = " + scale);
|
851
|
+
|
852
|
+
// если подан аргумент scale(масштаб)
|
853
|
+
// перемещаемся анимированно
|
854
|
+
if (scale !== undefined) {
|
855
|
+
|
856
|
+
// на время движения скрываем слой с полосатой анимацией
|
857
|
+
if (self.current_area != null) {
|
858
|
+
$("#masked").addClass('hiddn');
|
859
|
+
setTimeout(__moveToTimeout, d);
|
860
|
+
setTimeout(__moveToStep, d);
|
861
|
+
}
|
862
|
+
|
863
|
+
self.map.stop().animate(
|
864
|
+
{
|
865
|
+
'left': x,
|
866
|
+
'top': y,
|
867
|
+
'width': self.contentWidth * scale,
|
868
|
+
'height': self.contentHeight * scale
|
869
|
+
},
|
870
|
+
//{ 'step': __moveToStep },
|
871
|
+
d,
|
872
|
+
easing,
|
873
|
+
__moveToAnimate
|
874
|
+
);
|
875
|
+
|
876
|
+
}
|
877
|
+
|
878
|
+
// если не подан аргумент scale(масштаб)
|
879
|
+
// перемещаемся без анимации
|
880
|
+
else {
|
881
|
+
|
882
|
+
self.map.css({
|
883
|
+
'left': x,
|
884
|
+
'top': y
|
885
|
+
});
|
886
|
+
|
887
|
+
var t = (-x) + " " + (-y) + " " + self.contentWidth * self.scale + " " + self.contentHeight * self.scale;
|
888
|
+
self.svg.attr('viewBox',t);
|
889
|
+
self.svg_overlay.attr('viewBox', t);
|
890
|
+
}
|
891
|
+
|
892
|
+
if (self.current_area != null) {
|
893
|
+
self.current_area.invalidateAnimationMask();
|
894
|
+
}
|
895
|
+
|
896
|
+
//if (self.tooltip) self.tooltip.position();
|
897
|
+
//if (self.minimap) self.minimap.update(x, y);
|
898
|
+
};
|
899
|
+
|
900
|
+
// показать инфо о здании
|
901
|
+
self.showBuildingInfo = function (building_hash) {
|
902
|
+
//"building_hash": {
|
903
|
+
// "id": 2,
|
904
|
+
// "title": "Здание 2",
|
905
|
+
// "props": {
|
906
|
+
// "square": "1234 кв.м.",
|
907
|
+
// "square_free": "124 кв. м",
|
908
|
+
// "floor_height": "124 кв. м",
|
909
|
+
// "column_step": "2 м",
|
910
|
+
// "gate_type": "распашные",
|
911
|
+
// "communications": "Интернет, электричество, водоснабжение",
|
912
|
+
// "price": "от 155 руб/кв.м в месяц"
|
913
|
+
// }
|
914
|
+
|
915
|
+
$building_info.find("h2").text(building_hash["title"]);
|
916
|
+
|
917
|
+
var v;
|
918
|
+
for (var p in building_hash["props"]) {
|
919
|
+
v = building_hash["props"][p];
|
920
|
+
$building_info.find("#" + p).find('span').text(v);
|
921
|
+
}
|
922
|
+
|
923
|
+
$building_info.find("#square_free").css('height', 'auto');
|
924
|
+
|
925
|
+
};
|
926
|
+
|
927
|
+
// показать инфо о просматриваемой площади
|
928
|
+
self.showAreaInfo = function (area_hash, parent_building_hash) {
|
929
|
+
//clog(area_hash);
|
930
|
+
|
931
|
+
//"area_hash": {
|
932
|
+
// "id": 2,
|
933
|
+
// "title": "Площадь 2.12",
|
934
|
+
// "is_free": false,
|
935
|
+
// "props": {
|
936
|
+
// "square": "100 кв.м.",
|
937
|
+
// "floor_height": "6 кв. м",
|
938
|
+
// "column_step": "2 м",
|
939
|
+
// "gate_type": "распашные",
|
940
|
+
// "communications": "Интернет, электричество, водоснабжение",
|
941
|
+
// "price": "от 155 руб/кв.м в месяц"
|
942
|
+
// }
|
943
|
+
|
944
|
+
//"building_hash": {
|
945
|
+
// "id": 2,
|
946
|
+
// "title": "Здание 2",
|
947
|
+
// "props": {
|
948
|
+
// "square": "1234 кв.м.",
|
949
|
+
// "square_free": "124 кв. м",
|
950
|
+
// "floor_height": "6 кв. м",
|
951
|
+
// "column_step": "2 м",
|
952
|
+
// "gate_type": "распашные",
|
953
|
+
// "communications": "Интернет, электричество, водоснабжение",
|
954
|
+
// "price": "от 155 руб/кв.м в месяц"
|
955
|
+
// }
|
956
|
+
|
957
|
+
$building_info.find("h2").html("</span>" + area_hash["title"] + "<span style='color:#D0B2B2;'> / " + parent_building_hash["title"]);
|
958
|
+
|
959
|
+
var v;
|
960
|
+
for (var p in area_hash["props"]) {
|
961
|
+
v = area_hash["props"][p];
|
962
|
+
$building_info.find("#" + p).find('span').text(v);
|
963
|
+
}
|
964
|
+
|
965
|
+
$building_info.find("#square_free").css('height', '0');
|
966
|
+
|
967
|
+
};
|
968
|
+
|
969
|
+
// перевод экранных координат в логические
|
970
|
+
self.rightX = function(x) {
|
971
|
+
return (x - self.x - self.container.offset().left) / self.scale;
|
972
|
+
};
|
973
|
+
|
974
|
+
self.rightY = function(y) {
|
975
|
+
return (y - self.y - self.container.offset().top) / self.scale
|
976
|
+
}
|
977
|
+
|
978
|
+
};
|
979
|
+
|
980
|
+
// Create a jQuery plugin
|
981
|
+
$.fn.beMap = function (params) {
|
982
|
+
var len = this.length;
|
983
|
+
|
984
|
+
return this.each(function (index) {
|
985
|
+
var me = $(this),
|
986
|
+
key = 'beMap' + (len > 1 ? '-' + ++index : ''),
|
987
|
+
instance = (new Map).init(me, params);
|
988
|
+
});
|
989
|
+
};
|
990
|
+
|
991
|
+
})
|
992
|
+
(jQuery);
|