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 --m
item diposisikan di lingkaran dan itu jika mereka berada di tengah-tengah tepi poligon dari --m
tepi, 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 2em
setengah 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 deg0
atau deg45
atau 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 img
tag.
EDIT : contoh dengan fallback untuk IE8 dan yang lebih lama (diuji di IE8 dan IE7)
Inilah solusi mudah tanpa pemosisian absolut:
http://jsfiddle.net/mD6H6/
sumber
Berdasarkan jawaban yang sangat baik dari @ Ana, saya membuat versi dinamis ini yang memungkinkan Anda untuk menambah dan menghapus elemen dari DOM dan mempertahankan jarak yang proporsional antara elemen - lihat biola saya: https://jsfiddle.net/skwidbreth/q59s90oy/
sumber
var rotateAngle = zero_start + (offsetAngle * i || 0);
saya juga menambahkan variabel untuk zero_start jadi jika Anda ingin memulai pada titik 270 daripada 0, atau yang serupa. jsfiddle.net/q59s90oy/13 . Terakhir saya mengubah css untuk item daftar menggunakan margin negatif. Serius, terima kasih telah berbagi pekerjaan, banyak membantu.Tidak ada cara untuk secara ajaib menempatkan item yang dapat diklik dalam lingkaran di sekitar elemen lain dengan CSS. Cara saya melakukan ini adalah dengan menggunakan wadah dengan
position:relative;
. Dan kemudian tempatkan semua elemen denganposition:absolute;
dan menggunakantop
danleft
untuk menargetkan tempatnya.Meskipun Anda belum menempatkan jquery di tag Anda mungkin lebih baik menggunakan jQuery / javascript untuk ini.
Langkah pertama adalah menempatkan gambar tengah Anda dengan sempurna di tengah wadah menggunakan
position:relative;
.Setelah itu Anda bisa menempatkan elemen lain di sekitarnya dengan menggunakan
offset()
centerImage dikurangioffset()
container. Memberi Anda gambaran yang tepattop
dan tepatleft
.Apa yang saya lakukan di sini adalah menempatkan elemen relatif terhadap centerImage. Semoga ini membantu.
sumber
Anda pasti bisa melakukannya dengan css murni atau menggunakan JavaScript. Saran saya:
Jika Anda sudah tahu bahwa jumlah gambar tidak akan pernah berubah, hitung saja gaya Anda dan gunakan css biasa (pro: kinerja lebih baik, sangat andal)
Jika jumlahnya dapat bervariasi baik secara dinamis di aplikasi Anda atau hanya dapat bervariasi di masa mendatang, gunakan solusi Js (pro: lebih tahan masa depan)
Saya memiliki pekerjaan serupa untuk dilakukan, jadi saya membuat skrip dan open source di sini di Github untuk siapa saja yang mungkin membutuhkannya. Itu hanya menerima beberapa nilai konfigurasi dan hanya mengeluarkan kode CSS yang Anda butuhkan.
Jika Anda ingin mencari solusi Js, berikut adalah penunjuk sederhana yang dapat berguna bagi Anda. Menggunakan html ini sebagai titik awal sebagai
#box
wadah dan.dot
gambar / div di tengah Anda ingin semua gambar Anda yang lain ada:Memulai html:
Memulai Css:
Anda dapat membuat fungsi cepat di sepanjang baris ini:
Anda dapat melihat contoh langsung di sini
sumber
Menggunakan solusi yang diusulkan oleh @Ana:
Saya membuat jsFiddle berikut yang menempatkan lingkaran secara dinamis menggunakan JavaScript biasa (versi jQuery juga tersedia).
Cara kerjanya cukup sederhana:
sumber
Ini adalah versi yang saya buat di React dari contoh di sini.
Contoh CodeSandbox
sumber
Anda bisa melakukannya seperti ini: biola
Jangan pedulikan pemosisiannya, ini contoh cepat
sumber