За последние 24 часа нас посетили 20656 программистов и 1828 роботов. Сейчас ищет 991 программист ...

Алгоритм правильного смещения яркости (градиент)

Тема в разделе "Прочие вопросы по PHP", создана пользователем qwert_ukg, 7 май 2012.

  1. qwert_ukg

    qwert_ukg Активный пользователь

    С нами с:
    20 июл 2010
    Сообщения:
    387
    Симпатии:
    0
    Адрес:
    Алмата
    есть такая тема
    100 квадратиков в ряд закрасить в цикле в #f00 цвет, интенсивностью от #fff до #f00
    какие идеи есть? чтобы попроще, покрасивее
    з.ы.
    сделал через rgb(%,%,%);
    но че-то не очень, слишком много нюансов

    Добавлено спустя 20 минут 25 секунд:
    хотелось бы указать цвета от и до а в цикле работал правильный перебор цветов
     
  2. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    Если именно к индексной палитре приводить #fff (что равно в палитре true color #ffffff), то там всего 256 значений, у большинства которых в начале нет f. Как на 100 разбить?
    На 16 легко
    Код (PHP):
    1. <style>
    2. div.ct div{
    3.     float:left;
    4.     width:20px;
    5.     height:20px;
    6.     font-size:10px;
    7. }
    8. </style>
    9. <?php
    10. echo '<div class="ct">';
    11. for($i=0;$i<16;$i++){
    12.     $dehe=dechex($i);
    13.     echo sprintf('<div style="background:#f%s%s"></div>',$dehe,$dehe);
    14. }
    15. echo '</div>'; 
    Иначе нужно переходить к плавным переходам, это формат #ffffff.

    Поправка.
    Если цвета имеют диапазон от 0-f (16 цветов), то при форме записи #fff будет значений всего 16*16*16=4096.
    Так как нужен красный цвет всегда в значении f, то для цветов Green и Blue остаются 16*16=256 значений.
    Но так как требуется плавный переход интенсивности цвета, Green и Blue должны быть равны. Остаётся всего 16 значений яркости красного при форме записи #fff:
    Код (Text):
    1. f00
    2. f11
    3. f22
    4. f33
    5. f44
    6. f55
    7. f66
    8. f77
    9. f88
    10. f99
    11. faa
    12. fbb
    13. fcc
    14. fdd
    15. fee
    16. fff
    В формате #ffffff можно так разбить на 100 цветов:
    Код (PHP):
    1. div.ct div{
    2.     float:left;
    3.     width:20px;
    4.     height:20px;
    5. }
    6. <?php
    7. echo '<div class="ct">';
    8. for($i=0;$i<100;$i++){
    9.     $dehe=dechex($i*2.56);//256/100=2.56
    10.     $hexStr=($i*2.56<16)?'0'.$dehe:''.$dehe;
    11.     echo sprintf('<div style="background:#ff%s%s">%d</div>',$hexStr,$hexStr,$i+1);
    12. }
    13. echo '</div>'; 
     
  3. qwert_ukg

    qwert_ukg Активный пользователь

    С нами с:
    20 июл 2010
    Сообщения:
    387
    Симпатии:
    0
    Адрес:
    Алмата
    хотя бы для 16^3
    не обязательно #fff или #ffffff подойдут и другие способы указания цвета rgb(255,255,255) или rgb(100%,100%,100%)
     
  4. YSandro

    YSandro Старожил

    С нами с:
    7 апр 2011
    Сообщения:
    2.523
    Симпатии:
    2
    А что значит "правильный перебор цветов"?
    Если представить пространство RGB в виде куба, ось X будет соответствовать Red, Y - Green, Z - Blue, то удобно пользоваться векторами.

    Код (PHP):
    1. div.ct div{
    2.     float:left;
    3.     width:2px;
    4.     height:30px;
    5. }
    6. <?php
    7. include 'Vector3D.php';
    8.  
    9. $colorStart=new Vector3D(222,239,34);//начальное значение RGB
    10. $colorEnd=new Vector3D(222,121,48);//конечное значение RGB
    11. $colorVec=$colorEnd->sub($colorStart);//вектор направления
    12. $divVec=$colorVec->div(100);//вектор приращения//2.56
    13.  
    14. echo '<div class="ct">';
    15. for($i=0;$i<=100;$i++){
    16.     $color=$colorStart->add($divVec->mul($i));
    17.     echo sprintf('<div style="background:rgb(%d,%d,%d)"></div>',$color->x,$color->y,$color->z);
    18. }
    19. echo '</div>'; 
    Накидал простой класс с несколькими векторными функциями
    Vector3D.php
    Код (PHP):
    1. <?php
    2. /**
    3.  * Вектор содержит 3д координаты и полезные функции.
    4.  * @author Sandro
    5.  */
    6. class Vector3D{
    7.     private $x=0;
    8.     private $y=0;
    9.     private $z=0;
    10.     private $length=0;//длина вектора
    11.  
    12.  
    13.     private function modulus(){
    14.         $this->length=sqrt($this->x*$this->x+$this->y*$this->y+$this->z*$this->z);
    15.     }
    16.  
    17.  
    18.     function __construct($x=0,$y=0,$z=0){
    19.         $this->x=$x;
    20.         $this->y=$y;
    21.         $this->z=$z;
    22.         $this->modulus();
    23.     }
    24.  
    25.  
    26.     function __get($field){
    27.         if(isset($this->$field)){
    28.             return $this->$field;
    29.         }
    30.     }
    31.  
    32.  
    33.     function __set($field,$val){
    34.         if(isset($this->$field)){
    35.             $this->$field=$val;
    36.             $this->modulus();
    37.         }
    38.     }
    39.  
    40.  
    41.     /**
    42.      * Возвращает вектор единичной длины.
    43.      */
    44.     public function norm(){
    45.         return new Vector3D($this->x/$this->length, $this->y/$this->length, $this->z/$this->length);
    46.     }
    47.  
    48.  
    49.     /**
    50.      * Умножить значения вектора на число.
    51.      * @param type $val
    52.      * @return \Vector3D
    53.      */
    54.     public function mul($val){
    55.         $ret=new Vector3D($this->x,$this->y,$this->z);
    56.         if(is_numeric($val)){
    57.             $ret=new Vector3D($this->x*$val,$this->y*$val,$this->z*$val);
    58.         }
    59.         return $ret;
    60.     }
    61.  
    62.     /**
    63.      * Разделить значения вектора на число.
    64.      * @param type $val
    65.      * @return \Vector3D
    66.      */
    67.     public function div($val){
    68.         $ret=new Vector3D($this->x,$this->y,$this->z);
    69.         if(is_numeric($val) && $val!=0){
    70.             $ret=new Vector3D($this->x/$val,$this->y/$val,$this->z/$val);
    71.         }
    72.         return $ret;
    73.     }
    74.  
    75.     /**
    76.      * Сложение векторов.
    77.      * @param type $vec Тип Vector3D
    78.      * @return \Vector3D
    79.      */
    80.     public function add(Vector3D $vec){
    81.         return new Vector3D($vec->x+$this->x,$vec->y+$this->y,$vec->z+$this->z);
    82.     }
    83.  
    84.     /**
    85.      * Вычесть вектор из текущего значения вектора.
    86.      * @param type $vec Тип Vector3D
    87.      * @return \Vector3D
    88.      */
    89.     public function sub(Vector3D $vec){
    90.         return new Vector3D($this->x-$vec->x,$this->y-$vec->y,$this->z-$vec->z);
    91.     }
    92. }