На прошлой неделе Энди Шора опубликовал отличную статью о анимации фигур и контуров с помощью D3.JS, охватывающую все, от основ D3-интерполяторов до перехода срезов дуги в круговую диаграмму.

Говоря об интерполяции, Энди упоминает, что

Единственное наиболее важное требование для выполнения интерполяции - это то, что структура A должна соответствовать структуре B.

и он продолжает правильно указывать, что мы можем увеличить размер круга, изменив свойство радиуса, или даже кривую пути, интерполируя контрольные точки между двумя значениями. Наконец, он дразнит нас перспективой превратить связку шаров в символ Бэтмена, но, увы, это «почти невозможно, поскольку структуры не совпадают». Вы просто не можете создать разумные промежуточные состояния ». Совершенно верно, но давайте все равно попробуем;)



Хорошо, я признаю, что это своего рода обман, но в каком-то смысле он выполняет свою работу. Что здесь происходит, так это то, что круги, которые вы видите первыми, - это не элементы круга, а просто пути, нарисованные в виде кругов. Очевидно, что логотип Бэтмена - это всего лишь путь, поэтому мы по-прежнему придерживаемся того факта, что структура A должна соответствовать структуре B при интерполяции.

По-настоящему умная часть этого - функция pathTween, которая является одной из моих любимых особенностей Mike Bostock и заслуживает подробного объяснения. К чему я доберусь, но во-первых, нам нужно понять, зачем эта функция вообще нужна. Не могли бы вы просто переместить контур круга прямо на логотип Бэтмена без этой функции? Кажется разумным, оба объекта - просто пути!

Давай посмотрим что происходит



Ух, это довольно омерзительно! Проблема в том, что внутренняя структура двух путей несовместима. Конечно, это оба пути, но в одном из них используется набор команд дуги SVG для рисования круга, а другой, вероятно, был экспортирован из какого-то инструмента дизайна, такого как Adobe Illustrator (отказ от ответственности: я только что поискал в Google «бесплатный SVG с логотипом Бэтмена»)

Итак, мы знаем, что не можем просто перейти с одного пути на другой напрямую, так что именно делает функция pathTween? Это очень похоже на магию в том смысле, что это действительно довольно просто, если вы знаете трюк.

Что он здесь делает, так это выборка обоих путей через равные промежутки времени (определяемые параметром точности) и создание группы интерполяторов между каждым набором точек. Итак, интерполятор от точки A на первом пути до точки A на втором пути и т. Д. Затем он фактически заменяет исходный путь ломаной линией, которая будет выглядеть почти так же, как исходный путь, за исключением того, что это просто очень простой ( потенциально очень длинный) путь, который рисует линии от одной точки выборки к другой.

M p[0].x p[0] L p[1].x p[1].y L ... L p[n].x p[n].y 

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

Достаточно слов, нет лучшего способа визуализировать это, чем… визуализация!



Вот и все. Это небольшая изящная функция, с помощью которой можно плавно преобразовать любой путь в любой другой. Это может быть полезно для преобразования гистограммы в диаграмму с областями, кольцевую диаграмму или любой другой тип диаграммы, который вы можете придумать.

Однако одно предупреждение: вы потенциально можете создать множество функций интерполятора, используя этот метод, что, безусловно, окажет негативное влияние на производительность. Этого можно в некоторой степени избежать, увеличив параметр точности, чтобы на каждом пути бралось меньше выборок, что приводило к созданию и вызову меньшего количества интерполяторов. Возможно, вам придется настроить это, чтобы найти правильный баланс между производительностью и визуальным эффектом. YMMV!