Эффектный переключатель с использованием CSS3 и jQuery
В данном уроке мы создадим плагин jQuery для представления глянцевого переключателя в качестве элемента управления на веб страницах. Названный knobKnob, данный плагин будет использовать трансформации CSS3 и новые методы jQuery для обработки событий, чтобы предоставить пользователю новый способ интерактивного выбора значения из доступного диапазона.
HTML
Разметка HTMLдля страницы достаточно проста и очевидна. Нужно использовать элемент для обозначения места, где будет располагаться переключатель. Весь остальной код будет генерироваться плагином:
index.html
Code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<!-- Стили CSS -->
<link rel="stylesheet" href="assets/css/styles.css" />
<link rel="stylesheet" href="assets/knobKnob/knobKnob.css" />
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<section id="main">
<div id="bars">
<div id="control">
<!-- Разметка переключателя будет вставлена здесь -->
</div>
<!-- Разметка цветной полосы -->
</div>
</section>
<!-- JavaScript -->
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="assets/knobKnob/transform.js"></script>
<script src="assets/knobKnob/knobKnob.jquery.js"></script>
<script src="assets/js/script.js"></script>
</body>
</html>
<html>
<head>
<meta charset="utf-8" />
<!-- Стили CSS -->
<link rel="stylesheet" href="assets/css/styles.css" />
<link rel="stylesheet" href="assets/knobKnob/knobKnob.css" />
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
</head>
<body>
<section id="main">
<div id="bars">
<div id="control">
<!-- Разметка переключателя будет вставлена здесь -->
</div>
<!-- Разметка цветной полосы -->
</div>
</section>
<!-- JavaScript -->
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="assets/knobKnob/transform.js"></script>
<script src="assets/knobKnob/knobKnob.jquery.js"></script>
<script src="assets/js/script.js"></script>
</body>
</html>
К странице подключается jQuery, transform.js, который обеспечивает поддержку кросс-браузерности свойства CSS3 transform, сам плагин knobKnob и файл script.js, который объединяет все в одно целое.
Элемент div #control является местом, куда вставляется разметка переключателя. Ниже будет вставлен элемент div, который представляет цветную полоску вокруг выключателя. Она не является частью плагина KnobKnob, и будет зависеть от устанавливаемого значения. Плагин KnobKnob также использует стили для формирования внешнего вида переключателя.
Теперь перейдем к созданию плагина.
Код jQuery
Исходный код плагина вы можете найти в прилагаемом к уроку архиве.
assets/knobKnob/knobKnob.jquery.js
Code
(function($){
$.fn.knobKnob = function(props){
var options = $.extend({
snap: 0,
value: 0,
turn: function(){}
}, props || {});
var tpl = '<div class="knob">\
<div class="top"></div>\
<div class="base"></div>\
</div>';
return this.each(function(){
var el = $(this);
el.append(tpl);
var knob = $('.knob',el),
knobTop = knob.find('.top'),
startDeg = -1,
currentDeg = 0,
rotation = 0,
lastDeg = 0,
doc = $(document);
if(options.value > 0 && options.value <= 359){
rotation = currentDeg = options.value;
knobTop.css('transform','rotate('+(currentDeg)+'deg)');
options.turn(currentDeg/359);
}
knob.on('mousedown', function(e){
e.preventDefault();
var offset = knob.offset();
var center = {
y : offset.top + knob.height()/2,
x: offset.left + knob.width()/2
};
var a, b, deg, tmp,
rad2deg = 180/Math.PI;
knob.on('mousemove.rem',function(e){
a = center.y - e.pageY;
b = center.x - e.pageX;
deg = Math.atan2(a,b)*rad2deg;
// Нужно преобразовать отрицательные значения угла в положительные
if(deg<0){
deg = 360 + deg;
}
// сохраняем начальную позицию перетаскивания
if(startDeg == -1){
startDeg = deg;
}
// Вычисляем текущий поворот
tmp = Math.floor((deg-startDeg) + rotation);
// Проверяем, что текущий поворот
// осуществляется в диапазоне от 0 до 359 градусов
if(tmp < 0){
tmp = 360 + tmp;
}
else if(tmp > 359){
tmp = tmp % 360;
}
// Переключение в положение "выключено"
if(options.snap && tmp < options.snap){
tmp = 0;
}
// Проверяем, что мы находимся в конечном положении;
// в данном случае надо блокировать дальнейшее вращение
if(Math.abs(tmp - lastDeg) > 180){
return false;
}
currentDeg = tmp;
lastDeg = tmp;
knobTop.css('transform','rotate('+(currentDeg)+'deg)');
options.turn(currentDeg/359);
});
doc.on('mouseup.rem',function(){
knob.off('.rem');
doc.off('.rem');
// Сохраняем текущее значение
rotation = currentDeg;
// Отмечаем стартовый угол как неправильный
startDeg = -1;
});
});
});
};
})(jQuery);
$.fn.knobKnob = function(props){
var options = $.extend({
snap: 0,
value: 0,
turn: function(){}
}, props || {});
var tpl = '<div class="knob">\
<div class="top"></div>\
<div class="base"></div>\
</div>';
return this.each(function(){
var el = $(this);
el.append(tpl);
var knob = $('.knob',el),
knobTop = knob.find('.top'),
startDeg = -1,
currentDeg = 0,
rotation = 0,
lastDeg = 0,
doc = $(document);
if(options.value > 0 && options.value <= 359){
rotation = currentDeg = options.value;
knobTop.css('transform','rotate('+(currentDeg)+'deg)');
options.turn(currentDeg/359);
}
knob.on('mousedown', function(e){
e.preventDefault();
var offset = knob.offset();
var center = {
y : offset.top + knob.height()/2,
x: offset.left + knob.width()/2
};
var a, b, deg, tmp,
rad2deg = 180/Math.PI;
knob.on('mousemove.rem',function(e){
a = center.y - e.pageY;
b = center.x - e.pageX;
deg = Math.atan2(a,b)*rad2deg;
// Нужно преобразовать отрицательные значения угла в положительные
if(deg<0){
deg = 360 + deg;
}
// сохраняем начальную позицию перетаскивания
if(startDeg == -1){
startDeg = deg;
}
// Вычисляем текущий поворот
tmp = Math.floor((deg-startDeg) + rotation);
// Проверяем, что текущий поворот
// осуществляется в диапазоне от 0 до 359 градусов
if(tmp < 0){
tmp = 360 + tmp;
}
else if(tmp > 359){
tmp = tmp % 360;
}
// Переключение в положение "выключено"
if(options.snap && tmp < options.snap){
tmp = 0;
}
// Проверяем, что мы находимся в конечном положении;
// в данном случае надо блокировать дальнейшее вращение
if(Math.abs(tmp - lastDeg) > 180){
return false;
}
currentDeg = tmp;
lastDeg = tmp;
knobTop.css('transform','rotate('+(currentDeg)+'deg)');
options.turn(currentDeg/359);
});
doc.on('mouseup.rem',function(){
knob.off('.rem');
doc.off('.rem');
// Сохраняем текущее значение
rotation = currentDeg;
// Отмечаем стартовый угол как неправильный
startDeg = -1;
});
});
});
};
})(jQuery);
Плагин имеет несколько опций, которые можно задавать через объект параметров:
snap - число градусов, которые соответствуют переключению в значение ноль;
value - начальное положение переключателя (в градусах);
turn - возвратная функция, которая вызывается каждый раз при переключении значения. Имеет единственный аргумент - коэффициент (от 0 до 1) поворота. Мы буем использовать ее для определения количества цветных полосок, которые надо вывести.
В коде используется функция Math.atan2 для вычисления угла (в радианах) между указателем мыши и центром переключателя. Отслеживая угол в начале и завершении перетаскивания мы можем определить величину поворота переключателя.
Также используются новые методы jQuery 1.7 для манипулирования обработчиками событий – on и off.
Теперь посмотрим, как использовать плагин.
assets/js/script.js
Code
$(function(){
var colors = [
'26e000','2fe300','37e700','45ea00','51ef00',
'61f800','6bfb00','77ff02','80ff05','8cff09',
'93ff0b','9eff09','a9ff07','c2ff03','d7ff07',
'f2ff0a','fff30a','ffdc09','ffce0a','ffc30a',
'ffb509','ffa808','ff9908','ff8607','ff7005',
'ff5f04','ff4f03','f83a00','ee2b00','e52000'
];
var rad2deg = 180/Math.PI;
var deg = 0;
var bars = $('#bars');
for(var i=0;i<colors.length;i++){
deg = i*12;
// Создаем цветную полоску
$('<div class="colorBar">').css({
backgroundColor: '#'+colors[i],
transform:'rotate('+deg+'deg)',
top: -Math.sin(deg/rad2deg)*80+100,
left: Math.cos((180 - deg)/rad2deg)*80+100,
}).appendTo(bars);
}
var colorBars = bars.find('.colorBar');
var numBars = 0, lastNum = -1;
$('#control').knobKnob({
snap : 10,
value: 154,
turn : function(ratio){
numBars = Math.round(colorBars.length*ratio);
// Обновляем DOM только тогда, когда изменяется число активных полосок,
// вместо реагирования на каждое движение
if(numBars == lastNum){
return false;
}
lastNum = numBars;
colorBars.removeClass('active').slice(0, numBars).addClass('active');
}
});
});
var colors = [
'26e000','2fe300','37e700','45ea00','51ef00',
'61f800','6bfb00','77ff02','80ff05','8cff09',
'93ff0b','9eff09','a9ff07','c2ff03','d7ff07',
'f2ff0a','fff30a','ffdc09','ffce0a','ffc30a',
'ffb509','ffa808','ff9908','ff8607','ff7005',
'ff5f04','ff4f03','f83a00','ee2b00','e52000'
];
var rad2deg = 180/Math.PI;
var deg = 0;
var bars = $('#bars');
for(var i=0;i<colors.length;i++){
deg = i*12;
// Создаем цветную полоску
$('<div class="colorBar">').css({
backgroundColor: '#'+colors[i],
transform:'rotate('+deg+'deg)',
top: -Math.sin(deg/rad2deg)*80+100,
left: Math.cos((180 - deg)/rad2deg)*80+100,
}).appendTo(bars);
}
var colorBars = bars.find('.colorBar');
var numBars = 0, lastNum = -1;
$('#control').knobKnob({
snap : 10,
value: 154,
turn : function(ratio){
numBars = Math.round(colorBars.length*ratio);
// Обновляем DOM только тогда, когда изменяется число активных полосок,
// вместо реагирования на каждое движение
if(numBars == lastNum){
return false;
}
lastNum = numBars;
colorBars.removeClass('active').slice(0, numBars).addClass('active');
}
});
});
Цветная полоска выводится вокруг переключателя и не является частью плагина. Плагин реализует только переключатель, который является универсальным элементом.
Выше приведенный код создает набор из 30 элементов div, которые изменяют цвет от зеленого к красному по градиенту. Они затем поворачиваются с инкрементом в 12 градусов. Благодаря функции turn, мы можем определить, сколько цветных элементов надо выводить. Стили элементов задаются в файле assets/css/styles.css.
Готово!
-
FalleN -
5573 -
1 -
263
Но только нужно ставить наверное на те модули которые обновляться должны не раньше через пару тройку минут
С Уважением, Андрей...