- PVSM.RU - https://www.pvsm.ru -

Решение проблемы border-radius + overflow:hidden с помощью canvas

Передо мной стояла следующая задача:

image

Есть блок с фоном (необязательно однородным), в нем какое-то количество круглых элементов с белым фоном, внутри которых размещены закругленные картинки любого размера. Если размер картинки меньше размера блока — она центрируется (как по вертикали, так и по горизонтали), если же размер картинки больше размера блока — больший параметр картинки занимает 100% параметра блока, а второй параметр сохраняет пропорциональное отношение, как и в оригинальной картинке.

Для многих не секрет, что если закруглять саму картинку, то красиво получится, только с картинкой, соотношение сторон у которой 1:1, в остальных случаях возникнут проблемы:

image

Использование стандартных css свойств (border-radius:150px; overflow:hidden;), применительно к блоку с картинкой, не работает во многих браузерах. Можно найти много разных решений проблемы, но не одно из них мне не подошло.

Я предлагаю следующее решение (оно не универсально, в т.ч. не работает в IE7, IE8) но я считаю его полезным.

jsfiddle.net/iLight/EsFTG/23/ [1]

Центрируем картинку по вертикали:

$('.i-img-cont').each(function(){
	$(this).find('img').css('margin-top', parseInt(-$(this).find('img').height()/2));
});

Заменяем картинку на canvas

var i=0, mywidth, myheight;		
$('.i-img-cont').each(function(){
    var contWidth = $(this).width(),
        contHeight = $(this).height(), //получаем значение ширины и высоты контейнера
        cnv = document.createElement("canvas"); //создаем канву
    cnv.width=contWidth;
    cnv.height=contHeight;	//задаем ей значения высоты и ширины такие как у контейнера				
    $(this).prepend(cnv); //добавляем в начало контейнера канву, картинка при этом просто уезжает вниз
    i++;
    var j=i-1;
    $(this).find('canvas').attr('id', 'canvas'+j); //даем канве свой id
    var ctx = document.getElementById('canvas'+j).getContext('2d'), //инициализируем контекст
        img = new Image(), //создаем в канве картинку
        attrsrc=$(this).find('img').attr('src'); //получаем путь исходной картинки
    img.src = attrsrc; //присваиваем картинке в канве путь исходной картинки				
    img.onload = function(){
        mywidth = $('#canvas'+j).next('img').width();
        myheight = $('#canvas'+j).next('img').height(); //получаем высоту и ширину исходной картинки
        var xpos = (contWidth-mywidth)/2, 
        ypos = (contHeight-myheight)/2; //рассчитываем расположение картинки в канве
        ctx.drawImage(img, xpos, ypos, mywidth, myheight);	//рисуем картинку на холст
    }	
});

Затем просто закругляем canvas:

.i-img-cont canvas{border-radius:150px;}

Можно так же указать браузеры в которых не нужно создавать canvas (Напимер FF, IE9-10, Chrome). Или те в которых это необходимо, чтобы не делать лишней работы для «умных» браузеров.

P.S. Excanvas не выручает, если есть решения для IE7-8, кроме вырезания уголков в фотошопе — буду признателен.

Автор: iLight

Источник [2]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/javascript/45898

Ссылки в тексте:

[1] jsfiddle.net/iLight/EsFTG/23/: http://jsfiddle.net/iLight/EsFTG/23/

[2] Источник: http://habrahabr.ru/post/179525/