Трансформация картинок в кубе

Всем привет. Как сделать трансформацию картинок по граням куба? Чтобы они плавно перетекали от одной грани к другой?

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Perspective</title>
  <style>
    body {
      margin: 0 auto;
    }

    .cube-container {
      height: 200px;
      top: 50%;
      left: 50%;
      margin-left: -100px;
      margin-top: -100px;
      perspective: 600px;
      perspective-origin: 50% 50%;
      position: absolute;
      width: 200px;
    }

    .cube {
      height: 100%;
      position: absolute;
      transform: translateZ(100px);
      transform-style: preserve-3d;
      width: 100%;
      animation: spin 5s linear infinite;
    }

    .side {
      background: transparent;
      border: 3px solid grey;
      height: 196px;
      position: absolute;
      width: 196px;
      overflow: hidden;

    }

    .front {
      transform: translateZ(100px);
    }

    .back {
      transform: rotateX(180deg) translateZ(100px);
    }

    .back .img-inner {
      width: 100%;
      height: 100%;
      background-image: url(https://cdn.sportmaster.ru/upload/content/mediahab/prod/0c868511-3fc5-4da6-9092-56235985e840.jpg);
      background-position: top;
      background-size: 33%;
      background-repeat: no-repeat;
    }

    .left {
      transform: rotateY(-90deg) translateZ(100px);
    }

    .right {
      transform: rotateY(90deg) translateZ(100px);
    }

    .top {
      transform: rotateX(90deg) translateZ(100px);
    }

    .bottom {
      transform: rotateX(-90deg) translateZ(100px);
    }

    .img-inner {
      animation: marquee-vertical 5s linear infinite;
    }

    @keyframes marquee-vertical {
      0% {
        transform: translateY(0);
      }

      100% {
        transform: translateY(-100%);

      }

    }
  </style>
</head>

<body>
  <div class="cube-container">
    <div class="cube">
      <figure class="side front"></figure>
      <figure class="side back">
        <div class="img-inner"></div>
        <div class="img-inner"></div>
        <div class="img-inner"></div>
      </figure>
      <figure class="side left"></figure>
      <figure class="side right"></figure>
      <figure class="side top"></figure>
      <figure class="side bottom"></figure>
    </div>
  </div>
</body>

</html>


Ответы (3 шт):

Автор решения: BlackStar1991

Это довольно трудоёмкая задача. Вам необходимо каждой грани куба задать свойство overflow:hidden затем в каждую из этих граней поместить картинку, одинаковую или разные, но они все должны быть одинаковых размеров. Дальше все другие изображения кроме главного сместить относительно центра за областью видимости. Например, transform:translate(-100%, 0) или что-то в этой области. Дальше вешаете обработчик событий который отслеживает в какой именно части куба сейчас перебывает курсор. Два состояния: 1 - в которой был, 2 - в которой стал. И дальше идет синхронизация по времени с изменением для данных картинок положений transform... Что б обе картинки были как бы взаимозависимы.

Для простоты я б вам рекомендовал начать просто с двух плоскостей. Когда реализуете на 2 тогда и на 6 получиться... хотя по факту на меньше, если ваш куб не вертится.

→ Ссылка
Автор решения: puffleeck

эм... случаем не оно?

p.s. слушалка мыши только чтоб не гадать - какой ракурс нагляднее.

var cub = document.querySelector(".cube");

window.addEventListener("mousemove",
  function (e) {
    var leftCord = e.pageX;
    var TopCord = e.pageY;

    document.querySelector(".cube").style.cssText =
      "transform: rotateY(" + (leftCord / 2.5) + "deg) rotateX(" + (TopCord / 2.5) + "deg);";
  },
  false
);

var posX, posY;

function positFingers(e) {
  posX = e.pageX;
  posY = e.pageY;
  document.querySelector(".cube").style.cssText =
    "-webkit-transform:rotateY(" + posX + "deg) rotateX(" + posY + "deg);";
}
window.addEventListener("touchmove", positFingers, false);
body {
  margin: 0 auto;
}

.cube-container {
  height: 225px;
  top: 50%;
  left: 50%;
  margin-left: -100px;
  margin-top: -100px;
  perspective: 600px;
  perspective-origin: 50% 50%;
  position: absolute;
  width: 225px;
}

.cube {
  height: 100%;
  position: absolute;
  transform: translateZ(100px);
  transform-style: preserve-3d;
  width: 100%;
}

.side {
  background: transparent;
  border: 3px solid grey;
  height: 196px;
  position: absolute;
  width: 196px;
  overflow: hidden;

}

.front {
  transform: translateZ(100px);
}

.back {
  transform: rotateX(180deg) translateZ(100px);
}

:is(.back, .top, .bottom) .img-inner /*!!!!!!!!!!!*/
{
  width: 100%;
  height: 100%;
  background-image: url(https://cdn.sportmaster.ru/upload/content/mediahab/prod/0c868511-3fc5-4da6-9092-56235985e840.jpg);
  background-position: top;
  background-size: 75%;
  background-repeat: no-repeat;
}

.left {
  transform: rotateY(-90deg) translateZ(100px);
}

.right {
  transform: rotateY(90deg) translateZ(100px);
}

.top {
  transform: rotateX(90deg) translateZ(100px);
}

.bottom {
  transform: rotateX(-90deg) translateZ(100px);
}

.img-inner {
  animation: marquee-vertical 5s linear infinite;
}

@keyframes marquee-vertical {
  0% {
    transform: translateY(0);
  }

  100% {
    transform: translateY(-100%);

  }

}
<div class="cube-container">
  <div class="cube">
    <figure class="side front"></figure>
    <figure class="side back">
      <div class="img-inner"></div>
      <div class="img-inner"></div>
      <div class="img-inner"></div>
    </figure>
    <figure class="side left"></figure>
    <figure class="side right"></figure>
    <figure class="side top">
      <div class="img-inner"></div>
      <div class="img-inner"></div>
      <div class="img-inner"></div>
    </figure>
    <figure class="side bottom">
      <div class="img-inner"></div>
      <div class="img-inner"></div>
      <div class="img-inner"></div>
    </figure>
  </div>
</div>

→ Ссылка
Автор решения: Agzam

Придал анимацию каждой стороне с картинкой и рассчитал им animation-delay, а так же поставил transform: translateY(100%); для изначального состояния

back>.img-inner {
    animation-delay: 1s;
}
.bottom>.img-inner {
    animation-delay: 2s;
}

Для верхней стороны это 0s, для задней 1s, для нижней 2s

Анимация теперь идет от 100% до -400%

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Perspective</title>
  <style>
    body {
      margin: 0 auto;
    }

    .cube-container {
      height: 200px;
      top: 50%;
      left: 50%;
      margin-left: -100px;
      margin-top: -100px;
      perspective: 600px;
      perspective-origin: 50% 50%;
      position: absolute;
      width: 200px;
    }

    .cube {
      height: 100%;
      position: absolute;
      transform: translateZ(100px);
      transform-style: preserve-3d;
      width: 100%;
      animation: spin 2s linear infinite;
    }

    .side {
      background: transparent;
      border: 3px solid grey;
      height: 196px;
      position: absolute;
      width: 196px;
      overflow: hidden;

    }

    .front {
      transform: translateZ(100px);
    }

    .back {
      transform: rotateX(180deg) translateZ(100px);
    }

    .img-inner {
      width: 100%;
      height: 100%;
      background-image: url(https://cdn.sportmaster.ru/upload/content/mediahab/prod/0c868511-3fc5-4da6-9092-56235985e840.jpg);
      background-position: top;
      background-size: 100%;
      background-repeat: no-repeat;
    }

    .left {
      transform: rotateY(-90deg) translateZ(100px);
    }

    .right {
      transform: rotateY(90deg) translateZ(100px);
    }

    .top {
      transform: rotateX(90deg) translateZ(100px);
    }

    .bottom {
      transform: rotateX(-90deg) translateZ(100px);
    }

    .img-inner {
        animation: marquee-vertical 4s linear infinite;
        transform: translateY(100%);
    }

    .back>.img-inner {
      animation-delay: 1s;
    }

    .bottom>.img-inner {
      animation-delay: 2s;
    }


    @keyframes marquee-vertical {
      0% {
        transform: translateY(100%);
      }
      100% {
        transform: translateY(-400%);
      }
    }
  </style>
</head>

<body>
  <div class="cube-container">
    <div class="cube">
      <figure class="side front"></figure>
      <figure class="side back">
        <div class="img-inner"></div>
      </figure>
      <figure class="side left"></figure>
      <figure class="side right"></figure>
      <figure class="side top">
        <div class="img-inner"></div>
      </figure>
      <figure class="side bottom">
        <div class="img-inner"></div>
      </figure>
    </div>
  </div>
</body>

</html>

→ Ссылка