Elemen div mengikuti jalur melengkung dengan CSS3

Jadi ide dasarnya adalah 1 - 9 kursi di meja melengkung seolah-olah Anda melihatnya melalui sudut pandang orang pertama. Saya mencoba membuat elemen div yang akan menjadi tempat duduk mengalir di luar elemen div lain yang memiliki radius batas untuk menjadikannya lingkaran semi lonjong. Saya telah menemukan beberapa contoh dengan elemen yang dianimasikan untuk mengalir melintasi wadah dalam bentuk busur, tetapi saya memerlukan div/kursi menjadi statis. Saya mencari ide atau contoh yang dapat membawa saya ke jalan yang benar.


person jhorton    schedule 03.09.2015    source sumber
comment
Berikut adalah gambaran kasar tentang cara menerapkannya - jsfiddle.net/5c59m5q4. Tidak cukup dekat untuk memposting sebagai jawaban dan saya tidak punya waktu sekarang untuk menyempurnakannya.   -  person Harry    schedule 03.09.2015
comment
Itu akan bekerja dengan baik untuk membantu saya memulai. Dan sebenarnya saya baru memikirkan hal serupa ketika saya berjalan-jalan. Terima kasih Harry, jika Anda ingin menjadikannya sebagai jawaban, saya akan dengan senang hati menjadikannya jawabannya.   -  person jhorton    schedule 03.09.2015
comment
silakan lihat ini, karena ini menyerupai konsep yang familier dengan konsep yang Anda coba untuk mencapai.   -  person jbutler483    schedule 08.09.2015


Jawaban (1)


Menemukan poin pada elips dan menerjemahkan:

Jika lingkaran lonjong Anda menyerupai elips maka Anda dapat mencari titik pada elips menggunakan rumus matematika dan kemudian menerjemahkan setiap elemen div ke titik tersebut.

Rumus matematika untuk menghitung titik (x,y) pada elips is(a * cos(t), b * sin(t)). Dalam rumus ini, a melambangkan jari-jari elips pada sumbu x, b melambangkan jari-jari elips pada sumbu y, dan t melambangkan sudut dalam radian. Sudut dalam radian = Sudut dalam derajat * pi / 180.

Untuk menggunakan pendekatan ini, kami melakukan hal berikut:

  • Tempatkan elemen div tepat di titik tengah elips.
  • Hitung (x,y) yang bersesuaian dengan setiap sudut dan terjemahkan div ke tempatnya dengan menggunakan transform: translateX(...) translateY(...). Sudutnya bertahap 22,5 derajat karena ada total 9 elemen yang ditempatkan dalam 180 derajat.

.container {
  position: relative;
  height: 400px;
  width: 600px;
  padding: 12.5px;
  border: 1px solid;
  border-radius: 50%;
}
div > div {
  position: absolute;
  top: 0px;
  left: 0px;
  height: 50%;
  width: 50%;
  transform-origin: bottom right;
}
div > div:after {
  position: absolute;
  content: '';
  bottom: 0px;
  right: 0px;
  height: 25px;
  width: 25px;
  background: black;
  border-radius: 50%;
  transform: translateX(50%) translateY(50%);
}
div > div:after {
  background: red;
}
div > div:nth-child(n+4):after {
  background: orange;
}
div > div:nth-child(n+7):after {
  background: green;
}
div > div:nth-child(1) {
  transform: translateX(-300px) translateY(0px);
}
div > div:nth-child(2) {
  transform: translateX(-277.17px) translateY(-76.5px);
}
div > div:nth-child(3) {
  transform: translateX(-212.13px) translateY(-141.42px);
}
div > div:nth-child(4) {
  transform: translateX(-114.80px) translateY(-184.77px);
}
div > div:nth-child(5) {
  transform: translateX(0px) translateY(-200px);
}
div > div:nth-child(6) {
  transform: translateX(114.80px) translateY(-184.77px);
}
div > div:nth-child(7) {
  transform: translateX(212.13px) translateY(-141.42px);
}
div > div:nth-child(8) {
  transform: translateX(277.17px) translateY(-76.5px);
}
div > div:nth-child(9) {
  transform: translateX(300px) translateY(0px);
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

masukkan deskripsi gambar di sini

Catatan: Koordinat merupakan nilai perkiraan sehingga mungkin tidak 100% sejajar dengan benar.


Menggunakan rotasi dan transformasi skala: (ide awal)

Cuplikan di bawah memberikan gambaran kasar tentang cara memposisikan elemen di sepanjang lingkaran. Ini sama sekali bukan hasil yang lengkap tetapi Anda dapat menyesuaikannya agar sesuai dengan kebutuhan Anda.

Komponennya sangat sederhana:

  • Salah satu elemen wadah berbentuk lingkaran dan berfungsi sebagai elemen acuan penempatan kursi.
  • 9 elemen div individu untuk setiap kursi. Semuanya memiliki 50% width wadah dan 50% height.
  • Elemen semu (:after) yang melekat pada elemen turunan div yang menghasilkan kursi seperti lingkaran/titik dan ditempatkan secara mutlak di bagian bawah wadah.
  • Setiap elemen anak div diputar sebesar 180/(n-1) derajat karena kita membutuhkannya untuk diposisikan di sekitar setengah lingkaran.

.container {
  position: relative;
  height: 200px;
  width: 200px;
  border: 1px solid;
  border-radius: 50%;
}
div > div {
  position: absolute;
  top: 0px;
  left: 0px;
  height: 50%;
  width: 50%;
  transform-origin: bottom right;
}
div > div:after {
  position: absolute;
  content: '';
  bottom: 0px;
  left: 0px;
  height: 25px;
  width: 25px;
  background: black;
  border-radius: 50%;
  transform: translateY(50%);
}
div > div:nth-child(1) {
  transform: rotate(0deg);
}
div > div:nth-child(2) {
  transform: rotate(22.5deg);
}
div > div:nth-child(3) {
  transform: rotate(45deg);
}
div > div:nth-child(4) {
  transform: rotate(67.5deg);
}
div > div:nth-child(5) {
  transform: rotate(90deg);
}
div > div:nth-child(6) {
  transform: rotate(112.5deg);
}
div > div:nth-child(7) {
  transform: rotate(135deg);
}
div > div:nth-child(8) {
  transform: rotate(157.5deg);
}
div > div:nth-child(9) {
  transform: rotate(180deg);
}
div > div:after {
  background: red;
}
div > div:nth-child(n+4):after {
  background: orange;
}
div > div:nth-child(n+7):after {
  background: green;
}

/* Just for demo */

.container{
  transition: all 1s;
}  
.container:hover {
  height: 400px;
  width: 400px;
  transition: all 1s;
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Ada metode sederhana untuk mengubah bentuk di atas menjadi lingkaran lonjong dan itu adalah dengan menskalakan wadah pada sumbu X. Satu hal yang perlu diperhatikan adalah bahwa anak-anak juga akan mengalami peningkatan skala dan oleh karena itu perlu dilakukan transformasi terbalik.

.container {
  position: relative;
  height: 200px;
  width: 200px;
  border: 1px solid;
  border-radius: 50%;
  transform: scaleX(1.25);
  transform-origin: left;
}
div > div {
  position: absolute;
  top: 0px;
  left: 0px;
  height: 50%;
  width: 50%;
  transform-origin: bottom right;
}
div > div:after {
  position: absolute;
  content: '';
  bottom: 0px;
  left: 0px;
  height: 25px;
  width: 25px;
  background: black;
  border-radius: 50%;
  transform: translateY(50%);
}
div > div:nth-child(1) {
  transform: rotate(0deg);
}
div > div:nth-child(2) {
  transform: rotate(22.5deg);
}
div > div:nth-child(3) {
  transform: rotate(45deg);
}
div > div:nth-child(4) {
  transform: rotate(67.5deg);
}
div > div:nth-child(5) {
  transform: rotate(90deg);
}
div > div:nth-child(6) {
  transform: rotate(112.5deg);
}
div > div:nth-child(7) {
  transform: rotate(135deg);
}
div > div:nth-child(8) {
  transform: rotate(157.5deg);
}
div > div:nth-child(9) {
  transform: rotate(180deg);
}
div > div:after {
  background: red;
}
div > div:nth-child(n+4):after {
  background: orange;
}
div > div:nth-child(n+7):after {
  background: green;
}

/* Just for demo */

.container {
  transition: all 1s;
}
.container:hover {
  height: 400px;
  width: 400px;
  transform: scaleX(1.25);
  transform-origin: left;
}
<div class="container">
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
  <div></div>
</div>

Metode pertama adalah pendekatan yang sempurna dan direkomendasikan karena tidak menyebabkan distorsi apa pun pada elemen div. Yang kedua adalah gagasan kasar yang menghindari perhitungan trigonometri yang rumit.

person Harry    schedule 03.09.2015
comment
Matematika suci penuh keajaiban!!! Kamu berusaha sekuat tenaga dalam hal ini. Terima kasih atas jawaban detailnya. Saya selalu bertanya-tanya mengapa begitu banyak matematika menjadi bagian dari kurikulum Ilmu Komputer, dan sekarang saya tahu. Saya akan mencoba menggunakan jawaban pertama. Sekali lagi terima kasih atas bantuan Anda. - person jhorton; 08.09.2015
comment
Sebenarnya, setelah melihatnya lebih jauh saya melihat satu masalah. Saya membutuhkan halaman web untuk menjadi desain responsif. Jadi jika saya menggunakan persamaan ini, saya harus menentukan tinggi dan lebar absolut. Dan menetapkan nilai melalui javascript pada pengubahan ukuran halaman akan memakan biaya. Tahukah Anda jika jawaban pertama bisa digunakan dengan persentase? - person jhorton; 08.09.2015
comment
@jhorton: Jawaban pertama memerlukan JS agar responsif karena posisinya dihitung berdasarkan radius X & Y elips. Yang kedua dapat dibuat responsif tanpa perhitungan tambahan tetapi seperti disebutkan dalam jawaban, diperlukan transformasi skala menjadi lonjong dan itu berarti div di dalamnya juga akan terlihat berskala. - person Harry; 08.09.2015