30 ноября

Создание визуальных эффектов на jQuery

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

Демо Скачать

Задача сводится к заполнению двумерного массива по диагонали:
<?php
$matrix = array(array()); // задаем двумерный массив
$w = 10; // количество блоков по ширине
$h = 10; // количество блоков по высоте
$count = 1; // Счетчик блоков

for ($i = 1; $i <= $w+$h; $i++) {
	$index = min($i,$w); // номер текущего блока по горизонтали
	$row = max(1,($i-($w+1)+2)); // номер текущего блока по вертикали
	
	while ($index != 0 && $row <= $h) {
		$matrix[$row][$index] = $count;
		$count++; // счетчик блоков +1
		$index--; // уменьшаем на 1 номер текущего блока по горизонтали
		$row++; // увеличиваем на 1 номер текущего блока по вертикали
	}
}
?>

Теперь осталось адаптировать данный алгоритм под нашу задачу - диагональное заполнение фоном или фоновым изображением блока на jQuery.
Структура будет иметь следующий вид:

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="content-type" content="text/html; charset=utf-8" />
	<title> Плавное появление из угла </title>
	<script type="text/javascript" src="js/jquery.min.js"></script>
	<script type="text/javascript" src="js/main.js"></script>
	<link rel="stylesheet" href="css/styles.css" type="text/css" />
</head>
<body>
	<div class="screen">
		<div class="block"></div>
	</div>
	<a class="ts_btn ts_demo" href="#">
		<span>Show</span>
	</a>
	<a class="ts_btn ts_hide" href="#">
		<span>hide</span>
	</a>
</body>
</html>

стили:

body{
	font-size: 14px;
	font-family: Arial, Helvetica, sans-serif;
	background:#ffffff;
	font-weight: normal;
	margin:0px;
	padding:0px;
}

.screen{
	margin: 0 auto;
	width: 1200px;
	height: 675px;
	color: #000000;
	background:#000000;
	position: relative;
	display: block;
	overflow: hidden;
	background: url(../img/img01.jpg) no-repeat left top;
	
}
.screen .block{
	position: absolute;
	z-index: 100;
	top: 0;
	display: none;
}
.pixel{
	z-index: 0;
	position: absolute;
	background-color: #d6e4fc;
	background-image: url(../img/img02.jpg);
	float:right;
}

Предусмотрим 2 варианта заполнения:

  • из верхнего левого края к нижнему правому;
  • из верхнего правого края к нижнему левому.

для заполнение фоновым изображением блоков сетки первый вариант совсем простой - положение блока совпадает с отрицательным значением смещения фона.
Второй вариант интереснее: положение фона по оси x рассчитывается исходя из положения текущего блока относительно левого края (w-index)*size, а чтобы компенсировать смещение, вызванное не целым количеством блоков, помещающихся в заполняемый блок, из этого значения вычитаем разницу: $(block).width()-w*size

В итоге мы получили следующий код:

$(document).ready(function(){
	$('.ts_btn.ts_demo').click(function(){
		pixelFade('in', '.screen');
		$(this).hide();
		$('.ts_btn.ts_hide').css('display', 'inline-block');
		
		return false;
	})
	$('.ts_btn.ts_hide').click(function(){
		pixelFade('out', '.screen');
		$(this).hide();
		$('.ts_btn.ts_demo').css('display', 'inline-block');
		
		return false;		
	})
})
function pixelFade(arg, block) {
	var size = 60; //Размер блока (не делайте его слишком маленьким)
	var fadeTime = 1000; // Время Fade эффекта
	var dir_from = 'right'; // Направление. right или left (из верхнего правого угла или из верхнего левого угла)
	var h = Math.round($(block).height() / size - 0.1)+1; // Расчет числа блоков по ширине
	var w = Math.round($(block).width() / size - 0.1)+1; // Расчет количества блоков по высоте
	var count = 1; // счетчик блоков

	for(i = 1; i <= (w + h); i++) {
		var index = Math.min( i, w); // номер текущего блока по горизонтали
		var row = Math.max(1,(i - ( w + 1 ) + 2 ) ); // номер текущего блока по вертикали
		 
		while (index != 0 && row <= h) {
			if (dir_from == 'right'){ // расчет позиции фона для направления из правого верхнего края
				var bg_x = -(w-index)*size - ($(block).width()-w*size);
				var bg_y = -(row-1)*size;
			}else{ // расчет позиции фона для направления из левого верхнего края
				var bg_x = -(index-1)*size;
				var bg_y = -(row-1)*size;
			}
			if (arg == 'in') { // Если блоки генерируются
				$(block).append('<div style="display: none;" id="block-'+index+'-'+row+'" class="pixel"></div>');
				if (dir_from == 'right') // положение блока для направления из правого верхнего края
					$('#block-'+index+'-'+row).css('right', (index-1)*size);
				else // положение блока для направления из левого верхнего края
					$('#block-'+index+'-'+row).css('left', (index-1)*size);
				$('#block-'+index+'-'+row).css({
					'top': (row-1)*size, 
					'background-position': bg_x+'px '+bg_y+'px', 
					'width': size+'px', 
					'height': size+'px'
				}).delay(i*(size*.75)).fadeIn(fadeTime);
			}else if (arg == 'out') {  // Если блоки скрываются
				$('#block-'+Math.abs(index-(w+1))+'-'+Math.abs(row-(h+1))).delay(i*(size*.75)).fadeOut(fadeTime, function(){
					$(this).remove(); // Удаляем уже скрытые блоки
				});
			}
			count++; // счетчик блоков +1
			index--; // уменьшаем на 1 номер текущего блока по горизонтали
			row++; // увеличиваем на 1 номер текущего блока по вертикали
		}
	}
}

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

Демо Скачать