Переход между фигурами с помощью javascript или d3.js

Я пытаюсь написать программу, которая переходит между двумя фигурами, созданными в Adobe Illustrator, с использованием javascript. Я смог добиться этого, экспортировав фигуры в формате SVG, а затем используя Raphael.js:

http://jsfiddle.net/ZLfkZ/4/

Однако интерполяции между двумя фигурами выглядят довольно плохо. Я узнал из исследований в этой теме предпочтительнее интерполировать с помощью алгоритмов, использующих кривые b-сплайна и добавляющих или вычитающих вершины где это уместно, что, как я предполагаю, стандарт SVG, используемый Рафаэлем, не делает. Мне интересно, можно ли это сделать с помощью d3.js, поскольку я заметил, что в документации SVG есть параметры интерполяции, а «основа», похоже, использует b-сплайн. Можно ли выполнить мой jsfiddle в d3 с правильной интерполяцией?

В качестве альтернативы, есть ли лучший способ приблизиться к этому? Возможно, я пошел по неправильному пути, используя SVG, так как результирующий путь все равно будет отображаться на холсте. Первоначально я выбрал SVG, потому что путь было бы легко сохранить в виде строки. Я заметил, что существует плагин Illustrator to canvas, который экспортирует команды холста. Можно ли их интерполировать? Должен ли я как-то захватывать форму из иллюстратора в виде массива точек? Любое понимание будет оценено!


person Saiato    schedule 09.08.2012    source источник


Ответы (2)


Я не знаю отличного готового решения для этого в JavaScript; реализация алгоритмов в документах, на которые вы ссылаетесь, выглядит довольно трудоемкой (хотя и забавной!). В зависимости от конкретных форм, которые вы пытаетесь интерполировать, вам может сойти с рук более простое решение.

Обычно вам нужно передискретизировать либо исходную, либо целевую форму (или обе), чтобы они имели одинаковое количество контрольных точек. После повторной выборки фигур можно использовать стандартную линейную интерполяцию, например d3. интерполировать.

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

Линейная интерполяция имеет тенденцию к самопересечению, но для большинства выпуклых форм она работает достаточно хорошо и быстро.

person mbostock    schedule 09.08.2012
comment
Спасибо за ваш ответ! Я понимаю, что вы говорите, однако я все еще очень новичок в d3, и у меня проблемы с его реализацией. Я смог зайти так далеко на основе вашего примера, но похоже, что я неправильно передискретизирую. Все фигуры SVG, которые я планирую импортировать, будут этими маленькими тварями, поэтому я решил, что функция круга должна работать нормально, если я смогу понять, как передавать координаты из путей SVG... если это то, что я должен делать . - person Saiato; 09.08.2012
comment
Ну, у вас есть изогнутый путь, а не координаты многоугольника, как в моем примере, так что это добавляет некоторую дополнительную сложность. Вы можете использовать getTotalLength элемента пути SVG и getPointAtLength для выборки фигур через равные интервалы и преобразования их в многоугольники (кусочно-линейные сегменты). . - person mbostock; 09.08.2012
comment
В этом есть смысл! Извините за столько проблем, но я все еще новичок в d3. Я попытался преобразовать свой путь в многоугольник, а затем заменить california.json из вашего примера своим JSON. Однако он больше ничего не отображает.var pathone = $("svg path")[0]; var polyone = [[]]; for(var i = 0; i < pathone.getTotalLength(); i++){ var coordinate = [pathone.getPointAtLength(i).x, pathone.getPointAtLength(i).y]; polyone[0].push(coordinate); } var polygonone = {}; polygonone["type"] = "Polygon"; polygonone["coordinates"] = polyone; - person Saiato; 13.08.2012

Существует новое решение этой проблемы с помощью плагина superformular: http://bl.ocks.org/mbostock/1020902< /а>

person atomless    schedule 16.03.2015