Javascript-форум (https://javascript.ru/forum/)
-   Events/DOM/Window (https://javascript.ru/forum/events/)
-   -   Элемнты не двигаются по кругу дальше угла pi/2 (https://javascript.ru/forum/events/44833-ehlemnty-ne-dvigayutsya-po-krugu-dalshe-ugla-pi-2-a.html)

Synov_son 03.02.2014 23:54

Элемнты не двигаются по кругу дальше угла pi/2
 
Доброго времени суток. Ребята помогите пожалуйста. Написал скрипт для сайта с продуктом. В чем его суть. Продукт задал фоновой картинкой блока а в блоке по кругу движутся всякие возможные ингредиенты к этому продукту. Ну в общем:
-php выстраивает мой круг из продуктов по такой логике. Блоку квадратный 400х400 пикселей, он берет центр блока за точку 0(200;200) -начало координат. Ну и я беру радиус круга(r) за 200 и элементам даю стиль left и top, x и y соответственно. Таким образом у меня
Код:

x=r+r*cosA - el_width; y=r-r*sinA - el_height
, где A - такой угол что A=0; A0=2*pi/(кол-во элементов) и при каждом новом элементе я A увеличиваю на A0.
Так я построил свой круг из элементов.
$this->csize = 400;//Размер квадратного блока с кругом внутри
		$this->iwidth = 60;//Ширина картинок с папки images/flavors
		$this->iheight = 42;//Высота картинок с папки images/flavors
		$this->images = glob('images/flavors/*.png');
		$a = 2*M_PI/(count($this->images));//шаг круга
		$a0 = M_PI*1.5;//градус начала отсчета
		$r = $this->csize/2;
		foreach($this->images as $key=>$value){
			$this->images[$key] = str_replace(array('images/flavors/','.png'), '', $value);
			$this->top[$key]= ( $r*(1 - sin($a0)) ) + ($this->iheight/2);//от центра квадратного блока берем отсчет
			$this->left[$key]= ( $r*(1 + cos($a0)) ) + ($this->iwidth/2.6);//и смещаем елементы по кругу
			$a0 += $a;
		}
<?php foreach ($this->images as $key=>$value){?>
				<img id="<?=$key?>" src="<?=BASE?>images/flavors/<?=$value?>.png" alt="<?=$value?>" width="<?=$this->iwidth?>" height="<?=$this->iheight?>" style="top:<?=$this->top[$key]?>px;left:<?=$this->left[$key]?>px">
			<?php }?>


-ну а дальше вне нужно сделать так что бы круг вращался с анимацией. Сначала я сделал так:
var css = $('#next').css(['top','left']);
$('current').animate({'top':css['top'],'left':css['left']}),slow);

То есть я брал координаты следующего элемента и перемещал в их предыдущий, но это оказалось неправильным вариантом. Так как js брал координаты следующего элемента до того как тот окончательно закончил движение и получался маленький круг.
По этому я повторил тоже что и было в php коде, только за угол начального отсчета я брал угол на котором лежит нулевой элемент.
function rotate(){
	var images = $('#menu img').length;
	var a = 2*Math.PI/images;
	var r = $('#menu').height()/2;
	var iheight = $('#menu img').height();
	var iwidth = $('#menu img').width();
	var y0 = +$('#menu #0').css('top').replace( 'px', '');
	var y = y0 - iheight/2;
	var a0 = Math.asin( 1 - y/r );
	for(var i=0;i<images;i++){
		a0 += a;
		itop = ( r*(1 - Math.sin(a0)) ) + (iheight/2);
		ileft = ( r*(1 + Math.cos(a0)) ) + (iwidth/2.6);
		$('#menu #'+i).animate({'top':itop,'left':ileft}, 1200, 'easeOutQuart');
	}
}

Проблема в том что нулевой элемент (при каком бы первичном положении он не был A=0 или A=-p/2 или A=p/2) далее угла pi/2 не перемещается. А если я ставлю его изначально на угол pi/2 он перемещается на один шаг вперед и на один назад (циклично).
Подскажите, пожалуйста, в чем проблема, если смогли понять о чем я (писал на быструю руку). Благодарю. :help: :help: :help:

рони 04.02.2014 00:44

Synov_son,
а без php пример можно? и тут можно посмотреть анимацию движения по кругу

Synov_son 04.02.2014 19:55

Да, Вот html
<div id="menu" style="width:400px;height:400px;">
	<img id="0" src="images/flavors/Blackberry.png" alt="Blackberry" width="60" height="42" style="top:421px;left:223.07692307692px">
	<img id="1" src="images/flavors/Blueberry.png" alt="Blueberry" width="60" height="42" style="top:403.70909152852px;left:304.42425169208px">
	<img id="2" src="images/flavors/Cherry.png" alt="Cherry" width="60" height="42" style="top:354.82612127177px;left:371.7058881724px">
	<img id="3" src="images/flavors/Chocolate sprinkles.png" alt="Chocolate sprinkles" width="60" height="42" style="top:282.80339887499px;left:413.28822633595px">
	<img id="4" src="images/flavors/Coconut.png" alt="Coconut" width="60" height="42" style="top:200.09430734647px;left:421.98130215058px">
	<img id="5" src="images/flavors/Hazelnut.png" alt="Hazelnut" width="60" height="42" style="top:121px;left:396.28200383381px">
	<img id="6" src="images/flavors/Kiwi.png" alt="Kiwi" width="60" height="42" style="top:59.196601125011px;left:340.63397353542px">
	<img id="7" src="images/flavors/Mango.png" alt="Mango" width="60" height="42" style="top:25.370479853239px;left:264.65926124048px">
	<img id="8" src="images/flavors/Oreo pieces.png" alt="Oreo pieces" width="60" height="42" style="top:25.370479853239px;left:181.49458491337px">
	<img id="9" src="images/flavors/Pineapple.png" alt="Pineapple" width="60" height="42" style="top:59.19660112501px;left:105.51987261843px">
	<img id="10" src="images/flavors/Pomegranate.png" alt="Pomegranate" width="60" height="42" style="top:121px;left:49.871842320035px">
	<img id="11" src="images/flavors/Rainbow sprinkles.png" alt="Rainbow sprinkles" width="60" height="42" style="top:200.09430734647px;left:24.172544003268px">
	<img id="12" src="images/flavors/Raspberry.png" alt="Raspberry" width="60" height="42" style="top:282.80339887499px;left:32.865619817892px">
	<img id="13" src="images/flavors/Strawberry.png" alt="Strawberry" width="60" height="42" style="top:354.82612127177px;left:74.447957981444px">
	<img id="14" src="images/flavors/Tangerine.png" alt="Tangerine" width="60" height="42" style="top:403.70909152852px;left:141.72959446176px">
</div>

#menu, #slideshow {
	position: relative;
}
#menu img {
	position: absolute;
}

function rotate(){
	var images = $('#menu img').length;
	var a = 2*Math.PI/images;
	var r = $('#menu').height()/2;
	var iheight = $('#menu img').height();
	var iwidth = $('#menu img').width();
	var y0 = +$('#menu #0').css('top').replace( 'px', '');
	var y = y0 - iheight/2;
	var a0 = Math.asin( 1 - y/r );
	for(var i=0;i<images;i++){
		a0 += a;
		itop = ( r*(1 - Math.sin(a0)) ) + (iheight/2);
		ileft = ( r*(1 + Math.cos(a0)) ) + (iwidth/2.6);
		$('#menu #'+i).animate({'top':itop,'left':ileft}, 1200, 'easeOutQuart');
	}

function play_menu(){
	return m_interval = setInterval(rotate, 2000)
}
$(document).ready(function() { play();});
}

рони 04.02.2014 23:43

Synov_son,
вы скобочки неперепутали строка 16 и 21?
:write: вариант по кругу ... :)
<!DOCTYPE HTML>

<html>

<head>
  <title>Untitled</title>
  <meta charset="utf-8">
  <style type="text/css">
 #menu, #slideshow, body {
	position: relative;
}
#menu img {
	position: absolute;
}
  </style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script>
$(function () {
    var menu = $("#menu");
    var r = menu.height() / 2 ;
    var images = $("#menu img");
    var t =  r - images.eq(0).height()/2;
    var l =  r - images.eq(0).width()/2;
    var sin = Math.sin,
        cos = Math.cos,
        PI = 2 * Math.PI,
        n = 10;
    var arr_animate = [];
    for (var i = 0; i < PI; i += PI / (images.length * n)) {
        var top =  t + t * sin(i) + "px";
        var left = l + t * cos(i) + "px";
        arr_animate.push({
            "top": top,
            "left": left
        })
    }
    images.each(function (indx, el) {
        $(el).data({
            "indx": indx * n
        });
        next_animate(el)
    });

    function next_animate(el) {
        el = $(el);
        var indx = +$(el).data("indx");
        el.animate(arr_animate[indx], 100, function () {
            next_animate(this)
        });
        indx = ++indx % arr_animate.length;
        el.data({
            "indx": indx
        })
    }
});
</script>
</head>

<body>
<div id="menu" style="width:400px;height:400px; border:  #FF0000 1px solid; margin: 0% auto">
	<img id="0" src="images/flavors/Blackberry.png" alt="Blackberry" width="60" height="42" style="top:421px;left:223.07692307692px">
	<img id="1" src="images/flavors/Blueberry.png" alt="Blueberry" width="60" height="42" style="top:403.70909152852px;left:304.42425169208px">
	<img id="2" src="images/flavors/Cherry.png" alt="Cherry" width="60" height="42" style="top:354.82612127177px;left:371.7058881724px">
	<img id="3" src="images/flavors/Chocolate sprinkles.png" alt="Chocolate sprinkles" width="60" height="42" style="top:282.80339887499px;left:413.28822633595px">
	<img id="4" src="images/flavors/Coconut.png" alt="Coconut" width="60" height="42" style="top:200.09430734647px;left:421.98130215058px">
	<img id="5" src="images/flavors/Hazelnut.png" alt="Hazelnut" width="60" height="42" style="top:121px;left:396.28200383381px">
	<img id="6" src="images/flavors/Kiwi.png" alt="Kiwi" width="60" height="42" style="top:59.196601125011px;left:340.63397353542px">
	<img id="7" src="images/flavors/Mango.png" alt="Mango" width="60" height="42" style="top:25.370479853239px;left:264.65926124048px">
	<img id="8" src="images/flavors/Oreo pieces.png" alt="Oreo pieces" width="60" height="42" style="top:25.370479853239px;left:181.49458491337px">
	<img id="9" src="images/flavors/Pineapple.png" alt="Pineapple" width="60" height="42" style="top:59.19660112501px;left:105.51987261843px">
	<img id="10" src="images/flavors/Pomegranate.png" alt="Pomegranate" width="60" height="42" style="top:121px;left:49.871842320035px">
	<img id="11" src="images/flavors/Rainbow sprinkles.png" alt="Rainbow sprinkles" width="60" height="42" style="top:200.09430734647px;left:24.172544003268px">
	<img id="12" src="images/flavors/Raspberry.png" alt="Raspberry" width="60" height="42" style="top:282.80339887499px;left:32.865619817892px">
	<img id="13" src="images/flavors/Strawberry.png" alt="Strawberry" width="60" height="42" style="top:354.82612127177px;left:74.447957981444px">
	<img id="14" src="images/flavors/Tangerine.png" alt="Tangerine" width="60" height="42" style="top:403.70909152852px;left:141.72959446176px">
</div>

</body>

</html>

Synov_son 05.02.2014 00:01

Да, случайно перепутал. Спасибо большое, сейчас гляну Ваш вариант.

Synov_son 05.02.2014 00:17

А для чего там menu.offset() ?

рони 05.02.2014 00:38

Цитата:

Сообщение от Synov_son
А для чего там menu.offset() ?

убрал.

Synov_son 05.02.2014 00:44

Я уже примерно понял принцип работы, спасибо. Но мне нужно что бы кружилось на заданный угол и интегрально а не все время. Так как у меня есть блок, при совпадении координат элемента с которым вылезает надпись что это за ингредиент.

рони 05.02.2014 00:50

Synov_son,
изменил вычисления )))

Synov_son 05.02.2014 00:51

Но спасибо за идею с циклом, который учитывает угол:)


Часовой пояс GMT +3, время: 15:29.