CSS 3D-преобразование вращается: исходная точка перемещается при первом переходе

Я создал 3D-застолье. Он размещает содержимое в горизонтальном круге, который вращается по оси Y, применяя transform: rotateY и translate к родителю.

Проблема в том, что источник преобразования кажется смещающимся, но только при первом переходе. При последующих поворотах начало координат остается в центре, как и должно быть.

Воспроизведено в:

  • Хром 38 ОС X
  • Хром 38 Win7
  • Файрфокс 30 ОСХ
  • Сафари 7.0.6 OSX

В IE 10 (Win7) есть другая ошибка: он вращается вокруг оси x при первом переходе.

Ручка: http://codepen.io/tricki/full/BGuwo.

Нажмите «Повернуть»: исходная точка перемещается во время перехода. Нажмите «Повернуть еще раз»: исходная точка не перемещается. Нажмите «Повернуть» еще раз: исходная точка не перемещается.

Сначала я подумал, что это ошибка браузера, но тот факт, что у Firefox такая же проблема, заставил меня скептически отнестись к этому. Может ли кто-нибудь увидеть ошибку, которую я сделал, или подтвердить, что это на самом деле ошибка браузера?

HTML:

<div id="parent">
    <div class="card card-1"></div>
    <div class="card card-2"></div>
    <div class="card card-3"></div>
    <div class="card card-4"></div>
    <div class="card card-5"></div>
    <div class="card card-6"></div>
    <div class="card card-7"></div>
    <div class="card card-8"></div>
    <div class="card card-9"></div>
    <div class="card card-10"></div>
</div>

CSS:

#parent {
    background: red;
    height: 300px;
    width: 300px;
    margin: auto;

    transform-style: preserve-3d;
    transform-origin: center center -461px;
    transform: translate3d(0, 0, -461px);
}

#parent.active {
    transition: transform 5s linear;
    transform:rotateY(-144deg) translate3d(0px, 0px, -461px);
}

#parent.active2 {
    transition: transform 5s linear;
    transform:rotateY(-288deg) translate3d(0px, 0px, -461px);
}

.card {
    background: blue;
    border: 1px solid green;
    position: absolute;
    backface-visibility: hidden;

    opacity: .5;
    height: 100%;
    width: 100%;
}

.card-1  { transform: rotateY( 0deg )   translate3d(0, 0, 461px ); }
.card-2  { transform: rotateY( 36deg )  translate3d(0, 0, 461px ); }
.card-3  { transform: rotateY( 72deg )  translate3d(0, 0, 461px ); }
.card-4  { transform: rotateY( 108deg ) translate3d(0, 0, 461px ); }
.card-5  { transform: rotateY( 144deg ) translate3d(0, 0, 461px ); }
.card-6  { transform: rotateY( 180deg ) translate3d(0, 0, 461px ); }
.card-7  { transform: rotateY( 216deg ) translate3d(0, 0, 461px ); }
.card-8  { transform: rotateY( 252deg ) translate3d(0, 0, 461px ); }
.card-9  { transform: rotateY( 288deg ) translate3d(0, 0, 461px ); }
.card-10 { transform: rotateY( 324deg ) translate3d(0, 0, 461px ); }

person Thomas    schedule 05.11.2014    source источник
comment
Единственное происхождение, которое у вас есть, это родитель, и это никогда не меняется...   -  person Zach Saucier    schedule 05.11.2014
comment
Я знаю, поэтому я не понимаю, почему он меняется при переходе.   -  person Thomas    schedule 06.11.2014


Ответы (1)


Удаление исходного смещения -461px и связанных с ним перемещений по оси Z на #parent достаточно, чтобы решить вашу проблему.

Вы не должны смещать начало преобразования, когда вы уже сместили элементы, которые будут двигаться: «слайды» уже расположены относительно точки z = 0 вашего #parent. Так что повороты #parent тоже надо делать относительно этой точки.

Ручка: http://codepen.io/anon/pen/nAeDc.

PS: вы не возражаете, если я оставлю это в папке «Эксперименты» :)? Это довольно круто!

var parent = document.getElementById('parent');

var degree = 0;

document.getElementById('rotate').addEventListener('click', function() {
  parent.style.transform = "rotateY(" + (degree+=36) + "deg)";
});
document.getElementById('active').addEventListener('click', function() {
    parent.style.transform = "";
    parent.classList.remove('active2');
    parent.classList.add('active');
});
document.getElementById('active2').addEventListener('click', function() {
    parent.style.transform = "";
    parent.classList.remove('active');
    parent.classList.add('active2');
});
#parent {
    height: 300px;
    width: 300px;
    margin: auto;
    
    transform-style: preserve-3d;
    transform-origin: center center 0;

    transition: transform 1s linear;
}

#parent:before {
  content: "";
  display: block;
  width: 6px;
  height: 6px;
  position: absolute;
  top: 50%;
  left: 50%;
  margin: -3px 0 0 -3px;
  background: red;
}

#parent.active {
    transform: rotateY(-144deg);
}

#parent.active2 {
    transform: rotateY(-288deg);
}

.card {
    background: blue;
    border: 1px solid green;
    position: absolute;
    backface-visibility: hidden;
    
    opacity: .5;
    height: 100%;
    width: 100%;
}

.card-1  { transform: rotateY( 0deg )   translate3d(0, 0, 461px ); }
.card-2  { transform: rotateY( 36deg )  translate3d(0, 0, 461px ); }
.card-3  { transform: rotateY( 72deg )  translate3d(0, 0, 461px ); }
.card-4  { transform: rotateY( 108deg ) translate3d(0, 0, 461px ); }
.card-5  { transform: rotateY( 144deg ) translate3d(0, 0, 461px ); }
.card-6  { transform: rotateY( 180deg ) translate3d(0, 0, 461px ); }
.card-7  { transform: rotateY( 216deg ) translate3d(0, 0, 461px ); }
.card-8  { transform: rotateY( 252deg ) translate3d(0, 0, 461px ); }
.card-9  { transform: rotateY( 288deg ) translate3d(0, 0, 461px ); }
.card-10 { transform: rotateY( 324deg ) translate3d(0, 0, 461px ); }
<div id="parent">
    <div class="card card-1">1</div>
    <div class="card card-2">2</div>
    <div class="card card-3">3</div>
    <div class="card card-4">4</div>
    <div class="card card-5">5</div>
    <div class="card card-6">6</div>
    <div class="card card-7">7</div>
    <div class="card card-8">8</div>
    <div class="card card-9">9</div>
    <div class="card card-10">10</div>
</div>
<button id="rotate">Rotate 1step</button>
<button id="active">Rotate</button>
<button id="active2">Rotate again</button>

person Antoine Combes    schedule 05.11.2014