사진처럼 보는 각도에 따라 보이는 이미지가 달라지는 걸 렌티큘러 카드(Lenticular Card)라 부릅니다.

저번에 작성했던 기기 방향을 감지하는 스크립트를 이용하면 굉장히 쉽게 구현할 수 있습니다.

HTML

<div id="card">
    <div id="layer1" class="lenticular"></div>
    <div id="layer2" class="lenticular"></div>
</div>

배경 이미지가 보일 메인 레이어 하나와 각도에 따라 표시할 레이어 두 개만 추가해주면 끝납니다.

CSS

#card {
    position: relative;
    max-width: 100%;
    height: 0;
    padding-bottom: 100%;
    background-image: url(배경_이미지);
    background-size: cover;
}

#card .lenticular {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0
}

#card .lenticular {
    background-position: center;
    background-size: contain;
}

#layer1 {
    background-image: url(각도에_따라_보일_이미지_1);
}

#layer2 {
    background-image: url(각도에_따라_보일_이미지_2);
}

당연한 소리지만 배경 이미지는 제거하셔도 무관하며, 전 배경에 무늬를 넣을 예정이라 layer1과 2에 background-repeat을 제거하지 않았습니다만, 위 사진처럼 인물을 넣을 예정이라면 background-repeat을 제거하고 background-size를 조절하셔야 합니다.

Javascript

기기의 각도에 따라 Opacity를 조절해야 하는데, 제일 먼저 떠오르는 함수가 삼각함수더라고요.

sin(x)와 cos(x)는 -1과 1 사이를 오가지만, opacity는 0 ~ 1 사이를 오가야 하니, sin 함수는 (sin(x) + 1) / 2 이렇게 이동해야 하고, sin(x)의 결과와 cos(x)의 결과가 정반대여야 하니, cos 함수는 (cos(x + 1/2*PI) + 1) / 2가 되어야 합니다.
Opacity가 조금 더 천천히 바뀌도록 x 에 1/3을 곱해줍니다.

여담으로, 채영 렌틸카드와 비교했을 땐 1/10을 곱해야 렌틸카드와 이미지 바뀌는 각도가 비슷하더라고요.

const layer1 = document.getElementById("layer1"),
  layer2 = document.getElementById("layer2");

function handleOrientation(event) {
  const beta = 1/10 * event.beta;

  if (event.alpha === null) {
    //자바스크립트에선 0 !== null이라 이래도 됩니다.
    window.removeEventListener("deviceorientation"handleOrientation),
    document.getElementById("card").addEventListener("mousemove"handleMouseMove);
  }

  layer1.style.opacity = (Math.sin(beta+ 1/ 2,
  layer2.style.opacity = (Math.cos(beta + 1.570795+ 1)/ 2
}

function handleMouseMove(event) {
  const y = 1/30 * event.clientY;

  layer1.style.opacity = (Math.sin(y+ 1/ 2,
  layer2.style.opacity = (Math.cos(y + 1.570795+ 1)/ 2
}

window.addEventListener("deviceorientation"handleOrientation);

위 원리만 알면 모든 건 끝납니다. x축을 중심으로 움직였을 때 이미지가 바뀌어야 하므로, event.beta 값을 x에 대입해 레이어의 opacity를 조절하면 끝납니다.
1/2*PI는 그냥 3.14159를 2로 나눈 값을 넣었습니다.
파이 값을 넣고 싶으시면 Math.PI를 사용하시면 파이 값을 반환합니다.

event.alpha 값이 null일 땐(자이로 센서가 없을 때) 마우스의 y 좌표값에 따라 opacity가 변경되도록 했습니다.

결과물

휴대폰을 기울이거나 마우스를 올려두고 움직여보세요!

profile

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다

(?)

  • Kiss Me ♥

    모바일에서 보니 확실히 이쁘네요~~!!
    PC에서도 마우스 움직이면 변화가 보이긴하는데 모바일에서 만큼 제대로 표현되지 않는거 같아 아쉽네요..
    참 이쁜 기능인데..

    https://chaeyoung.tistory.com/attachment/cfile10.uf@9973C24F5DF7A22E290E67.mp4

    1. PC에선 무슨 짓을 해도 모바일 느낌은 안 나더라고요. ㅠㅠ
      예쁘긴 예쁜데 활용 방안은 많지 않아 슬픈 코드입니다.

      https://chaeyoung.tistory.com/attachment/cfile5.uf@992BBC4F5DF6436D28DA35.mp4

  • 땀똔

    오~ 이거 좋으네요 @.@

    https://i.imgur.com/S94gVsQ.jpg

    1. PC에선 제대로 사용할 수 없는 게 안타까울 따름입니다 ㅠㅠ
      모바일, PC 모두에서 가능하면 훌륭한 장난감이 될 텐데 말이죠.