Рабочая задача: карта + объекты

Ничего экстраординарного, просто задача по работе попалась.

Дана карта местности (картинка), на неё нанесено большое количество объектов, несколько тысяч. В каждый объект можно тыцнуть мышкой, карта большая, её надо позволять «таскать» мышкой.

Текущее решение тормозит, а надо сделать так, чтобы не тормозило.

У меня была гипотеза, что если нарисовать всё это дело на большущем CANVAS, выходящем за пределы экрана и позволить его таскать мышкой, то тормозит не будет.

В общем-то, похоже, подтвердилось. Я взял CANVAS 2000×2000 точек, накидал на него 4000 квадратов случайного цвета и в случайных координатах, CANVAS положил в DIV, растянутый 100% на 100% и скрыл у него скроллеры.

Муляж карты (38.97КиБ)

При клике происходит поиск объекта по списку (безо всякой оптимизации пока), если объект найден, то выводит информацию по цвету, если зажать кнопку мыши, срабатывает флаг «пользователь желает тащить», если пошевелить в этот момент мышью, координаты CANVAS будут меняться вслед за мышью.

Вроде не тормозит, хороший способ делать карты. Делюсь, вдруг пригодится кому.
29 июня 2011 00:25

Счастливая Oki-Sun (happy-ksu.ya.ru)
29 июня 2011, 01:33

это то, что я думаю?))

indeec17 (инкогнито)
29 июня 2011, 08:39

А это правда карта? Насколько я понимаю, если это действительно карта и она очень широкая, то может быть надо смоделировать как освобождающееся место будет заполняться новыми объектами и самой картой, и замерить время, что быстрее: добавлять канвасы или преобразовывать имеющийся?

indeec17 (инкогнито)
29 июня 2011, 08:49

прости за вопрос, а что это за оператор такой ~~ ?

SiMM (mr-simm.livejournal.com)
29 июня 2011, 09:59, ответ предназначен indeec17

а что это за оператор такой ~~ ?
real to int, видимо (в JS не силён)
http://wdh.suncloud.ru/js04.htm#ref343

bolk (bolknote.ru)
29 июня 2011, 10:48, ответ предназначен Счастливая Oki-Sun (happy-ksu.ya.ru):

это то, что я думаю?))
Ога :)

bolk (bolknote.ru)
29 июня 2011, 10:50, ответ предназначен indeec17

А это правда карта?
Правда, но карта ограниченной местности. Она вся тут поместится.
прости за вопрос, а что это за оператор такой ~~ ?
Выше правильно ответили, это действительно приведение к целому. Точнее, это побочный эффект оператора „~“.

Orcinus Orca (orcinus.ru)
29 июня 2011, 10:54

Есть маленький побочный эффект. Если тащить карту, за один из цветных прямоугольников, то после отпускания выводится информация об объекте на который тыкнули мышкой. Я считаю, что это неправильное поведение. Если начали тащить карту, то не должно быть вывода информации об объекте. Так, что нужно предусмотреть обработку перетаскивания если курсор попал на объект, а не на чистое поле карты.

Тестировалоь на: UA: Mozilla/5.0 (Windows NT 5.1; rv:2.0) Gecko/20100101 Firefox/4.0

Kildor (kildor.ya.ru)
29 июня 2011, 11:26, ответ предназначен bolk (bolknote.ru):

Не знаю, чья бага, оперы (11.5) или скрипта, но если отпустить кнопку мыши вне канваса (где-нибудь в хроме браузера), то скрипт не ловит событие, и соответственно продолжает таскаться. Необходимо кликнуть ещё раз.

По поводу карт, разработчики World of Tanks сделали карту на SVG, http://challenge.worldoftanks.ru/uc/clanwars/maps/

indeec17 (инкогнито)
29 июня 2011, 11:46, ответ предназначен SiMM (mr-simm.livejournal.com):

спасибо

indeec17 (инкогнито)
29 июня 2011, 11:55, ответ предназначен bolk (bolknote.ru):

Выше правильно ответили, это действительно приведение к целому. Точнее, это побочный эффект оператора „~“.
Спасибо, буду знать. Замечательно сокращает код. Как-то даже не подумал, что операция not отбрасывает дробную часть. Как-то, когда экспериментировал с C--, там дробная часть имела битовое представление и нормально инвертировалась.

bolk (bolknote.ru)
29 июня 2011, 12:17, ответ предназначен Orcinus Orca (orcinus.ru):

Есть маленький побочный эффект. Если тащить карту, за один из цветных прямоугольников, то после отпускания выводится информация об объекте на который тыкнули мышкой.
Спасибо! Это у меня проверочный прототип, скорее, чем реальный проект.

bolk (bolknote.ru)
29 июня 2011, 12:19, ответ предназначен Kildor (kildor.ya.ru):

По поводу карт, разработчики World of Tanks сделали карту на SVG
SVG сильно тормозит, если отображается много объектов (у меня на карте их 4000, это смерть для SVG).

Это не сама технология плохая, просто она пока не «модная», поэтому разработчики браузеров не оптимизируют отображение SVG.

bolk (bolknote.ru)
29 июня 2011, 12:20, ответ предназначен indeec17

Как-то, когда экспериментировал с C--, там дробная часть имела битовое представление и нормально инвертировалась.
JS не умеет работать побитно с дробной частью. Примеры: 1.5|0, 1.5<<0 и так далее.

zve55 (openid.yandex.ru/zve55/)
29 июня 2011, 15:37

на заметку: если взяться за верхний левый квадратик и утащить в правый нижний угол, то обратно достать не удается

bolk (bolknote.ru)
29 июня 2011, 15:49, ответ предназначен zve55 (openid.yandex.ru/zve55/):

Спасибо! Там есть масса недоделок. Это потому что это прототип.

boltai-shaltai (инкогнито)
29 июня 2011, 20:20, ответ предназначен bolk (bolknote.ru):

Интересный факт; кажется, пригодится. Но, поскольку до сих пор самому рисовать карту не доводилось, трудновато понять, на именно тут делается акцент.

Правильно ли я думаю, что тормоза в "текущем решении" происходят оттого, что тысячи нанесённых объектов физически являются отдельными дом-объектами (дивы, картинки)? И контейнер с этой тучей маркеров сдвигается с большой мукой? Но если контейнером маркеров сделать canvas, то ему-то сдвигаться становится легче?

Сама карта ни при чём (неважно, огромная картинка или тайлы), она лишь подложка к оверлейному слою.
А фишка именно в отрисовке огромного количества мелких мулек поверх неважно какой карты?

bolk (bolknote.ru)
29 июня 2011, 22:35, ответ предназначен boltai-shaltai

Правильно ли я думаю, что тормоза в "текущем решении" происходят оттого, что тысячи нанесённых объектов физически являются отдельными дом-объектами (дивы, картинки)? И контейнер с этой тучей маркеров сдвигается с большой мукой?
Точно.
Но если контейнером маркеров сделать canvas, то ему-то сдвигаться становится легче?
Канвас не контейнер. Это «холст», картинка.

boltai-shaltai (инкогнито)
29 июня 2011, 22:46, ответ предназначен bolk (bolknote.ru):

Канвас не контейнер. Это «холст», картинка.
Понимаю; но визуально и функционально эффект достигается именно такой.

Спасибо.

Азат Разетдинов (razetdinov.ya.ru)
30 июня 2011, 07:52

http://api.yandex.ru/maps/jsapi/doc/mod/concepts/hotspots.xml :-)

bolk (bolknote.ru)
30 июня 2011, 11:18, ответ предназначен Азат Разетдинов (razetdinov.ya.ru):

Я тебе в личку отвечу.

ded_flint (ded-flint.livejournal.com)
30 июня 2011, 11:51, ответ предназначен bolk (bolknote.ru):

На айпаде не работает :(
интересно, почему?

bolk (bolknote.ru)
30 июня 2011, 12:00, ответ предназначен ded_flint (ded-flint.livejournal.com):

Там другие события обрабатывать надо. Там мышки нет.

bolk (bolknote.ru)
30 июня 2011, 12:01, ответ предназначен ded_flint (ded-flint.livejournal.com):

Или квадратики не рисуются?

ded_flint (ded-flint.livejournal.com)
30 июня 2011, 12:06, ответ предназначен bolk (bolknote.ru):

Квадратики рисуются, но перетаскивание не работает. Так же как на сайте яндекс.карты в андроидных браузерах (nook color, viewsonic viewpad 10s)
а можно подробнее про различия в событиях?

bolk (bolknote.ru)
30 июня 2011, 15:43, ответ предназначен ded_flint (ded-flint.livejournal.com):

Вот, например: http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/

Shurik (shurshur.livejournal.com)
30 июня 2011, 15:51

Вот тут люди тоже страдают канвасом: https://github.com/kothic/kothic-js
Там же есть обзор, что не работает в каких браузерах.

bolk (bolknote.ru)
30 июня 2011, 16:20, ответ предназначен Shurik (shurshur.livejournal.com):

Многие «страют канвасом». А где обзор?

Александр (инкогнито)
1 июля 2011, 00:54

При таком решении сделать увеличение карты будет крайне сложно, а перемещение при увеличении еще сложнее :)

bolk (bolknote.ru)
1 июля 2011, 00:56, ответ предназначен Александру

Почему это? С чего вдруг?

Александр (инкогнито)
1 июля 2011, 01:44

Предполагаю что квадраты-маркеры должны быть привязаны к географическим координатам.

При увеличении прийдется масштабировать весь canvas на 18-19 уровне увеличения из-за размера производительность уже может быть не такой хорошей, но самое неприятное что по-скольку маркеры уже отрисованы на канвасе, то для них нужно будет скомпенсировать масштабирование, чтобы они остались изначального размера. Для простых квадратов это может быть чуть легче, но если будет графика, то это проблема. Также если все-таки сделать масштабирование без потери качества, то может возникнуть необходимость чуть-чуть смещать маркеры чтобы они оставались по-центру, относительно изначальной точки. Т.е. по сути это будет такое же позициоранивание как в обычном подходе, просто без необходимости вычислять координаты на канвасе каждый раз.

А чтобы такое решение работало на мобильных устройствах с поддержкой жестов, нужно очень постараться. Производительность может быть даже ниже.

Shurik (shurshur.livejournal.com)
1 июля 2011, 12:02, ответ предназначен bolk (bolknote.ru):

Тут: https://github.com/kothic/kothic-js/wiki/Browser-bugs

bolk (bolknote.ru)
1 июля 2011, 12:22, ответ предназначен Александру

Откуда столько уровней? Вот текущий вид — это уже максимальное увеличение. Больше в этой задаче не требуется. И вообще, карты не масштабируют до бесконечности, какой в этом смысл?

Кроме того, я всё-таки не понимаю в чём проблема. Сейчас какие-нибудь «Яндекс.Карты» (так же как и карты Гугла) — это куча растра для разных масштабов с нанесёнными объектами. Тут ровно то же. Только объекты на графику наносятся на клиенте.

bolk (bolknote.ru)
1 июля 2011, 12:23, ответ предназначен Shurik (shurshur.livejournal.com):

Тут: https://github.com/kothic/kothic-js/wiki/Browser-bugs
Полезная ссылка, спасибо!

ded_flint (ded-flint.livejournal.com)
1 июля 2011, 14:51, ответ предназначен bolk (bolknote.ru):

отличную штуку нашёл, недалеко от темы http://paperjs.org/about/

bolk (bolknote.ru)
1 июля 2011, 17:24, ответ предназначен ded_flint (ded-flint.livejournal.com):

Да их как грибов после дождя повылезало этих фреймворков. Чем именно этот-то хорош?

Ваше имя или адрес блога (можно OpenID):

Текст вашего комментария, не HTML:

Кому бы вы хотели ответить (или кликните на его аватару)