基于JQuery和CSS3实现仿Apple TV海报背景视觉差特效源码分享


Posted in Javascript onSeptember 21, 2015

效果展示如下:

基于JQuery和CSS3实现仿Apple TV海报背景视觉差特效源码分享

查看演示     下载源码

HTML结构

Apple TV是由苹果公司继 Airport Express 之后推出的一款高清电视机顶盒产品。如果你曾经使用过,一定会被其中的炫酷电影海报视觉差特效所吸引。

该视觉差特效的HTML结构使用一个<div>作为容器,在它里面的每一个<div>都是一个“层”。

<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旋转效果,它的父元素需要设置透视和transform-style。

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;
}

海报的居中采用的是绝对定位居中法:left和top分别为50%,然后设置margin-left和margin-top为负的宽度值和高度值。

海报中所有的“层”可以通过div[class*="layer-"]选择器来选择。所有的图层都被设置为绝对定位,背景图片不重复,background-position设置到左上角位置,背景的大小设置为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;
}

注意上面代码中的top,left,right和bottom属性的值都是-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');
}

JavaScript

该视觉差效果的原理是每次用户移动鼠标是时候,.poster的transforms: translateY、rotate和rotateY属性将根据鼠标的位置发生变化。鼠标距离左上角越远,动画可见的区域就越多。

计算的公式类似于 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>

data-offset的值越大,可见的动画区域就越大。

整个视觉差效果的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);
 });
Javascript 相关文章推荐
js 中 document.createEvent的用法
Aug 29 Javascript
jquery提升性能最佳实践小结
Dec 06 Javascript
JavaScript实现url地址自动检测并添加URL链接示例代码
Nov 12 Javascript
jQuery ui 利用 datepicker插件实现开始日期(minDate)和结束日期(maxDate)
May 22 Javascript
教你用十行node.js代码读取docx的文本
Mar 08 Javascript
JS检测数组类型的方法小结
Mar 14 Javascript
jQuery实现可兼容IE6的滚动监听功能
Sep 20 jQuery
vue中v-model动态生成的实例详解
Oct 27 Javascript
Vue配合iView实现省市二级联动的示例代码
Jul 27 Javascript
vue与iframe之间的信息交互的实现
Apr 08 Javascript
Vue 3.0 全家桶抢先体验
Apr 28 Javascript
如何用JS实现简单的数据监听
May 06 Javascript
Java Mybatis框架入门基础教程
Sep 21 #Javascript
JS实现仿微博可关闭弹出层效果
Sep 21 #Javascript
jQuery+HTML5美女瀑布流布局实现方法
Sep 21 #Javascript
JavaScript实现网页加载进度条代码超简单
Sep 21 #Javascript
Javascript验证方法大全
Sep 21 #Javascript
JavaScript验证Email(3种方法)
Sep 21 #Javascript
基于jQuery实现多层次的手风琴效果附源码
Sep 21 #Javascript
You might like
一个改进的UBB类
2006/10/09 PHP
PHP操作mysql函数详解,mysql和php交互函数
2011/05/19 PHP
PHP中nowdoc和heredoc使用需要注意的一点
2014/03/21 PHP
Yii2中关联查询简单用法示例
2016/08/10 PHP
php微信开发之关注事件
2018/06/14 PHP
详解php中curl返回false的解决办法
2019/03/18 PHP
一个javascript图片阅览组件
2010/11/09 Javascript
基于jquery的滑动样例代码
2010/11/20 Javascript
Extjs中TabPane如何嵌套在其他网页中实现思路及代码
2013/01/27 Javascript
select标签模拟/美化方法采用JS外挂式插件
2013/04/01 Javascript
js的正则test,match,exec详细解析
2014/01/29 Javascript
JavaScript跨浏览器获取页面中相同class节点的方法
2015/03/03 Javascript
jQuery实现将页面上HTML标签换成另外标签的方法
2015/06/09 Javascript
浅谈angularJS 作用域
2015/07/05 Javascript
JS实现IE状态栏文字缩放效果代码
2015/10/24 Javascript
浅谈JavaScript的内置对象和浏览器对象
2016/06/03 Javascript
教你如何在Node.js中使用jQuery
2016/08/28 Javascript
微信小程序实现tab和swiper切换结合效果
2020/07/17 Javascript
在vue中使用css modules替代scroped的方法
2018/03/10 Javascript
vue组件中的数据传递方法
2018/05/14 Javascript
[40:03]Liquid vs Optic 2018国际邀请赛淘汰赛BO3 第一场 8.21
2018/08/22 DOTA
python简单获取数组元素个数的方法
2015/07/13 Python
Python的mysql数据库的更新如何实现
2017/07/31 Python
python 文件转成16进制数组的实例
2018/07/09 Python
Python 获取windows桌面路径的5种方法小结
2019/07/15 Python
django admin组件使用方法详解
2019/07/19 Python
深入浅析python 中的self和cls的区别
2020/06/20 Python
python 利用panda 实现列联表(交叉表)
2021/02/06 Python
socket.io 和canvas 实现的共享画板功能
2019/05/22 HTML / CSS
详解如何获取localStorage最大存储大小的方法
2020/05/21 HTML / CSS
《明天,我们毕业》教学反思
2014/04/24 职场文书
学雷锋宣传标语
2014/06/25 职场文书
网络舆情信息简报
2015/07/21 职场文书
2015年主婚人婚礼致辞
2015/07/28 职场文书
JVM上高性能数据格式库包Apache Arrow入门和架构详解(Gkatziouras)
2021/05/26 Servers
MySQL分区表实现按月份归类
2021/11/01 MySQL