Domanda

Hello I was trying to find a solution for a small script that can rotate objects around 1 center but it seems a bit too tricky for me. I've found almost perfect solution and tried to modify it to suit my needs but there's a problem.

I'm trying to make 3 objects with text to rotate with same speed, same orbit but different start positions as if they were apexes(vertices) of equilateral triangle.

Here's my fiddle so far:

    ( function ( $ ) {
        jQuery.fn.orbit = function(s, options){
            var settings = {
                            orbits:    1     // Number of times to go round the orbit e.g. 0.5 = half an orbit
                           ,period:    3000  // Number of milliseconds to complete one orbit.
                           ,maxfps:    25    // Maximum number of frames per second. Too small gives "flicker", too large uses lots of CPU power
                           ,clockwise: false  // Direction of rotation.
            };
            $.extend(settings, options);  // Merge the supplied options with the default settings.

            return(this.each(function(){
                var p        = $(this);

/* First obtain the respective positions */

                var p_top    = p.css('top' ),
                    p_left   = p.css('left'),
                    s_top    = s.css('top' ),
                    s_left   = s.css('left');

/* Then get the positions of the centres of the objects */

                var p_x      = parseInt(p_top ) + p.height()/2,
                    p_y      = parseInt(p_left) + p.width ()/2,
                    s_x      = parseInt(s_top ) + s.height()/2,
                    s_y      = parseInt(s_left) + s.width ()/2;

/* Find the Adjacent and Opposite sides of the right-angled triangle */
                var a        = s_x - p_x,
                    o        = s_y - p_y;

/* Calculate the hypotenuse (radius) and the angle separating the objects */

                var r        = Math.sqrt(a*a + o*o);
                var theta    = Math.acos(a / r);

/* Calculate the number of iterations to call setTimeout(), the delay and the "delta" angle to add/subtract */

                var niters   = Math.ceil(Math.min(4 * r, settings.period, 0.001 * settings.period * settings.maxfps));
                var delta    = 2*Math.PI / niters;
                var delay    = settings.period  / niters;
                if (! settings.clockwise) {delta = -delta;}
                niters      *= settings.orbits;

/* create the "timeout_loop function to do the work */

                var timeout_loop = function(s, r, theta, delta, iter, niters, delay, settings){
                    setTimeout(function(){

/* Calculate the new position for the orbiting element */

                        var w = theta + iter * delta;
                        var a = r * Math.cos(w);
                        var o = r * Math.sin(w);
                        var x = parseInt(s.css('left')) + (s.height()/2) - a;
                        var y = parseInt(s.css('top' )) + (s.width ()/2) - o;

/* Set the CSS properties "top" and "left" to move the object to its new position */

                        p.css({top:  (y - p.height()/2),
                               left: (x - p.width ()/2)});

/* Call the timeout_loop function if we have not yet done all the iterations */

                        if (iter < (niters - 1))  timeout_loop(s, r, theta, delta, iter+1, niters, delay, settings);
                    }, delay);
                };

/* Call the timeout_loop function */

                timeout_loop(s, r, theta, delta, 0, niters, delay, settings);
            }));
        }
    }) (jQuery);

       $('#object1'  ).orbit($('#center'  ), {orbits:  2, period:  8000});
$('#object2'  ).orbit($('#center'  ), {orbits:  4, period:  4000});
$('#object3'  ).orbit($('#center'  ), {orbits:  8, period:  2000});

HTML:

<h1> Example</h1>
<div id='rotation'>
    <div id='center'    >C</div>
    <div id='object1'  >Text1</div>
    <div id='object2'  >Text2</div>
    <div id='object3'  >Text3</div>
</div>

CSS:

#rotation {position: relative; width: 600px; height: 600px; background-color: #898989}
#center         {position: absolute; width:  20px; height:  20px;
           top: 300px; left: 300px; background-color: #ffffff;
           -moz-border-radius: 40px; border-radius: 40px;
           text-align: center; line-height: 15px;
}
#object1        {position: absolute; width:  36px; height:  36px;
           top: 300px; left: 200px; background-color: #ff8f23;
           -moz-border-radius: 18px; border-radius: 18px;
           text-align: center; line-height: 30px;
}

#object2        {position: absolute; width:  36px; height:  36px;
           top: 300px; left: 200px; background-color: #ff8f23;
           -moz-border-radius: 18px; border-radius: 18px;
           text-align: center; line-height: 30px;
}

#object3        {position: absolute; width:  36px; height:  36px;
           top: 300px; left: 200px; background-color: #ff8f23;
           -moz-border-radius: 18px; border-radius: 18px;
           text-align: center; line-height: 30px;
}

I used different speed and revolutions for each object because I can't figure out how to set different start positions without messing up. If I touch x,y coordinates of any object in CSS then the orbiting messes up. It seems that object positions calculations are connected. And if I change coordinates then the calculation also changes. But I can't figure out how to fix this.

È stato utile?

Soluzione 2

Got it working as intended

Fiddle

Jquery code:

var txt = $('#text .txt'), txtLen = txt.size();

var deg2rad = function(a) { return a*Math.PI/180.0; }

var angle = 0, speed=0.1, delay = 0, r = 100;

(function rotate() {
for (var i=0; i<txtLen; i++) {

    var a = angle - (i * 360 / txtLen);

    $(txt[i]).css({top: r+(Math.sin(deg2rad(a))*r), left: r+(Math.cos(deg2rad(a))*r)});
}

angle = (angle - speed) % 360;

setTimeout(rotate, delay);
})(); 

var rotation = function (){
$("#image").rotate({
   duration: 6000,
  angle:360, 
  animateTo:0, 
  callback: rotation,
  easing: function (x,t,b,c,d){        

      var d = 6000
      return c*(t/d)+b;

  }
});
}
rotation();





var txt2 = $('#text2 .txt2'), txt2Len = txt2.size();

var deg2rad = function(a) { return a*Math.PI/180.0; }

var angle = 13, speed=0.2, delay = 0, r = 100;

(function rotate() {
for (var i=0; i<txt2Len; i++) {

    var a = angle - (i * 360 / txt2Len);

    $(txt2[i]).css({top: r+(Math.sin(deg2rad(a))*r), left:
r+(Math.cos(deg2rad(a))*r)});
}
// increment our angle and use a modulo so we are always in the range [0..360] degrees
angle = (angle - speed) % 360;
// after a slight delay, call the exact same function again
setTimeout(rotate, delay);
})();  // invoke this boxed function to initiate the rotation

var rotation = function (){
$("#image").rotate({
   duration: 6000,
  angle:360, 
  animateTo:0, 
  callback: rotation,
  easing: function (x,t,b,c,d){        


      var d = 6000
      return c*(t/d)+b;

  }
});
}
rotation();

Altri suggerimenti

If you change the starting position of each element and call the .orbit function on each of them passing the same arguments it should work.

Check this out: fiddle

This is a slightly modified version of your fiddle. (Changed the starting positions and the arguments when calling the .orbit function.

Correct me if I'm wrong or if I didn't answer your question.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top