jQuery,获取围绕圆圈的元素位置

时间:2014-06-02 08:31:41

标签: jquery css

我正在努力让div围绕一个圆圈旋转。我一直在研究JSFiddle,我刚才发现它似乎几乎是我想要的:

http://jsfiddle.net/c7b6H/

但我似乎无法获得我想要的预期效果。如果单击“向右移动”按钮,您将看到图像平滑地旋转到右侧的位置。这很棒,但是当我点击Go Left链接时,他们似乎跳到左边然后重新开始。

如何获取div的位置,然后让它们滚动到圆圈周围的某些位置。例如,如果我点击向右走,他们会做他们现在做的事情,如果我再次点击它们,他们会更进一步,而不是从头开始。

以下是代码:

var t, delta, finish;

window.goLight = function() {
    $('.circle').removeClass('right').attr("style", "");
    t = [-Math.PI, -Math.PI, -Math.PI],
    delta = [0.07, 0.055, 0.04],
    finish = [-0.5, -1.0, -1.5];
    moveit(0);
    moveit(1);
    moveit(2);
}

window.goLeft = function() {
    $('.circle').addClass('right').attr("style", "");
    t = [0,0,0],
    delta = [-0.07, -0.055, -0.04],
    finish = [-Math.PI+0.5, -Math.PI+1.0, -Math.PI+1.5];
    moveit(0);
    moveit(1);
   moveit(2);
}

function moveit(i) {
    var r = 300; // radius

    var newLeft = Math.floor(r - 50 + (r * Math.cos(t[i])));
    var newTop = Math.floor(r - 50 + (r * Math.sin(t[i])));

    $('div.circle'+(i+1)).animate({
       top: newTop,
       left: newLeft,
    },1, function() {
       t[i] += delta[i];
       if (delta[i] < 0) {
      if (t[i] > finish[i]) moveit(i);
    } else {
      if (t[i] < finish[i]) moveit(i);
    }
});
}

2 个答案:

答案 0 :(得分:2)

使用jQuery的不同版本

概述

这是你要求的一个例子,我重写了这个方法,但是当我发现在角度偏移中工作时更直接,更容易修改。这个版本可以通过多种不同的方式进行改进,但它只是为了给你一个想法。它的工作原理是将隐藏的非实时元素上的jQuery线性width动画通过step函数转换为margin-leftmargin-top值 - 而不是使用一个复杂的缓动函数,必须用Math.PI计算环绕所有东西。

screenshot of circles within circles

拨弄

http://jsfiddle.net/nf7kA/

边距?

我使用保证金进行定位的原因是可以保留lefttop以确保较小圆圈的中心热点始终位于较大圆圈的中心位置圈。这可以通过多种不同的方式实现,但这取决于您的喜好,即使用单独的包装层来抵消小圆圈,或者依赖于css转换。

每个圆圈都有一个测量对象

通过将每个动画与其自己的圆圈分开,它应该意味着您可以以不同的速度和偏移动画它们,但是您真的喜欢。基本上每个圆圈都有一个measure个对象。这只是一个隐藏的div,jQuery动画了“虚构”的宽度。然后通过将width值视为角度(以度为单位),将其转换为弧度,然后使用Math.cosMath.sin,将该动画转换为2d坐标。

扩展标记

系统从data-angle属性读入圆圈的起始角度,这意味着在不同的偏移处添加和删除圆圈应该非常容易,甚至可以根据需要动态删除(尽管你需要更新spin.circles数组。您还可以通过添加data-duration属性来扩展此想法,如果您想让特定的圆圈移动得比对应的更快,或者如果您需要不同大小的圆圈,则可以添加data-radius属性。

无论如何,只是一个想法,可以通过多种不同的方式进行扩展。

要小心

此版本需要注意的一点是,只要您将隐藏div的width值保持在零以上,它就能完美运行。第二个你开始负值动画显然事情有点奇怪。这是将起始宽度定义为8 x 360的原因。随着这种前进或后退将工作正常,直到你围绕圆圈倒退超过8次。如果这是一个真正的问题,那么有很多解决方案。最简单的是增加乘数,其他选项是找到一个css属性,jQuery可以正面或负面地开箱即用动画...我试过z-index和{{ 1}}但两者都有奇怪的后果。

的javascript

line-height

CSS

jQuery(function($){

  /// a quick easing import
  !jQuery.easing && (jQuery.easing = {});
  !jQuery.easing.easeOutQuad && 
  (jQuery.easing.easeOutQuad = function( p ) { 
    return 1 - Math.pow( 1 - p, 2 );
  });

  /// the object the controls each individual circle
  var circleController = {
    create: function( circle ){
      var angle = parseFloat(circle.data('angle'));
      var obj = {
        angle: angle,
        element: circle,
        measure: $('<div />').css('width', 360 * 8 + angle),
        update: circleController.update,
        reposition: circleController.reposition,
      };
      obj.reposition();
      return obj;
    },
    update: function( angle ){
      this.angle = angle;
      this.reposition();
    },
    reposition: function(){
      var radians = this.angle * Math.PI / 180, radius = 600 / 2;
      this.element.css({
        marginLeft: (Math.sin( radians ) * radius - 50) + 'px',
        marginTop: (Math.cos( radians ) * radius - 50) + 'px'
      });
    }
  };

  /// the overall manager that keeps track of each circle
  var spin = {
    circles: [],
    left: function(){
      var self = this;
      $.each(this.circles, function(i, circle){
        circle.measure.stop(true, false).animate(
          { 'width': '-=45' },
          {
            easing: 'easeOutQuad',
            duration: 1000,
            step: function( now ){ circle.update( now ); }
          }
        );
      });
    },
    right: function(){
      var self = this;
      $.each(this.circles, function(i, circle){
        circle.measure.stop(true, false).animate(
          { 'width': '+=45' },
          {
            easing: 'easeOutQuad',
            duration: 1000,
            step: function( now ){ circle.update( now ); }
          }
        );
      });
    },
    prep: function( circles ){
      for ( var i=0, circle; i<circles.length; i++ ) {
        this.circles.push(circleController.create($(circles[i])));
      }
    }
  };

  $('#goL').click(function(){ spin.left() });
  $('#goR').click(function(){ spin.right() });

  spin.prep($('.circle'));

});

HTML

.maincircle {
  position: absolute;
  height: 600px;
  left:50%;
  margin-left:-300px;
}

.inner {
  position: relative;
  width:600px;
  height:600px;
  border-radius: 50%;
  background-color:#02E3E7;
}

.circle {
  position: absolute;
  width:100px;
  height:100px;
  border-radius: 50%;
  font-family: "Segoe UI", tahoma, sans-serif;
  font-size: 12px;
  text-align:center;
  vertical-align:middle;
  background-color: white;
  box-shadow: 0px 0px 10px 10px teal;
  margin-top: -50px;
  margin-left: -50px;
  left: 50%;
  top: 50%;
  line-height: 100px;
}

答案 1 :(得分:-1)

.circle {
      position: absolute;
      width:100px;
      height:100px;
      border-radius: 50%;
      font-family:"Segoe UI";
      font-size: 12px;
      text-align:center;
      vertical-align:middle;
      background-color:#30EB0B;
      top: 91%; 
      right: 42%;
   }
  .right.circle {
     top: 89% ; 
     left: 50%;
     position:absolute;
  }
  .circle1.circle.right{
       top:xxx;
       left:xxx;
   }
  .circle2.circle.right{
       top:xxx;
       left:xxx;
   }
   .circle3.circle.right{
       top:xxx;
       left:xxx;
   }

//custom use position