Некоторое время назад появилась задача для дизайнера сделать стилизованный под дикий запад сайт. Мне, как верстальщику, пришла задача от дизайнера сделать картинки и некоторые бэкграунды, стилизованные под дикозападские вывески. На каждой странице в неизвестном количестве и неизвестных размеров. Задача усугублялась сложным фоном и необходимостью прозрачных дырок в изображениях. Т.е. нужно было использовать border-radius:inset, которого, как оказалось, не существует… Нарезать кучу картинок под каждую страницу и случай, само-собой, нереально и бессмысленно. Заказчик не был одним из «адептов explorer 6», поэтому я решил упростить себе жизнь связкой jQuery и HTML5.
Что получилось
Получился маленький jQuery плагинчик. Принцип предельно прост: по селектору находим нужные картинки, прячем, создаем рядом канвас с такими-же размерами, в который дублируется исходная картинка, дырявим. Плагин опционально принимает три параметра: массив радиусов скруглов (в пикселях), толщину бордюра и его цвет (если он нужен, конечно).
Пример:
$(".block-4 img").borderRadiusInset({
radius: [30,60,0,20],
width: 10,
color: "#00719e"
});
В массив радиусов можно передать от одного до четырех значений, которые работают по тому же принципу, что и радиусы в css для border-radius:
- все радиусы одинаковы;
- первое значение — радиус левого верхнего и правого нижнего скругла, второе — оставшиеся;
- первое — левый верхий, второе — правый верхний и левый нижний, третье — правый нижний;
- каждому скруглу присвоен свой радиус, начиная с левого верхнего и дальше по часовой стрелке.
Работает плагинчик только с изображениями, но при должном уровне ненормальности или срочной необходимости стилями можно организовать и фоны для блоков контента, статичных после загрузки страницы, но с неизвестными размерами до загрузки.
Почему для дырявого канваса ctx.globalCompositeOperation лучше, чем ctx.clip()
Собственно, и из картинки все понятно. Везде скруглы как скруглы, но в хроме при использовании ctx.clip() дырки в канвасе получаются со ступенчатыми рваными краями (в других браузерах все нормально). Решение нашлось тут. На этом ад перфекциониста закончился.
Ссылки
Пощупать пример: jsfiddle.net/53vq5pn1
Поковырять исходник: github.com/tegArt/border-radius-inset
Скруглы?*
* Последний абзац для передачи эмоций автора следует читать голосом Шелдона Купера и с соответствующей интонацией.
Да, скруглы. Круг плюс угол. Почему не кругл? Потомучто угол не кругл, а скруглен. «Кругл» — это прилагательное, и, в принципе, пончики тоже круглы. Но скругл — это новое слово в веб-разработке, облегчающее работу верстальщикам и дизайнерам, сокращая время донесения своих мыслей до коллег в среднем на 4 (четыре!) секунды в неделю. Я серьезен как никогда. Ребята, это прорыв.
Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.
Комментарии (20)
mr47
25.06.2015 15:51А SVG чем вам не угодил?
tegArt Автор
25.06.2015 16:02Каюсь, я с svg мало знаком, мне было проще то, что описано выше сделать… Пришлите ссылки на примеры вырезания прозрачных дырок в изображениях при помощи svg, чтобы был вариант альтернативного решения.
Serator
25.06.2015 16:34+2Lea Verou проталкивает подобную идею в W3C. Есть и пример реализации как раз на SVG: leaverou.github.io/corner-shape.
+, статья по теме: lea.verou.me/2013/03/preview-border-corner-shape-before-implementations.
Serator
25.06.2015 16:42+1lea.verou.me/2011/03/beveled-corners-negative-border-radius-with-css3-gradients — интересное решение подобной задачачи с использованием градиентов в CSS.
ReklatsMasters
25.06.2015 16:56А вот решение с использованием дополнительного элемента
tegArt Автор
25.06.2015 17:04Я тогда натыкался на этот вариант, но если поменять фон у body — видно, что дырки не прозрачные, т.е. по факту и не дырки вовсе.
ReklatsMasters
25.06.2015 17:48Обновил, теперь всё корректно и с фоновой картинкой.
tegArt Автор
25.06.2015 18:02Как вариант, но тут разные радиусы у скруглов сделать не получится + нужно изначально знать точные размеры блока.
ReklatsMasters
25.06.2015 18:15Да вам не угодишь! :D
На самом деле размеры блока знать не нужно, они нигде не используются. Все псевдоэлементы позиционируются абсолютно по отношению к самому блоку. Насчёт разных радиусов — можете поиграться с размерами внутреннего body и box-shadow.
Хотя как по мне, лучше использовать SVG.tegArt Автор
25.06.2015 18:33Всем сразу никогда не угодить — поэтому и опубликовал свой способ, вдруг кому пригодится. Ваше решение лучше подходит для контента в блоке с однородным фоном, а мое для картинок и сложного фона, который необходимо продырявить. Просто в примере они белые, а поставить то можно любую — и как тогда с box-shadow выкручиваться?
SelenIT2
26.06.2015 09:46Я года этак с 2011-го называю скруглы круголками (еще из той же песни — градиентени и трансформанимации:), до сих пор меня вроде бы все понимали:)
LeonidFrolov
07.07.2015 13:15Для решения с canvas нужно учитывать рендеринг на HiDPI экранах — jondavidjohn.github.io/hidpi-canvas-polyfill — можно использовать полифил, но вариант с SVG лучше, мне кажется. Он проще для рендеринга и полифилы не нужны.
tzlom
Скруглы напоминают мне о маркетинговом прорыве M$
en.wikipedia.org/wiki/Scroogled