Статьи

Динамический Sprite Framework с PHP

В этом учебном пособии по Nettuts + PLUS вы узнаете, как создать динамический «Image Sprite Framework» из набора значков по вашему выбору. Фреймворк будет состоять из изображения спрайта, таблицы стилей спрайта, имена и свойства классов которой соответствуют значкам в нашем изображении спрайта, и страницы предварительного просмотра HTML, на которой мы можем использовать краткое справочное руководство по фреймворку.

«Dynamic Sprite Framework» позволит вам использовать любой значок из спрайта, указав его относительное имя класса, которое будет напрямую соответствовать имени файла значка.

К концу этого учебного курса вы будете чувствовать себя комфортно, создавая динамические спрайты изображений самостоятельно, и должны быть в состоянии реализовать и в полной мере воспользоваться многими преимуществами, которые предоставляет эта система.

Прокрутите вниз, чтобы найти полный премиум скринкаст!


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

  • Каталог, содержащий значки, которые мы хотели бы использовать для спрайта, с завершающей косой чертой в конце
  • Ширина значков
  • Высота значков
  • Смещение по x, которое мы хотели бы для каждой иконки — это будет их горизонтальное расстояние
  • Смещение по оси Y, которое мы хотели бы для каждой иконки — это их вертикальное расстояние
  • Тип изображения для иконок — PNG, GIF или JPG
  • Сколько иконок мы хотели бы отобразить на строку в нашем спрайте
  • Целевой каталог для нашего спрайта — с косой чертой в конце
  • Имя цели для нашего нового изображения спрайта

Мы собираемся создать HTML-страницу с простой формой для сбора этих данных. Давайте посмотрим на эту форму:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
<!doctype html>
<html lang=»en»>
  
<head>
     <title>Sprite Builder</title>
     <meta charset=»utf-8″>
  
     <link rel=»stylesheet» type=»text/css» href=»main.css»>
</head>
  
    <body>
  
         <div id=»content»>
  
               <form action=»sprite_builder.php» method=»POST»>
                    <fieldset>
                         <legend>Sprite Builder</legend>
  
                         <label for=»icon_source» class=»label»>Image Directory:</label>
                         <input id=»icon_source» class=»ui-corner-all» type=»text» name=»icon_source» value=»»>
  
                         <label for=»icon_width» class=»label»>Icon Width:</label>
                         <input id=»icon_width» class=»ui-corner-all» type=»text» name=»icon_width» value=»»>
  
                         <label for=»icon_height» class=»label»>Icon Height:</label>
                         <input id=»icon_height» class=»ui-corner-all» type=»text» name=»icon_height» value=»»>
  
                         <label for=»x_offset» class=»label»>Icon X Offset:</label>
                         <input id=»icon_width» class=»ui-corner-all» type=»text» name=»x_offset» value=»»>
  
                         <label for=»y_offset» class=»label»>Icon Y Offset:</label>
                         <input id=»y_offset» class=»ui-corner-all» type=»text» name=»y_offset» value=»»>
  
                         <div class=»radio»>
                              <label for=»icon_type» class=»label»>Image Type:</label>
                              <div class=»radioWrap»><input type=»radio» name=»icon_type[]» value=»png»>PNG</div>
                              <div class=»radioWrap»><input type=»radio» name=»icon_type[]» value=»jpg»>JPEG</div>
                              <div class=»radioWrap»><input type=»radio» name=»icon_type[]» value=»gif»>GIF</div>
                         </div><!— DIV.radio —>
  
  
                         <label for=»icons_per_row» class=»label»>Icons per Row:</label>
                         <input id=»icons_per_row» class=»ui-corner-all» type=»text» name=»icons_per_row» value=»»>
  
                         <label for=»target_directory» class=»label»>Target Directory:</label>
                         <input id=»target_directory» class=»ui-corner-all» type=»text» name=»target_directory» value=»»>
  
                         <label for=»target_name» class=»label»>Target Name:</label>
                         <input id=»target_name» class=»ui-corner-all» type=»text» name=»target_name» value=»»>
  
                         <button type=»submit»>Submit</button>
  
                    </fieldset>
               </form>
  
          </div>
  
    </body>
  
</html>

Как вы можете видеть выше, мы создали простую страницу HTML5 с ФОРМОЙ.

ФОРМА разместит свои результаты на нашей странице sprite_builder.php.

Сама ФОРМА имеет девять полей для сбора необходимой нам информации:

  • icon_source
  • icon_width
  • icon_height
  • x_offset
  • y_offset
  • icon_type
  • icons_per_row
  • целевой_каталог
  • target_name


Теперь, когда у нас есть ФОРМА, мы сможем собрать все данные, которые нам нужны …

В нашем PHP мы начнем с проверки, все ли поля формы были отправлены со значением.

Если какое-либо из ЗНАЧЕНИЙ не установлено, мы просто перенаправим пользователя обратно на страницу FORM.

Обратите внимание, что в производственной среде вы захотите еще немного закрепить / обезопасить эту ФОРМУ и предоставить некоторую обратную связь пользователю.

Давайте теперь создадим новый php-файл с именем sprite_builder.php и проверим, чтобы все указанные ФОРМОВЫЕ ПОЛЯ были переданы со значением VALUE.

1
2
3
4
5
6
7
8
9
<?php
    if (isset($_POST[‘icon_source’]) && isset($_POST[‘icon_width’]) && isset($_POST[‘icon_height’]) && isset($_POST[‘icon_type’]) && isset($_POST[‘icons_per_row’]) && isset($_POST[‘target_directory’]) && isset($_POST[‘target_name’]))
    {
  
     }
     else
     {
          header(‘Location: http://localhost/Sprite/index.html’);
     }

Если вышеуказанное условие выполнено, то есть все элементы в массиве POST имеют значение, мы немного очистим и подготовим эти ЗНАЧЕНИЯ.

Давайте создадим функцию для подготовки наших данных для нас.

1
2
3
4
5
function prep($post)
{
     $post = htmlspecialchars(trim($post));
     return $post;
}

Функция prep () выполняет следующие действия:

  • htmlspecialchars — все данные, передаваемые в функцию «prep», будут иметь «ключевые» HTML-теги, любые символы внутри которых преобразуются в HTML-объекты
  • обрезать — мы затем обрезать все пустое пространство от начала и конца строки

Мы будем подготавливать данные из нашего массива POST при создании нового массива ‘sprite’ с этими предварительно заданными значениями.

Сначала мы инициализируем наш массив спрайтов.

Затем мы начнем перебирать все array_keys для массива POST.

Выполняя итерацию по ключам массива POST, мы проверим, что каждое POST VALUE является строкой.

Если VALUE является строкой, мы добавим ее в наш массив «sprite», используя ключ массива в качестве его имени в массиве sprite.

После этого цикла foreach мы также сохраним наш «выходной путь» в массиве «sprite».

Мы определим «output_path» путем объединения переменной «target_directory» с переменной «target_name».

Обратите внимание, что мы не будем добавлять расширение файла здесь, мы определим это позже.

Поскольку FIELD ‘icon_type’ является массивом, мы будем проходить через него, чтобы получить переданное значение VALUE, а затем выполнить это значение через нашу функцию prep () и добавить его в наш массив ‘sprite’.

Далее мы инициализируем массив ‘icon_name’, который будет содержаться в нашем массиве спрайтов.

Примечание: мы создадим массив ‘icon_name’, как только мы откроем и будем читать целевой каталог …

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<?php
  
     function prep($post)
     {
          $post = htmlspecialchars(trim($post));
          return $post;
     }
  
    if (isset($_POST[‘icon_source’]) && isset($_POST[‘icon_width’]) && isset($_POST[‘icon_height’]) && isset($_POST[‘icon_type’]) && isset($_POST[‘icons_per_row’]) && isset($_POST[‘target_directory’]) && isset($_POST[‘target_name’]))
    {
          $sprite = array();
  
          $array_key = array_keys($_POST);
          foreach($array_key as $key)
          {
               if(is_string($_POST[$key]))
               {
                    $sprite[$key] = prep($_POST[$key]);
               }
          }
  
          $sprite[‘path’] = $sprite[‘target_directory’].$sprite[‘target_name’];
  
          foreach($_POST[‘icon_type’] as $key => $value)
          {
               $sprite[‘icon_type’] = prep($value);
          }
  
          $sprite[‘icon_name’] = array();
     }
     else
     {
          header(‘Location: http://localhost/Sprite/index.html’);
     }

Теперь, когда мы создали массив, который содержит все значения из массива POST, мы создадим массив имен изображений.

Вот что мы будем делать в следующих нескольких строках кода:

  • Мы начнем с открытия каталога значков, указанного в нашей ФОРМЕ.
  • Затем мы установим общее количество изображений на ноль и, читая этот каталог, добавляя имена изображений в наш массив, будем увеличивать это значение для каждого. Это даст нам общее количество изображений в нашем каталоге / массиве.
  • Далее мы прочитаем каталог, используя простой цикл while
  • Читая каталог, мы получим информацию о пути для каждого файла и проверим его расширение. Мы преобразуем расширение в нижний регистр и сравним его с типом изображения, указанным в форме Sprite Builder.
  • Если расширения совпадают, мы снова будем использовать path_info, чтобы получить имя файла изображения и добавить его в наш массив ‘icon_name’.
  • Затем мы увеличим нашу иконку на 1.
  • Как только мы закончим чтение содержимого этого каталога, мы отсортируем массив ‘icon_name’ в алфавитном порядке и добавим общее количество значков в наш массив ‘sprite’.
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
$sprite_directory = opendir( $sprite[‘icon_source’] );
$image_total = 0;
  
while ($file_name = readdir( $sprite_directory ))
{
     $path_info = pathinfo( $file_name );
  
     if ( strtolower($path_info[‘extension’]) === $sprite[‘icon_type’] )
     {
          $sprite[‘icon_name’][] = $path_info[‘filename’];
          $image_total++;
     }
}
  
sort($sprite[‘icon_name’]);
$sprite[‘icon_total’] = $image_total;

Когда массив sprite завершен, мы можем перейти к созданию объекта sprite_builder.



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

Этот объект будет делать три вещи:

  • Создать изображение спрайта
  • Создайте файл CSS для изображения спрайта с классами и положениями фона, соответствующими именам и местоположениям отдельных значков в спрайте.
  • Создайте страницу предварительного просмотра HTML для спрайта и соответствующие правила CSS

Первое, что мы сделаем, это определим наш объект / класс и его типы свойств.

Поскольку мы работаем только с одним объектом, и нам не нужно обращаться к каким-либо его свойствам вне класса, мы сделаем их все приватными.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
class Sprite_builder
{
     private $icon_source;
     private $icon_width;
     private $icon_height;
     private $icons_per_row;
     private $target_directory;
     private $target_name;
     private $path;
     private $icon_type;
     private $icon_total;
     private $icon_name;
     private $x_offset;
     private $y_offset;
}

Теперь мы создадим наш конструктор классов .

В нашем конструкторе мы определим каждое из свойств нашего объекта, используя соответствующие значения в нашем массиве спрайтов.

Это сделает все эти свойства доступными для каждого метода в нашем классе.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Sprite_builder
{
     private $icon_source;
     private $icon_width;
     private $icon_height;
     private $icons_per_row;
     private $target_directory;
     private $target_name;
     private $path;
     private $icon_type;
     private $icon_total;
     private $icon_name;
     private $x_offset;
     private $y_offset;
  
     function Sprite_builder($sprite)
     {
          $this->icon_source= $sprite[‘icon_source’];
          $this->icon_width= $sprite[‘icon_width’];
          $this->icon_height= $sprite[‘icon_height’];
          $this->icons_per_row= $sprite[‘icons_per_row’];
          $this->target_directory= $sprite[‘target_directory’];
          $this->target_name= $sprite[‘target_name’];
          $this->path= $sprite[‘path’];
          $this->icon_type= $sprite[‘icon_type’];
          $this->icon_total= $sprite[‘icon_total’];
          $this->icon_name= $sprite[‘icon_name’];
          $this->x_offset= $sprite[‘x_offset’];
          $this->y_offset= $sprite[‘y_offset’];
     }
}

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



Нашим первым методом будет функция create_sprite ().

Этот метод создаст новый спрайт, состоящий из всех допустимых изображений, указанных в нашем массиве ‘image_name’.

Вот общий обзор шагов, которые мы предпримем для достижения этой цели:

  • Сначала мы определим свойства x_position и y_position. Эти свойства будут определять положение значка вдоль осей x и y соответственно. Мы будем использовать настройки ‘x_offset’ и ‘y_offset’, указанные в нашей форме Sprite Builder.
  • Затем мы установим наш icon_per_row_count на 0. Мы будем увеличивать это на 1 для каждого значка, который мы добавляем к спрайту.
  • Теперь, используя данные, имеющиеся у нас в Sprite Builder FORM, мы рассчитаем общую высоту и ширину для нового спрайта изображения
  • С заданными размерами спрайта мы создадим «основное» изображение:
    • Сначала мы создадим «общее» изображение с помощью команды imagecreatetruecolor . Мы укажем его размеры с результатами наших вычислений высоты и ширины, упомянутых выше
    • Далее мы настроим это изображение для сохранения прозрачности. Мы будем использовать команду imagesavealpha для этого. Это установит флаг «Сохранить прозрачность» для этого изображения.
    • Пометив наше изображение для прозрачности, мы теперь определим его значения цвета и прозрачности, используя команду imagecolorallocatealpha . Мы установим все значения канала RGB на 0, а канал прозрачности на 127, что является полной прозрачностью.
    • Наконец, мы «залим» заливку изображения нашими значениями «imagecolorallocatealpha» с помощью команды imagefill
  • Изображение спрайта теперь готово к работе. Наш следующий шаг — начать итерацию по нашему массиву icon_name. Когда мы переберем этот массив, мы сделаем следующее:
    • В зависимости от типа изображения, указанного в нашей форме Sprite Builder, мы создадим новое изображение для каждого значка, используя одну из следующих команд: imagecreatefrompng , imagecreatefromgif или imagecreatefromjpeg . Мы объединим ‘icon_name’ со свойством ‘icon_type’, чтобы указать источник изображения.
    • Теперь, используя команду imagecopy , мы скопируем этот значок на наш спрайт. Мы сместим его, используя наши свойства ‘x_position’ и ‘y_position’, и установим его размеры, используя свойства ‘icon_width’ и ‘icon_height’.
    • Добавив иконку в наш спрайт, мы теперь увеличим наш icon_per_row_count на 1
    • Далее нам нужно определить, достигли ли мы предела ‘icons_per_row’, который мы указали в форме Sprite Builder. Если у нас есть, мы сделаем следующее:
      • Во-первых, нам нужно пересчитать положение значков по вертикали, когда мы начинаем новую строку. Мы сделаем это, взяв его текущее положение y и добавив к нему значения icon_height и y_offset.
      • Далее, мы вернем ‘x_position’ к его настройке по умолчанию, которая является свойством ‘x_offset’, определенным в нашей форме Sprite Builder. Таким образом, следующая иконка будет скопирована в крайнюю левую часть нашего спрайта.
      • Теперь мы сбросим наш icon_per_row_count на 0, так как в этом ряду еще нет изображений
      • Наконец, мы увеличим наш row_count на 1, так как мы только что завершили ряд
    • Если счетчик ‘icon_per_row_count’ не соответствует нашему пределу ‘icons_per_row’, нам нужно будет только пересчитать ‘x_position’, чтобы следующий значок располагался дальше вниз по оси x
    • Теперь, когда этот «значок» скопирован в наш спрайт, мы можем уничтожить его с помощью команды imagedestroy .
  • Мы закончим наш цикл foreach здесь
  • Перебрав все наши «значки» и скопировав каждую из них в спрайт, мы продолжим и выведем изображение спрайта в файл. Однако сначала мы еще раз проверим тип изображения, чтобы использовать соответствующий метод для вывода спрайта. Для этого мы будем использовать команду imagepng , imagegif или imagejpeg .
  • С нашим изображением спрайта, сохраненным в файл, мы можем пойти дальше и уничтожить изображение GD, с которым мы работали, с помощью команды imagedestroy .
01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function create_image()
{
     $this->x_position = $this->x_offset;
     $this->y_position = $this->y_offset;
 
     $this->icon_per_row_count = 0;
 
     $this->sprite_width = (($this->icon_width + $this->x_offset) * $this->icons_per_row) + $this->x_offset;
     $this->sprite_height = (($this->icon_height + $this->y_offset) * ceil($this->icon_total / $this->icons_per_row)) + $this->y_offset;
 
     $this->new_sprite = imagecreatetruecolor($this->sprite_width, $this->sprite_height);
     imagesavealpha($this->new_sprite, true);
 
     $this->new_sprite_opacity= imagecolorallocatealpha($this->new_sprite, 0, 0, 0, 127);
     imagefill($this->new_sprite, 0, 0, $this->new_sprite_opacity);
 
     foreach ($this->icon_name as $image)
     {
          if($this->icon_type == ‘png’)
          {
               $this->icon = imagecreatefrompng(«{$this->icon_source}{$image}.{$this->icon_type}»);
          }
          else if($this->icon_type == ‘gif’)
          {
               $this->icon = imagecreatefromgif(«{$this->icon_source}{$image}.{$this->icon_type}»);
          }
          else if($this->icon_type == ‘jpg’ || $this->icon_type == ‘jpeg’)
          {
               $this->icon = imagecreatefromjpeg(«{$this->icon_source}{$image}.{$this->icon_type}»);
          }
 
          imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
 
          $this->icon_per_row_count++;
 
          if ($this->icon_per_row_count == $this->icons_per_row)
          {
               $this->y_position = $this->y_position + $this->icon_width + $this->y_offset;
               $this->x_position = $this->x_offset;
               $this->icon_per_row_count = 0;
               $this->row_count++;
          }
          else
          {
               $this->x_position = $this->x_position + $this->icon_width + $this->x_offset;
          }
 
          imagedestroy($this->icon);
     }
 
     if($this->icon_type == ‘png’)
     {
          imagepng($this->new_sprite, «{$this->path}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘gif’)
     {
          imagegif($this->new_sprite, $this->path.’.’.$this->icon_type);
     }
     else if($this->icon_type == ‘jpg’ || $this->icon_type == ‘jpeg’)
     {
          imagejpeg($this->new_sprite, $this->path.’.’.$this->icon_type);
     }
     imagedestroy($this->new_sprite);
}

Прежде чем мы поближе познакомимся с этим методом, нам нужно сначала определить несколько настроек.

  • x_position — Когда мы будем повторять «имена_имя», нам нужно будет вычислить смещение по x для каждого нового значка в строке. Мы начнем с использования свойства x_offset, которое было определено в нашей форме Sprite Builder.
  • y_position — мы будем использовать свойство y_offset, которое также было определено в нашей форме Sprite Builder, чтобы установить начальное положение значка вдоль оси Y. Как только мы достигнем предела значков для этой строки, мы пересчитаем y-положение, чтобы переместить следующие и следующие значки вниз на 1 строку.
  • icon_per_row_count — Первоначально, это будет установлено в 0. По мере того как мы перебираем наши ‘icon_names’ и добавляем их в спрайт, мы увеличиваем это на 1 для каждого значка.
  • sprite_width — здесь мы рассчитаем ширину изображения спрайта, используя некоторые значения, которые мы собрали в нашей форме Sprite Builder
  • sprite_height — Кроме того, мы также рассчитаем высоту изображения спрайта, используя некоторые из тех же значений, которые мы собрали в FORM
01
02
03
04
05
06
07
08
09
10
function create_image()
     {
          $this->x_position = $this->x_offset;
          $this->y_position = $this->y_offset;
  
          $this->icon_per_row_count = 0;
  
          $this->sprite_width = (($this->icon_width + $this->x_offset) * $this->icons_per_row) + $this->x_offset;
          $this->sprite_height = (($this->icon_height + $this->y_offset) * ceil($this->icon_total / $this->icons_per_row)) + $this->y_offset;
     }

ШИРИНА — Чтобы определить ширину изображения Sprite, мы добавим ширину каждого значка к его x_offset, указанному в ФОРМЕ Sprite Builder.

Затем мы умножим это значение на общее количество значков на предел строки, указанное в ФОРМЕ Sprite Builder.

Наконец, мы добавим x_offset к этому целому числу. Это даст спрайту поле по правой стороне или, если хотите, добавит изображения по правой стороне спрайта.

ВЫСОТА — чтобы рассчитать высоту изображения Sprite, мы добавим высоту каждого значка к его y_offset, указанному в ФОРМЕ Sprite Builder.

Затем мы умножим это на общее количество значков, которое у нас есть, деленное на количество значков, которые у нас есть на строку, округленное до следующего целого числа, используя метод ceil .

Наконец, мы добавим y_offset к этому целому числу, чтобы дать спрайту поле по нижней части, или, если хотите, «добавим» изображения вдоль нижней части спрайта.

Определив размеры спрайтов, мы можем теперь создать реальное изображение.

Для этого мы будем использовать команду imagecreatetruecolor .

Эта команда принимает два аргумента, ширину и высоту. Мы будем использовать только что рассчитанные значения sprite_width и sprite_height.

01
02
03
04
05
06
07
08
09
10
11
12
function create_image()
     {
          $this->x_position = $this->x_offset;
          $this->y_position = $this->y_offset;
  
          $this->icon_per_row_count = 0;
  
          $this->sprite_width = (($this->icon_width + $this->x_offset) * $this->icons_per_row) + $this->x_offset;
          $this->sprite_height = (($this->icon_height + $this->y_offset) * ceil($this->icon_total / $this->icons_per_row)) + $this->y_offset;
  
          $this->new_sprite = imagecreatetruecolor($this->sprite_width, $this->sprite_height);
     }

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

Мы делаем это с помощью команды imagesavealpha .

Эта команда принимает два аргумента: источник изображения и логическое значение, которое определяет, хотите ли вы сохранить прозрачность для этого изображения.

Мы укажем true для второго параметра.

01
02
03
04
05
06
07
08
09
10
11
12
13
function create_image()
     {
          $this->x_position = $this->x_offset;
          $this->y_position = $this->y_offset;
  
          $this->icon_per_row_count = 0;
  
          $this->sprite_width = (($this->icon_width + $this->x_offset) * $this->icons_per_row) + $this->x_offset;
          $this->sprite_height = (($this->icon_height + $this->y_offset) * ceil($this->icon_total / $this->icons_per_row)) + $this->y_offset;
  
          $this->new_sprite = imagecreatetruecolor($this->sprite_width, $this->sprite_height);
          imagesavealpha($this->new_sprite, true);
     }

С нашим изображением, созданным и помеченным для прозрачности, мы теперь определим его значения цвета и прозрачности.

Мы сделаем это с помощью команды imagecolorallocatealpha .

Эта команда принимает пять аргументов: источник изображения, красный канал, зеленый канал, синий канал и альфа-канал (прозрачность).

Мы определим наш источник изображения и установим для всех цветовых каналов значение 0, а для альфа-канала, который используется для прозрачности, зададим значение 127, которое является максимальным или полностью прозрачным.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
function create_image()
     {
          $this->x_position = $this->x_offset;
          $this->y_position = $this->y_offset;
  
          $this->icon_per_row_count = 0;
  
          $this->sprite_width = (($this->icon_width + $this->x_offset) * $this->icons_per_row) + $this->x_offset;
          $this->sprite_height = (($this->icon_height + $this->y_offset) * ceil($this->icon_total / $this->icons_per_row)) + $this->y_offset;
  
          $this->new_sprite = imagecreatetruecolor($this->sprite_width, $this->sprite_height);
          imagesavealpha($this->new_sprite, true);
  
          $this->new_sprite_opacity= imagecolorallocatealpha($this->new_sprite, 0, 0, 0, 127);
     }

Определив цвет и прозрачность наших спрайтов, мы теперь заполняем изображение этими значениями с помощью команды imagefill .

Эта команда принимает четыре аргумента: источник изображения, координату x, с которой начинается заливка, координату y, с которой начинается заливка, и настройки цвета / прозрачности, которые мы указали на предыдущем шаге.

Мы начнем заполнение с позиции 0,0, чтобы заполнить все изображение.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
function create_image()
     {
          $this->x_position = $this->x_offset;
          $this->y_position = $this->y_offset;
  
          $this->icon_per_row_count = 0;
  
          $this->sprite_width = (($this->icon_width + $this->x_offset) * $this->icons_per_row) + $this->x_offset;
          $this->sprite_height = (($this->icon_height + $this->y_offset) * ceil($this->icon_total / $this->icons_per_row)) + $this->y_offset;
  
          $this->new_sprite = imagecreatetruecolor($this->sprite_width, $this->sprite_height);
          imagesavealpha($this->new_sprite, true);
  
          $this->new_sprite_opacity= imagecolorallocatealpha($this->new_sprite, 0, 0, 0, 127);
          imagefill($this->new_sprite, 0, 0, $this->new_sprite_opacity);
     }

Теперь, когда мы создали базовое изображение для нашего Sprite с прозрачностью, нам нужно перебрать значки в нашем массиве ‘icon_names’, извлечь их соответствующие изображения и скопировать их по отдельности в наш спрайт.

Вот общее описание шагов, которые мы предпримем в нашем цикле foreach:

  • Переберите все ‘icon_names’ в массиве ‘icon_name’, используя оператор foreach
    • Определите тип файла значка и создайте для него новое изображение, используя соответствующий метод imagecreatefrom.
    • Используйте команду imagecopy, чтобы скопировать значок в наш спрайт, указав его смещение внутри спрайта, используя свойства ‘x_position’ и ‘y_position’
    • Увеличьте наш icon_per_row_count на 1, поскольку мы только что добавили новый значок в Sprite.
    • Определите, достигли ли мы предела ‘icons_per_row’, сравнив значение нашего предела ‘icons_per_row’ с текущим значением ‘icon_per_row_count’
      • Если количество значков, которые мы итерировали до сих пор, icon_per_row_count, соответствует пределу icons_per_row, нам нужно будет переместиться вниз на строку, пересчитав наши x_position и y_position
        • Мы настроим y_position так, чтобы мы копировали наши иконки в «следующую» строку спрайта
        • Мы «сбросим» x_position обратно в начало новой строки — крайнюю левую сторону спрайта
      • Кроме того, мы сбросим наш ‘icon_per_row_count’ на 0 и увеличим наш ‘row_count’ на 1
    • Если мы не достигли предела ‘icons_per_row’, мы просто пересчитаем свойство ‘x_position’, чтобы скопировать следующий значок ниже по оси X
  • Завершить цикл foreach
  • Теперь мы будем использовать команду imagedestroy, чтобы уничтожить текущий значок, с которым мы работаем в GD, так как он нам больше не нужен

Вот как будет выглядеть код, начиная с цикла foreach:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
foreach ($this->icon_name as $image)
{
     if($this->icon_type == ‘png’)
     {
          $this->icon = imagecreatefrompng(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘gif’)
     {
          $this->icon = imagecreatefromgif(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘jpg’ || $this->icon_type == ‘jpeg’)
     {
          $this->icon = imagecreatefromjpeg(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
 
     imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
 
     $this->icon_per_row_count++;
 
     if ($this->icon_per_row_count == $this->icons_per_row)
     {
          $this->y_position = $this->y_position + $this->icon_width + $this->y_offset;
          $this->x_position = $this->x_offset;
          $this->icon_per_row_count = 0;
          $this->row_count++;
     }
     else
     {
          $this->x_position = $this->x_position + $this->icon_width + $this->x_offset;
     }
 
     imagedestroy($this->icon);
}

Внутри цикла вы увидите, что мы начинаем с определения типа изображения.

Затем мы создаем соответствующее изображение для «icon_name», с которым мы работаем.

Мы получаем фактическое изображение, объединяя свойство ‘icon_source’ со свойствами ‘icon_name’ и ‘icon_type’.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
foreach ($this->icon_name as $image)
{
     if($this->icon_type == ‘png’)
     {
          $this->icon = imagecreatefrompng(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘gif’)
     {
          $this->icon = imagecreatefromgif(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘jpg’ || $this->icon_type == ‘jpeg’)
     {
          $this->icon = imagecreatefromjpeg(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
}

Вы заметите выше, что мы используем фигурные скобки.

Это известно как сложный фигурный синтаксис .

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

Это позволяет вам использовать имя переменной рядом с любым символом, сохраняя при этом отдельную переменную.

Он также более удобен для чтения, чем обычная конкатенация, и особенно полезен при работе с правилами CSS, в которых буквы, такие как «px» или «em», сразу же следуют за значением свойства.

Например: background-position: {$ foo} px {$ bar} px.

Далее мы скопируем этот значок на наше изображение спрайта с помощью команды imagecopy .

Команда imagecopy принимает восемь параметров: конечное изображение, исходное изображение, координату x на цели, координату y на цели, координату x исходного изображения, координату y исходного изображения, ширину исходного изображения и высоту исходного изображения. ,

Мы определим наш new_sprite в качестве цели для копии.

Мы будем использовать свойства ‘x_position’ и ‘y_position’ соответственно, чтобы определить расположение значков на спрайте.

Мы установим исходные координаты для нашего значка на 0, 0, чтобы скопировать весь значок.

Наконец, мы будем использовать свойства ‘icon_width’ и ‘icon_’height’ соответственно, чтобы установить размеры значков в Sprite.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
foreach ($this->icon_name as $image)
{
     if($this->icon_type == ‘png’)
     {
          $this->icon = imagecreatefrompng(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘gif’)
     {
          $this->icon = imagecreatefromgif(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘jpg’ || $this->icon_type == ‘jpeg’)
     {
          $this->icon = imagecreatefromjpeg(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
 
     imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
}

Скопировав иконку в Sprite, мы увеличим наш icon_per_row_count на 1

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
foreach ($this->icon_name as $image)
{
     if($this->icon_type == ‘png’)
     {
          $this->icon = imagecreatefrompng(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘gif’)
     {
          $this->icon = imagecreatefromgif(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘jpg’ || $this->icon_type == ‘jpeg’)
     {
          $this->icon = imagecreatefromjpeg(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
 
     imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
 
     $this->icon_per_row_count++;
}

Теперь мы проверим, достигли ли мы максимального предела изображения вдоль оси x (по горизонтали).

Мы делаем это, сравнивая количество строк изображения с пределом images_per_row, указанным в нашей форме Sprite Builder.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
foreach ($this->icon_name as $image)
{
     if($this->icon_type == ‘png’)
     {
          $this->icon = imagecreatefrompng(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘gif’)
     {
          $this->icon = imagecreatefromgif(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘jpg’ || $this->icon_type == ‘jpeg’)
     {
          $this->icon = imagecreatefromjpeg(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
 
     imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
 
     $this->icon_per_row_count++;
 
     if ($this->icon_per_row_count == $this->icons_per_row)
     {
     }
     else
     {
     }
 
}

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

  • Пересчитайте y_position для наших значков, чтобы переместить их вниз в новую строку на изображении спрайта.
  • Сбросьте x_position для следующего правила иконки в положение по умолчанию, которое является начальной / левой стороной нашего изображения спрайта
  • Сбросим наш icon_per_row_count на 0, так как в этом ряду еще нет изображений
  • Увеличьте нашу ‘row_count’ на 1, так как теперь мы переместились вниз на строку

Чтобы вычислить новую позицию для наших значков вдоль оси Y, нам нужно взять текущее положение y_, добавить к нему значение y_offset и затем добавить к нему высоту значков.

Это будет эффективно перемещать изображение вниз в новую строку, сохраняя при этом значение y_offset, указанное в форме Sprite Builder.

Кроме того, мы снова установим наше свойство ‘x_position’ равным нашему свойству ‘x_offset’

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
foreach ($this->icon_name as $image)
{
     if($this->icon_type == ‘png’)
     {
          $this->icon = imagecreatefrompng(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘gif’)
     {
          $this->icon = imagecreatefromgif(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
     else if($this->icon_type == ‘jpg’ || $this->icon_type == ‘jpeg’)
     {
          $this->icon = imagecreatefromjpeg(«{$this->icon_source}{$image}.{$this->icon_type}»);
     }
 
     imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
 
     $this->icon_per_row_count++;
 
     if ($this->icon_per_row_count == $this->icons_per_row)
     {
          $this->y_position = $this->y_position + $this->icon_width + $this->y_offset;
          $this->x_position = $this->x_offset;
          $this->icon_per_row_count = 0;
          $this->row_count++;
     }
     else
     {
     }
}

Если значения ‘icon_per_row_count’ и ‘icons_per_row’ не совпадают, мы не достигли конца значков в этой строке, и нам просто нужно пересчитать свойство ‘x_position’, чтобы переместить следующий значок дальше вниз вдоль ось х.

Мы делаем это, беря текущее положение x_position и добавляя к нему свойство x_offset, а затем добавляя к нему ширину значков.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
foreach ($this->icon_name as $image)
{
     if($this->icon_type == 'png')
     {
          $this->icon = imagecreatefrompng("{$this->icon_source}{$image}.{$this->icon_type}");
     }
     else if($this->icon_type == 'gif')
     {
          $this->icon = imagecreatefromgif("{$this->icon_source}{$image}.{$this->icon_type}");
     }
     else if($this->icon_type == 'jpg' || $this->icon_type == 'jpeg')
     {
          $this->icon = imagecreatefromjpeg("{$this->icon_source}{$image}.{$this->icon_type}");
     }
 
     imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
 
     $this->icon_per_row_count++;
 
     if ($this->icon_per_row_count == $this->icons_per_row)
     {
          $this->y_position = $this->y_position + $this->icon_width + $this->y_offset;
          $this->x_position = $this->x_offset;
          $this->icon_per_row_count = 0;
          $this->row_count++;
     }
     else
     {
          $this->x_position = $this->x_position + $this->icon_width + $this->x_offset;
     }
}

Теперь, когда иконки добавлены в спрайт, мы можем уничтожить значок, с которым мы работаем в GD, и завершить цикл foreach.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
foreach ($this->icon_name as $image)
{
     if($this->icon_type == 'png')
     {
          $this->icon = imagecreatefrompng("{$this->icon_source}{$image}.{$this->icon_type}");
     }
     else if($this->icon_type == 'gif')
     {
          $this->icon = imagecreatefromgif("{$this->icon_source}{$image}.{$this->icon_type}");
     }
     else if($this->icon_type == 'jpg' || $this->icon_type == 'jpeg')
     {
          $this->icon = imagecreatefromjpeg("{$this->icon_source}{$image}.{$this->icon_type}");
     }
 
     imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
 
     $this->icon_per_row_count++;
 
     if ($this->icon_per_row_count == $this->icons_per_row)
     {
          $this->y_position = $this->y_position + $this->icon_width + $this->y_offset;
          $this->x_position = $this->x_offset;
          $this->icon_per_row_count = 0;
          $this->row_count++;
     }
     else
     {
          $this->x_position = $this->x_position + $this->icon_width + $this->x_offset;
     }
 
     imagedestroy($this->icon);
}

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

Опять же, мы сделаем это в соответствии с типом файла изображения.

Хорошо использовать команды imagepng , imagegif или imagejpeg соответственно.

Как только мы выведем Sprite в файл, мы можем уничтожить изображение «спрайта», с которым мы работали в GD.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
foreach ($this->icon_name as $image)
{
     if($this->icon_type == 'png')
     {
          $this->icon = imagecreatefrompng("{$this->icon_source}{$image}.{$this->icon_type}");
     }
     else if($this->icon_type == 'gif')
     {
          $this->icon = imagecreatefromgif("{$this->icon_source}{$image}.{$this->icon_type}");
     }
     else if($this->icon_type == 'jpg' || $this->icon_type == 'jpeg')
     {
          $this->icon = imagecreatefromjpeg("{$this->icon_source}{$image}.{$this->icon_type}");
     }
 
     imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
 
     $this->icon_per_row_count++;
 
     if ($this->icon_per_row_count == $this->icons_per_row)
     {
          $this->y_position = $this->y_position + $this->icon_width + $this->y_offset;
          $this->x_position = $this->x_offset;
          $this->icon_per_row_count = 0;
          $this->row_count++;
     }
     else
     {
          $this->x_position = $this->x_position + $this->icon_width + $this->x_offset;
     }
 
     imagedestroy($this->icon);
}
 
if($this->icon_type == 'png')
{
     imagepng($this->new_sprite, "{$this->path}.{$this->icon_type}");
}
else if($this->icon_type == 'gif')
{
     imagegif($this->new_sprite, $this->path.'.'.$this->icon_type);
}
else if($this->icon_type == 'jpg' || $this->icon_type == 'jpeg')
{
     imagejpeg($this->new_sprite, $this->path.'.'.$this->icon_type);
}
 
imagedestroy($this->new_sprite);

Вот полный метод create_image () во всей его полноте:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
function create_image()
{
     $this->x_position = $this->x_offset;
     $this->y_position = $this->y_offset;
 
     $this->icon_per_row_count = 0;
 
     $this->sprite_width = (($this->icon_width + $this->x_offset) * $this->icons_per_row) + $this->x_offset;
     $this->sprite_height = (($this->icon_height + $this->y_offset) * ceil($this->icon_total / $this->icons_per_row)) + $this->y_offset;
 
     $this->new_sprite = imagecreatetruecolor($this->sprite_width, $this->sprite_height);
     imagesavealpha($this->new_sprite, true);
 
     $this->new_sprite_opacity= imagecolorallocatealpha($this->new_sprite, 0, 0, 0, 127);
     imagefill($this->new_sprite, 0, 0, $this->new_sprite_opacity);
 
     foreach ($this->icon_name as $image)
     {
          if($this->icon_type == 'png')
          {
               $this->icon = imagecreatefrompng("{$this->icon_source}{$image}.{$this->icon_type}");
          }
          else if($this->icon_type == 'gif')
          {
               $this->icon = imagecreatefromgif("{$this->icon_source}{$image}.{$this->icon_type}");
          }
          else if($this->icon_type == 'jpg' || $this->icon_type == 'jpeg')
          {
               $this->icon = imagecreatefromjpeg("{$this->icon_source}{$image}.{$this->icon_type}");
          }
 
          imagecopy($this->new_sprite, $this->icon, $this->x_position, $this->y_position, 0, 0, $this->icon_width, $this->icon_height);
 
          $this->icon_per_row_count++;
 
          if ($this->icon_per_row_count == $this->icons_per_row)
          {
               $this->y_position = $this->y_position + $this->icon_width + $this->y_offset;
               $this->x_position = $this->x_offset;
               $this->icon_per_row_count = 0;
               $this->row_count++;
          }
          else
          {
               $this->x_position = $this->x_position + $this->icon_width + $this->x_offset;
          }
 
          imagedestroy($this->icon);
     }
 
     if($this->icon_type == 'png')
     {
          imagepng($this->new_sprite, "{$this->path}.{$this->icon_type}");
     }
     else if($this->icon_type == 'gif')
     {
          imagegif($this->new_sprite, $this->path.'.'.$this->icon_type);
     }
     else if($this->icon_type == 'jpg' || $this->icon_type == 'jpeg')
     {
          imagejpeg($this->new_sprite, $this->path.'.'.$this->icon_type);
     }
     imagedestroy($this->new_sprite);
}


Нашим вторым методом будет функция create_stylesheet (). Этот метод выведет новую таблицу стилей для нашего спрайта изображения.

Наш первый селектор будет селектором класса, который будет соответствовать «target_name», указанному в нашей форме Sprite Builder.

Мы преобразуем это ‘target_name’ в нижний регистр, так как имена классов всегда должны начинаться со строчной буквы.

Этот класс будет иметь только одно свойство background-image, и значением этого свойства будет только что созданное нами изображение спрайта.

Мы переберем наш массив ‘icon_name’ и создадим новое правило для каждого ‘icon_name’, используя это имя в качестве селектора класса.

Каждое из этих правил будет иметь только одно свойство background-position, и значение этого свойства будет зависеть от размеров иконки, смещений x / y и количества отображаемых нами иконок в строке.

Свойство CSS background-position будет соответствовать положению значка x / y на изображении спрайта.

Прежде чем идти дальше, нам нужно определить несколько параметров в этом методе.

  • icon_per_row_count — Первоначально, это будет установлено в 0. По мере того, как мы перебираем наши ‘icon_names’ и добавляем их в спрайт, мы увеличиваем это на 1 для каждого значка.
  • row_count — подобно ‘icon_per_row_count’, нам нужно отслеживать, в какой строке мы находимся. Мы будем увеличивать количество строк на 1 каждый раз, когда достигаем предела ‘icons_per_row’ в нашем цикле foreach и перемещаемся вниз по строке
  • x_position — Когда мы будем перебирать ‘icon_names’, нам нужно будет вычислить положение фона для каждого значка внутри спрайта. Это будет сервер как позиция ‘x’ в правиле CSS.
  • y_position — Подобно x_position, как только мы достигнем предела ‘icons_per_row’ в нашем цикле, нам нужно будет вычислить новую позицию ‘y’ для нашего правила класса.
1
2
3
4
5
6
7
function create_stylesheet()
{
     $this->icon_per_row_count = 0;
     $this->row_count = 0;
     $this->x_position = ($this->x_offset * (-1));
     $this->y_position = ($this->y_offset * (-1));
}

Чтобы определить наши базовые координаты x / y, мы возьмем нашу настройку x_offset и нашу настройку y_offset, которые были указаны в форме Sprite Builder, и умножим каждую из них на отрицательную 1.

Позиция 0px 0px на самом спрайте будет самым верхним левым углом изображения.

Нам нужно переместить изображение «вверх» и «влево» — отсюда и отрицательные значения.

Кроме того, поскольку каждый значок смещен по вертикали и горизонтали на смещения по осям x и y, указанные в нашей форме Sprite Builder, мы будем использовать эти настройки для соответствующей установки нашего фона.

Теперь, когда у нас есть базовые настройки и расчеты, мы можем создать нашу таблицу стилей.

В PHP это можно сделать с помощью команды fopen в режиме ‘a’, который создаст файл, если он еще не существует, и запишет новые данные в конец файла.

Мы объединяем нашу настройку «путь» из Sprite Builder FORM с расширением файла для таблиц стилей, которое называется «css».

1
2
3
4
5
6
7
8
9
function create_stylesheet()
{
     $this->icon_per_row_count = 0;
     $this->row_count = 0;
     $this->x_position = ($this->x_offset * (-1));
     $this->y_position = ($this->y_offset * (-1));
  
     $create_css = fopen($this->path.'.css', 'a');
}

Создав и открыв новый файл CSS, мы теперь можем определить наше основное правило CSS.

Это правило будет своего рода мета-правилом для всех наших изображений спрайтов.

Его единственным свойством будет ‘background-image’. Этот класс будет использоваться вместе с правилами класса для каждого отдельного значка в нашем спрайте.

В качестве базового класса мы будем использовать ‘target_name’, указанное в нашей форме Sprite Builder, преобразованной в нижний регистр. Нам нужно только определить свойство background-image как новое изображение спрайта, которое мы только что создали.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
function create_stylesheet()
{
     $this->icon_per_row_count = 0;
     $this->row_count = 0;
     $this->x_position = ($this->x_offset * (-1));
     $this->y_position = ($this->y_offset * (-1));
  
     $create_css = fopen($this->path.'.css', 'a');
     $base_class = strtolower($this->target_name);
  
     $base_css_rule =
".$base_class {
     background-image: url({$this->target_name}.{$this->icon_type});
}\n";
«;
  
}

Вы заметите выше, что мы используем фигурные скобки.

Это известно как сложный фигурный синтаксис .

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

Это позволяет вам использовать имя переменной рядом с любым символом, сохраняя при этом отдельную переменную.

Он также более удобен для чтения, чем обычная конкатенация, и особенно полезен при работе с правилами CSS, в которых буквы, такие как «px» или «em», сразу же следуют за значением свойства.

Например: background-position: {$ foo} px {$ bar} px.

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

Эта команда принимает два параметра: исходный файл, в который мы пишем, и контент, который мы будем писать.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
function create_stylesheet()
{
     $this->icon_per_row_count = 0;
     $this->row_count = 0;
     $this->x_position = ($this->x_offset * (-1));
     $this->y_position = ($this->y_offset * (-1));
  
     $create_css = fopen($this->path.'.css', 'a');
     $base_class = strtolower($this->target_name);
  
     $base_css_rule =
".$base_class {
     background-image: url({$this->target_name}.{$this->icon_type});
}\n";
«;
  
     fwrite($create_css, $base_css_rule);
  
}

С нашим базовым правилом мы теперь будем перебирать каждое отдельное имя значка.

Выше вы заметите, что мы еще не закрыли наш CSS-файл.

Это хорошо, так как нам не нужно изменять его права доступа с помощью chmod, так как он уже открыт.

В продолжение, каждая иконка будет иметь различную позицию вдоль оси X, поэтому нам нужно пересчитать позицию X перед каждым новым правилом.

Кроме того, как только мы достигнем предела ‘icons_per_row’, указанного в нашей форме Sprite Builder, нам необходимо пересчитать положение значков вдоль оси Y.

Вот общий план шагов, которые мы предпримем здесь:

  • Начните цикл foreach для всех ‘icon_names’ в нашем массиве ‘icon_name’ и немедленно преобразуйте имя файла в символы нижнего регистра.
    • Определите новое правило CSS для текущего элемента в нашей итерации, используя свойства x_position и y_position
    • Запишите новое правило CSS в наш файл CSS, который все еще открыт
    • Увеличьте наше свойство icon_per_row_count на 1
    • Определите, достигли ли мы предела ‘icons_per_row’, сравнив значение нашего атрибута ‘icons_per_row’ со значением нашего свойства ‘icon_per_row_count’
      • Если количество значков, через которые мы перебрали ‘icon_per_row_count’, соответствует пределу ‘icons_per_row’, мы достигли конца изображений для этой строки. Таким образом, нам нужно пересчитать наши x_position и y_positions соответственно
        • Мы настроим y_position для перемещения вниз к следующему ряду — мы делаем это, «перемещая изображение вверх»
        • Мы «сбросим» положение x_ в начало значков для этой строки — крайнюю левую сторону спрайта
      • Кроме того, мы сбросим наш ‘icon_per_row_count’ на 0 и увеличим наш ‘row_count’ на 1
    • Если мы не достигли предела ‘icons_per_row’, мы пересчитаем наше свойство ‘x_position’, чтобы переместить положение фона дальше вдоль оси x к следующему значку.
  • Завершить цикл foreach
  • Закройте файл CSS, так как мы закончили написание всех новых правил класса

Вот как будет выглядеть код, начиная с цикла foreach:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_css_rule =
".{$icon_name} {
     background-position: {$this->x_position}px {$this->y_position}px;
}
«;
               fwrite($create_css, $new_css_rule);
  
               $this->icon_per_row_count++;
  
               if ($this->icon_per_row_count == $this->icons_per_row)
               {
                    $this->y_position = $this->y_position - $this->y_offset - $this->icon_height;
                    $this->x_position = ($this->x_offset * (-1));
                    $this->icon_per_row_count = 0;
                    $this->row_count++;
               }
               else
               {
                    $this->x_position = $this->x_position - $this->x_offset - $this->icon_width;
               }
          }
          fclose($create_css);

В цикле вы увидите, что мы начинаем с определения нашего нового правила CSS. Мы будем использовать базовые значения «x_position» и «y_position», которые мы определили ранее.

1
2
3
4
5
6
7
8
9
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_css_rule =
".{$icon_name} {
     background-position: {$this->x_position}px {$this->y_position}px;
}
«;
          }

Далее, мы будем писать эту строку в файл CSS , используя FWRITE команды

01
02
03
04
05
06
07
08
09
10
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_css_rule =
".{$icon_name} {
     background-position: {$this->x_position}px {$this->y_position}px;
}
«;
               fwrite($create_css, $base_css_rule);
          }

Затем мы увеличим наш icon_per_row_count на 1

01
02
03
04
05
06
07
08
09
10
11
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_css_rule =
".{$icon_name} {
     background-position: {$this->x_position}px {$this->y_position}px;
}
«;
               fwrite($create_css, $base_css_rule);
               $this->icon_per_row_count++;
          }

Далее мы проверим, достигли ли мы конца изображения вдоль оси x (по горизонтали).

Мы делаем это путем сравнения текущего количества изображений со свойством images_per_row, которое было определено в нашей форме Sprite Builder.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_css_rule =
".{$icon_name} {
     background-position: {$this->x_position}px {$this->y_position}px;
}
«;
               fwrite($create_css, $base_css_rule);
               $this->icon_per_row_count++;
  
               if ($this->icon_per_row_count == $this->icons_per_row)
               {
  
               }
          }

Если значения совпадают, мы достигли конца значков для этой строки, и нам нужно будет сделать следующее:

  • Пересчитайте y_position для наших правил, поскольку нам нужно перейти к следующей строке на изображении спрайта.
  • Сбросьте x_position для следующего правила CSS, так как мы сейчас работаем с крайней левой стороны спрайта
  • Сбросьте наш icon_per_row_count, так как мы еще не написали никаких правил для изображений в этом ряду.
  • Увеличьте нашу ‘row_count’ на 1, так как теперь мы сдвинулись вниз по строке

Вычисление, которое мы используем для определения новой позиции значков вдоль оси y (по вертикали), будет зеркальным отображением вычислений, которые мы используем для определения положения x для каждого значка.

Нам просто нужно взять текущее положение y_, вычесть из него значение y_offset, а затем вычесть из него высоту значков.

Это будет эффективно перемещать изображение «вверх», перенося следующий ряд в «видимую» область.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_css_rule =
".{$icon_name} {
     background-position: {$this->x_position}px {$this->y_position}px;
}
«;
               fwrite($create_css, $base_css_rule);
               $this->icon_per_row_count++;
  
               if ($this->icon_per_row_count == $this->icons_per_row)
               {
                    $this->y_position = $this->y_position - $this->y_offset - $this->icon_height;
                    $this->x_position = ($this->x_offset * (-1));
                    $this->icon_per_row_count = 0;
                    $this->row_count++;
               }
          }

Если значения не совпадают, мы не достигли конца значков в этой строке.

Нам нужно будет пересчитать свойство ‘x_position’, чтобы переместить фоновое положение дальше вниз вдоль оси x в положение следующего значка.

Мы делаем это, беря текущее значение x_position и вычитая свойство x_offset, которое было определено в нашей форме Sprite Builder, а затем вычитая ширину значков, также определенную в нашей форме Sprite Builder.

Это, в основном, прокрутит наше изображение влево, перенеся следующий значок в область просмотра.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_css_rule =
".{$icon_name} {
     background-position: {$this->x_position}px {$this->y_position}px;
}
«;
               fwrite($create_css, $base_css_rule);
               $this->icon_per_row_count++;
  
               if ($this->icon_per_row_count == $this->icons_per_row)
               {
                    $this->y_position = $this->y_position - $this->y_offset - $this->icon_height;
                    $this->x_position = ($this->x_offset * (-1));
                    $this->icon_per_row_count = 0;
                    $this->row_count++;
               }
               else
               {
                    $this->x_position = $this->x_position - $this->x_offset - $this->icon_width;
               }
          }

Теперь, когда мы перебрали все наши ‘icon_names’ и определили новое имя класса CSS и правило для каждого из них, мы можем пойти дальше и закрыть этот файл.

Вот и все для нашего метода create_stylesheet!

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_css_rule =
".{$icon_name} {
     background-position: {$this->x_position}px {$this->y_position}px;
}
«;
               fwrite($create_css, $base_css_rule);
               $this->icon_per_row_count++;
  
               if ($this->icon_per_row_count == $this->icons_per_row)
               {
                    $this->y_position = $this->y_position - $this->y_offset - $this->icon_height;
                    $this->x_position = ($this->x_offset * (-1));
                    $this->icon_per_row_count = 0;
                    $this->row_count++;
               }
               else
               {
                    $this->x_position = $this->x_position - $this->x_offset - $this->icon_width;
               }
               fclose($create_css);
          }

Вот полный метод create_stylesheet () во всей его полноте:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
     function create_stylesheet()
     {
          $this->icon_per_row_count = 0;
          $this->row_count = 0;
          $this->x_position = ($this->x_offset * (-1));
          $this->y_position = ($this->y_offset * (-1));
  
          $create_css = fopen($this->path.'.css', 'a');
          $base_class = strtolower($this->target_name);
  
          $base_css_rule =
".$base_class {
     background-image: url({$this->target_name}.{$this->icon_type});
}\n";
          fwrite($create_css, $base_css_rule);
  
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_css_rule =
".{$icon_name} {
     background-position: {$this->x_position}px {$this->y_position}px;
}
«;
               fwrite($create_css, $new_css_rule);
  
               $this->icon_per_row_count++;
  
               if ($this->icon_per_row_count == $this->icons_per_row)
               {
                    $this->y_position = $this->y_position - $this->y_offset - $this->icon_height;
                    $this->x_position = ($this->x_offset * (-1));
                    $this->icon_per_row_count = 0;
                    $this->row_count++;
               }
               else
               {
                    $this->x_position = $this->x_position - $this->x_offset - $this->icon_width;
               }
          }
          fclose($create_css);
     }


Наш последний метод будет функцией create_html.

Этот метод выведет предварительный просмотр HTML для нашего спрайта изображения и перечислит соответствующие имена классов для каждого изображения.

Мы начнем с определения нескольких базовых настроек. Затем мы создадим HTML-заголовок, а также часть тела.

В заголовке мы определим несколько правил CSS для содержимого страницы. Некоторые из этих правил будут динамичными относительно размеров наших значков.

Как только мы запишем эти базовые данные в наш HTML-файл, мы начнем итерацию по нашему массиву ‘icon_name’ с циклом foreach.

В этом цикле мы создадим новые DIV, SPAN и P ELEMENT для каждой иконки.

Нашему SPAN ELEMENT будут даны имена CLASS, соответствующие «icon_name», с которым мы работаем, а также имя цели для нашего изображения спрайта, оба преобразуются в нижний регистр.

Как только мы запишем все эти данные в наш HTML-файл, мы добавим в файл новую строку, которая закроет все открытые теги.

Затем мы закроем сам HTML-файл.

Прежде чем идти дальше, мы определим свойство в этом методе.

  • div_width — Проще говоря, мы определяем ширину контейнера для иконки и текста. Мы добавим 245 пикселей к ширине иконки, с которой мы работаем. В большинстве случаев этого будет достаточно, чтобы содержать значок и текст. Оглядываясь назад, можно получить длину каждого ‘icon_name’ в массиве и установить ширину этого DIV равной длине самого длинного имени плюс ширина значков. Но для простоты давайте просто используем 245px.
1
2
3
4
function create_html()
{
     $this->div_width = $this->icon_width + 245;
}

После этого мы создадим наш новый HTML-файл с командой fopen в режиме ‘a’.

Это создаст файл, если он еще не существует, и запишет все новые данные в конец файла.

Мы объединяем нашу настройку «путь» из Sprite Builder FORM с расширением файла «html».

1
2
3
4
5
6
function create_html()
{
     $this->div_width = $this->icon_width + 245;
 
     $sprite_html = fopen($this->path.'.html', 'a');
}

Создав и открыв новый HTML-файл, мы теперь можем создать наш элемент HEAD.

Кроме того, мы откроем тег BODY TAG, DIV для всего нашего контента, а также элемент заголовка первого уровня, который будет использоваться в качестве заголовка страницы.

Ниже вы заметите, что мы выводим наше свойство ‘target_name’ как часть заголовка страницы, наше свойство ‘icon_height’ как высоту для DIV.icon и наше свойство ‘div_width’ как ширину DIV.icon.

Кроме того, мы будем использовать наши свойства ‘icon_height’ и ‘icon_width’ как значения высоты и ширины для SPAN, который будет содержать фоновое изображение.

Наконец, мы снова повторим наше имя_целевого объекта в элементе HEADER первого уровня.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
     function create_html()
     {
          $this->div_width = $this->icon_width + 245;
          $sprite_html = fopen($this->path.'.html', 'a');
  
          $html_head =
"<!doctype html>
<html lang=’en’>
  
<head>
     <title>{$this->target_name} sprite classes</title>
     <meta charset=’utf-8′>
  
     <link rel='stylesheet' type='text/css' href='{$this->target_name}.css'>
  
     <style type=’text/css’>
          H1
          {
               color: #434343;
               font: small-caps bold 33.1pt Helvetica;
               margin-left: 20px;
               text-align: left;
          }
          DIV#content
          {
               margin: 0 auto;
          }
          DIV.icon
          {
               float: left;
               height: {$this->icon_height}px;
               margin: 0px 0px 25px 20px;
               width: {$this->div_width}px;
          }
          DIV.icon SPAN
          {
               float: left;
               height: {$this->icon_height}px;
               width: {$this->icon_width}px;
          }
          DIV.icon P
          {
               font: 10pt/{$this->icon_height}px Helvetica;
               margin: 0 0 0 45px;
          }
     </style>
</head>
  
<body>
  
     <div id=’content’>
  
         <h1>{$this->target_name} sprite classes</h1>
«;
     }

Вы заметите выше, что мы используем фигурные скобки.

Это известно как сложный фигурный синтаксис .

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

Это позволяет вам использовать имя переменной рядом с любым символом, сохраняя при этом отдельную переменную.

Он также более удобен для чтения, чем обычная конкатенация, и особенно полезен при работе с правилами CSS, в которых буквы, такие как «px» или «em», сразу же следуют за значением свойства.

Например: background-position: {$ foo} px {$ bar} px.

Теперь, когда мы определили наш HEAD и открыли тег BODY TAG, а также контейнер DIV, мы можем записать эти данные в наш файл HTML, используя fwrite .

Нам просто нужно указать файл, в который мы пишем, а также контент, который мы пишем.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
     function create_html()
     {
          $this->div_width = $this->icon_width + 245;
          $sprite_html = fopen($this->path.'.html', 'a');
  
          $html_head =
"<!doctype html>
<html lang=’en’>
  
<head>
     <title>{$this->target_name} sprite classes</title>
     <meta charset=’utf-8′>
  
     <link rel='stylesheet' type='text/css' href='{$this->target_name}.css'>
  
     <style type=’text/css’>
          H1
          {
               color: #434343;
               font: small-caps bold 33.1pt Helvetica;
               margin-left: 20px;
               text-align: left;
          }
          DIV#content
          {
               margin: 0 auto;
          }
          DIV.icon
          {
               float: left;
               height: {$this->icon_height}px;
               margin: 0px 0px 25px 20px;
               width: {$this->div_width}px;
          }
          DIV.icon SPAN
          {
               float: left;
               height: {$this->icon_height}px;
               width: {$this->icon_width}px;
          }
          DIV.icon P
          {
               font: 10pt/{$this->icon_height}px Helvetica;
               margin: 0 0 0 45px;
          }
     </style>
</head>
  
<body>
  
     <div id=’content’>
  
         <h1>{$this->target_name} sprite classes</h1>
«;
          fwrite($sprite_html, $html_head);
     }

Теперь мы можем начать итерацию по нашему массиву icon_name с циклом foreach.

В этом цикле мы сначала преобразуем имя значка в нижний регистр.

Затем мы создадим DIV, который будет содержать SPAN для нашего изображения значка, а также P для имен классов, связанных с этим изображением.

Класс SPAN, а также текст параграфа будут использовать наши свойства имени ‘target_name’ и ‘icon_name’ name.

Помните, что ‘target_name’ было указано в нашей форме Sprite Builder.

Он будет служить именем нашего Sprite Image, а также именем класса по умолчанию для всех изображений в этом спрайте.

Единственным CSS-свойством, связанным с «target_name», будет свойство «background-image», а его значением будет само изображение спрайта.

Все другие имена классов, которые мы получим из массива ‘icon_name’, будут иметь одно свойство CSS — ‘background-position’ спрайта, в котором находится изображение, соответствующее классу этого SPAN.

Вот как будет выглядеть цикл foreach:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_paragraph =
«
          <div class='icon'>
               <span class='{$this->target_name} {$icon_name}'></span>
                 
  
.{$this->target_name} .{$icon_name}
  
  
          </div>
«;
  
          }

Как только мы определили наш контент в строке, мы пойдем дальше и запишем его в наш HTML-файл с помощью команды fwrite .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_paragraph =
«
          <div class='icon'>
               <span class='{$this->target_name} {$icon_name}'></span>
                 
  
.{$this->target_name} .{$icon_name}
  
  
          </div>
«;
               fwrite($sprite_html, $new_paragraph);
          }

Со всем нашим новым содержимым, записанным в файл, мы завершаем цикл foreach, а затем создаем новую строку, которая содержит закрывающие теги для нашего HTML-файла.

Мы запишем эти данные на страницу HTML, а затем закроем саму страницу и все!

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_paragraph =
«
          <div class='icon'>
               <span class='{$this->target_name} {$icon_name}'></span>
                 
  
.{$this->target_name} .{$icon_name}
  
  
          </div>
«;
               fwrite($sprite_html, $new_div);
          }
  
          $close_html =
' </div>
</body>';
  
          fwrite($sprite_html, $close_html);
          fclose($sprite_html);

Вот полный метод create_html ():

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
     function create_html()
     {
  
          $this->div_width = $this->icon_width + 245;
  
          $sprite_html = fopen($this->path.'.html', 'a');
          $html_head =
"<!doctype html>
<html lang=’en’>
  
<head>
     <title>{$this->target_name} sprite classes</title>
     <meta charset=’utf-8′>
  
     <link rel='stylesheet' type='text/css' href='{$this->target_name}.css'>
  
     <style type=’text/css’>
          H1
          {
               color: #434343;
               font: small-caps bold 33.1pt Helvetica;
               margin-left: 20px;
               text-align: left;
          }
          DIV#content
          {
               margin: 0 auto;
          }
          DIV.icon
          {
               float: left;
               height: {$this->icon_height}px;
               margin: 0px 0px 25px 20px;
               width: {$this->div_width}px;
          }
          DIV.icon SPAN
          {
               float: left;
               height: {$this->icon_height}px;
               width: {$this->icon_width}px;
          }
          DIV.icon P
          {
               font: 10pt/{$this->icon_height}px Helvetica;
               margin: 0 0 0 45px;
          }
     </style>
</head>
  
<body>
  
     <div id=’content’>
  
         <h1>{$this->target_name} sprite classes</h1>
«;
  
          fwrite($sprite_html, $html_head);
  
          foreach($this->icon_name as $icon_name)
          {
        $icon_name = strtolower($icon_name);
        $new_paragraph =
«
          <div class='icon'>
               <span class='{$this->target_name} {$icon_name}'></span>
                 
  
.{$this->target_name} .{$icon_name}
  
  
          </div>
«;
               fwrite($sprite_html, $new_div);
          }
  
          $close_html =
' </div>
</body>';
  
          fwrite($sprite_html, $close_html);
          fclose($sprite_html);
     }


This ends the PHP Sprite Framework tutorial! I hope you’ve learned something new from this tut and are able to create and use your own «Sprite Frameworks» with ease!

NOTE: A copy of the Quartz and DF Aqua Gloss icon sets will be included with the source code for demo purposes.