Рабочая задача: карта + объекты
Ничего экстраординарного, просто задача по работе попалась.
Дана карта местности (картинка), на неё нанесено большое количество объектов, несколько тысяч. В каждый объект можно тыцнуть мышкой, карта большая, её надо позволять «таскать» мышкой.
Текущее решение тормозит, а надо сделать так, чтобы не тормозило.
У меня была гипотеза, что если нарисовать всё это дело на большущем CANVAS, выходящем за пределы экрана и позволить его таскать мышкой, то тормозит не будет.
В общем-то, похоже, подтвердилось. Я взял CANVAS 2000×2000 точек, накидал на него 4000 квадратов случайного цвета и в случайных координатах, CANVAS положил в DIV, растянутый 100% на 100% и скрыл у него скроллеры.
При клике происходит поиск объекта по списку (безо всякой оптимизации пока), если объект найден, то выводит информацию по цвету, если зажать кнопку мыши, срабатывает флаг «пользователь желает тащить», если пошевелить в этот момент мышью, координаты CANVAS будут меняться вслед за мышью.
Вроде не тормозит, хороший способ делать карты. Делюсь, вдруг пригодится кому.
это то, что я думаю?))
А это правда карта? Насколько я понимаю, если это действительно карта и она очень широкая, то может быть надо смоделировать как освобождающееся место будет заполняться новыми объектами и самой картой, и замерить время, что быстрее: добавлять канвасы или преобразовывать имеющийся?
прости за вопрос, а что это за оператор такой ~~ ?
Комментарий для indeec17:
real to int, видимо (в JS не силён)
http://wdh.suncloud.ru/js04.htm#ref343
Комментарий для happy-ksu.ya.ru:
Ога :)
Комментарий для indeec17:
Правда, но карта ограниченной местности. Она вся тут поместится.
Выше правильно ответили, это действительно приведение к целому. Точнее, это побочный эффект оператора „~“.
Есть маленький побочный эффект. Если тащить карту, за один из цветных прямоугольников, то после отпускания выводится информация об объекте на который тыкнули мышкой. Я считаю, что это неправильное поведение. Если начали тащить карту, то не должно быть вывода информации об объекте. Так, что нужно предусмотреть обработку перетаскивания если курсор попал на объект, а не на чистое поле карты.
Тестировалоь на: UA: Mozilla/5.0 (Windows NT 5.1; rv:2.0) Gecko/20100101 Firefox/4.0
Комментарий для Евгения Степанищева:
Не знаю, чья бага, оперы (11.5) или скрипта, но если отпустить кнопку мыши вне канваса (где-нибудь в хроме браузера), то скрипт не ловит событие, и соответственно продолжает таскаться. Необходимо кликнуть ещё раз.
По поводу карт, разработчики World of Tanks сделали карту на SVG, http://challenge.worldoftanks.ru/uc/clanwars/maps/
Комментарий для mr-simm.livejournal.com:
спасибо
Комментарий для Евгения Степанищева:
Спасибо, буду знать. Замечательно сокращает код. Как-то даже не подумал, что операция not отбрасывает дробную часть. Как-то, когда экспериментировал с C--, там дробная часть имела битовое представление и нормально инвертировалась.
Комментарий для orcinus.ru:
Спасибо! Это у меня проверочный прототип, скорее, чем реальный проект.
Комментарий для kildor.ya.ru:
SVG сильно тормозит, если отображается много объектов (у меня на карте их 4000, это смерть для SVG).
Это не сама технология плохая, просто она пока не «модная», поэтому разработчики браузеров не оптимизируют отображение SVG.
Комментарий для indeec17:
JS не умеет работать побитно с дробной частью. Примеры: 1.5|0, 1.5<<0 и так далее.
на заметку: если взяться за верхний левый квадратик и утащить в правый нижний угол, то обратно достать не удается
Комментарий для openid.yandex.ru/zve55/:
Спасибо! Там есть масса недоделок. Это потому что это прототип.
Комментарий для Евгения Степанищева:
Интересный факт; кажется, пригодится. Но, поскольку до сих пор самому рисовать карту не доводилось, трудновато понять, на именно тут делается акцент.
Правильно ли я думаю, что тормоза в «текущем решении» происходят оттого, что тысячи нанесённых объектов физически являются отдельными дом-объектами (дивы, картинки)? И контейнер с этой тучей маркеров сдвигается с большой мукой? Но если контейнером маркеров сделать canvas, то ему-то сдвигаться становится легче?
Сама карта ни при чём (неважно, огромная картинка или тайлы), она лишь подложка к оверлейному слою.
А фишка именно в отрисовке огромного количества мелких мулек поверх неважно какой карты?
Комментарий для boltai-shaltai:
Точно.
Канвас не контейнер. Это «холст», картинка.
Комментарий для Евгения Степанищева:
Понимаю; но визуально и функционально эффект достигается именно такой.
Спасибо.
http://api.yandex.ru/maps/jsapi/doc/mod/concepts/hotspots.xml :-)
Комментарий для razetdinov.ya.ru:
Я тебе в личку отвечу.
Комментарий для Евгения Степанищева:
На айпаде не работает :(
интересно, почему?
Комментарий для ded-flint.livejournal.com:
Там другие события обрабатывать надо. Там мышки нет.
Комментарий для ded-flint.livejournal.com:
Или квадратики не рисуются?
Комментарий для Евгения Степанищева:
Квадратики рисуются, но перетаскивание не работает. Так же как на сайте яндекс.карты в андроидных браузерах (nook color, viewsonic viewpad 10s)
а можно подробнее про различия в событиях?
Комментарий для ded-flint.livejournal.com:
Вот, например: http://www.sitepen.com/blog/2008/07/10/touching-and-gesturing-on-the-iphone/
Вот тут люди тоже страдают канвасом: https://github.com/kothic/kothic-js
Там же есть обзор, что не работает в каких браузерах.
Комментарий для shurshur.livejournal.com:
Многие «страют канвасом». А где обзор?
При таком решении сделать увеличение карты будет крайне сложно, а перемещение при увеличении еще сложнее :)
Комментарий для Александр:
Почему это? С чего вдруг?
Предполагаю что квадраты-маркеры должны быть привязаны к географическим координатам.
При увеличении прийдется масштабировать весь canvas на 18-19 уровне увеличения из-за размера производительность уже может быть не такой хорошей, но самое неприятное что по-скольку маркеры уже отрисованы на канвасе, то для них нужно будет скомпенсировать масштабирование, чтобы они остались изначального размера. Для простых квадратов это может быть чуть легче, но если будет графика, то это проблема. Также если все-таки сделать масштабирование без потери качества, то может возникнуть необходимость чуть-чуть смещать маркеры чтобы они оставались по-центру, относительно изначальной точки. Т. е. по сути это будет такое же позициоранивание как в обычном подходе, просто без необходимости вычислять координаты на канвасе каждый раз.
А чтобы такое решение работало на мобильных устройствах с поддержкой жестов, нужно очень постараться. Производительность может быть даже ниже.
Комментарий для Евгения Степанищева:
Тут: https://github.com/kothic/kothic-js/wiki/Browser-bugs
Комментарий для Александр:
Откуда столько уровней? Вот текущий вид — это уже максимальное увеличение. Больше в этой задаче не требуется. И вообще, карты не масштабируют до бесконечности, какой в этом смысл?
Кроме того, я всё-таки не понимаю в чём проблема. Сейчас какие-нибудь «Яндекс.Карты» (так же как и карты Гугла) — это куча растра для разных масштабов с нанесёнными объектами. Тут ровно то же. Только объекты на графику наносятся на клиенте.
Комментарий для shurshur.livejournal.com:
Полезная ссылка, спасибо!
Комментарий для Евгения Степанищева:
отличную штуку нашёл, недалеко от темы http://paperjs.org/about/
Комментарий для ded-flint.livejournal.com:
Да их как грибов после дождя повылезало этих фреймворков. Чем именно этот-то хорош?