Как разместить два или более кубов рядом друг с другом в правильной перспективе с помощью CSS-преобразования? - PullRequest
0 голосов
/ 10 декабря 2018

У меня есть настройки этого проекта в изолированной программной среде кода:

Edit Vue Template

Снимок экрана (кубы не будут выглядеть так, если вы измените размер области просмотра):

Screenshot

Цель:

Моя цель - , чтобы иметь возможность размещать кубы рядом друг с другом или сверхудруг от друга и продолжайте укладывать, как заполнение задней части грузовика: начиная с глубокого конца грузовика, заполняя первый слой коробками, затем укладывайте сверху до потолка;продолжайте складывать перед этими коробками, пока грузовик не заполнится.

Кроме того, если мы масштабируем экран, позиции кубов все равно должны выглядеть так, как будто они находятся рядом друг с другом (в моем примере вы можете видеть, что это не так).

Мы можемиспользуйте Vue или Javascript для вычисления вещей, которые мы не можем вычислить с помощью CSS, но давайте попробуем максимально использовать CSS.

Данные:

Моя разметка такова:

<div class="container">
  <div class="cubes-container">
    <!-- for each cube --->
    <div class="cube-wrap" >
        <div class="cube depth cube-isometric">
          <div class="front-pane">cube 1</div>
          <div class="back-pane">back 1</div>
          <div class="top-pane">top 1</div>
          <div class="bottom-pane">bottom 1</div>
          <div class="left-pane">left 1</div>
          <div class="right-pane">right 1</div>
        </div>
    </div>
  </div>
</div>

Не было хорошей идеей размещать куб с правой стороны первого куба, это работает только в определенных разрешениях:

.cube-wrap:nth-child(2) .cube {
    transform: translate3d(142.5px, 50px, 125px) rotateX(-30deg) rotateY(-45deg);
    transform-style: preserve-3d;
}

Элементы управления слева у меня тоже были не так хороши,Они меняли значения left и top значения .cube-wrap.Если вы введете число, вы увидите, что кубы движутся.Также, если вы добавите куб, вы увидите, что третий приземляется на origin .Я собирался использовать эти элементы управления, чтобы проверить, где будут находиться кубы.

Я попытался установить перспективу контейнера, чтобы посмотреть на все кубы с этой перспективы:

.container {
  position: absolute;
  left: 240px;
  top: 0;
  bottom: 0;
  right: 0;
  background: grey;
  perspective: 1000px;
  perspective-origin: 50% 100px;
}

CSS моего куба как таковой (удален с поддержкой css, например -ms или -moz для экономии места). Я получил этот куб из https://davidwalsh.name/css-cube

.cube-isometric {
  transform: rotateX(-30deg) rotateY(-45deg);
  transform-origin: 50% 50% 0;
}
/*************** STANDARD CUBE ***************/

.cube {
  position: relative;
  width: 200px;
  margin: 0 auto;
  transform-style: preserve-3d;
  animation: cube-spin 5s infinite linear;
}
.cube div {
  position: absolute;
  width: 200px;
  height: 200px;
  background: rgba(38, 93, 79, 0.87);
  box-shadow: inset 0 0 30px #c7ffb6;
  font-size: 20px;
  text-align: center;
  line-height: 200px;
  color: rgb(255, 255, 255);
  font-family: sans-serif;
  text-transform: uppercase;
}
.depth div.back-pane {
  transform: translateZ(-100px) rotateY(180deg);
}
.depth div.right-pane {
  transform: rotateY(-270deg) translateX(100px);
  transform-origin: top right;
}
.depth div.left-pane {
  transform: rotateY(270deg) translateX(-100px);
  transform-origin: center left;
}
.depth div.top-pane {
  transform: rotateX(-90deg) translateY(-100px);
  transform-origin: top center;
}
.depth div.bottom-pane {
  transform: rotateX(90deg) translateY(100px);
  transform-origin: bottom center;
}
.depth div.front-pane {
  transform: translateZ(100px);
}

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

1 Ответ

0 голосов
/ 12 декабря 2018

Создайте кубы, начиная с грани, и создавая другие грани, начиная с того же места, что и основа, но вращая или переводя их.

Кубы можно расположить в двухмерном пространстве с помощью flexили то, что лучше для вас

И просто дайте контейнеру ту ориентацию, которая вам нравится.

Наведите указатель мыши на контейнер, чтобы сложить грани и лучше понять базовый макет

div {
    transform-style: preserve-3d;
    transition: transform 5s;
}

.container:hover .cubebase div {
    transform: rotate(0deg);
}
.container:hover .cubebase .cover {
    transform: transformZ(0px);
}


.cubebase {
    width: 100px;
    height: 100px;
    position: relative;
    background-color: rgba(255,0,0, 0.1);
    box-shadow: inset 0px 0px 5px red;
}
.cubebase:nth-child(2) {
    background-color: rgba(0,255,0, 0.2);
    box-shadow: inset 0px 0px 5px green;
}
.cubebase:nth-child(3) {
    background-color: rgba(0,0,255, 0.2);
    box-shadow: inset 0px 0px 5px blue;
}
.cubebase:nth-child(4) {
    background-color: rgba(200,200,0, 0.3);
    box-shadow: inset 0px 0px 5px brown;
}

.cubebase div {
   width: 100px;
   height: 100px;
   position: absolute;
   background-color: inherit;
   box-shadow: inherit;
   top: 0px;
   left: 0px;
}

div.rface {
    transform: rotateY(90deg);
    transform-origin: right;
}

.lface {
    transform: rotateY(-90deg);
    transform-origin: left;
}

.tface {
    transform: rotateX(90deg);
    transform-origin: top;
}
.bface {
    transform: rotateX(-90deg);
    transform-origin: bottom;
}

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


.container {
    border: solid 1px silver;
    transform: rotateY(20deg) rotateX(190deg);
    perspective: 5000px;
    top: 50px;
    left: 50px;
    position: relative;
    width: 300px;
    display: flex;
    flex-wrap: wrap;
}
<div class="container">
    <div class="cubebase">
        <div class="rface"></div>
        <div class="lface"></div>
        <div class="tface"></div>
        <div class="bface"></div>
        <div class="cover"></div>
    </div>
    <div class="cubebase">
        <div class="rface"></div>
        <div class="lface"></div>
        <div class="tface"></div>
        <div class="bface"></div>
        <div class="cover"></div>
    </div>
    <div class="cubebase">
        <div class="rface"></div>
        <div class="lface"></div>
        <div class="tface"></div>
        <div class="bface"></div>
        <div class="cover"></div>
    </div>
    <div class="cubebase">
        <div class="rface"></div>
        <div class="lface"></div>
        <div class="tface"></div>
        <div class="bface"></div>
        <div class="cover"></div>
    </div>
</div>
...