>  기사  >  웹 프론트엔드  >  H5 Amazing CSS3D로 3D 장면 만들기

H5 Amazing CSS3D로 3D 장면 만들기

高洛峰
高洛峰원래의
2016-11-07 17:00:302131검색

우리는 3D 표현을 통해 실제 물체의 표시 효과를 평면을 통해 다양한 각도에서 볼 수 있다는 것을 알고 있습니다.

컴퓨터 세계에서 3D 세계는 점으로 구성되어 있습니다. 두 점은 직선을 형성할 수 있고, 직선 위에 있지 않은 세 점은 삼각형 면을 형성할 수 있으며, 수많은 삼각형 면은 다양한 모양을 형성할 수 있습니다. .객체를 사용합니다.

H5 Amazing CSS3D로 3D 장면 만들기

Three의 모델 파서의 원리는 모델의 정점을 정점 배열에 저장한 후 three의 얼굴 함수를 이용하여 3개 또는 3개를 구하는 것입니다. 고정 소수점 배열 네 개의 정점의 인덱스는 공간 평면을 형성합니다. 이 과정을 반복하면 모델이 완성됩니다.

따라서 객체가 복잡할수록 더 많은 메쉬 접합이 필요합니다. CSS에는 좌표를 기반으로 공간 평면을 설정하는 기능이 없습니다.

(여담이지만 실제로 CSS에는 좌표와 관련된 속성인 클립 경로가 있습니다. 이 속성의 특성은 CSS3에 특정 모델링 기능을 제공합니다. 구현 방법은 이 기사 Pure Clip을 참조하세요. - 경로로 생성된 3D 모델 렌더러

CSS3는 3D 파노라마를 구현합니다

. 이전 기사에서는 Web3D의 몇 가지 표현을 소개했습니다. 여기서는 CSS3를 사용하여 3D 파노라마를 구현하는 방법에 중점을 두었습니다. 다음으로 WebGL의 임계값과 학습 비용이 여전히 상대적으로 높고 빠른 개발에는 적합하지 않기 때문에 파노라마를 구현하기 위한 Three의 솔루션을 살펴보겠습니다. CSS3D Panorama of the Creation Festival에 관한 기사에서 기술을 탐구한 적이 있지만 그 중 구체적인 구현 방법에 대해 깊이 다룬 기사는 없습니다.

구현 방법을 명확하게 이해하려면 CSS3 변환 및 관점에 대한 어느 정도 이해가 필요합니다.
CSS3D에 대한 일반적인 아이디어를 얻으려면 먼저 이 기사를 읽어보세요.
CSS 3D로 놀기 - 원리

CSS 파노라마는 기둥이나 큐브를 만든 다음 텍스처를 사용하여 얻을 수 있습니다. 어떤 사람들은 구체가 작동할 수 있는지 묻습니다. 실제로 구형 모델은 서로 이어져 일관된 표면을 형성하는 수많은 작은 평면으로 구성되며 CSS에는 평면을 왜곡하는 속성이 부족합니다. 위에서 언급한 Clip-3d를 사용하여 구형 모델을 구축할 수 있지만 텍스처 문제는 해결되지 않습니다.

스카이박스

이 개념은 3D 파노라마를 만들거나 배워본 동료들이 많을 거라 믿습니다. 사실 스카이박스는 6개의 면에 서로 다른 그림을 붙여서 모서리를 매끄럽게 맞추고 원근감이 상자 내부까지 확장되는 큐브입니다. 우리가 거대한 큐브 상자 안에 서 있는 것을 상상해 볼 수 있으며, 관점을 움직여 다양한 장면을 볼 수 있습니다.

H5 Amazing CSS3D로 3D 장면 만들기

1. 텍스처
스카이박스의 텍스처를 살펴보겠습니다. 절단된 헤드가 가리키는 가장자리는 이음매 없이 끼워져야 하는 가장자리를 나타냅니다.

H5 Amazing CSS3D로 3D 장면 만들기

위 그림에서 볼 수 있듯이, 서로 맞는 두 면의 이미지가 이음매 없이 접합될 수 있는 한, 그런 다음 각 표면, 하늘 상자를 만들 수 있습니다.

그럼 이런 사진은 어떻게 찍느냐는 질문입니다. 이를 위해서는 pano2vr, max 등과 같은 일부 전문 소프트웨어가 필요합니다. 실제로 이러한 전문 도구를 사용하여 만든 파노라마는 이미지 품질과 스티칭에 대한 요구 사항이 매우 높으며 CSS3의 변경 사항에만 의존하면 좋은 경험을 제공할 수 없습니다.

그러나 오늘 우리가 논의할 것은 H5가 특정 작전 활동을 위해 만든 파노라마입니다. 이 파노라마는 실제로 존재하지 않을 수도 있고, 실제 장면과 일정 비율의 차이가 있을 수도 있습니다. 예를 들어, 별이 빛나는 하늘과 바다 밑바닥. 인위적으로 핏을 변경할 수 있는 이런 종류의 파노라마를 만들기 위해 기존 고화질 사진을 사용하고 PS를 통해 6면 파노라마로 변환할 수 있습니다.
기사 게시 사진에서 Skybox 만들기
사실 주요 아이디어는
큰 사진에서 6개의 얼굴 선택 개요>
큰 사진에서 특정 얼굴의 인접한 얼굴을 선택하는 것입니다. 조립할 상자의 특정 면으로 회전시켜 완벽하게 맞물리도록>
가장 합리적인 6면 맵을 얻은 후 새로운 모서리가 생성되는지 관찰하고 마스크와 같은 도구를 사용하여 자연스럽게 섞으세요.

2. 텍스처 구축이 완료되면 큐브를 생성할 수 있습니다. 먼저 생성된 6개의 면을 잘라내고 표시된 위치에 앞, 뒤, 왼쪽, 오른쪽...

 .sence {      -webkit-perspective: 1000px;    }
    .cube {      width: 500px;      height: 500px;      margin: 100px auto;      transform-style: preserve-3d;    }
    .cube img {      width: 130px;      height: 130px;      position: absolute;    }
    .cube img:nth-child(1) {    }
    .cube img:nth-child(2) {      transform:  rotateY(180deg);    }
    .cube img:nth-child(3) {      transform:  rotateY(90deg);    }
    .cube img:nth-child(4) {      transform:  rotateY(-90deg);    }
    .cube img:nth-child(5) {      transform:  rotateX(90deg);    }
    .cube img:nth-child(6) {      transform:  rotateX(-90deg);    }
<div class="sence">
    <div class="cube">
      <img src="img/skybox/front.jpg" alt="" />
      <img src="img/skybox/back.jpg" alt="" />
      <img src="img/skybox/left.jpg" alt="" />
      <img src="img/skybox/right.jpg" alt="" />
      <img src="img/skybox/top.jpg" alt="" />
      <img src="img/skybox/bottom.jpg" alt="" />
    </div>
  </div>

6개의 면을 준비하고 텍스처를 로드합니다. 회전하면 각 면이 해당 위치로 회전됩니다. 예를 들어, 왼쪽 표면은 원래 우리를 향한 그림을 Y축을 중심으로 시계 반대 방향으로 90° 회전하여 얻은 것입니다. (참고로 Y축의 반시계방향 회전은 양수입니다.)

이때 아래와 같은 효과를 얻게 됩니다.

H5 Amazing CSS3D로 3D 장면 만들기

그러나 각 표면의 회전 중심은 중앙 위치에 있으므로 아직 정육면체를 형성할 수 없습니다. 따라서 각 표면에 특정 변위가 있도록 허용해야 합니다.

모두가 이해할 수 있도록 좌표계 다이어그램을 게시하세요.

H5 Amazing CSS3D로 3D 장면 만들기

이제 먼저 앞쪽을 원래 있어야 할 위치로 이동합니다. 파노라마의 렌즈가 큐브 내부에 있으므로 사진을 뒤로 이동해야 한다고 상상할 수 있습니다. 이동한 거리는 분명히 큐브 측면 길이의 절반입니다. 여기서는 65px입니다. 아래에서 결과를 얻으세요.

.cube img:nth-child(1) {    
  transform: translateZ(-65px); 
     }

H5 Amazing CSS3D로 3D 장면 만들기

이렇게 보면 뒤쪽 변위가 이동 Z(65px), 왼쪽이 이동 X(-65px), 위쪽 이동이 Y(-65px)인가요? 그러나 결과는 우리가 원하는 것이 아니다.

H5 Amazing CSS3D로 3D 장면 만들기

위의 공간 좌표계 지도를 다시 보면 평면이 회전한 후 해당 세 축의 위치도 바뀌는 것을 알 수 있습니다. 예를 들어 사진이 Y를 중심으로 회전한 후 Z축은 화면의 가로 방향을 가리킵니다. X를 중심으로 회전한 후 Z축은 수직 방향을 가리킵니다. 따라서 실제로 베니어를 올바른 위치로 이동하려면 Z(-width/2px)를 변환하도록 요청하면 된다는 것을 쉽게 알 수 있습니다.

H5 Amazing CSS3D로 3D 장면 만들기

여러분의 이해를 돕기 위해 더 큰 관점을 설정했습니다. 파노라마 효과를 얻으려면 확대하여 상자 안으로 들어가도록 하면 됩니다.

H5 Amazing CSS3D로 3D 장면 만들기

다음으로 제스처를 묶어서 움직이게 하면 됩니다.

코드 부분:

viewer.on(&#39;touchstart&#39;, function(e) {
    x1 = e.targetTouches[0].pageX; - $(this).offset().left;
    y1 = e.targetTouches[0].pageY; - $(this).offset().top;
});

viewer.on(&#39;touchmove&#39;,function(){
    var dist_x = x2 - x1,
        dist_y = y2 - y1,
        deg_x = Math.atan2(dist_y, perspective) / Math.PI * 180,
        deg_y = -Math.atan2(dist_x, perspective) / Math.PI * 180,
        i,
        c_x_deg += deg_x;
        c_y_deg += deg_y;
        
    cube.css(&#39;transform&#39;, &#39;rotateX(&#39; + deg_x + &#39;deg) rotateY(&#39; + deg_y + &#39;deg)&#39;);
})

Math.atan2(y,x) 메서드: x축에서 점(x,y)까지의 각도를 구합니다. 공간의 왼쪽 체계를 이해하기는 어렵습니다. X축의 양의 방향을 Y축으로 하여 공간의 Z축을 기준으로 한 평면의 회전 각도는 큐브를 중심으로 하는 회전 각도라고 상상할 수 있습니다. 공간의 Y축.

실린더

원통형 파노라마는 그리 복잡하지 않습니다. 원통형 모양을 만드는 방법에 대해서는 CSS3 3D 변환 시리즈 튜토리얼-3D 캐러셀
기사를 참조하세요. 이 기반을 사용하면 원통형 파노라마를 빠르게 구성하는 함수를 작성할 수 있습니다.

먼저 페이지 구조를 살펴보겠습니다

<style>
  body {
    height: 100%;
    overflow: hidden;
  }
    .scene {
      width: 100%;
      height: 1170px;
      transform: translateX(-50%) translateY(-50%);
      top: 50%;
      left: 50%;
      position: absolute;
    }
    .cube {
      transform-style: preserve-3d;
      height: 100%;
      width: 100%;
      margin: 0px auto;
    }
    .cube_bg {
      transform-style: preserve-3d;
      height: 100%;
      width: 128px;
      margin: 0px auto;
    }
    .cube_bg div {
      height: 100%;
      
      /* 这里为圆柱形的每个面都设定了同样的背景图 那么在建造柱形时不再需要手动切图 */
      background-image: url("img/zao/zao.png");
      
      background-repeat: no-repeat;
      position: absolute;
      top: 0;
    }
</style>

<body>
  <div class="scene">
    <div class="cube">
      <div class="cube_bg">
        <!--
        这里是柱形全景背景贴图
        -->
      </div>
      <div class="cube_item">
        <!--
        这里是柱形全景中的小元件
        -->
      </div>
    </div>
  </div>
</body>
function creCylinder(lenZ,pieceWid,angle,slice){

    /* 
    pieceWid 表示单个柱形块状宽度
    angle表示柱形内角
    slice表示有多少个面拼接 
    slice越多,拼合的面越接近曲面
    */
    
  var l = pieceWid*slice; // 画布全长
  var ag = angle/slice // 旋转角度

  var html = &#39;&#39;;

  /*
    设置每个面的旋转角度和位移 因为要分割成多个面,所以应该为每个面的背景图设置不同的`background-position`
    */

  for(var i=0,len=slice;i<len;i++){
    html+=&#39;<div style="transform: rotateY(-&#39;+ag*i+&#39;deg) &#39;+
          &#39;translateZ(&#39;+lenZ+&#39;px);&#39;+
          &#39;width:&#39;+(pieceWid)+&#39;px;&#39;+
          &#39;background-position: -&#39;+(i*pieceWid)+&#39;px 0;&#39;+
          &#39;background-size: &#39;+(l)+&#39;px 100%;"></div>&#39;;
  }

    return html;
}

function renderPano(pieceWid,angle,slice){

    var vw = $(window).width();

    var RADIAN = 0.017453293; // 弧度制 将角度转成弧度

    var innerAngle = angle/(2*slice); //内角,用来计算translateZ

    // 这里的原理和上文旋转木马链接一致
    var lenZ = -(pieceWid/2)*Math.tan((90-innerAngle)*RADIAN);

    /*  
        因为默认是由画布的最左端开始旋转 所以处于我们面前的是画布的最左端和最右端及其连接处
        要想画布中央显示再我们面前,这里需要给cube_bg加上一定的绕Y旋转角度
    */
    var rotate = ((angle/slice)*(slice-1))/2,
        perspective = -lenZ-5;

    var cube_bg = $(&#39;.cube_bg&#39;),
        scene = $(&#39;.scene&#39;);

    var cylinder = creCylinder(lenZ,pieceWid,angle,slice);

    cube_bg.html(cylinder).css(&#39;transform&#39;,&#39;rotateY(&#39;+rotate+&#39;deg)&#39;);
    scence.css(&#39;-webkit-perspective&#39;,perspective+&#39;px&#39;);
    
    //最后调用一下
    renderPano(128,360,20);

perspective를 -lenZ-5로 설정해야 하는 이유를 설명합니다
사진을 보면 lenZ 위의 moveZ 값은 음수 값입니다.
원근감은 렌즈에서 화면까지의 거리입니다. 이때 렌즈가 원통 안에 있기 때문에 원통 뒤의 이미지는 볼 수 없습니다.
원근감 값이 -lenZ이면 원통의 뒷면이 렌즈와 동일한 평면에 있을 수 있습니다. 렌즈를 가리는 확률을 피하기 위해 렌즈에 더 가까이 확대할 수 있습니다. -lenZ-5로 설정되어 있습니다. 이때, 렌즈가 원통 내부에 있음을 확인할 수 있으며 동시에 원통의 파노라마 뷰를 더 넓은 각도에서 관찰할 수 있습니다.

H5 Amazing CSS3D로 3D 장면 만들기

코드를 복사하여 체험해 보실 수 있습니다. 여기 배경이미지는 제가 직접 합성한 창작페스티벌 배경이미지입니다.

장단점 비교

스카이박스는 제작이 상대적으로 간단하고, 하늘과 땅을 모두 고려할 수 있다는 점은 다들 아실 거라 믿습니다. 그러나 면 사이의 끼워맞춤 각도가 너무 크기 때문에 물체가 서로 붙어 있는 두 면에 우연히 놓이게 되면 허리가 부러지는 듯한 느낌을 받게 됩니다. 기둥형 차트는 이 상황에 대한 더 나은 솔루션을 제공하지만 하늘과 땅 텍스처는 더 어렵습니다. 일반적으로 장면에 배경 이미지를 추가해야만 시뮬레이션할 수 있습니다.


성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.