UXPUB 🇺🇦 Дизайн-спільнота

Cover image for Как создавалась функция shadow spread в Figma
Редакція
Редакція

Опубліковано

Как создавалась функция shadow spread в Figma

Начиная с сегодняшнего дня, вы можете настроить в Figma размер тени для прямоугольников, эллипсов, фонов фреймов и фонов компонентов, совсем как с помощью параметра CSS box-shadow.

Первоначально я планировал добавить эту функцию во время проведенного недавно мероприятия Maker Week, когда каждый сотрудник компании изучал проект, выходящий за рамки своих повседневных обязанностей. То, что казалось простой функцией, которую я мог бы сделать за несколько дней, превратилось в неделю алгоритмических идей, разборов спецификации W3C и уточнение решений, используемых в продуктах. В этой статье я расскажу о том, как нам удалось найти компромисс для этого (на первый взгляд) простого пользовательского запроса.

Существует много возможностей для формирования надежной веб-платформы проектирования для команд, вместе создающих продукты. Мы предоставляем систему, которая помогает вам разрабатывать и понимать ценность сложных дизайн-систем, обеспечивать совместную работу в реальном времени для дизайнеров, разбросанных по всему миру и даже совершенствовать старые инструменты, такие как перо. Вы можете спросить: тогда почему до сих пор нет поддержки изменения размера тени, базовой функции CSS box-shadow? Хотя прошло уже 958 дней с тех пор, как пользователь в Spectrum впервые попросил добавить ее. Неужели нам так сложно сделать тень, просто ... больше?

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

Как видите, форма теней выглядят знакомо. Чтобы создать подобную тень, мы копируем геометрию объекта, заливаем его одним цветом, делаем его размытым и визуализируем под самим узлом.

Может показаться, что рендеринг тени со значением spread может быть таким же простым, как масштабирование геометрии тени. Это так для прямоугольника, но не для более сложного объекта – скажем, логотипа Figma, в котором полно дыр:

Если мы будем руководствоваться определением shadow spread – расширение тени на определенное количество пикселей наружу (или внутрь) от фигуры во всех направлениях, то получим примерно такой результат:

Но никто не сказал мне этого до того, как в прекрасный майский день во время Maker Week я решил заняться созданием этой функции. Осознав ошибочность этого подхода, я решил разобраться. Это не ракетостроение, подумал я. Мы можем выяснить, как визуализировать тени 2D-фигур.

Это правда, что есть несколько интересных алгоритмических способов решения этой проблемы, но ни один из них не вписывался в нашу существующую систему рендеринга. Также можно использовать неалгоритмический способ – используя штрихи для эмуляции теней – но я быстро понял, что это тоже не вариант. Мы обрабатываем определенные углы вершин в штрихах иначе, чем нужно для shadow spread, и в нашем прототипе рендерера нет кода генерации штрихов. Каким-то образом нам нужно было найти способ заставить эту функцию работать без добавления тонны сложного кода в две разные кодовые базы рендеринга.

Фреймворк для определения приоритетов

Если есть одна вещь, которая мне нравится больше, чем отладка ошибок рендеринга, это чтение спецификаций об интернет-технологиях. (Спросите меня обо всех странных вещах, которые я узнал о GIF89 в прошлом году, добавляя в Figma поддержку GIF). Я опросил коллег каких предположений касательно размера тени мы придерживались. Мы знаем, что сегодня пользователи Figma внедряют обходные пути и добавляют документацию для передачи проекта разработчикам, когда речь идет о значениях shadow spread. Если мы хотим облегчить передачу проекта разработчикам, то наши ограничения должны определяться CSS. Нужно ли нам рисовать идеальную тень для лого Figma? Можем ли мы сделать это в CSS?!

На самом деле, не можем. Особенность параметра box-shadow заключается в том, что он работает только для рендеринга теней блоков (и других подобных объектов, которые включают эллипсы, если вы правильно настроили радиусы углов). box-shadow не будет отображать тень логотипа Figma, как копию логотипа, но как блок.

(Кроме того: на каждом этапе этого процесса кто-то говорил мне: «на самом деле, значения размера тени поддерживаются в filter: drop-shadow()», и указывал на страницу MDN, которая по ошибке утверждала, что значения размера тени еще не поддерживались браузерами. К сожалению, это не правда, что явно указано в спецификации W3C).

Мы провели дискуссию с нашими дизайнерами. Они были уверены, что в большинстве вариантов использования будет достаточно функции shadow spread для прямоугольников и эллипсов. Кроме того, подкрепленный идеей, что соответствие CSS должно мотивировать наши решения, мы решили, что не имеет значения, можем ли мы сделать логотип в форме Figma. Мы решили безжалостно расставить приоритеты: по крайней мере, мы будем делать то, что умеет CSS.

Для этого мы решили реализовать CSS-подобные параметры shadow spread только для фигур, к которым будет применен параметр box-shadow: прямоугольники, эллипсы, фон фрейма и фоновые компоненты. Казалось этого можно добиться просто, генерируя большую или меньшую версию исходного узла. Это не просто растягивание узла, так как это нарушило бы закругленные углы. Тем не менее, достаточно просто генерировать новые геометрии прямоугольников в обоих наших механизмах рендеринга.

Вверху: тень, создаваемая простым растяжением геометрии объекта; внизу: тень, созданная путем создания нового закругленного прямоугольника

Препятствия

Конечно, это не было так просто, как мы ожидали. В этом плане было несколько проблем: как создать правильные эллипсы? (Тень эллипса больше не будет определенно эллиптической; наш код генерации эллипса не генерирует не эллипсы, а простые преобразования эллипса в любом направлении сохраняют свои эллиптические свойства). Как отображать закругленные углы, когда эффект spread shadow был применен к прямоугольнику с закругленными углами? (Спецификация W3 определяет, как общее правило о преобразовании угловых радиусов, так и конкретную формулу, которая будет использоваться для больших значений spread shadow). Как отображать shadow spread на узлах только для обводки?

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

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

Что еще более удивительно, после следования кубическому правилу W3C для угловых радиусов теней с большими значениями shadow spread (тщательно продуманное правило!), сравнение наших результатов с CodePen показало, что браузеры вообще не реализуют это. Чтобы создать тень для прямоугольника с закругленными углами, браузеры – а теперь и Figma – просто добавляют или вычитают значение shadow spread и исходный радиус угла.

Но CodePen не помог бы в определении shadow spread только для узлов обводки, поскольку наш подход уже значительно отличается от CSS. Даже полностью прозрачная заливка в CSS влияет на их собственные тени и маскирует их (но не другие тени). В Figma используется подход, близкий к физическому рендерингу, позволяющий пользователю видеть тени сквозь прозрачные и полупрозрачные заливки.

Ниже те же прямоугольники (заливки с нулевой непрозрачностью, с обводками и тенями) в CSS (слева) и Figma (справа):

Хотя легко узнать, как визуализировать тень для узла с заливкой (внизу слева), вы можете представить, как применить shadow spread для обводки несколькими способами:

A. Начните обводку с помощью параметра spread, оставив обводку постоянной

B. Добавьте spreadна внешнюю сторону ширины обводки.

C. Добавьтеspread к ширине штриха, отцентрированный так, чтобы тень распределялась по обе стороны

D. Добавьте параметр spread к каждому краю ширины обводки, в конечном итоге добавив 2 * spread к ширине обводки.

Изучив варианты, мы пришли к варианту D: мы подумали, что, когда вы переключаете видимость заливки объекта, внешний след тени должен оставаться прежним, что исключает вариант C. Из оставшихся вариантов D, похоже, больше всего соответствует идее shadow spread: тень, вытянутая вдоль каждой точки с помощью параметра spread.

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


Перевод статьи figma.com

Найстарші коментарі (0)