Отримати відносний x та y div після обертання

Отже, ось що я хотів, я звернув більше уваги в класі математики:

http://i.imgur.com/noKxg.jpg

У мене є великий контейнер div і всередині цього я маю кілька контенту divs, які обертаються.

Те, що я намагаюся зробити, - це анімація між дитиною, переміщаючи головний диск в області перегляду. Це було б дуже легко, якщо б я просто робив це на основі простих розрахунків x/y (зверху/ліворуч), однак, коли відбувається обертання, моя математика просто розбивається.

Я спробував кілька речей і не дуже тріснув його.

Ось спрощена версія моїх результатів сортуйте далеко, будь ласка, не соромся:

http://jsfiddle.net/dXKJH/3/

Я дійсно не можу зрозуміти це!

[EDIT]

Я йду з цим рішенням як перевагу просто тому, що я вже працював над тим, як зробити плагін повертати з MSIE6 +.

Як я повинен сказати, що, хоча я йду за всіма математичними функціями, і вони здаються чистими, результати не є ідеальними для пікселів, це щось робити з розрахунком PI? Здається, що чим більше і більше відстань, я роблю коробки, тим менша ймовірність, що вони підійдуть до верхньої лівої? Незвичайність

Також хтось може нагадати мені, що треба, що я повинен робити, якщо кут більше 45 градусів, я не можу знайти посилання, я пам'ятаю це з класу математики років тому, коли було 4 квадранти або щось ... rr як я бажаю, щоб я приділяв більше уваги ..-)

Спасибі величезною за всю допомогу до сих пір !!

7
Math.sin / cos вимагає радіанів, а не градусів.
додано Автор pimvdb, джерело

3 Відповіді

Ну, це якраз далеко ... Я зробив все менше, щоб краще побачити, де закінчився код div , а також додавав смуги прокрутки з цієї причини.

Важливі моменти:

  • Math.sin/Math.cos require radians, not degrees
  • CSS rotates around the midpoint of the element, not (0, 0) (this applies to both the main div and the box divs; first translate -width/2, -height/2, rotate, and then translate back)
  • Use parseInt(x, 10) to make sure you're using base 10

Остаточний код: http://jsfiddle.net/pimvdb/dXKJH/10/ . Це рішення потребує твердокодування позицій та обертів у HTML, оскільки .css мав деякі примхи з поворотними елементами.

$("#div-1").rotate("-10deg");
$("#div-2").rotate("10deg");
$("#div-3").rotate("15deg");
$("#div-4").rotate("75deg");

$("#main").click(function() {
    console.log($('body').scrollLeft(), $('body').scrollTop());
});

$("a").click(function(e){
    goTo($(this).attr("id").substring(4,5));
    return false;
});


function n(x) {
    return parseInt(x, 10);
}

function sin(x) {
    return Math.sin(x/180 * Math.PI);
}

function cos(x) {
    return Math.cos(x/180 * Math.PI);
}

function rotate(x, y, a) {
    var x2 = cos(a) * x - sin(a) * y;
    var y2 = sin(a) * x + cos(a) * y;
    return [x2, y2];
}


var offsets = [null,
              [0,100,-10],
              [100,200, 10],
              [300,100, 15],
              [400,100, 75]].map(function(v) {
                  if(!v) return v;
                  var rotated = rotate(-50, -50, v[2]);
                  rotated[0] += v[0] + 50;
                  rotated[1] += v[1] + 50;
                  return rotated.concat(v[2]);
               });


function goTo(num){
    var obj = $("#div-" + num);
    var angle = -n(obj.rotate());
    var pointX = offsets[num][0] - 500;
    var pointY = offsets[num][1] - 500;
    var rotated = rotate(pointX, pointY, angle);
    var newX = rotated[0] + 500;
    var newY = rotated[1] + 500;

    $("#main").animate({rotate: angle + "deg"}, 1000);  
    $("body").animate({scrollLeft: newX,
                       scrollTop:  newY}, 1000)
}
2
додано
приємно, мені подобається такий підхід. Величезна подяка за вашу допомогу !!
додано Автор Alex, джерело

Схоже, ви намагаєтесь імітувати веб-сайт iPhone від Apple: http://www.apple.com/iphone/. Я наслідував цю техніку тут:

http://jsfiddle.net/Yw9SK/2/ (uses Webkit transitions)

This really doesn't require much math, don't over-engineer it. You just need to cancel the rotation of the child <div>s and adjust for their width/height and offset from the container <div>.

Here's how to do it:

container width: 500  height: 500  rotation: 0       top: 0    left: 0
child     width: 90   height: 90   rotation: 120deg  top: 330  left: 0


  1. To ensure the rotation is correct, the container must get the negative rotation of the child:

    child rotation: 120deg  --> container rotation: -120deg
    
  2. To have the child centered in the view, we need to subtract its width from the container width, divide by 2 (to keep it centered), and then subtract any offsets. The same thing happens for height:

    Width                                   Height
     500    (container width)                 500    (container height)
    - 60    (child width)                    - 40    (child height)
    ----                                     ----
     440                                      460
      /   (divide by 2                       /   (divide by 2
       2     to keep it centered)               2     to keep it centered)
    ----                                     ----
     220                                      230
    -  0    (subtract the left: offset)      -330    (subtract the top: offset)
    ----                                     ----
     220    translateX                       -100    translateY
    


Because the "stage" is centered on top of the container, the new transform will also be centered within the stage. (It's not much harder to make this happen for a rectangle compared to a square.) Thus our transform to be applied to the container <div> is:

transform: rotate(-120eg) translateX(220px) translateY(-100px)

Rinse and repeat for the other child elements and transition through them accordingly.


This JSFiddle is just an example of how to accomplish this. It is not a very well-designed implantation. A more optimal solution would have a transition-delay or animation-delay (instead of setInterval) and then listen for the 'transitionEnd' or 'animationEnd' events.

I would definitely recommend NOT trying to calculate the new positions and rotations programmatically on the fly (although you can, and then you just have to get those values from the .style property in JS). I would recommend having the translations/rotations you need pre-defined upfront (as seen in my example, though they should be in CSS) and simply apply them in correct order to the container. This will ensure the transitions are fast and smooth.

1
додано
Спасибі за це, так, щось подібне, але не це річ iphone, не така, як цей вид: zeitgeistbot.com
додано Автор Alex, джерело
люблячи переходи webkit, майбутня річ, можливо, але мені потрібно, щоб вона була наскрізь сумісна як можлива.
додано Автор Alex, джерело
Перевірте цей код сторінки, насправді вони використовують перетворення у браузері за допомогою jQuery :) Вони також зберігають всі правильні перекладені X/Y позиції в масиві та застосовують їх після натискання вказаної посилання ... точно так, як демонструє моє приклад .
додано Автор skyline3000, джерело

Я хотів би запропонувати інший підхід:

  1. Перехід до div-2 із початкового стану (перемістіть Main Div, використовуючи лівий/верхній стилі)
  2. Встановіть трансформацію походження Головного диску до центру перегляду (також центру div-2)
  3. Поверніть Main Div на протилежну кількість div-2 (div-2 має бути правильно центрованим)
  4. Поверніть головний диск до 0 градусів.
  5. Перемістити до розділу div-3
  6. Встановіть трансформацію походження Main Div в центрі перегляду (також центр div-3)
  7. Поверніть Main Div на протилежну кількість div-3 (div-3 має бути правильно центрованим)
  8. Промити і повторити

Це може бути простіше і призвести до менш складного коду. Зауважте, що рухи та обертання можуть бути анімованими. Крім того, якщо ви використовуєте переклади, а не лівий/верхній стилі, це рішення буде набагато складнішим через зміну трансформації.

1
додано
ІТ КПІ - JavaScript
ІТ КПІ - JavaScript
504 учасників

співтовариство javascript розробників в Telegram