Маскирование объекта, чтобы он выглядел так, как будто он идет за предметом, вокруг которого он вращается - PullRequest
9 голосов
/ 11 апреля 2019

Я пытаюсь создать 'точечную' орбиту вокруг другого объекта (круга), но из-за z-index точка всегда появляется над кругом, вокруг которого она предназначена.

Ссылка CodePen: https://codepen.io/moy/pen/ROVZXd?editors=1100

В идеале 2-я половина анимации должна происходить за объектом, поэтому она не видна, пока не выйдет с другой стороны - это возможно?

Я думал о затухании движущегося объекта, но не думаю, что это дало бы эффект сглаживания / маскировки?

Немного застрял в том, как бы я замаскировал эту областьпоскольку я не могу понять, каким образом CSS узнает, что он должен быть скрыт.Я подумал, что, возможно, я мог бы изменить z-index 50%, хотя анимация и сбросить его на 0% / 100%, но это, похоже, ничего не делает.

Есть идеи?Заранее спасибо!

.earth {
  background: white;
  border: 1px solid black;
  border-radius: 50%;
  display: block;
  height: 100px;
  margin: 30px auto;
  position: relative;
  width: 100px;
  z-index: 20;
}

.orbit {
  border: 2px #eee transparent;
  border-radius: 50%;
  height: 140px;
  margin: auto;
  position: absolute;
  top: -20px;
  left: -20px;
  transform: rotateZ(60deg) rotateY(60deg);
  transform-style: preserve-3d;
  width: 140px;
  z-index: 10;
}
.orbit .moon {
  animation: move ease-in-out infinite;
  animation-duration: 2s;
  background: black;
  border-radius: 50%;
  height: 15px;
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 15px;
  z-index: 10;
}

@keyframes move {
  0% {
    transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg); z-index: 20;
  }
  50% {
    z-index: -20;
  }
  100% {
    transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg); z-index: 20;
  }
}
<div class="earth">
  <div class="orbit">
    <div class="moon"></div>
  </div>
</div>

Ответы [ 3 ]

2 голосов
/ 11 апреля 2019

Кажется, я решил эту проблему, добавив отрицательный z-index к анимации, примененной к родителю .orbit

Ссылка: https://codepen.io/moy/pen/wZdpRw?editors=1100

Сначала я применил это на 50% через анимацию, так как это должно быть дальше от точки до того, как она вернется за большой круг. Однако это не сработало, установка на 100% сработала. Не совсем уверен, почему, но это похоже на работу!

1 голос
/ 11 апреля 2019

Первоначальная проблема возникла из-за того, что вы применяете z-index к родительскому элементу, и при этом невозможно заставить дочерний элемент двигаться за ним ( Почему элементы с любым значением z-index никогда не могут прикрыть своего ребенка? ) при этом чан z-index бесполезен

Даже если вы удалите z-index из родительского объекта, у вас все еще есть преобразование, которое также создает стековый контекст, делающий невозможным перемещение дочернего элемента, поэтому вы не можете заставить .moon двигаться позади .earth .

Единственный способ сделать это (как вы уже заметили) - удалить z-index из .earth, чтобы избежать создания земным контекстом стека и анимированного z-индекса орбиты, чтобы заставить орбиту И Луну двигаться позади. земля (не только луна).

Добавьте немного окраски, чтобы лучше видеть это:

.earth {
  background: white;
  border: 1px solid black;
  border-radius: 50%;
  display: block;
  height: 100px;
  margin: 60px auto;
  position: relative;
  width: 100px;
}

.orbit {
  animation: hide ease-in-out infinite;
  animation-duration: 2s;
  background:red;
  border-radius: 50%;
  height: 140px;
  margin: auto;
  position: absolute;
  top: -20px;
  left: -20px;
  transform: rotateZ(60deg) rotateY(60deg);
  transform-style: preserve-3d;
  width: 140px;
}

.orbit .moon {
  animation: move ease-in-out infinite;
  animation-duration: 2s;
  background: black;
  border-radius: 50%;
  height: 15px;
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 15px;
}

@keyframes move {
  0% {
    transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg);
  }
  100% {
    transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg);
  }
}

@keyframes hide {
  0% {
    z-index: 20;
  }
  100% {
    z-index: -20;
  }
}
<div class="earth">
  <div class="orbit">
    <div class="moon"></div>
  </div>
</div>

Теперь, если вы добавите обратно z-index на землю, он перестанет работать из-за контекста стека:

.earth {
  background: white;
  border: 1px solid black;
  border-radius: 50%;
  display: block;
  height: 100px;
  margin: 60px auto;
  position: relative;
  width: 100px;
  z-index:2;
}

.orbit {
  animation: hide ease-in-out infinite;
  animation-duration: 2s;
  background:red;
  border-radius: 50%;
  height: 140px;
  margin: auto;
  position: absolute;
  top: -20px;
  left: -20px;
  transform: rotateZ(60deg) rotateY(60deg);
  transform-style: preserve-3d;
  width: 140px;
}

.orbit .moon {
  animation: move ease-in-out infinite;
  animation-duration: 2s;
  background: black;
  border-radius: 50%;
  height: 15px;
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 15px;
}

@keyframes move {
  0% {
    transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg);
  }
  100% {
    transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg);
  }
}

@keyframes hide {
  0% {
    z-index: 20;
  }
  100% {
    z-index: -20;
  }
}
<div class="earth">
  <div class="orbit">
    <div class="moon"></div>
  </div>
</div>
0 голосов
/ 11 апреля 2019

Вы можете попробовать создать прозрачность для клавиш:

.earth {
  background: white;
  border: 1px solid black;
  border-radius: 50%;
  display: block;
  height: 100px;
  margin: 30px auto;
  position: relative;
  width: 100px;
  z-index: 20;
}

.orbit {
  border: 2px #eee transparent;
  border-radius: 50%;
  height: 140px;
  margin: auto;
  position: absolute;
  top: -20px;
  left: -20px;
  transform: rotateZ(60deg) rotateY(60deg);
  transform-style: preserve-3d;
  width: 140px;
  z-index: 10;
}
.orbit .moon {
  animation: move ease-in-out infinite;
  animation-duration: 2s;
  background: black;
  border-radius: 50%;
  height: 15px;
  margin: auto;
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  width: 15px;
  z-index: 10;
}

@keyframes move {
  0% {
    transform: rotateZ(-90deg) translateX(70px) rotateZ(90deg) rotateY(-70deg); opacity: 1;
  }
  56% {
    opacity: 1;
  }
  58% {
    opacity: 0;
  }
  77% {
    opacity: 0;
  }
  78% {
  opacity: 1;
  }
  100% {
    transform: rotateZ(270deg) translateX(70px) rotateZ(-270deg) rotateY(-70deg); opacity: 1;
  }
}
<div class="earth">
  <div class="orbit">
    <div class="moon"></div>
  </div>
</div>
...