Работа с изображениями
Размер изображения
Отличительной особенностью Less версии 2.2.0 стали встроенные функции для работы с изображениями, которые позволяют получить следующие данные:
- Размер (ширина и высота) —
image-size(url)
. - Ширину —
image-width(url)
. - Высоту —
image-height(url)
.
Для того, чтобы получить ширину изображения, необходимо указать путь до него, относительно того файла, в котором вызывается эта функция.
Замечание
Все примеры из этой части доступны в архиве, который прилагается к этой книге.
Рассмотрим два случая, которые могут вводить новичков в заблуждение:
Случай 1. Один файл
Допустим, что работа ведётся с less-файлом, который находится в директории:
styles/less/_styles.less
В этом файле необходимо узнать ширину или высоту изображения, которое находится в директории:
images/logo.png
В этом случае, любая из трёх функций должна вызываться следующим образом:
@logo-path: "../../images/avatar.jpg";
.logo {
@logo-width: image-width(@logo-path);
@logo-height: image-height(@logo-path);
@logo-size: image-size(@logo-path);
content: "@{logo-size} [@{logo-width} x @{logo-height}]";
}
В итоге, если вы правильно укажете путь до файла изображения из файла, где была вызвана функция, свойство content
получит значение:
.logo {
content: "460px 460px [460px x 460px]";
}
Если же путь будет не верным, то компилятор выдаст ошибку.
Случай 2. Структурный файл
Ранее путь писался относительно того файла, в котором была вызвана та или иная функция для получения размера изображения. Допустим, что у нас имеется конфигурация:
- Рабочий файл:
styles/less/components/_styles.less
- Главный файл:
styles/less/main.less
- Файл изображения:
images/logo.png
Содержимое каждого файла будет таким:
// file: `styles/less/main.less`
@import "components/_styles.less";
// file: `styles/less/components/_styles.less`
@logo-path: "../../images/avatar.jpg";
.logo {
@logo-width: image-width(@logo-path);
@logo-height: image-height(@logo-path);
@logo-size: image-size(@logo-path);
content: "@{logo-size} [@{logo-width} x @{logo-height}]";
}
Хотя файл _styles.less
поменял своё расположение — при компиляции ошибки не будет. Дело в том, что путь, указанный в переменной @logo-path
полностью соответствует ситуации.
Вся хитрость заключается в файле main.less
, который является точкой входа для компилятора. Именно относительно него нужно прописывать любой путь к изображениям.
При попытке указать путь, относительно файла _styles.less
, компилятор выдаст ошибку, говорящую о том, что по указанному пути файл не найден:
FileError: error evaluating function `image-width`: '../../../images/avatar.jpg' wasn't found.
C:\<-- path -->\chapter_4\examples\4.3.2\styles\less\components\_styles.less on line 4, column 16:
3 .logo {
4 @logo-width: image-width(@logo-path);
5 @logo-height: image-height(@logo-path);
Встраиваемые ресурсы
Под встроенными ресурсами стоит понимать закодированный ресурс (картинку, скрипт, стили), содержащийся внутри строки кода.
Сейчас, в виду того, что дизайн веб-приложений становится плоским и материальным, а возможности браузеров растут (количество изображений в оформлении падает), довольно часто можно встреть следующую конструкцию в стилях:
.logo {
/* Пример из документации */
background-image: url('data:image/jpeg;base64,bm90IGFjdHVhbGx5IGEganBlZyBmaWxlCg==');
}
Этот подход используется для того, чтобы уменьшить число HTTP-запросов к серверу и должен применяться только тогда, когда количество и размер изображений достаточно мал.
При обнаружении такой конструкции в подключённых к странице стилях браузер декодирует строку, получает исходное изображение и выводит пользователю.
В багажнике препроцессора Less есть мощная функция data-uri()
, предоставляющая возможность кодировать ресурсы без использования сторонних инструментов.
Синтаксис этой функции таков:
.logo {
background-image: data-uri(mimetype, path);
}
Параметр mimetype определяет строку, содержащую тип изображения для браузера в соответствии с принятым документом RFC 1521. Этот параметр необязателен и его можно опустить, так как компилятор сам в состоянии понять, какой ему ресурс предоставили для кодирования.
Вот пример того, какие изображения можно закодировать с помощью этой функции и её результатов работы:
.logo {
background-image: data-uri("image.jpg");
// url("data:image/jpeg;base64,/9j/7gAOQWRvYmUAZAAAAAAA/9sAQwA...")
background-image: data-uri("image/jpeg;base64", "image.jpg");
// url("data:image/jpeg;base64,/9j/7gAOQWRvYmUAZAAAAAAA/9sAQwA...")
background-image: data-uri("image.png");
// url("data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAAB...")
background-image: data-uri("image.gif");
// url("data:image/gif;base64,R0lGODlhQABAAPeAAP7+/v39/fz8/Pv7...")
background-image: data-uri("image.svg");
// url("data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20e...")
background-image: data-uri("image/svg+xml;charset=UTF-8", "image.svg");
// url("data:image/svg+xml;charset=UTF-8,%3C%3Fxml%20version%3...")
}
Как не сложно заметить, различный результат проявился только у пары, где используется SVG изображение.
SVG-градиенты
Кроме стандартных функций для работы с изображениями и их кодированием, препроцессор Less умеет генерировать SVG-градиенты. Для этого используется функция, которая принимает на вход три параметра: направление, цвет и позиция. Вот синтаксис этой функции:
.gradient {
background-image: svg-gradient(ellipse at center, blue, red 15%);
}
Такой вызов функции породит Base64-код, в котором закодировано изображение сгенерированного градиента:
.gradient {
background-image: url('data:image/svg+xml,%3C%3Fxml%20version%3D%221.0%22%20%3F%3E%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20version%3D%221.1%22%20width%3D%22100%25%22%20height%3D%22100%25%22%20viewBox%3D%220%200%201%201%22%20preserveAspectRatio%3D%22none%22%3E%3CradialGradient%20id%3D%22gradient%22%20gradientUnits%3D%22userSpaceOnUse%22%20cx%3D%2250%25%22%20cy%3D%2250%25%22%20r%3D%2275%25%22%3E%3Cstop%20offset%3D%220%25%22%20stop-color%3D%22%230000ff%22%2F%3E%3Cstop%20offset%3D%2215%25%22%20stop-color%3D%22%23ff0000%22%2F%3E%3C%2FradialGradient%3E%3Crect%20x%3D%22-50%22%20y%3D%22-50%22%20width%3D%22101%22%20height%3D%22101%22%20fill%3D%22url(%23gradient)%22%20%2F%3E%3C%2Fsvg%3E');
}
При декодировании этого кода можно получить внутренности изображения и убедиться, что функция создала верный градиент:
<?xml version="1.0" ?>
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">
<radialGradient id="gradient" gradientUnits="userSpaceOnUse" cx="50%" cy="50%" r="75%">
<stop offset="0%" stop-color="#0000ff"/>
<stop offset="15%" stop-color="#ff0000"/>
</radialGradient>
<rect x="-50" y="-50" width="101" height="101" fill="url(#gradient)" />
</svg>
Конечно, функция может генерировать не только эллиптические градиенты. В список поддерживаемых направлений входят следующие значения:
- to (top | right | bottom | left)
- комбинации: to top bottom | to right bottom и прочие
- ellipse
- ellipse at center
Внимание
Если вы используете компилятор версии ниже 2.2.0, то Base64 кодирование не поддерживается и, как следствие, функция
data-uri()
не будет работать. Кроме того, функцияsvg-gradient()
не будет кодировать результат своей работы в Base64-код.