Решение 2020
Вот более современное решение, которое я использую сейчас.
Я начинаю с создания HTML, начиная с массива изображений. Генерируется ли HTML с использованием PHP, JS, какого-нибудь препроцессора HTML, что угодно ... это не так важно, поскольку основная идея остается той же.
Вот код Pug, который сделает это:
- let imgs = [
- {
- src: 'image_url.jpg',
- alt: 'image alt text'
- }
- ];
- let n_imgs = imgs.length;
- let has_mid = 1;
- let m = n_imgs - has_mid;
- let tan = Math.tan(Math.PI/m);
.container(style=`--m: ${m}; --tan: ${+tan.toFixed(2)}`)
- for(let i = 0; i < n_imgs; i++)
a(href='#' style=i - has_mid >= 0 ? `--i: ${i}` : null)
img(src=imgs[i].src alt=imgs[i].alt)
Сгенерированный HTML выглядит следующим образом (и да, вы также можете написать HTML вручную, но потом будет сложно вносить изменения):
<div class="container" style="--m: 8; --tan: 0.41">
<a href='#'>
<img src="image_mid.jpg" alt="alt text"/>
</a>
<a style="--i: 1">
<img src="first_img_on_circle.jpg" alt="alt text"/>
</a>
</div>
Скажем, в CSS мы определяем размер изображений 8em
. Эти --m
элементы расположены по кругу , и это , если они находятся в середине ребер многоугольника --m
края, все из которых являются касательной к окружности.
Если вам сложно это представить, вы можете поиграть с этой интерактивной демонстрацией, которая строит вписанную и описанную окружность для различных многоугольников, количество ребер которых вы выбираете, перетаскивая ползунок.
Это говорит нам о том, что размер контейнера должен быть в два раза больше радиуса круга плюс вдвое меньше половины размера изображений.
Мы еще не знаем радиус, но мы можем вычислить его, если мы знаем количество ребер (и, следовательно, тангенс половины базового угла, предварительно вычисленный и установленный как настраиваемое свойство --tan
) и ребро многоугольника. Мы, вероятно, хотим, чтобы край многоугольника был как минимум размером с изображения, но то, сколько мы оставляем по бокам, произвольно. Допустим, у нас есть половина размера изображения с каждой стороны, поэтому край многоугольника вдвое больше размера изображения. Это дает нам следующий CSS:
.container {
--d: 6.5em;
--rel: 1;
--r: calc(.5*(1 + var(--rel))*var(--d)/var(--tan));
--s: calc(2*var(--r) + var(--d));
position: relative;
width: var(--s); height: var(--s);
background: silver
}
.container a {
position: absolute;
top: 50%; left: 50%;
margin: calc(-.5*var(--d));
width: var(--d); height: var(--d);
--az: calc(var(--i)*1turn/var(--m));
transform:
rotate(var(--az))
translate(var(--r))
rotate(calc(-1*var(--az)))
}
img { max-width: 100% }
См. Старое решение для объяснения того, как работает цепочка преобразований.
Таким образом, добавление или удаление изображения из массива изображений автоматически размещает новое количество изображений по кругу таким образом, что они разнесены на равные расстояния, а также регулирует размер контейнера. Вы можете проверить это в этой демонстрации .
СТАРОЕ решение (сохранилось по историческим причинам)
Да, это возможно и очень просто, используя только CSS. Вам просто нужно иметь четкое представление об углах, под которыми вы хотите видеть ссылки с изображениями (я добавил в конце фрагмент кода только для того, чтобы показывать углы при наведении курсора на одно из них).
Для начала вам понадобится обертка. Я установил его диаметр равным 24em
( width: 24em; height: 24em;
делает это), вы можете установить все, что захотите. Ты даешь этоposition: relative;
.
Затем вы размещаете свои ссылки с изображениями в центре этой оболочки как по горизонтали, так и по вертикали. Вы делаете это, устанавливая, position: absolute;
а затем top: 50%; left: 50%;
и margin: -2em;
(где 2em
половина ширины ссылки с изображением, которую я установил как4em
- опять же, вы можете изменить его на все, что захотите, но не забудьте изменить поле в тот случай).
Затем Вы выбираете углов , при которых вы хотите , чтобы ваши ссылки с изображениями и добавить класс deg{desired_angle}
(например , deg0
или deg45
или любой другой ). Затем для каждого такого класса вы применяете связанные преобразования CSS, например:
.deg{desired_angle} {
transform: rotate({desired_angle}) translate(12em) rotate(-{desired_angle});
}
где вы заменяете {desired_angle}
с 0
, 45
и так далее ...
Первое преобразование поворота поворачивает объект и его оси, преобразование преобразования перемещает объект вдоль повернутой оси X, а второе преобразование поворота возвращает объект в положение.
Преимущество этого метода в том, что он гибкий. Вы можете добавлять новые изображения под разными углами, не изменяя текущую структуру.
КОД СНОВА
.circle-container {
position: relative;
width: 24em;
height: 24em;
padding: 2.8em;
border: dashed 1px;
border-radius: 50%;
margin: 1.75em auto 0;
}
.circle-container a {
display: block;
position: absolute;
top: 50%; left: 50%;
width: 4em; height: 4em;
margin: -2em;
}
.circle-container img { display: block; width: 100%; }
.deg0 { transform: translate(12em); }
.deg45 { transform: rotate(45deg) translate(12em) rotate(-45deg); }
.deg135 { transform: rotate(135deg) translate(12em) rotate(-135deg); }
.deg180 { transform: translate(-12em); }
.deg225 { transform: rotate(225deg) translate(12em) rotate(-225deg); }
.deg315 { transform: rotate(315deg) translate(12em) rotate(-315deg); }
<div class='circle-container'>
<a href='#' class='center'><img src='image.jpg'></a>
<a href='#' class='deg0'><img src='image.jpg'></a>
<a href='#' class='deg45'><img src='image.jpg'></a>
<a href='#' class='deg135'><img src='image.jpg'></a>
<a href='#' class='deg180'><img src='image.jpg'></a>
<a href='#' class='deg225'><img src='image.jpg'></a>
<a href='#' class='deg315'><img src='image.jpg'></a>
</div>
Кроме того, вы можете еще больше упростить HTML, используя фоновые изображения для ссылок вместо img
тегов.
РЕДАКТИРОВАТЬ : пример с резервным вариантом для IE8 и старше (проверено в IE8 и IE7)