Показаны сообщения с ярлыком графика. Показать все сообщения
Показаны сообщения с ярлыком графика. Показать все сообщения

14 июля 2011 г.

Пишем фото-галерею на JavaScript, используя библиотеку jQuery

Привет всем! Сегодня я написал в своем новом блоге статью о том, как написать фото-галерею на JavaScript, используя библиотеку jQuery. Статья рассчитана на начинающих программистов, которые только начинают углубляться в сам процесс программирования. Моей целью было как можно четче и проще, человеческим языком понятному для начинающих JavaScript-программистов, описать сам процесс построения алгоритма. Ведь самое главное в программировании - это правильно построить алгоритм, который в последствии можно будет перевести на любой язык программирования. Конечно, создавая алгоритм для определенного языка наше мышление начинает поддаваться некоторым штампам, которые позволяют нам сэкономить время на построении алгоритма. Вот и здесь не обошлось без этих штампов языка JavaScript, но я надеюсь, что, тем не менее, статья все-таки будет полезна для начинающих программистов.

26 мая 2011 г.

Выбор цвета как в photoshop на javascript

Всем, здравствуйте!
Сегодня мы напишем скрипт, который позволит нам выбирать цвет, если не как в photoshop, то близкое к тому. Ведь самое главное суть!
Для этого нам понадобятся следующие изображения.













Последнее изображение я делал php-скриптом. Как это реализовано, я писал в предыдущей статье. Выглядеть все это будет следующим образом


Итак, приступим!

<form action="" method="POST">
<table style="margin:auto; border:1px solid #000; position:relative;">
<tr><td>Введите свой цвет или выберите из набора.
 <div class="ppic" id="surname_pic" style="height:20px; width:20px;position:relative;top:0;right:0;margin:0;float:right;padding:0;border:1px solid #000000;z-index:5"></div>
 <div class="all_for_clr" id="surname_main" style="background:#aaaaaa;height:0; width:0;position:relative;top:0;right:0;margin:0;padding:0;overflow:hidden;float:right;border:1px solid #000000;filter:alpha(opacity=0);opacity:0;z-index:0">
 <div class="preview" id="surname_pre" style="height:50px;width:50px;position:relative;float:right;z-index:0;background:#ffffff;border:1px solid #000000;"></div>
 <div class="brightness" id="surname_br" style="height:128px;width:20px;position:relative;float:right;z-index:0;background:url(nasyschen.png);overflow:hidden;border:1px solid #000000;margin:0 5px 0 0;padding:0;"><div id="surname_line" style="height:1px;width:20px;position:absolute;top:0;left:0;background:#ff0000;margin:0;padding:0;border:0"></div></div>
 <div class="gradus" id="surname" style="height:128px;width:128px;background:url(spec.png) no-repeat 0 0;overflow:hidden;position:relative;float:right;z-index:0;margin:0 5px 0 0;padding:0;border:1px solid #000000;"><div id="surname_krest" style="height:15px;width:15px;position:absolute;top:0;left:0;background:url(krest.png);margin:0;padding:0;border:0"></div></div></div></td>
 <td><input type="text" name="surname" /></td>
</tr>
</table>
</form>
это у нас непосредственно сама форма.
div с class="ppic" - это у нас квадратик, в котором будет показан ткущий цвет.
div с классом "all_for_color" - здесь мы разместим спектр, где у нас будет бегать крестик и где мы будем выбирать цвет, а так же полосу, в которой будем выбирать яркость. Здесь же у нас будет окошко, в котором будет отображаться выбираемый цвет.
В этом диве у нас будет:
div с классом "preview" - т.е. предпросмотр цвета
div с классом "gradus" - не знаю почему я его так назвал, здесь у нас спектр, по которому будем кликать, чтобы выбрать цвет
div с классом "drightness" - здесь черно-белый градиент, выбор яркости.
div с ID="surname_line" - это линия, которая будет держать нас в курсе, где мы кликнули последний раз по яркости
и div с ID="surname_krest" - это крестик, который показывает, где мы кликнули последний раз по спектру.

Ну, а теперь самое страшное :)
Только не забудьте подключить библиотеку jQuery!

<script type="text/javascript">
open_color=false;
function findX(el){
 var curX=0;
 if(el.offsetParent){
  while(el.offsetParent){
   curX+=el.offsetLeft;
   el=el.offsetParent;
  }
 }
 else if(el.x) curX+=el.x;
 return curX;
}
function findY(el){
 var curY=0;
 if(el.offsetParent){
  while(el.offsetParent){
   curY+=el.offsetTop;
   el=el.offsetParent;
  }
 }
 else if(el.y) curY+=el.y;
 return curY;
}
function getColor(x,y){
 var dec_r;
 var dec_g;
 var dec_b;
 if(y<22){
  dec_g=(256-y*12)/128;
  dec_r=0;
  dec_b=2;
 }
 else if(y>21&&y<43){
  dec_g=0;
  dec_r=(y*12-256)/128;
  dec_b=2;
 }
 else if(y>42&&y<65){
  dec_r=2;
  dec_b=(768-y*12)/128;
  dec_g=0;
 }
 else if(y>64&&y<86){
  dec_b=0;
  dec_g=(y*12-768)/128;
  dec_r=2;
 }
 else if(y>85&&y<107){
  dec_g=2;
  dec_r=(1280-y*12)/128;
  dec_b=0;
 }
 else if(y>106){
  dec_r=0;
  dec_b=(y*12-1280)/128;
  dec_g=2;
 }
 red=Number(Math.abs(Math.round(255-x*dec_r))).toString(16);
 green=Number(Math.abs(Math.round(255-x*dec_g))).toString(16);
 blue=Number(Math.abs(Math.round(255-x*dec_b))).toString(16);
 if(red.length<2) red="0"+red;
 if(green.length<2) green="0"+green;
 if(blue.length<2) blue="0"+blue;
 return '#'+red+green+blue;
}
function chColor(x,y,k){
 var dec_r;
 var dec_g;
 var dec_b;
 if(y<22){
  dec_g=(256-y*12)/128;
  dec_r=0;
  dec_b=2;
 }
 else if(y>21&&y<43){
  dec_g=0;
  dec_r=(y*12-256)/128;
  dec_b=2;
 }
 else if(y>42&&y<65){
  dec_r=2;
  dec_b=(768-y*12)/128;
  dec_g=0;
 }
 else if(y>64&&y<86){
  dec_b=0;
  dec_g=(y*12-768)/128;
  dec_r=2;
 }
 else if(y>85&&y<107){
  dec_g=2;
  dec_r=(1280-y*12)/128;
  dec_b=0;
 }
 else if(y>106){
  dec_r=0;
  dec_b=(y*12-1280)/128;
  dec_g=2;
 }
 red=Number(Math.abs(Math.round((255-x*dec_r)*k))).toString(16);
 green=Number(Math.abs(Math.round((255-x*dec_g)*k))).toString(16);
 blue=Number(Math.abs(Math.round((255-x*dec_b)*k))).toString(16);
 if(red.length<2) red="0"+red;
 if(green.length<2) green="0"+green;
 if(blue.length<2) blue="0"+blue;
 return '#'+red+green+blue;
}
mmousedown=false;
bmousedown=false;
$(document).ready(function(){
 $(".gradus").mousedown(function(){
  mmousedown=true;
 });
 $(".gradus").mouseup(function(){
  mmousedown=false;
 });
 $(".gradus").mousemove(function(e){
  if(!mmousedown) return;
  var x=e.pageX-findX(this);
  var y=e.pageY-findY(this);
  if(x>127 || x<0 || y>127 || y<0){
   mmousedown=false;
   return;
  }
  var color=getColor(x,y);
  var field=$(this).attr("id");
  $("#"+field+"_krest").css("top",y-7);
  $("#"+field+"_krest").css("left",x-7);
  $("[name="+field+"]").val(color);
  $("#"+field+"_pre").css("background",color);
  $("#"+field+"_pic").css("background",color);
  $("#"+field+"_line").css("top",0);  
 });
 $(".gradus").click(function(e){
  var x=e.pageX-findX(this);
  var y=e.pageY-findY(this);
  if(x>127 || x<0 || y>127 || y<0){
   mmousedown=false;
   return;
  }
  var color=getColor(x,y);
  var field=$(this).attr("id");
  $("#"+field+"_krest").animate({top:y-7, left:x-7},"fast");
  $("[name="+field+"]").val(color);
  $("#"+field+"_pre").css("background",color);
  $("#"+field+"_pic").css("background",color);
  $("#"+field+"_line").css("top",0);  
 });
 $(".ppic").mouseenter(function(e){
  if(open_color) return;
  open_color=true;
  var len=$(this).attr("id");
  len=len.length-4;
  var id=$(this).attr("id").substr(0,len);
  $(this).css("z-index","-1");
  $("#"+id+"_main").css("position","absolute");
  $("#"+id+"_main").css("left",e.pageX-100);
  $("#"+id+"_main").css("width","215px");
  $("#"+id+"_main").css("height","130px");
  $("#"+id+"_main").css("padding","5px");
  $("#"+id+"_main").css("z-index","0");
  $("#"+id+"_main").animate({opacity:1},"slow");
  open_color=false;
 });
 $(".all_for_clr").mouseleave(function(){
  if(open_color) return;
  open_color=true;
  $(this).animate({opacity:0},"slow",function(){
   $(this).css("position","relative");
   $(this).css("left","0");
   $(this).css("width","0");
   $(this).css("height","0");
   $(this).css("padding","0");
   $(this).css("z-index","-1");
   $(".ppic").css("z-index","5");
   open_color=false;
  });
 });
 $(".brightness").mousedown(function(){
  bmousedown=true;
 });
 $(".brightness").mouseup(function(){
  bmousedown=false;
 });
 $(".brightness").mousemove(function(e){
  if(!bmousedown) return;
  var y=e.pageY-findY(this);
  var x=e.pageX-findX(this);
  if(x>19 || x<0 || y>127 || y<0){
   bmousedown=false;
   return;
  }
  var k=(127-y)/127;
  var len=$(this).attr("id");
  len=len.length-3;
  var id=$(this).attr("id").substr(0,len);
  var spec=document.getElementById(id);
  var krest=document.getElementById(id+"_krest");
  var x_color=findX(krest)+7-findX(spec);
  var y_color=findY(krest)+7-findY(spec);
  var color=chColor(x_color,y_color,k);
  $("#"+id+"_line").css("top",y);
  $("[name="+id+"]").val(color);
  $("#"+id+"_pre").css("background",color);
  $("#"+id+"_pic").css("background",color);
 });
 $(".brightness").click(function(e){
  var y=e.pageY-findY(this);
  var x=e.pageX-findX(this);
  if(x>19 || x<0 || y>127 || y<0){
   bmousedown=false;
   return;
  }
  var k=(127-y)/127;
  var len=$(this).attr("id");
  len=len.length-3;
  var id=$(this).attr("id").substr(0,len);
  var spec=document.getElementById(id);
  var krest=document.getElementById(id+"_krest");
  var x_color=findX(krest)+7-findX(spec);
  var y_color=findY(krest)+7-findY(spec);
  var color=chColor(x_color,y_color,k);
  $("#"+id+"_line").animate({top:y},"fast");
  $("[name="+id+"]").val(color);
  $("#"+id+"_pre").css("background",color);
  $("#"+id+"_pic").css("background",color);
 });
});
</script>

Первая переменная нам необходима, чтобы контролировать панель выбора цвета. В начале она у нас содержит значение false. Т.е. панель не отображается.
Функция findX() и findY() возвращают значение X и Y от верхнего левого угла страницы.
getColor() возвращает значение цвета в формате #xxxxxx. Функция работает по той же логике, что и php-скрипт, которым мы нарисовали спектр.
chColor() возвращает измененный цвет, т.е. меняет яркость выбранного цвета. k это коэффициент.
mmousedown - переменная, которая требуется нам для отслеживания, где нажата кнопка мыши. Она принимает значение true, если кнопка мыши была нажата на спектре. Когда пользователь отпускает кнопку, она принимает значение false. Также ведет себя переменная bmousedown по нажатию/отпусканию кнопки мыши на яркости. Это нам необходимо, чтобы при нажатой кнопке, цвет изменялся при каждом смещении мыши.
Дальше мы прикрепляем обработчики событий на каждое важное для нас поле. Т.е. если курсор попадает на маленький квадрат с текущим цветом, то мы отображаем панель выбора цвета. Если курсов покидает панель, она скрывается. Такие же действия мы поделываем и со всем остальным.
Думаю остальное понятно. Если будут вопросы, задавайте, буду рад ответить!
А пока до скорых встреч!

24 мая 2011 г.

Рисуем градиент на PHP

Как-то мне поступил заказ, чтобы я сделал выбор цвета как в Photoshop. Конечно, один в один я его не сделал, ну, этого и не требовалось, но суть не в этом. Для того, чтобы осуществить нечто подобное, необходимо знать по какому цвету ты щелкаешь. Для этого оказалось проще самому программным образом нарисовать такой квадратик, тогда я буду на 100% уверен какой пиксель, какой цвет содержит. Т.е. его шестнадцатеричный код.
Вот, что у меня получилось.

Теперь я продемонстрирую сам код:
<?php
$im = imagecreatetruecolor(128,128);
$dec_r = 0;
$dec_g = 2;
$dec_b = 2;
for($y = 0; $y < 128; $y++){
 $red = 255;
 $green = 255;
 $blue = 255;
 if($y < 22) $dec_g = (256 - $y * 12) / 128;
 else if($y > 21 && $y < 43){
  $dec_g = 0;
  $dec_r = ($y * 12 - 256) / 128;
 }
 else if($y > 42 && $y < 65){
  $dec_r = 2;
  $dec_b = (768 - $y * 12) / 128;
 }
 else if($y > 64 && $y < 86){
  $dec_b = 0;
  $dec_g = ($y * 12 - 768) / 128;
 }
 else if($y > 85 && $y < 107){
  $dec_g = 2;
  $dec_r = (1280 - $y * 12) / 128;
 }
 else if($y > 106){
  $dec_r = 0;
  $dec_b = ($y * 12 - 1280) / 128;
 }
 for($x = 0; $x < 128; $x++){
  $color_now = imagecolorallocate($im, round($red - $x * $dec_r), round($green - $x * $dec_g),round($blue - $x * $dec_b));
  imagesetpixel($im, $x, $y, $color_now);
 }
}

header("Content-type: image/png");
imagepng($im);
imagedestroy($im);
?>

Тут логика проста. Создаем изображение размером 128х128. Потом для каждой строчки определяем правило, по которому будут происходить изменения цвета каждого следующего пикселя.
Переменные $dec_r, $dec_g, $dec_b отвечают за шаг каждого цвета. Т.е. сначала у нас $dec_r = 0, $dec_g = 2 и $dec_b = 2. Это означает, что красный цвет изменятся не будет. А зеленый и синий будут уменьшаться на 2. Так будет только в первой строчке. Во второй правило изменится для шага зеленого цвета. Его шаг замедлится и не достигнет нуля. Таким образом, в конце второй строчки у нас уже будет не чистый красный цвет, а начнет приближаться к желтому. На 21-й строчке значение зеленого цвета практический перестает изменятся и, начиная с 22-й строчке оно будет равно 255. Но теперь начинает увеличиваться шаг красного цвета, когда он достигнет 2, начинает уменьшаться шаг синего цвета и т.д. Таким образом, мы пройдем по всей цветовой гамме. Конечно, частота дискретизации не позволит нам сделать это более плавно уместившись в такой маленький участок экрана, но наш глаз скачков цвета не заметит.

Дорогие читатели. В следующей статье я хочу вам рассказать о том, как осуществить выбор цвета как в photoshop на javascript. Если же вас интересуют другие темы, то пишите, обсудим.
До новых встреч!