Rotasyondan sonra göreli x ve y div olsun

Yani burada istediğim, matematik dersinde daha fazla dikkat ettim:

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

Büyük bir konteyner divum var ve bunun içinde döndüğüm birkaç içerik div'um var.

Yapmaya çalıştığım şey, ana div'u manzaranın etrafına taşıyarak çocuk divleri arasında canlandırmadır. Basit x/y (üstte/solda) hesaplamalara dayanıyor olsaydım bu gerçekten kolay olurdu, ancak rotasyon söz konusu olduğunda, matematiklerim bozuluyor.

Birkaç şey denedim ve gerçekten kırmadım.

İşte sonuçların sıralamasının basitleştirilmiş bir versiyonu, lütfen çekinmeyin:

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

Bunu gerçekten çözemiyorum!

[DÜZENLE]

Bu çözümle tercihim olarak gidiyorum çünkü halihazırda MSIE6 + ile döndürme eklentisi yapmanın bir yolunu çalıştım.

Ben tüm matematik fonksiyonlarını takip etsem ve temiz göründüğüne rağmen sonuçların piksel mükemmel olmadığını söylemem gerektiğini söylemeliyim ki bu bir PI hesaplamasıyla ilgili bir şey mi? Görünüşe bakılırsa, daha büyük ve daha fazla aralıklı kutular kutuların üst solla eşleşmeleri daha az olasıdır? Oddness.

Ayrıca herkes bana açıyı 45 derece daha fazla olursa ne yapmam gerekiyor trig şey hatırlatmak olabilir, bir referans bulamadım matematik sınıfından yıllar önce 4 çeyrek vardı ya da bir şey olduğunu hatırlıyorum ... rr nasıl Daha fazla dikkat etmeyi dilerdim .. :-)

Şimdiye kadar tüm yardım için çok teşekkür ederim!

7
Math.sin / cos , derece değil radyan gerektirir.
katma yazar pimvdb, kaynak

3 cevap

Eh, bu ne kadar uzağa var ... Ben her şeyi div in sonunda daha iyi görmek için daha küçük yaptım ve bu nedenle de kaydırma çubukları ekledi.

Önemli noktalar:

  • 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

Son kod: http://jsfiddle.net/pimvdb/dXKJH/10/ . Bu çözüm, .css 'in rotasyonlu elemanlara sahip bazı quirkslere sahip olmasından dolayı HTML'de de sabit kodlanmış konumlara ve rotasyonlara ihtiyaç duyar.

$("#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
katma
güzel, bu yaklaşımı seviyorum. Yardımınız için çok teşekkürler!
katma yazar Alex, kaynak

Apple'ın iPhone web sitesini taklit etmeye çalıştığınız anlaşılıyor: http://www.apple.com/iphone/. Bu tekniği burada taklit ettim:

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
katma
Bunun için teşekkürler, evet benzer bir şey ama bu iphone şey değil, nav böyle bir tür: nrefer =======
katma yazar Alex, kaynak
webkit geçişlerini sevmek, belki de gelecekteki bir şey ama bende olabildiğince uyumlu olması gerekiyor.
katma yazar Alex, kaynak
Sayfanın kodunu inceleyerek, aslında jQuery ile tarayıcıya özgü dönüşümleri kullanıyorlar :) Aynı zamanda bir dizide X/Y konumlarını düzgün bir şekilde çeviriyorlar ve belirtilen bir linke tıkladıktan sonra bunları uyguluyorlar ... tıpkı benim örneğim gibi .
katma yazar skyline3000, kaynak

Farklı bir yaklaşım önermek isterim:

  1. Başlangıç ​​durumundan div-2'ye geçin (sol/üst stilleri kullanarak Ana Bölmeyi yeniden konumlandırın)
  2. Ana Div'un dönüşüm-orjinini merkeze getirin (aynı zamanda div-2'nin merkezi)
  3. Ana Div'u div-2'nin tersi ile döndürün (div-2 doğru şekilde ortalanmalıdır)
  4. Ana Bölümü 0 dereceye geri döndürün.
  5. div-3'e taşı
  6. Ana Div'un dönüşüm-menşesini bakış açısına ayarlayın (aynı zamanda div-3'ün merkezi)
  7. Ana Div'u div-3'ün tersi ile döndürün (div-3 doğru şekilde ortalanmalıdır)
  8. Durulayın ve tekrarlayın

Bu daha kolay olabilir ve daha az karmaşık (daha sürdürülebilir) kodla sonuçlanabilir. Hamle ve rotasyonların animasyonlu olabileceğini unutmayın. Ayrıca, sol/üst stilleri yerine çeviriler kullanırsanız, bu çözüm, dönüşüm kaynaklı değişiklikler nedeniyle çok daha karmaşık olacaktır.

1
katma