2020 Lösung
Hier ist eine modernere Lösung, die ich heutzutage verwende.
Ich beginne mit der Generierung des HTML-Codes aus einer Reihe von Bildern. Ob der HTML-Code mit PHP, JS oder einem HTML-Präprozessor generiert wird, was auch immer ... dies ist weniger wichtig, da die Grundidee dahinter dieselbe ist.
Hier ist der Mops-Code, der dies tun würde:
//- 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)
Der generierte HTML-Code sieht wie folgt aus (und ja, Sie können den HTML-Code auch manuell schreiben, aber es wird schwierig sein, danach Änderungen vorzunehmen):
<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>
Im CSS legen wir beispielsweise eine Größe für die Bilder fest 8em
. Die --m
Elemente befinden sich auf einem Kreis und befinden sich in der Mitte der Kanten eines Kantenpolygons --m
, die alle den Kreis tangieren.
Wenn Sie sich das nur schwer vorstellen können, können Sie mit dieser interaktiven Demo spielen, die den Kreis und den Kreis für verschiedene Polygone erstellt, deren Anzahl der Kanten Sie durch Ziehen des Schiebereglers auswählen.
Dies sagt uns, dass die Größe des Containers doppelt so groß sein muss wie der Radius des Kreises plus doppelt so groß wie die Größe der Bilder.
Wir kennen den Radius noch nicht, aber wir können ihn berechnen, wenn wir die Anzahl der Kanten (und damit die Tangente der Hälfte des Basiswinkels, vorberechnet und als benutzerdefinierte Eigenschaft festgelegt --tan
) und die Polygonkante kennen . Wir möchten wahrscheinlich, dass die Polygonkante mindestens so groß wie die Bilder ist, aber wie viel wir an den Seiten lassen, ist willkürlich. Angenommen, wir haben auf jeder Seite die Hälfte der Bildgröße, sodass die Polygonkante doppelt so groß ist wie die Bildgröße. Dies gibt uns das folgende CSS:
.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% }
In der alten Lösung finden Sie eine Erklärung der Funktionsweise der Transformationskette.
Auf diese Weise ordnet das Hinzufügen oder Entfernen eines Bilds zum Array von Bildern die neue Anzahl von Bildern auf einem Kreis automatisch so an, dass sie gleichmäßig verteilt sind, und passt auch die Größe des Containers an. Sie können dies in dieser Demo testen .
ALTE Lösung (aus historischen Gründen erhalten)
Ja, es ist sehr gut möglich und sehr einfach, nur CSS zu verwenden. Sie müssen nur die Winkel im Auge behalten, in denen Sie die Verknüpfungen mit den Bildern herstellen möchten (ich habe am Ende einen Code hinzugefügt, um die Winkel anzuzeigen, wenn Sie mit der Maus über einen von ihnen fahren).
Sie benötigen zuerst einen Wrapper. Ich stelle seinen Durchmesser so ein 24em
( width: 24em; height: 24em;
macht das), du kannst ihn auf alles einstellen, was du willst. Du gibst es position: relative;
.
Anschließend positionieren Sie Ihre Links mit den Bildern horizontal und vertikal in der Mitte des Wrappers. Sie tun dies, indem Sie position: absolute;
und dann top: 50%; left: 50%;
und margin: -2em;
(wo 2em
ist die halbe Breite des Links mit dem Bild, das ich festgelegt habe - einstellen 4em
- wieder können Sie es nach Belieben ändern, aber vergessen Sie nicht, den Rand in zu ändern dieser Fall).
Sie entscheiden dann über die Winkel , in denen Sie Ihre Links mit den Bildern haben wollen und fügen Sie eine Klasse deg{desired_angle}
(zum Beispiel deg0
oder deg45
oder was auch immer). Dann wenden Sie für jede dieser Klassen verkettete CSS-Transformationen wie folgt an:
.deg{desired_angle} {
transform: rotate({desired_angle}) translate(12em) rotate(-{desired_angle});
}
wo Sie ersetzen {desired_angle}
mit 0
, 45
und so weiter ...
Die erste Drehtransformation dreht das Objekt und seine Achsen, die Translationstransformation verschiebt das Objekt entlang der gedrehten X-Achse und die zweite Drehtransformation bringt das Objekt wieder in Position.
Der Vorteil dieser Methode ist, dass sie flexibel ist. Sie können neue Bilder in verschiedenen Winkeln hinzufügen, ohne die aktuelle Struktur zu ändern.
CODE-AUSZUG
.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>
Sie können den HTML-Code auch weiter vereinfachen, indem Sie Hintergrundbilder für die Links anstelle von img
Tags verwenden.
BEARBEITEN : Beispiel mit Fallback für IE8 und älter (getestet in IE8 und IE7)
Hier ist die einfache Lösung ohne absolute Positionierung:
http://jsfiddle.net/mD6H6/
quelle
Aufbauend auf der hervorragenden Antwort von @ Ana habe ich diese dynamische Version erstellt, mit der Sie Elemente zum DOM hinzufügen und daraus entfernen und einen angemessenen Abstand zwischen den Elementen beibehalten können. Schauen Sie sich meine Geige an: https://jsfiddle.net/skwidbreth/q59s90oy/
quelle
var rotateAngle = zero_start + (offsetAngle * i || 0);
Außerdem habe ich eine Variable für zero_start hinzugefügt, wenn Sie also bei Punkt 270 anstatt bei 0 oder ähnlichem beginnen möchten.jsfiddle.net/q59s90oy/13 . Zuletzt habe ich das CSS für Listenelemente geändert, um negative Ränder zu verwenden. Im Ernst, danke für das Teilen der Arbeit, hat viel geholfen.Es gibt keine Möglichkeit, anklickbare Elemente mit CSS auf magische Weise in einem Kreis um ein anderes Element zu platzieren. Die Art und Weise, wie ich dies tun würde, ist die Verwendung eines Containers mit
position:relative;
. Und dann platziere alle Elemente mitposition:absolute;
und benutzetop
undleft
ziele auf ihren Platz.Auch wenn Sie nicht platziert haben jquery In Ihren Tags ist es möglicherweise am besten, dafür jQuery / Javascript zu verwenden.
Der erste Schritt besteht darin, Ihr mittleres Bild mit perfekt in der Mitte des Containers zu platzieren
position:relative;
.Danach können Sie die anderen Elemente mit einem
offset()
der centerImage minus deroffset()
des Containers um ihn herum platzieren . Geben Sie das genauetop
undleft
des Bildes.Was ich hier gemacht habe, ist das Platzieren der Elemente relativ zum centerImage. Hoffe das hilft.
quelle
Sie können dies sicherlich mit reinem CSS tun oder JavaScript verwenden. Mein Vorschlag:
Wenn Sie bereits wissen, dass sich die Bildnummer niemals ändern wird, berechnen Sie einfach Ihre Stile und entscheiden Sie sich für einfaches CSS (Profis: bessere Leistungen, sehr zuverlässig)
Wenn die Anzahl entweder dynamisch in Ihrer App oder nur in Zukunft variieren kann, wählen Sie eine Js-Lösung (Profis: zukunftssicherer)
Ich hatte einen ähnlichen Job zu erledigen, also habe ich ein Skript erstellt und es hier auf Github als Open-Source- Lösung für alle bereitgestellt , die es benötigen könnten. Es akzeptiert nur einige Konfigurationswerte und gibt einfach den benötigten CSS-Code aus.
Wenn Sie sich für die Js-Lösung entscheiden möchten, finden Sie hier einen einfachen Zeiger, der für Sie nützlich sein kann. Verwenden Sie dieses HTML als Ausgangspunkt als
#box
Container und.dot
das Bild / Div in der Mitte verwenden, möchten Sie alle Ihre anderen Bilder in der Nähe haben:HTML starten:
CSS starten:
Sie können eine Schnellfunktion in dieser Richtung erstellen:
Hier können Sie ein Live-Beispiel sehen
quelle
Verwendung der von @Ana vorgeschlagenen Lösung:
Ich habe die folgende jsFiddle erstellt , die Kreise dynamisch mit einfachem JavaScript platziert (jQuery-Version ebenfalls verfügbar).
Die Art und Weise, wie es funktioniert, ist ziemlich einfach:
quelle
Hier ist eine Version, die ich in React aus den Beispielen hier erstellt habe.
CodeSandbox-Beispiel
quelle
Sie könnten es so machen: Geige
Die Positionierung macht nichts, es ist ein schnelles Beispiel
quelle