Краткое отступление. Извините за паузу в записях Design Diary (дневник дизайна). В последнем порыве, чтобы отправить Pedometer ++ v5, у меня не хватило времени, чтобы поддерживать их. Не бойтесь, хотя я записал кучу тематических идей, чтобы написать о них теперь, когда они были отправлены, и на меня снова меньше давят.

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

Однако всякий раз, когда я использовал их раньше, я использовал только встроенные значения direction (направления):.top,.topTrailing,.leading и т. д. И, если быть честным, это были единственные варианты, которыми я располагаю.

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

LinearGradient принимает в качестве управления direction аргумент типа UnitPoint. Обычно вы взаимодействуете с ними, используя встроенные параметры, но оказывается, что это просто нормализованная пара X/Y под капотом. Так что, если бы я мог подобрать подходящее значение X/Y, я мог бы рисовать свои градиенты под любым углом.

Теперь вся хитрость заключалась в том, чтобы выяснить, как рассчитать эти пары. Я начал пытаться сделать это с помощью математики (=)) и быстро разочаровался. Я уверен, что для этого есть умное алгебраическое решение, но я не смог найти его после небольшого поиска.

Затем я понял, что на самом деле я мог бы просто упростить всё это, поскольку меня заботила только одна переменная за один проход (например, значение Y на левом краю и значение X на нижнем краю).

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

Это прекрасно работает и позволяет рисовать градиенты под любым углом. Если вы хотите увидеть код или использовать его самостоятельно.

Вот он на GitHub.

Уточнение:

Rob Mayoff и robb указали мне, что мой метод не совсем правильный. Поскольку я выполняю линейную интерполяцию, а не тригонометрическую, мои повороты немного отличаются от фактического угла. В этом случае разница крошечная и визуально очень трудно различить, но всё же это не совсем правильно.

Вот анимация, сделанная Робом для иллюстрации этой ошибки:

Rob и robb были достаточно любезны, чтобы опубликовать свои альтернативные решения, которые правильно подходят для этого.

Комментарии (0)