효과는 아래와 같습니다.
HTML 구조
애플TV는 애플이 에어포트 익스프레스에 이어 출시한 고화질 TV 셋톱박스 제품이다. 사용해 본 적이 있다면 멋진 영화 포스터 시각 효과에 확실히 매료될 것입니다.
이 시각적 차이 효과의 HTML 구조는
<div class="poster"> <div class="shine"></div> <div class="layer-1"></div> <div class="layer-2"></div> <div class="layer-3"></div> <div class="layer-4"></div> <div class="layer-5"></div> </div> <div.shine>是用于制作流光效果的图层。
CSS 스타일
래핑된 요소인 .poster가 3D 회전 효과를 생성하려면 해당 상위 요소에서 관점과 변형 스타일을 설정해야 합니다.
body { background: linear-gradient(to bottom, #f6f7fc 0%,#d5e1e8 40%); transform-style: preserve-3d; transform: perspective(800px); }
여기의 포스터 크기는 고정된 320x500픽셀로 설정되어 페이지 중앙에 위치하며 둥근 모서리 효과와 일부 그림자 효과를 제공합니다.
.poster { width: 320px; height: 500px; position: absolute; top: 50%; left: 50%; margin: -250px 0 0 -160px; border-radius: 5px; box-shadow: 0 45px 100px rgba(0, 0, 0, 0.4); overflow:hidden; }
포스터는 절대 위치 지정 방법을 사용하여 중앙에 배치됩니다. 왼쪽과 위쪽은 각각 50%이고 margin-left와 margin-top은 음수 너비 및 높이 값으로 설정됩니다.
포스터의 모든 "레이어"는 div[class*="layer-"] 선택기를 통해 선택할 수 있습니다. 모든 레이어는 절대 위치 지정, 배경 이미지는 반복되지 않음, 배경 위치는 왼쪽 상단으로 설정, 배경 크기는 너비 100%, 높이 자동 설정으로 설정되었습니다.
div[class*="layer-"] { position: absolute; top: -10px; left: -10px; right: -10px; bottom: -10px; background-size: 100% auto; background-repeat: no-repeat; background-position: 0 0; transition:0.1s; }
위 코드의 위쪽, 왼쪽, 오른쪽, 아래쪽 속성 값은 모두 -10픽셀이라는 점에 유의하세요. 레이어의 크기를 포스터의 크기보다 20픽셀 크게 만드는 데 사용됩니다. 그 이유는 시각적 차이 효과를 만들 때 레이어의 가장자리를 숨기기 위해서입니다.
마지막으로 각 레이어의 배경 이미지를 설정합니다.
.layer-1 { background-image: url('images/1.png'); } .layer-2 { background-image: url('images/2.png'); } .layer-3 { top: 0; bottom: 0; left: 0; right: 0; background-image: url('images/3.png'); } .layer-4 { background-image: url('images/4.png'); } .layer-5 { background-image: url('images/5.png'); }
자바스크립트
이 시각적 차이 효과의 원리는 사용자가 마우스를 움직일 때마다 .poster의 변환Y, 회전 및 회전Y 속성이 마우스 위치에 따라 변경된다는 것입니다. 마우스가 왼쪽 상단 모서리에서 멀어질수록 애니메이션이 표시되는 영역이 더 넓어집니다.
계산 공식은 offsetX = 0.5 – 마우스 위치 / 창 너비와 유사합니다.
각 레이어에 서로 다른 애니메이션 속도를 부여하려면 사용자 정의 애니메이션 속도 값을 곱해야 합니다. 이 값은 HTML 태그의 data-offset="number"에서 제공됩니다.
<div data-offset="-2" class="layer-1"></div> <div class="layer-2"></div> <div data-offset="1" class="layer-3"></div> <div data-offset="3" class="layer-4"></div> <div data-offset="10" class="layer-5"></div>
데이터 오프셋 값이 클수록 표시되는 애니메이션 영역이 커집니다.
전체 시각적 차이 효과에 대한 JS 코드는 다음과 같습니다.
var $poster = $('.poster'), $shine = $('.shine'), $layer = $('div[class*="layer-"]'); $(window).on('mousemove', function(e) { var w = $(window).width(), //窗口宽度 h = $(window).height(), /窗口高度 offsetX = 0.5 - e.pageX / w, //鼠标X坐标 offsetY = 0.5 - e.pageY / h, //鼠标Y坐标 dy = e.pageY - h / 2, //@h/2 = 海报容器中心 dx = e.pageX - w / 2, //@w/2 = 海报容器中心 theta = Math.atan2(dy, dx), //鼠标和海报中心的RAD角度 angle = theta * 180 / Math.PI - 90, //转换 rad 为 degrees offsetPoster = $poster.data('offset'), transformPoster = 'translateY(' + -offsetX * offsetPoster + 'px) rotateX(' + (-offsetY * offsetPoster) + 'deg) rotateY(' + (offsetX * (offsetPoster * 2)) + 'deg)'; //get angle between 0-360 if (angle < 0) { angle = angle + 360; } //gradient angle and opacity $shine.css('background', 'linear-gradient(' + angle + 'deg, rgba(255,255,255,' + e.pageY / h * .5 + ') 0%,rgba(255,255,255,0) 80%)'); //poster transform $poster.css('transform', transformPoster); //parallax foreach layer $layer.each(function() { var $this = $(this), offsetLayer = $this.data('offset') || 0, transformLayer = 'translateX(' + offsetX * offsetLayer + 'px) translateY(' + offsetY * offsetLayer + 'px)'; $this.css('transform', transformLayer); });