인터랙티브 웹 개발(입체감이 느껴지는 interactive 예제 )

Dev_Go·2022년 7월 2일
0
post-thumbnail

입체감이 느껴지는 interactive 예제


7개 레이어를 쌓아서 입체감이 느껴지는 페럴랙스 페이지 구현 예제

예제보기

resize

window의 크기가 조정되면 resize이벤트가 발생합니다.

일부 이전 브라우저에서는 resize모든 HTML 요소에 이벤트 핸들러를 등록할 수 있었다. onresize속성 을 설정 하거나 addEventListener()모든 요소에 핸들러를 설정하는 데 사용할 수 있다. 그러나 resize이벤트는 window객체에서만 발생한다(즉, 에서 반환됨 document.defaultView). window개체 에 등록된 핸들러만 resize이벤트를 수신한다.


Window.requestAnimationFrame()

window.requestAnimationFrame()메서드는 브라우저에 애니메이션을 수행하고 싶다고 알리고 브라우저가 다시 실행하기 전에 애니메이션을 업데이트하기 위해 지정된 함수를 호출하도록 요청한다. 이 메서드는 다시 실행하기 전에 호출할 인수로 콜백을 사용한다.


HTML

  <main>
    <div class="progress"><span class="progressBar"></span></div>
    
    <section class="mainPage">
        <div class="imageWrap">
            <div class="parallax_image" id="parallax_0"></div>
            <div class="parallax_image" id="parallax_1"></div>
            <div class="parallax_image" id="parallax_2"></div>
            <div class="parallax_image" id="parallax_3"></div>
            <div class="parallax_image" id="parallax_4"></div>
            <div class="parallax_image" id="parallax_5"></div>
        </div>
    </section>

    <section class="subPage">
        <div id="parallax_6"></div>
        <div class="innerWrap">
            <div class="contWrap">
            </div>
        </div>
    </section>
    
</main>

CSS

* {
  -webkit-box-sizing: border-box;
          box-sizing: border-box;
}

body {
  overflow-x: hidden;
}

main {
  position: relative;
}

main .progress {
  position: fixed;
  width: 100%;
  height: 2px;
  background-color: black;
  z-index: 10000;
}

main .progress .progressBar {
  position: fixed;
  width: 0%;
  background: #ffa600;
  height: 2px;
  z-index: 10001;
  -webkit-transition: width .1s ease;
  -o-transition: width .1s ease;
  transition: width .1s ease;
}

section {
  position: relative;
  width: 100%;
}

section.mainPage {
  background: -webkit-gradient(linear, left top, left bottom, from(#4b0220), to(#691c46));
  background: -o-linear-gradient(#4b0220, #691c46);
  background: linear-gradient(#4b0220, #691c46);
  padding-bottom: 50px;
}

section.mainPage h1.title {
  position: fixed;
  text-align: center;
  color: #fff;
  font-size: 2.7rem;
  padding-top: 20vh;
  width: 400px;
  left: calc(50% - 200px);
}

section.mainPage .imageWrap {
  height: 1100px;
  overflow-y: hidden;
}

section.mainPage .imageWrap .parallax_image {
  position: fixed;
  width: 100%;
  height: inherit;
  background-position: top center;
  background-size: auto 100%;
  background-repeat: no-repeat;
}

section.mainPage .imageWrap .parallax_image:nth-child(1) {
  background-image: url(../images/main_0.png);
}

section.mainPage .imageWrap .parallax_image:nth-child(2) {
  background-image: url(../images/main_1.png);
}

section.mainPage .imageWrap .parallax_image:nth-child(3) {
  background-image: url(../images/main_2.png);
}

section.mainPage .imageWrap .parallax_image:nth-child(4) {
  background-image: url(../images/main_3.png);
}

section.mainPage .imageWrap .parallax_image:nth-child(5) {
  background-image: url(../images/main_4.png);
}

section.mainPage .imageWrap .parallax_image:nth-child(6) {
  background-image: url(../images/main_5.png);
  background-size: cover;
}

section.subPage {
  background: -webkit-gradient(linear, left top, left bottom, from(#000), to(#691c46));
  background: -o-linear-gradient(#000, #691c46);
  background: linear-gradient(#000, #691c46);
}

section.subPage #parallax_6 {
  position: relative;
  background: url(../images/main_6.png) bottom center no-repeat;
  background-size: auto 1100px;
  height: 400px;
  width: 100%;
  top: -400px;
}

section.subPage .innerWrap {
  position: relative;
  margin: 0 auto;
  padding: 500px 0;
  width: 900px;
  height: 4500px;
}

@media only screen and (max-width: 768px) {
  section.subPage .innerWrap {
    width: 100%;
  }
}

JS

let x = 0;
let y = 0;
let mx = 0;
let my = 0;
let speed = 0.03;
let scrollTop = 0;
let parallax_0, parallax_1, parallax_2, parallax_3, parallax_4, parallax_5, parallax_6, parallax_7;

window.onload = function () {
  progressBar = document.getElementsByClassName("progressBar")[0];

  parallax_0 = document.getElementById("parallax_0");
  parallax_1 = document.getElementById("parallax_1");
  parallax_2 = document.getElementById("parallax_2");
  parallax_3 = document.getElementById("parallax_3");
  parallax_4 = document.getElementById("parallax_4");
  parallax_5 = document.getElementById("parallax_5");
  parallax_6 = document.getElementById("parallax_6");

  window.addEventListener('resize', stageResize, false);
  window.addEventListener('mousemove', mouseMove, false);
  window.addEventListener('scroll', scrollFunc, false);

  stageResize();
  loop();
}

function scrollFunc(e) {
  scrollTop = document.documentElement.scrollTop;

  // scroll값을 받아서 %로 바꿔서 per에 할당한디.
  let per = Math.ceil(scrollTop / (_documentHum - _windowHNum) * 100);
  // per에 할당한 값을 progressBar 너비값에 할당한다.
  progressBar.style.width = per + "%";

  // 스크롤을 하면 y값이 주어진 값만큼 움직인다.
  parallax_0.style.transform = "translate3d(0px ," + scrollTop * .03 + "px , 0px"; // +는 아래로 내려감
  parallax_1.style.transform = "translate3d(0px ," + -scrollTop * .03 + "px , 0px"; // -는 위로 올라감
  parallax_2.style.transform = "translate3d(0px ," + -scrollTop * .12 + "px , 0px";
  parallax_3.style.transform = "translate3d(0px ," + -scrollTop * .16 + "px , 0px";
  parallax_4.style.transform = "translate3d(0px ," + -scrollTop * .22 + "px , 0px";
  parallax_5.style.transform = "translate3d(0px ," + -scrollTop * .25 + "px , 0px";
}

// 
function stageResize() {
  // document 너비값을 구해서 _documentHum에 할당
  _documentHum = document.body.offsetHeight;
  // window 높이값을 구해서 _windowHNum에 할당
  _windowHNum = window.outerHeight;
}

// 마우스가 움직이면 이미지도 움직이는 loop
function loop() {
  // 마우스 가속도
  mx += (x - mx) * speed;
  my += (y - my) * speed;

  // 이미지 4,5,6번은 마우스 움직임에 따라 주어진 값만큼 움직인다.
  parallax_4.style.transform = "translate3d(" + mx / 140 + "px , " + -scrollTop * .22 + "px, 0px)";
  parallax_5.style.transform = "scale(1.1) translate(" + mx / 50 + "px , " + -scrollTop * .25 + "px)";
  parallax_6.style.transform = "scale(1.2) translate(" + mx / 20 + "px , " + -my / 20 + "px)";

  window.requestAnimationFrame(loop);
}

function mouseMove(e) {
  // window의 너비와 높이값을 구해서 /2 해주면 정가운데가 0이된다.
  // 마우스를 오른쪽으로 가면 +고 왼쪽으로 가면 -이다.
  x = (e.clientX - window.innerWidth / 2);
  y = (e.clientY - window.innerHeight / 2);
profile
프론트엔드 4년차

0개의 댓글