【问题标题】:Creating a CSS 'path' on hover在悬停时创建 CSS“路径”
【发布时间】:2015-04-14 08:47:55
【问题描述】:

我正在尝试使用(主要)CSS 生成一个“漂亮”的 CSS 菜单,但也有一个 tinyjQuery

我的总体思路是:

+------------------------+
|                        |
|                        |
|         +---+          |
|         |   |          |
|         |___|          | <-- 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
+------------------------+

完成:

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

但是,假设会有四个 div 孩子,所以我试图在 jQuery 中生成一种“确定角度/位置”的方法(老实说,这种方法效果不太好)。


类似的设计:


所以最后,由于有四个 div,它们将与中心相隔 90 度(360/4 div = 90 度)。

假设有六个子 div;

360/6 = 60 degrees

因此它们将以 60 度的间隔均匀分布。


我将在它们之间添加动画,因此我一直在玩旋转等,但我似乎无法掌握它:

我目前的样本是:

$(".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>

Fiddle


有人愿意吗:

  • (A):知道如何让 div '旋转'与 jQuery 代码中指定的父级相关的指定角度或距离吗?

  • (B):让“动画”在悬停时重置?

  • (C):知道我在说什么吗?

类似的实现(虽然不准确):

【问题讨论】:

  • 你知道@keyframes吗?因为看起来你可以完全用 css 做你想做的事......
  • @Pa3k.m: 偶数度计算基于no。孩子?
  • @Pa3k.m:关键帧的唯一问题是它会寻找一个结束位置(直到 jquery 运行我才知道),而且还有很多前缀要添加.
  • @downvoter 你能解释一下为什么吗?
  • 那句话一点都不清楚,这就是Pa3k.m问的原因。您希望制作动画的精灵/div 的最大和最小数量是多少?你什么时候想确定角度?在动画期间,之前还是之后?何时确定 div 的数量 - 生成 HTML 时、页面加载时还是用户使用时? (如果是最后一个,具体是什么时候?)

标签: jquery css css-position css-transitions


【解决方案1】:

使用不同的方法,您会得到稍微不同的效果。您可以使用setTimeouttransition 的时间来修改行为。

See the fiddle

+ 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>

【讨论】:

  • 这太棒了。干杯实际上真的很喜欢标记:):)
  • @jbutler483 (-1 * index - 1.5) 为奇数个圆提供奇数位置。使用 -90 度偏移并使用 (-1 * index - 0.5) 会产生更好的结果。 :)
  • 再次感谢您。你可以看到我对你的例子的看法here - 所以谢谢你:)
【解决方案2】:

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

【讨论】:

  • 谢谢你,浏览你的 jquery 我不认为我的实现工作正常,所以谢谢你。但它非常清楚,我可以看到它是如何工作的,所以干杯:)
  • 也添加了悬停效果
  • @WouterHuysentruit:虽然这是一个很好的方法,但我认为如果您看到接受的答案,我想您可能会同意给出的解决方案。
  • @jbutler483 似乎另一个答案更适合这个问题,所以我对此没有任何问题:)
  • 恭喜获得 10k BTW
猜你喜欢
  • 1970-01-01
  • 2017-12-29
  • 2012-06-14
  • 1970-01-01
  • 2021-03-05
  • 1970-01-01
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
相关资源
最近更新 更多