#javascript #css #css3 #svg #css_animation
Подскажите, пожалуйста, есть ли возможность добиться эффекта, так называемой растущей
кривой, реализуемый изменением значения stroke-dashoffset с polyline объектом.
Приведу пример
.st1 {
fill: none;
stroke: #000;
stroke-width: 4;
stroke-miterlimit: 10;
}
Желательно средствами CSS
Ответы
Ответ 1
Для любого объекта, имеющего атрибут stroke-dashoffset, можно получить эффект рисования линиями. То есть для всех фигур svg: line, circle, ellipse, polygon, polyline, path. Необходимо только точно вычислить длину этой линии. В вашем случае длина линии -136px Ниже код утилиты для точного вычисления длиныДля вычисления длины другой polylineнеобходимо скопировать значения points #myLine{ fill: none; stroke: #000; stroke-width: 4; stroke-miterlimit: 10; stroke-dasharray:136; stroke-dashoffset:136; animation:dash 5s ease-in forwards; } @keyframes dash { 0% { stroke-dashoffset:136; } 100% { stroke-dashoffset:0; } } Добавлю ещё два варианта: #1. Вариант с заготовкой пути Это серый путь, по которому пойдет анимация рисования линии. Используется та же линия, что и в первом примере, но она неподвижна. (id="shadow") Анимируется ее дубликат -id="#myLine". #myLine{ fill: none; stroke: #000; stroke-width: 4; stroke-miterlimit: 10; stroke-dasharray:136; stroke-dashoffset:136; animation:dash 4s ease-in 1s forwards; } #shadow{ fill: none; stroke: #EAEAEA; stroke-width: 4; stroke-miterlimit: 10; } @keyframes dash { 0% { stroke-dashoffset:136; } 100% { stroke-dashoffset:0; } } #2. Вариант с анимацей тени Для получения тени клонируется первая линия и сдвигается вправо и вниз на несколько пикселейанимация линий выполняется совместно и реализуется точно также, как в самом верхнем, основном примере для одной линии: #myLine{ fill: none; stroke: #000; stroke-width: 4; stroke-miterlimit: 10; stroke-dasharray:136; stroke-dashoffset:136; animation:dash 5s ease-in forwards; } #shadow{ fill: none; stroke: grey; stroke-width: 4; stroke-miterlimit: 10; stroke-dasharray:136; stroke-dashoffset:136; animation:dash 5s ease-in forwards; opacity:0.5; } @keyframes dash { 0% { stroke-dashoffset:136; } 100% { stroke-dashoffset:0; } } Ответ 2
Приведение анимаций CSS и SVG Этот ответ на вопрос, создаю специально для тех, кто владеет приемами анимации CSS, но пока не решается освоить анимацию SVG для расширения своих возможностей. Всё познается в сравнении. Взят пример анимации CSS из первого ответа и я преобразую его в анимацию SMIL SVG В основе эффекта рисования линии в обоих видах анимации (css и svg) лежит один и тот же прием - использование атрибута stroke-dashoffset - отступ от начала линии. Когда максимальный отступ равен длине линии, то она полностью скрыта. Уменьшая stroke-dashoffset от максимального значения, в нашем случае - 136px до нуля, мы тем самым реализуем эффект рисования, появления линии. SVG очень гибко и мощно работает со стилями,- делая анимацию SMIL, вы можете, как привыкли, внести stroke-dasharray,stroke-dashoffset в таблицу стилей или разместить стили прямо непосредственно в команде SVG.Остается понять, как преобразовать анимацию CSS, в smil Для CSS команда уменьшения stroke-dashoffset от 136px до нуля выглядит следующим образом: #myLine{ stroke-dasharray:136; stroke-dashoffset:136; animation:dash 5s ease-in forwards; } @keyframes dash { 0% { stroke-dashoffset:136; } 100% { stroke-dashoffset:0; } } Для SVG smil аналогичная команда записывается так: вот, когда эти два способа (css, svg) рядом, то в принципе и так всё понятно. Добавлю лишь, что параметрforwards css делает тоже самое, что fill="freeze" svg - изображение по окончанию анимации замораживается на экране. Ниже полный пример анимации smil svg Ответ 3
Иногда полезно узнать длину в рантайм, для этого в современных браузерах у polyline есть метод SVGGeometryElement.getTotalLength(), полученное таким образом значение устанавливаем в stroke-dasharray первым аргументом, обозначающим длину штриха. вторым параметром идет размер между штрихами. line.setAttribute('stroke-dasharray', line.getTotalLength() + ' 10000'); Анимация получается за счет встроенной интерполяции при добавлении в css transition: 1s Кросс-браузерный вариант, со времен когда у polyline не было встроенного метода для того чтобы узнать длину. let polyline = document.querySelector("polyline"); let totalLength = [...polyline.points].reduce((acc, i) => { if (acc.prev) acc.len += Math.sqrt(Math.pow((i.x - acc.prev.x), 2) + Math.pow((i.y - acc.prev.y), 2)); acc.prev = i; return acc }, {len: 0}).len; console.log('total length:', totalLength); polyline { fill:none; stroke: red; stroke-width:3; }
Комментариев нет:
Отправить комментарий