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

Элемент и визуальный контент

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

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

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

Элемент изображения должен иметь дело с теми же ситуациями: размер элемента не обязательно совпадает с размером изображения. Правильный способ определения размера и положения визуального элемента зависит от дизайна; мы должны предоставить свойства, чтобы указать, что происходит. В Fuse я назвал это StretchMode; В CSS это свойство background-size или object-fit.

Точность пикселей и точек

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

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

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

Режим с точностью до пикселя сложно использовать на мобильных устройствах, так как плотность пикселей на устройствах сильно различается. При желании его следует использовать вместе с изображениями с множественной плотностью: элемент изображения, который использует разные исходные файлы в зависимости от целевой плотности. В Fuse я добавил режим PointPrefer, чтобы получить лучшее из обоих миров: он использует режим с точностью до пикселя, если размер одного из пикселей достаточно близок к размеру точки; в противном случае ближайшее изображение растягивается до нужного размера.

Заполнить и масштабировать9

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

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

Полезной функцией растяжения является растяжка по 9 сеткам: изображение делится на девять областей и растягивается самостоятельно. Это позволяет создавать границы для элемента с динамическим размером. CSS предоставляет довольно надежную функцию с border-image.

Униформа и Униформа для заполнения

Если все изображение должно поместиться внутри элемента, а соотношение сторон должно быть сохранено, мы используем режим Uniform (называемый contain в CSS). Это увеличивает размер изображения так, что оно касается двух сторон доступной области, оставляя оставшуюся часть элемента пустой.

Если вместо этого вы хотите заполнить весь элемент и при этом сохранить соотношение сторон, мы используем режим UniformToFill (называемый cover в CSS). Это масштабирует изображение до тех пор, пока оно не достигнет всех краев элемента, обрезая те части, которые находятся за пределами элемента.

Выравнивание контента

За исключением режима Fill или Scale9, изображение не помещается точно в доступное пространство. Это оставляет открытым вопрос о том, где расположить изображение? Должно ли изображение Uniform располагаться слева или справа? Должно ли изображение UniformToFill показывать нижнюю или верхнюю часть изображения?

Добавление ContentAlignment к Image позволяет пользователю указать эту опцию. Хорошим значением по умолчанию является наследование выравнивания элемента изображения. Если вы выровняете изображение по нижнему правому краю, вы ожидаете, что визуальный элемент также будет выровнен по нижнему правому краю.

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

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

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

Опции

Для Fuse у нас также была опция StretchDirection. Это может быть один из Both (по умолчанию), UpOnly или DownOnly. Изображение будет растягиваться только в разрешенных направлениях. Например, если у нас есть Image {StretchMode=Uniform StretchDirection=DownOnly}, визуальный элемент уменьшится, чтобы соответствовать элементу, но никогда не расширится за пределы своего естественного размера. На практике для этого есть ограниченные варианты использования.

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

В дополнение к привязке свойство Offset позволяет создавать простые анимации. Расположите и измените размер визуального элемента как обычно, затем примените смещение к полученному положению. Это, скорее всего, будет сочетаться с флагом Fill на мозаичных изображениях.

Другие элементы

Если вы пишете механизм пользовательского интерфейса, вам может быть интересно узнать, как выполнять все эти вычисления. Дайте мне знать, если вам нужна такая статья — в ней будет преобладать математика, хотя и не сложная. В Fuse вы можете найти класс SizingContainer, который инкапсулирует большую часть логики, хотя код расчета макета также является его частью.

Интересным моментом в этих режимах изменения размера является то, что они могут одинаково хорошо применяться к любому количеству типов элементов, а не только к изображениям. Общее свойство CSS object-fit работает в этом направлении. Однажды я даже реализовал Viewbox, который масштабировал произвольные элементы, который поддерживал StretchDirection, но заставлял режим заполнения Uniform.

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

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