Solusi 2020
Inilah solusi yang lebih modern yang saya gunakan hari ini.
Saya memulai dengan membuat HTML mulai dari serangkaian gambar. Apakah HTML dibuat menggunakan PHP, JS, beberapa praprosesor HTML, apa pun ... ini kurang penting karena ide dasar di baliknya sama.
Inilah kode Pug yang akan melakukan ini:
//- start with an array of images, described by url and alt text
- let imgs = [
- {
- src: 'image_url.jpg',
- alt: 'image alt text'
- } /* and so on, add more images here */
- ];
- let n_imgs = imgs.length;
- let has_mid = 1; /* 0 if there's no item in the middle, 1 otherwise */
- let m = n_imgs - has_mid; /* how many are ON the circle */
- let tan = Math.tan(Math.PI/m); /* tangent of half the base angle */
.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 yang dihasilkan terlihat sebagai berikut (dan ya, Anda juga dapat menulis HTML secara manual, tetapi akan merepotkan untuk membuat perubahan setelahnya):
<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>
<!-- the rest of those placed on the circle -->
</div>
Di CSS, kami memutuskan ukuran gambar, katakanlah 8em. The --mitem diposisikan di lingkaran dan itu jika mereka berada di tengah-tengah tepi poligon dari --mtepi, yang semuanya bersinggungan dengan lingkaran.
Jika Anda kesulitan membayangkannya, Anda dapat bermain dengan demo interaktif ini yang membangun incircle dan circumcircle untuk berbagai poligon yang jumlah tepinya Anda pilih dengan menyeret slider.

Ini memberi tahu kita bahwa ukuran wadah harus dua kali jari-jari lingkaran ditambah dua kali setengah ukuran gambar.
Kita belum mengetahui radiusnya, tetapi kita dapat menghitungnya jika kita mengetahui jumlah sisi (dan karenanya tangen dari setengah sudut alas, dihitung sebelumnya dan ditetapkan sebagai properti khusus --tan) dan tepi poligon. Kita mungkin ingin tepi poligon berukuran paling kecil dari gambarnya, tetapi seberapa banyak yang kita sisakan di sisi itu sewenang-wenang. Katakanlah kita memiliki setengah ukuran gambar di setiap sisi, jadi tepi poligon dua kali ukuran gambar. Ini memberi kita CSS berikut:
.container {
--d: 6.5em; /* image size */
--rel: 1; /* how much extra space we want between images, 1 = one image size */
--r: calc(.5*(1 + var(--rel))*var(--d)/var(--tan)); /* circle radius */
--s: calc(2*var(--r) + var(--d)); /* container size */
position: relative;
width: var(--s); height: var(--s);
background: silver /* to show images perfectly fit in container */
}
.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% }
Lihat solusi lama untuk penjelasan tentang cara kerja rantai transformasi.
Dengan cara ini, menambahkan atau menghapus gambar dari larik gambar secara otomatis mengatur jumlah gambar baru pada lingkaran sedemikian rupa sehingga jaraknya sama dan juga menyesuaikan ukuran wadah. Anda bisa mengujinya di demo ini .
Solusi LAMA (dipertahankan karena alasan historis)
Ya, itu sangat mungkin dan sangat sederhana hanya dengan menggunakan CSS. Anda hanya perlu mengingat dengan jelas sudut di mana Anda menginginkan tautan dengan gambar (saya telah menambahkan sepotong kode di bagian akhir hanya untuk menunjukkan sudut setiap kali Anda mengarahkan kursor ke salah satunya).
Pertama-tama Anda membutuhkan pembungkus. Saya mengatur diameternya menjadi 24em( width: 24em; height: 24em;melakukan itu), Anda dapat mengaturnya sesuai keinginan Anda. Anda memberikannya position: relative;.
Anda kemudian memposisikan tautan Anda dengan gambar di tengah pembungkus itu, baik secara horizontal maupun vertikal. Anda melakukannya dengan mengatur position: absolute;lalu top: 50%; left: 50%;dan margin: -2em;(di mana 2emsetengah lebar tautan dengan gambar, yang telah saya tetapkan 4em- sekali lagi, Anda dapat mengubahnya menjadi apa pun yang Anda inginkan, tetapi jangan lupa untuk mengubah margin di kasus itu).
Anda kemudian memutuskan sudut di mana Anda ingin memiliki tautan Anda dengan gambar dan Anda menambahkan kelas deg{desired_angle}(misalnya deg0atau deg45atau apa pun). Kemudian untuk setiap kelas tersebut Anda menerapkan transformasi CSS berantai, seperti ini:
.deg{desired_angle} {
transform: rotate({desired_angle}) translate(12em) rotate(-{desired_angle});
}
di mana Anda mengganti {desired_angle}dengan 0, 45, dan seterusnya ...
Transformasi putar pertama memutar objek dan sumbunya, transformasi terjemahan menerjemahkan objek sepanjang sumbu X yang diputar dan transformasi rotasi kedua mengembalikan objek ke posisinya.
Keuntungan dari metode ini adalah fleksibel. Anda dapat menambahkan gambar baru pada sudut yang berbeda tanpa mengubah struktur saat ini.
CUPLIKAN KODE
.circle-container {
position: relative;
width: 24em;
height: 24em;
padding: 2.8em;
/*2.8em = 2em*1.4 (2em = half the width of a link with img, 1.4 = sqrt(2))*/
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); } /* 12em = half the width of the wrapper */
.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>
Selain itu, Anda dapat lebih menyederhanakan HTML dengan menggunakan gambar latar belakang untuk tautan daripada menggunakan imgtag.
EDIT : contoh dengan fallback untuk IE8 dan yang lebih lama (diuji di IE8 dan IE7)