Сегодня мы хотели бы поделиться с вами интересным эффектом кнопки прогресса. Эффект доступен на сайте dribbble под названием «Кнопка загрузки» от автора xjw. Кнопка запускается нажатием на значок со стрелкой, и как только она нажата, оживляется забавный маленький провод и метка, указывающая процент загрузки.
В этой статье мы рассмотрим некоторые аспекты того, что необходимо для создания подобной анимации, некоторые методы и проблемы, с которыми можно столкнуться при установке.
Если вы хотите использовать этот эффект загрузки в своем проекте, перейдите на страницу сайта github и следуйте инструкциям.
Технология
В первую очередь, нужно решить, какую технологию браузера мы будем использовать, чтобы сделать и применить на сайте этот эффект.
По большей части, можно было бы сделать эту анимацию с помощью CSS. Проблема состоит в том, что она не обеспечит достаточную гибкость - рисование кривой, например, может быть трудным, или вовсе невозможным. Кроме того, это может выглядеть «по-хакерски», - фигура может быть искажена с помощью применения умных трюков, а в итоге, результат может получиться совсем не тем, на который мы рассчитывали.
Canvas может стать неплохим вариантом. Мы можем нарисовать любую форму, с нормальной производительностью, даже при использовании на мобильных устройствах. Но такой эффект сложно использовать, если вы не используете библиотеку, например paper.js. Более того, это как «черный ящик» глазами браузера, - он просто видит его как изображение, но игнорирует содержимое.
Другим вариантом является использование SVG. У него есть свои недостатки: в настоящее время он недостаточно быстрый, а также производительность меньше заявленной. Кроме того, он устарел и содержит ошибки. Тем не менее, он является достаточно гибким, легко загружается в проект, а браузер рассматривает каждый из его элементов, как объект DOM, что делает его наиболее подходящим вариантом для взаимодействия.
Кроме того, его недостатки могут быть и незначительными: производительность является достаточной, если анимируются небольшие объекты, и многие из них сортируются при помощи GSAP, которая является библиотекой анимации. Это достаточно хорошая анимационная библиотека, предоставляющая инструменты для облегчения работы с SVG в целом. Об этом мы узнаем немного позже.
Планирование SVG
Когда мы создаем SVG для анимации, мы должны заранее продумать, каким будет конечный результат. Мы должны проявлять особую осторожность с такими вещами, как слои названия, высота и прочее. Вот как я организовал слои в этом примере. Я воспользуюсь Adobe Illustrator, но редактор можно использовать любой по вашему выбору.
Важная деталь, которую нужно здесь использовать, помимо названия, - это группировка. Если вы намерены объединить отдельные элементы вместе, их нужно собрать на одном уровне, чтобы избежать одновременной работы одной и той же анимации для разных объектов.
Так как в этой демонстрации мы анимируем вершины индивидуально, мы должны заранее продумать этот вопрос.
Для упругой анимации, нам потребуется линия с гладкой кривой и точкой посередине. Однако мы также хотим, чтобы круглая кнопка трансформировалась в линию, поэтому нам нужна линия, которая вмещает обе формы, с наименьшим количеством возможных вершин, чтобы ее было легко оживить.
Это не совсем идеальный, но подходящий для анимации круг с тремя вершинами, который можно раскрыть, чтобы превратить в нашу гибкую форму.
Мы можем превратить эту свободную кривую в еще более натянутую форму, просто удерживая контрольные точки кривых Безье ближе к вершинам.
Это только один из примеров. Ваши требования будут зависеть от анимации, которую вы хотите сделать. Важно, когда вы делаете графику, подумайте заранее о том, как вы будете оживлять её.
Управление
Во-первых, вам нужно сначала загрузить SVG таким образом, чтобы была возможность управлять им с помощью JS. Вы можете вставить его прямо в HTML, или загрузить его с помощью AJAX или библиотеки, например snap.svg, или с помощью другого приложения.
Анимировать элементы SVG с помощью GSAP довольно просто. После выбора элемента ...
var circle = document.querySelector("#background");
... вы можете просто анимировать свойства, такие как x, y, и масштабировать, что создаст правильное преобразование.
TweenMax.to(circle, 1, {
scale: 0.1
});
Для вещей, которые невозможно преобразовать, используется attr свойство:
TweenMax.to(circle, 1, {
attr: {
"stroke-width": 4
}
});
Для нашей анимации пригодится эластичное смягчение GSAP, которое настраивается его свойством easeParams.
Еще одна очень полезная вещь, которая заключается в том, чтобы сгладить несогласованности браузеров transformOrigin для SVG.
TweenMax.to(circle, 1, {
transformOrigin: "50% 50%",
scale: 0.1
});
Говоря о проблемах с браузером: на данный момент firefox выдает ошибку, если вы пытаетесь анимировать или установить свойство, например transformOrigin скрытого объекта. Обязательно установите для display свойства объекта inline вместо none, чтобы не изменять что-либо еще.
Анимированные вершины
Существует ряд инструментов, которые можно использовать для выбора и анимации отдельных вершин SVG, такие как snap.svg, о которых упоминалось ранее. В этой демонстрации использовано svg-pathdata. Он получает строку пути SVG – от d атрибута к части a, которая содержит информацию о форме пути, и возвращает массив, являющийся отдельными точками. Изменить значения можно по своему усмотрению, проанализировав массив обратно на строке пути SVG и применить его к d атрибуту.
Это выглядит немного запутанным, но на деле это довольно просто. Вот пример:
var line = document.querySelector("#line path");
var d = line.getAttribute("d");
var pathData = new SVGPathData(d).toAbs();
var points = pathData.commands;
var middlePoint = points[1];
TweenTo(middlePoint,1,{
y: 0,
y1: 0,
onUpdate: updatePath,
onComplete: updatePath
});
function updatePath(){
line.setAttribute("d", pathData.encode());
};
Чтобы анимировать несколько вершин одного и того же пути, и избежать обновления пути несколько раз, сохраните onUpdate() функцию на отдельной анимации.
Tween.to(points[0], 1, {
x: -100
});
Tween.to(points[1], 1, {
x: 0
});
Tween.to(points[2], 1, {
x: 100
});
Tween.to(this, 1, {
onUpdate: updatePath
});
...
Взаимодействие
Если вы хотите сделать такую кнопку, вам не нужно использовать весь SVG, включая пустые области, вы хотите, чтобы кнопка была только кнопкой. Решение достаточно простое.
Для SVG вы устанавливаете следующее свойство CSS:
pointer-events: none;
Для элемента SVG, который вы хотите сделать кликабельным, нужно установить:
pointer-events: fill;
Это может быть сделано JS, setAttribute функцией или прямо в самом SVG-файле, или как правило CSS, или атрибут style. Хорошая техника, - удерживать отдельный прозрачный объект поверх всего остального только для использования в качестве области попадания. Таким образом, можно без проблем анимировать объекты под ним.
Доступность
Так как это неправильная кнопка и неправильный индикатор выполнения, она невидима для прошивок и всего остального, что зависит от семантики. Есть несколько вещей, которые мы можем сделать для устранения этого:
- Установите role атрибут кнопки;
- Чтобы сделать его доступным с клавиатуры, установите для tabindex атрибут кнопки значение 0 или больше и добавьте кнопку клавиатуры, которое будет запускаться щелчком с помощью пробела и кнопки возврата;
- Хотя в этой демонстрации кнопка визуально превращается в индикатор выполнения, мы не должны изменять role элемент. Создаем отдельный progressbar элемент, выставляем его из экрана, чтобы сделать его невидимым, и обновляем его вместе с нашей анимацией.
Теперь, когда вы получили некоторое представление о процессе создания такой анимации, посмотрите на весь исходный код и ознакомьтесь с инструкциями по интеграции этой кнопки.
Надеемся, вам понравится эта кнопка прогресса, и она окажется для вас полезной!