Написать функцию, которая соединяет два произвольных элемента на HTML странице. На вход функция получает два текстовых селектора. Ничего конкретного, кроме предположения, что селекторы указывают на два HTML элемента, мы не знаем. Также мы ничего не знаем о том как эти элементы ведут себя в HTML потоке. Под понятием "соединяем" подразумеваем, что между элементами появляется (каким образом — нужно придумать) кривая, которая явно даёт понять что элементы связаны друг с другом. Скрипт нужно реализовать как коробочное решение, с возможностью его вставить в консольку хрома и соединить два произвольных элемента на странице через консоль.
Творческая задача *
Сделать кривую между элементами анимированной, другими словами, каким-то образом показать что между элементами происходит взаимообмен информацией, анимация на усмотрение разработчика.
Важно P.S. Необходимо сделать наиболее универсальное решение, подумать о производительности, о том что могут быть соединены неограниченное количество пар элементов, о том, что анимация не должна препятствовать юзеру во взаимодействии со страничкой, о том что на странице могут появляться новые элементы. Другими словами, юзер активно взаимодействует со страницей, но кривая, соединяющая два произвольных элемента всегда рисуется между ними.
mousewheel
не всегда отзывается на скролл
Возможное решение - подниматься с уровня переданного элемента вверх и на все scrollable
-элементы навешивать onscroll
.
Определить, что элемент - scrollable
можно, проверив его рассчитанное свойство overflow
.
Недостаток решения со scrollable
-элементом - он может стать scrollable
и после инициализации приложения, для чего
придется следить за изменениями атрибутов className
и style
.
- как определять runtime-изменения положения элемента
Для решения этой задачи на window
был навешан обработчик события mousewheel
, который пересчитывает положение линии,
только если target
элемента, на котором mousewheel
произошел содержит в себе один из прикрепляемых элементов.
Этот способ помогает нам отлавливать scroll.
Для отлавливания любых иных манипуляций был использовать MutationObserver
, который навешан на document.body
.
А также на каждый элемент был навешен ResizeObserver
.
- как дорисовывать линии "уголки"
Для дорисовки уголков мы просто продолжаем линию за пределы контейнера, а сам контейнер делаем overflow: hidden
.
- как оптимизировать кол-во отрисовок линии
Для оптимизации мы на каждый чих только рассчитываем возможные точки прикрепления, и если они изменились не более, чем на D, то не перерисовываем линию.
- Плохо работает для слишком маленьких(<50px) и слишком больших(>2000px) элементов.
Пока не решено - скорее всего поможет решение TODO
-
Тесты
-
Более оптимизированный способ отслеживать за изменениями(например, ограничить число прослушиваемых атрибутов для
MutationObserver
) -
Возможно, стоит заменить свои написанные функции расчета матрицы расстояний на d3, например
-
Возможно, решение с абсолютным позиционированием будет оптимизированнее
-
Typescript
Конечно, дергать на каждый чих redraw
- это боль. Но в условиях задачи было заявлено, что нужно учесть ВСЕ кейсы, попытка это сделать была предпринята.
4h