Erstellen eines CSS-Pfads beim Hover

Lesezeit: 6 Minuten

Benutzer-Avatar
jbutler483

Ich versuche, ein ‘nettes’ CSS-Menü mit (hauptsächlich) CSS zu generieren, aber mit a sehr klein ein bisschen jQuery auch:

Meine Gesamtidee ist:

+------------------------+
|                        |
|                        |
|         +---+          |
|         |   |          |
|         |___|          | <-- Hover this center piece
|                        |
|                        |
|                        |
+------------------------+

+------------------------+
|     _                  |
|    |\                  | <-- All start moving up to top of screen
|      \  +---+          |
|         |   |          |
|         |___|          |
|                        |
|                        |
|                        |
+------------------------+

+------------------------+
| +---+                  |
| |   |                  |
| |___|                  |
|                        |
|  || All, but one       |
|  || moves down         |
|  \/                    |
|                        |
+------------------------+

+------------------------+
| +---+                  |
| |   |                  |
| |___|                  |
|                        |
|        One stays,      |
| +---+  the rest move this way
| |   |  --->            |
| |___|                  |
+------------------------+

+------------------------+
| +---+                  |
| |   |                  |
| |___|              ^   | The rest move up
|                    |   |
|                    |   |
| +---+            +---+ |
| |   |            |   | |
| |___|            |___| |<-- Another stays
+------------------------+

Vollständig:

+------------------------+
| +---+            +---+ |
| | 1 |            | 4 | |
| |___|            |___| |
|                        |
|                        |
| +---+            +---+ |
| | 2 |            | 3 | |
| |___|            |___| |
+------------------------+

Dies setzt jedoch voraus, dass es vier div-Kinder gibt. Ich versuche also, in jQuery einen Weg zu finden, um den Winkel/die Position zu bestimmen (was ehrlich gesagt nicht so gut funktioniert).


Ähnliches Design:

Geben Sie hier die Bildbeschreibung ein


Da es also vier Divs gibt, befinden sie sich am Ende in 90-Grad-Intervallen von der Mitte (360/4 Divs = 90 Grad auseinander).

Wenn es, sagen wir, sechs Kind-Divs gäbe;

360/6 = 60 degrees

Sie werden also gleichmäßig in 60-Grad-Intervallen verteilt.


Ich werde auch Animationen zwischen ihnen hinzufügen, also warum ich mit Rotationen usw. herumgespielt habe, aber ich kann es einfach nicht in den Griff bekommen:

Mein aktuelles Beispiel ist:

$(".wrap").hover(function(){
    var x =$(this).children().length; //Counts '.circles'
    var degree = 360 / x; //Gets angle
    var percent = 100 / x;
    var curPercent = percent;
    $(this).children().each(function (index) {
        $(this).css("transform","rotate(" + degree*index + "deg)");
        $(this).css("top",percent + "px");
        $(this).css("left",percent + "px");

        percent = percent + curPercent;
    });
});
.wrap{
    height: 300px;
    width: 300px;
    background: red;
    position: relative;
    transform-origin: center center;
    transition: all 0.8s;
}
.wrap:hover .circle{
    top: 0;
    left: 0;
}
.circle{
    transition: all 0.8s;
    position: absolute;
    height: 50px;
    width: 50px;
    top: calc(50% - 25px);
    left: calc(50% - 25px);
    background: tomato;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
    <div class="circle">1</div>
    <div class="circle">2</div>
    <div class="circle">3</div>
    <div class="circle">4</div>
</div>

Geige


Würde jemand:

  • (A): Wissen Sie, wie Sie die Divs dazu bringen, den angegebenen Winkel oder Abstand in Bezug auf das im jQuery-Code angegebene übergeordnete Element zu „drehen“?

  • (B): Holen Sie sich die ‘Animation’ zum Zurücksetzen beim Hover-Out?

  • (C): Haben Sie eine Ahnung, wovon ich spreche?

Ähnliche Implementierungen (wenn auch nicht exakt):

  • Kennst du @keyframes? Denn es sieht so aus, als könntest du mit CSS machen, was du willst …

    – Pa3k.m

    13. Februar 2015 um 10:31 Uhr

  • @Pa3k.m: Gerade Gradberechnung basierend auf Nr. von Kindern?

    – Harry

    13. Februar 2015 um 10:34 Uhr

  • @Pa3k.m: Das einzige Problem mit Keyframes ist, dass es nach einer Endposition sucht (die ich nicht kenne, bis jquery ausgeführt wird) und außerdem müssen viele Präfixe hinzugefügt werden.

    – jbutler483

    13. Februar 2015 um 10:34 Uhr

  • @downvoter könnten Sie bitte erklären, warum?

    – jbutler483

    13. Februar 2015 um 10:40 Uhr

  • Dieser Satz ist überhaupt nicht klar, weshalb Pa3k.m nachgefragt hat. Was ist die maximale und minimale Anzahl von Sprites/Divs, die Sie animieren möchten? Wann wollen Sie die Winkel bestimmen? Während der Animation, davor oder danach? Wann wird die Anzahl der Divs bestimmt – wenn der HTML-Code generiert wird, wenn die Seite geladen wird oder während der Benutzer sie verwendet? (Wenn das letzte, wann genau?)

    – Dekoration

    13. Februar 2015 um 12:23 Uhr

Benutzer-Avatar
Arnold Daniels

Wenn Sie einen anderen Ansatz verwenden, erhalten Sie einen etwas anderen Effekt. Sie können mit den Zeiten spielen setTimeout und die transition um das Verhalten zu ändern.

Siehe die Geige

+ function() {
  var to;
  $(".wrap").on('mouseenter', function() {
    var circles = $(this).children();
    var degree = (2 * Math.PI) / circles.length; //calc delta angle
    var transforms = [];

    // Calculate the position for each circle
    circles.each(function(index) {
        var x = 100 * Math.cos(-0.5 * Math.PI + degree * (-1 * index - 0.5));
        var y = 100 * Math.sin(-0.5 * Math.PI + degree * (-1 * index - 0.5));

      transforms.push('translate(' + x + 'px,' + y + 'px)');
    });

    // Function to moves all the circles
    // We'll pop a circle each time and than call this function recursively
    function moveCircles() {
      var transform = transforms.shift();
      circles.css('transform', transform);

      circles.splice(0, 1);
      if (circles.length) to = setTimeout(moveCircles, 400);
    }

    moveCircles();
  });

  $(".wrap").on('mouseleave', function() {
    var circles = $(this).children().css('transform', '');
    clearTimeout(to);
  });
}();
   .wrap {
     height: 300px;
     width: 300px;
     background: red;
     position: relative;
     transform-origin: center center;
     transition: all 0.8s;
   }
   .circle {
     transition: all 0.8s;
     position: absolute;
     height: 50px;
     width: 50px;
     text-align: center;
     line-height: 50px;
     top: calc(50% - 25px);
     left: calc(50% - 25px);
     background: tomato;
     border-radius: 50%;
   }
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
  <div class="circle">1</div>
  <div class="circle">2</div>
  <div class="circle">3</div>
  <div class="circle">4</div>
  <div class="circle">5</div>
  <div class="circle">6</div>
</div>

  • Das ist ziemlich toll. Prost Ich mag das Markup wirklich 🙂 🙂

    – jbutler483

    13. Februar 2015 um 11:50 Uhr

  • @jbutler483 Die (-1 * index - 1.5) gab ungerade Positionen für eine ungerade Anzahl von Kreisen an. Mit einem Offset von -90 Grad und mit (-1 * index - 0.5) ergibt ein besseres Ergebnis. 🙂

    – Arnold Daniels

    13. Februar 2015 um 14:15 Uhr

  • Dafür noch einmal vielen Dank. Sie können sehen, wie ich Ihr Beispiel annehme hier – also vielen Dank 🙂

    – jbutler483

    13. Februar 2015 um 14:17 Uhr

Benutzer-Avatar
huysentruitw

function rotateStep($this, $circle, angle) {
    $this.animate({
        rotation: angle
    }, {
        step: function(now, fx) {
            $this.css({
                transform: 'rotate(' + now + 'deg)'
            });
            $circle.css({
                transform: 'translate(-50%, -50%) rotate(' + -now + 'deg)'
            });
        }
    });
}

$('.wrap').hover(function() {
    var $this = $(this),
        $circleWrappers = $this.find('.circleWrapper'),
        angleOffset = 360 / $circleWrappers.length,
        angle = - angleOffset / 2,
        distance = Math.min($this.width(), $this.height()) / 2;
    
    $circleWrappers.each(function() {
        var $this = $(this),
            $circle = $(this).find('.circle');
        $circle.animate({ top: -distance });
        rotateStep($this, $circle, angle);
        angle -= angleOffset;
    });
}, function() {
    var $this = $(this),
        $circleWrappers = $this.find('.circleWrapper');
    
    $circleWrappers.each(function() {
        var $this = $(this),
            $circle = $(this).find('.circle');
        $circle.animate({ top: 0 });
        rotateStep($this, $circle, 0);
    });
});
.wrap {
    position: relative;
    background-color: #cccccc;
    width: 400px;
    height: 400px;
    transition:all 0.8s;
    transform-origin: center center;
}
.circleWrapper {
    display: inline-block;
    position: absolute;
    left: 50%;
    top: 50%;
}
.circle {
    position: absolute;
    width: 80px;
    height: 80px;
    border-radius: 40px;
    background-color: white;
    box-shadow: 0px 0px 5px rgba(0, 0, 0, 0.5);
    line-height: 80px;
    text-align: center;
    font-family: arial;
    font-size: 42px;
    font-weight: bold;
    transform: translate(-50%, -50%);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="wrap">
    <div class="circleWrapper"><div class="circle">1</div></div>
    <div class="circleWrapper"><div class="circle">2</div></div>
    <div class="circleWrapper"><div class="circle">3</div></div>
    <div class="circleWrapper"><div class="circle">4</div></div>
</div>

JSFiddle

  • Vielen Dank dafür. Wenn ich mir Ihre jquery ansehe, glaube ich nicht, dass ich meine Implementierung jemals zum Laufen gebracht hätte, also danke dafür. Aber es ist sehr klar und ich kann irgendwie sehen, wie es funktioniert, also Prost 🙂

    – jbutler483

    13. Februar 2015 um 11:17 Uhr

  • Der Hover-Out-Effekt wurde ebenfalls hinzugefügt

    – huysentruitw

    13. Februar 2015 um 11:18 Uhr

  • @WouterHuysentruit: Obwohl dies ein großartiger Ansatz ist, denke ich, dass Sie der gegebenen Lösung möglicherweise zustimmen werden, wenn Sie die akzeptierte Antwort sehen.

    – jbutler483

    13. Februar 2015 um 11:55 Uhr

  • @ jbutler483 scheint, dass die andere Antwort noch besser zur Frage passt, also habe ich kein Problem damit 🙂

    – huysentruitw

    13. Februar 2015 um 11:58 Uhr

  • Glückwunsch zu den 10k BTW

    – jbutler483

    13. Februar 2015 um 16:29 Uhr

1227520cookie-checkErstellen eines CSS-Pfads beim Hover

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy