3D Nexus реализованный с помощью CSS3 и JS

Мы будем использовать подготовленные ранее изображения, нам понадобятся текстуры планшета со всех сторон. Мы их скрепим в единую коробку.

Шаг 1. HTML

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

Код
<section class="container" id="container">
  <div class="shadowContainer">
  <div class="shadow" id="shadow"><div class="shadow2" id="shadow2"></div></div>
  </div>
  <div id="box">
  <figure class="front" id="front">
  <img src="backgroundlarge.png" id="largeBG" width="900" height="400" style="-webkit-transform: rotate(180deg)" />
  <img src="newFront2.png" height="500" width="305" style="-webkit-transform: rotate(180deg)" />
  <figure class="shine" id="shine"></figure>
  </figure>
  <figure class="back" id="back">
  <img src="back.png" height="500" width="305" />
  </figure>
  <figure class="farBack" id="farBack">
  <img src="farBack.png" height="500" width="305" />
  </figure>
  <figure class="right" id="right">
  <img src="left.png" height="500" width="28" style="-webkit-transform: rotate(180deg)" />
  </figure>
  <figure class="left" id="left">
  <img src="right.png" height="500" width="28" style="-webkit-transform: rotate(180deg)" />
  </figure>
  <figure class="top" id="top">
  </figure>
  <figure class="bottom" id="bottom">
  </figure>
  </div>
</section>


Как вы заметили, мы еще добавим трансформацию для некоторых изображений.

Шаг 2. CSS

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

Код
#box {
  width: 100%;
  height: 100%;
  position: absolute;
  -webkit-transform-style: preserve-3d;
}

figure {
  opacity: 1;
}

/* size of each face */
#box figure {
  display: block;
  position: absolute;
}

#box .front,
#box .back {
  width: 305px;
  height: 500px;
}

#box .right,
#box .left {
  width: 28px;
  height: 500px;
  left: 291px; /* (width - depth) /2*/
}

#box .top,
#box .bottom {
  width: 305px;
  height: 28px;
  top: 486px; /* (height - depth) /2*/
}

#box .front { -webkit-transform: rotateY( 0deg ) translateZ( 15px ); } /* translateZ : width / 2 */
#box .back { -webkit-transform: rotateX( 180deg ) translateZ( 14px ); } /* translateZ : width / 2 */
#box .farBack { -webkit-transform: rotateX( 180deg ) translateZ( 12px ); }
#box .right { -webkit-transform: rotateY( 90deg ) translateZ( 0px ); }
#box .left { -webkit-transform: rotateY( -90deg ) translateZ( 305px ); }
#box .top { -webkit-transform: rotateX( 90deg ) translateZ( 500px ); }
#box .bottom { -webkit-transform: rotateX( -90deg ) translateZ( 0px ); }

.shine {
  width: 299px;
  height: 495px;
  position: absolute;
  top: -13px;
  left: -37px;
  -webkit-transform: rotate(180deg);
  opacity: .4;
  border-radius: 20px;
  background-image: -webkit-linear-gradient(top left, rgba(255,255,255, 100) 38%, rgba(255,255,255, 0) 38%);
}
.shadowContainer {
  border-radius: 20px;
  position: absolute;
  top: 300px;
  left: -80px;
  height: 500px;
  width: 500px;
}
.shadow {
  top: -300px;
  left: -400px;
  border-radius: inherit;
  position: absolute;
  height: 120px;
  width: 305px;
  opacity: 1;
  -webkit-transform: rotate(0deg);

}
.front {
  overflow: hidden;
}
#largeBG {
  position: absolute;
  right: 0px;
  bottom: 30px;
}
#backgroundSurf {
  position: absolute;
  width: 1600px;
  height: 400px;
  z-index: -1;
  top: 0px;
}

Шаг 3. JS

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

Код
(function() {

document.getElementById('container').addEventListener('mousemove', function(e){
  var container = document.getElementById('container'),
  box = document.getElementById('box'),
  x = e.pageX - container.offsetLeft,
  y = e.pageY - container.offsetHeight,
  yAct = e.pageY - container.offsetTop,
  centerX = container.offsetWidth*0.5,
  centerY = container.offsetHeight*0.5,
  dist = Math.sqrt((x-centerX)*(x-centerX)+(y-centerY)*(y-centerY)),
  distPer = dist / container.offsetHeight,
  xPer = x / (container.offsetWidth+50),
  yPer = y / container.offsetHeight,
  frontFace = document.getElementById('front'),
  backFace = document.getElementById('back'),
  leftFace = document.getElementById('left'),
  rightFace = document.getElementById('right'),
  topFace = document.getElementById('top'),
  bottomFace = document.getElementById('bottom'),
  shine = document.getElementById('shine'),
  shadow = document.getElementById('shadow'),
  shadow2 = document.getElementById('shadow2'),
  largeBG = document.getElementById('largeBG'),
  farBack = document.getElementById('farBack'),
  gVal = yAct / 500,
  g1, g2, g3, tempG;

if (gVal > 1) {
  gVal = 1;
  }
  if (gVal <= .8) {
  tempG = Math.abs(1-gVal);
  g1 = tempG; // 100 - 66
  g2 = tempG*.5; // 66 - 33
  g3 = gVal; // 33 - 0
  } else {
  tempG = Math.abs(1-gVal);
  g1 = tempG; // 66 - 33
  g2 = tempG*2; // 100 - 66
  g3 = gVal; // 33 - 66
  }

largeBG.style.right = -(xPer*900)+90+'px';

shadow.style.height = (Math.abs(gVal)*200+100)+'px';

  shadow.style.top = (-(Math.abs((gVal))*150+150))+'px';
  shadow.style.left = (-(Math.abs(gVal*100)))+'px';

box.style.webkitTransform = 'rotateY('+(xPer*360)+'deg) rotateX('+((distPer*90)+90)+'deg)';

leftFace.style.opacity = 0;
  rightFace.style.opacity = 0;
  backFace.style.opacity = 0;
  frontFace.style.opacity = 0;
  farBack.style.opacity = 1;

leftFace.style.webkitTransform = 'rotateY( -90deg ) translateZ( 152px )'; // move to 305
  rightFace.style.webkitTransform = 'rotateY( 90deg ) translateZ( -152px )'; // move to 0
  backFace.style.webkitTransform = 'rotateX( 180deg ) translateZ( 14px )';

yPer = Math.abs((1+yPer)*50);

shine.style.backgroundImage = '-webkit-linear-gradient(top left, rgba(255,255,255, 100) '+yPer+'%, rgba(255,255,255, 0) '+yPer+'%)';
  if (xPer > 1) {
  xPer = 1;
  }
  if (xPer <= .25) {

xPer /= .25;

shadow.style.width = (305-(xPer*250))+'px'; // smaller

  leftFace.style.opacity = xPer+.2;
  rightFace.style.opacity = xPer+.2;
  backFace.style.opacity = 1;

leftFace.style.webkitTransform = 'rotateY( -90deg ) translateZ( '+(280 + (10*xPer))+'px )';
  backFace.style.webkitTransform = 'rotateX( 180deg ) translateZ( '+(14+(-24*xPer))+'px )';
  rightFace.style.webkitTransform = 'rotateY( 90deg ) translateZ( '+(-65 + (65*xPer))+'px )';

} else if (xPer <= .5) {

shadow.style.width = (((xPer-.25)*1080)+55)+'px';
  //shadow.style.left = 40-(xPer*80)+'px';

farBack.style.opacity = 0;

frontFace.style.opacity = 1;
  leftFace.style.opacity = 1;

leftFace.style.webkitTransform = 'rotateY( -90deg ) translateZ( '+(305 - (65*xPer))+'px )';

} else if (xPer <= .75) {

frontFace.style.opacity = 1;
  rightFace.style.opacity = 1;
  farBack.style.opacity = 0;

rightFace.style.webkitTransform = 'rotateY( 90deg ) translateZ( '+(-65 + (70*xPer))+'px )';

xPer -= .5;
  xPer /= .25;

shadow.style.width = (305-(xPer*250))+'px'; // smaller
  //shadow.style.left = (xPer*40)+'px';
  } else {

xPer -= .75;
  xPer /= .25;

shadow.style.width = (((xPer)*250)+55)+'px';
  //shadow.style.left = 40-(xPer*80)+'px';

rightFace.style.opacity = Math.abs(1-xPer);
  leftFace.style.opacity = Math.abs(1-xPer)-.1;
  backFace.style.opacity = 1;

leftFace.style.webkitTransform = 'rotateY( -90deg ) translateZ( '+(305-(xPer*48))+'px )';
  rightFace.style.webkitTransform = 'rotateY( 90deg ) translateZ( '+(-(xPer*65))+'px )';
  backFace.style.webkitTransform = 'rotateX( 180deg ) translateZ( '+(-10+(25*xPer))+'px )'; // from -10 to +14
  }
},true);

document.getElementById('perspRange').addEventListener('change', function(){
  document.getElementById('container').style.webkitPerspective = (this.value*10)+'px';
}, true);

})();


Вот и все. Готово!

  • FalleN

  • 3613

  • 1

  • 187

Ссылки на статью:

Похожие статьи: