Сглаженные углы с помощью CSS Houdini

Сглаженные углы с помощью CSS Houdini

От автора: в этой статье речь пойдет про углы CSS, а точнее, про их сглаживание. Недавно я поделился в Twitter статьей об оптических эффектах пользовательского интерфейса. Мне нравятся различные оптические эффекты, но для меня это новая сфера: преобразованный круг может выглядеть круче, чем обычная геометрическая фигура! Это справедливо и для прямоугольников со сглаженными углами. Удивительно, но я также обнаружил, что Apple использует этот прием для всех иконок в iOS7. В математике он известен, как кривая Ламе или суперэллипс.

Сглаженные углы с помощью CSS Houdini

Различия между формами значков в iOS6 и iOS7

Кроме того, я экспериментировал с Paint API от Houdini. Этот API определяет новый способ создания контента в CSS image во время фазы рисования процесса рендеринга. Это дает нам возможность программно рисовать изображение, которое будет использоваться в качестве фона, например. И нарисовать супер эллипс, оказывается, довольно просто.

Несколько недель спустя Sketch выпустили новую версию и представили функцию “Smooth corners”, которая, насколько мне известно, представляет собой не что иное, как тот же супер эллипс. Мне больше нравится название супер эллипс, поэтому давайте создадим его с помощью CSS. Сначала добавим новый модуль paintWorklet.

Практический курс по верстке адаптивного лендинга с нуля!

Научитесь с нуля верстать адаптивные лендинги на HTML5 и CSS3 за ближайшие 6 дней

Узнать подробнее
(CSS.paintWorklet || paintWorklet).addModule('smooth-corners.js')

Затем из этого модуля мы регистрируем новый рисунок smooth-corners, с методом paint, который рисует супер эллипс (алгоритм из QT codebase):

registerPaint('smooth-corners', class {
 paint(ctx, size) {
 ctx.fillStyle = 'black'
 
 // n=4 рисует круг
 const n = 4
 
 let m = n
 if (n > 100) m = 100
 if (n < 0.00000000001) m = 0.00000000001
 const r = size.width / 2
 const w = size.width / 2
 const h = size.height / 2
 
 ctx.beginPath();
 
 for (let i = 0; i < (2*r+1); i++) {
 const x = (i-r) + w
 const y = (Math.pow(Math.abs(Math.pow(r,m)-Math.pow(Math.abs(i-r),m)),1/m)) + h
 
 if (i == 0)
 ctx.moveTo(x, y)
 else
 ctx.lineTo(x, y)
 }
 
 for (let i = (2*r); i < (4*r+1); i++) {
 const x = (3*r-i) + w
 const y = (-Math.pow(Math.abs(Math.pow(r,m)-Math.pow(Math.abs(3*r-i),m)),1/m)) + h
 ctx.lineTo(x, y)
 }
 
 ctx.closePath()
 ctx.fill()
 }
})

Давайте рассмотрим аргументы метода paint подробнее:

сtx — это объект PaintRenderingContext2D, который является подмножеством CanvasRenderingContext2D, поэтому мы можем нарисовать что угодно (почти)

size — это объект PaintSize, который представляет размер изображения

Теперь мы можем использовать это в CSS с помощью новой функции paint(). Она нарисует черный округлый прямоугольник со сглаженными углами:

.el {
 background: paint(smooth-corners);
}

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

.el {
 background: linear-gradient(deeppink, orangered);
 mask-image: paint(smooth-corners);
}

Сглаженные углы с помощью CSS Houdini

Сглаженные углы в CSS

Это хороший, но не очень надежный способ. Поэтому мы нарисуем супер эллипс с именем squircle, потому что для переменной n установлено значение 4. Так как же нам нарисовать супер эллипс с другой экспонентой? Для иконок IOS используется 5. Давайте сделаем это с помощью пользовательских свойств CSS. Во-первых, мы используем пользовательское свойство —smooth-corners

.el {
 --smooth-corners: 4;
 background: linear-gradient(deeppink, orangered);
 mask-image: paint(smooth-corners);
}

И получим значение из функции registerPaint

registerPaint('smooth-corners', class {
 static get inputProperties() {
 return [
 '--smooth-corners'
 ]
 }
 paint(ctx, size, styleMap) {
 const exp = styleMap.get('--smooth-corners').toString()
 
 const n = exp
 }
})

Обратите внимание, что метод paint() получает третий аргумент styleMap, который является API для извлечения вычисляемых значений для свойств, перечисленных в inputProperties. Мы получаем значение —smooth-corners и используем его для переменной n.

И, самое замечательное, мы можем прописать —smooth-corners прямо в CSS, а само свойство можно также анимировать, если мы зарегистрируем его с помощью CSS.registerProperty (из CSS Houdini Properties & Values API). На данный момент API-интерфейс Paint от Houdini поддерживает только в Chrome, поэтому мы реализуем прогрессивное улучшение:

.el {
 border-radius: 60px;
 background: linear-gradient(...)
}
 
@supports (mask-image: paint(smooth-corners)) {
 .el.is-loaded {
 border-radius: 0;
 mask-image: paint(smooth-corners);
 --smooth-corners: 5;
 }
}

Кроме того, поскольку Houdini является JS-in-CSS, лучше подождать, пока JavaScript будет загружен. Здесь я решил добавить к элементу класс .is-loaded.

В процессе разработки нам нужно иметь возможность автоматизировать созданный CSS с помощью плагина PostCSS, например.
Вы можете поэкспериментировать с демо-версией http://lab.iamvdo.me/houdini/smooth-corners в поддерживающем браузере

Примечания

Использование маски CSS маскирует все за пределами блока (в этом и заключается предназначение маски). Вы должны иметь возможность добавить градиент или изображение с помощью registerPaint, если это необходимо (но, похоже, этот тип image еще не поддерживается должным образом, поэтому нам приходится иметь дело с тем, что есть на данный момент).

Если вы хотите немного поэкспериментировать, посмотрите другие демо-версии: создание собственных свойств фона, например, background-opacity или рисование градиента из 4 углов, где мы передаем аргументы вместо свойств. Буду рад, если вам понравятся мои работы!

Источник: http://iamvdo.me/

Редакция: Команда webformyself.

Практический курс по верстке адаптивного лендинга с нуля!

Научитесь с нуля верстать адаптивные лендинги на HTML5 и CSS3 за ближайшие 6 дней

Узнать подробнее
Самые свежие новости IT и веб-разработки на нашем Telegram-канале

Практика HTML5 и CSS3 с нуля до результата!

Получите бесплатный пошаговый видеокурс по основам адаптивной верстки с полного нуля на HTML5 и CSS3

Получить

Метки:

Похожие статьи:

Комментарии Вконтакте:

Комментарии Facebook:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Можно использовать следующие HTML-теги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Я не робот.

Spam Protection by WP-SpamFree