Эффект шевелёнки средствами SVG

demosourse

Урок, в котором вы узнаете как можно реализовать эффект шевелёнки с помощью JavaScript и SVG.

Данный эффект довольно-таки часто используется в анимационном дизайне и анимации движения объекта.

В этой статье мы рассмотрим каким образом можно воспроизвести данный эффект при перемещении объектов по вертикали или горизонтали.

Так же просим обратить внимание на тот факт, что данный пример является экспериментальным и работает на ура только в последних версиях браузеров. Лучше всего в Chrome.

Для того чтобы реализовать эффект шевелёнки нам необходимо применить к перемещаемому объекту эффект размытости в зависимости от скорости и направления движения.

Давайте взглянем на шаги, которые нам нужно предпринять для достижения нужного результата:

Настройка эффекта

Для размытия элемента воспользуемся SVG фильтрами. В нашем случае понадобится фильтр под названием feGaussianBlur.

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" class="filters">
	<defs>
		<filter id="blur">
			<feGaussianBlur in="SourceGraphic" stdDeviation="0,0" />
		</filter>
	</defs>
</svg>

Для указания насыщенности применения эффекта следует использовать атрибут stdDeviation, который принимает два параметра: настройки для вертикальной и горизонтальной направленности.

Применить фильтр к элементу можно следующим образом:

.selector{
	-webkit-filter: url("#blur");
	filter: url("../index.html#blur");
}

При анимации данного эффекта нам необходимо будет применить данный фильтр для каждого кадра с помощью JS.

Для начала запишем фильтр в переменную. Поскольку jQuery не очень хорошо ладит с SVG, то извлекать элемент мы будем с помощью нативных JS функций:

var filters = document.querySelector(".filters"), // SVG с фильтром
	defs = filters.querySelector("defs"), // элемент внутри SVG
	blur = defs.querySelector("#blur"), // эффект
	blurFilter = blur.firstElementChild; // настройка feGaussianBlur

Далее можем играть с настройками. К примеру выставить 12px для эффекта по горизонтали:

blurFilter.setAttribute("stdDeviation","12,0");

Помните, что данный эффект можно применять только по осям X или Y. Под углом не получится. Так что изначально продумайте как будет проходить анимация объекта.

Для каждого элемента страницы нам придётся создать отдельный фильтр т.к. он прикрепляется к элементу. Вот как это можно реализовать автоматически:

// проходимся по всем объектам, к которым нужно применить эффект
$(".js-blur").each(function(i){
	// копируем фильтр
	var blurClone=blur.cloneNode(true);

	// задаём новый ID, чтобы различать их через CSS
	var blurId="blur"+i;
	blurClone.setAttribute("id",blurId);

	defs.appendChild(blurClone);

	// применяем CSS
	var filter="url(#"+blurId+")";
	$(this)
		.css({
			webkitFilter:filter,
			filter:filter
		})
		// линкуем объект и эффект
		.data("blur",blurClone)
	;
});

Измеряем скорость

Следующий шаг: нам нужно вычислить насколько элемент продвинулся за предыдущий кадр. Делать это нужно на каждом кадре.

Для получения позиции воспользуемся jQuery функцией offset, которая возвращает координаты элемента относительно страницы, учитывая трансформацию объекта.

Для обновления каждого кадра напишем функцию requestAnimationFrame.

Вот пример:

// к данному элементу нужно применить эффект
var $element=$(".selector");
// записываем последнюю позицию
var lastPos=$element.offset();
// переменная для ограничения насыщенности эффекта
var multiplier=0.25;

// вспомогательная функция для применения эффекта.
function setBlur(x,y){
	blurFilter.setAttribute("stdDeviation",x+","+y);
}

(function updateMotionBlur(){
	// получаем текущую позицию элемента
	var currentPos=$element.offset();

	// вычисляем разницу по сравнению с предыдущим кадром и применяем ограничитель насыщенности
	var xDiff=Math.abs(currentPos.left-lastPos.left)*multiplier;
	var yDiff=Math.abs(currentPos.top-lastPos.top)*multiplier;

	// применяем эффект
	setBlur(xDiff,yDiff);

	// записываем текущую позицию
	lastPos=currentPos;

	// вызываем функцию для обработки следующего кадра
	requestAnimationFrame(updateMotionBlur);
})();

А вот и результат:

В данном примере рассматривается применение эффекта только для одного элемента. Для большего количества объектов может потребоваться небольшая оптимизация кода.

Вот и всё! Вдогонку хотим сказать, что применение фильтров и прочих эффектов приводят к большой затрате ресурсов устройства, так что не применяйте данный эффект для огромных объектов.

Данный урок подготовлен для вас командой сайта ruseller.com
Источник урока: http://tympanus.net/codrops/2015/04/08/motion-blur-effect-svg/
Перевел: Станислав Протасевич
Урок создан: 4 Мая 2015
Просмотров: 11091
Правила перепечатки


5 последних уроков рубрики "CSS"

^ Наверх ^