扒皮下GitHub 404的图片层次轴动特效
今天要克隆的前端特效非常有意思,可以参见GitHub404页面 https://github.com/vajoy/master/index.html
记得之前华为在站酷发布EMUI设计大赛的主页也用了这种特效。说简单点,就是鼠标在页面移动时,banner上的图片呈现有层次的空间轴动特效,效果图如下:

咱们先仿造GitHub 404页面来写一下banner原型——前景有“鱿鱼”和“对话框”,远景有俩小屋子:

代码如下
<!doctype html>
<html>
<head>
<style>
body,heml{margin:0; padding:0;}
.bannerWrap{ position:relative; margin:0 auto;width:1000px; height:350px; background-color:#F0E262; overflow:hidden;}
.bannerWrap img{ display:block; position:absolute;}
</style>
<script src="jq.js"></script>
<meta charset="utf-8">
<title>层级图片轴动效果</title>
</head> <body> <div class="bannerWrap" id="bannerWrap">
<img src="house2.png" class="small_house" id="small_house" />
<img src="house1.png" class="house" id="house" />
<img src="fish.png" class="fish" id="fish" />
<img src="404.png" class="info" id="info" />
</div><!--bannerWrap结束-->
</body>
</html>
接着写脚本前先分析一下,如何做到让鼠标在屏幕上的位置,可以映射为图片在banner上的位置呢?比如鼠标在屏幕最右上角的位置时,前景的图片也在banner里所能移动到的最右上角的位置(远景图片为相反的方位,即左下角)。
又如何让每个图片移动的距离和方位都各不相同?比如远景的两个小屋子图片,最远的屋子移动的速度比近一点的屋子的速度要快。且近景和远景图片所移动的方位是相反的。

⑴ 首先第一个问题,我们可以联想到数位板,一块长方形的数位板可以匹配各种型号的电脑屏幕,无论你的数控笔移动到数位板的哪个位置,它都能控制鼠标移动到对应比例的屏幕位置。是的,我们提到了“比例”这东西,它遵循:
鼠标x坐标 / 屏幕宽度 = 数控笔在数位板上的x坐标 / 数位板宽度 ;
鼠标y坐标 / 屏幕高度 = 数控笔在数位板上的y坐标 / 数位板高度 ;
我们引申到现在的例子来,不外乎是把数控笔换成banner上的图片,把数位板换成banner罢了。我们可以很轻易地获取屏幕宽度、banner宽度、鼠标移动时的x、y坐标,那么自然可以依据上面的公式来反推出图片所应在banner上的x、y坐标,哦,不对,应该说是相对banner而言的left、top偏移。
⑵ 至于第二个问题,我们可以给每张图片设置一个Boolean参数判断其是否前景图片,如果是,则依循鼠标移动位置移动,如果不是则以相反方向移动。
我们也可以给每张图片设置一个scale比例参数,参数越大者则移动的位置越大,从而控制其移动速度。
⑶ 另有一个需要考虑的问题是,在页面刚加载好(假设鼠标还没做任何移动)的时候,各图片所在banner的位置应当是与鼠标移动到屏幕正中点的时候所在位置一致的。这要求我们在初始化各图片的时候,就先模拟出鼠标指针在屏幕正中的效果。

我们可以写出初步的脚本代码:
$(function(){
var win_w, win_h,b_w, b_h,
small_house, house, fish, info, pToW_w, pToW_h, $img,
temp_p_l, temp_p_t;
var $banner = $("#bannerWrap");
var picArray = "small_house,house,fish,info".split(",");
small_house = { l: 800, t: -140, s: 0.09, isFront: false }, //smallhouse的参数
house = { l: 130, t: -130, s: 0.05, isFront: false }, //house的参数
fish = { l: -100, t: -90, s: 0.02, isFront: true }, //fish的参数
info = { l: -350, t: -110, s: 0.03, isFront: true }; //info的参数
win_w = $(window).width(); //初始化获取屏幕宽度
win_h = $(window).height(); //初始化获取屏幕高度
pToW_w = $banner.width()/win_w; //初始化获取banner宽度和屏幕宽度的比例
pToW_h = $banner.height()/win_h; //初始化获取banner高度和屏幕高度的比例
$.each( picArray, function(i ,id){ //初始化各图片的位置(相当于鼠标移到屏幕中间时图片的位置)
$img = $("#"+ id);
temp_p_l = pToW_w * eval(id+".s") * win_w/2 ; //这里使用win_w/2是为了模拟鼠标移到屏幕水平中点的效果
temp_p_t = pToW_h * eval(id+".s") * win_h/2 ; //这里使用win_h/2是为了模拟鼠标移到屏幕垂直中点的效果
if(eval(id +".isFront")){
$img.css({"left": eval(id +".l") + temp_p_l , "top": eval(id +".t") + temp_p_t });
}else{
$img.css({"left": eval(id +".l") - temp_p_l , "top": eval(id +".t") - temp_p_t });
}
})
var changePst = function( pageX, pageY ){
$.each( picArray, function(i ,id){
$img = $("#"+ id);
temp_p_l = pToW_w * eval(id +".s") * pageX ;
temp_p_t = pToW_h * eval(id +".s") * pageY ;
if(eval(id +".isFront")){
$img.css({"left": eval(id +".l") + temp_p_l , "top": eval(id +".t") + temp_p_t });
}else{
$img.css({"left": eval(id +".l") - temp_p_l , "top": eval(id +".t") - temp_p_t });
}
})
}
$("body,html").mousemove(function(e){ //鼠标在屏幕移动时触发changePst事件
changePst(e.pageX, e.pageY);
})
})
每个图片都有 l、t、s、isFront 这四个参数。
其中 l 和 t 表示图片相对banner的初步偏移位置(后面还要再加上或减去temp_p_*来得到最终偏移位置);s表示缩放级别,数值越大则该图片移动的距离越大;isFront则是判断是否前景图片。

虽然上方脚本初步实现我们想要的功能,却没考虑到一个问题,即屏幕被缩放时,图片的位置、应偏移的距离都会出错,因为可能banner的宽度已经不再是原来的宽度(banner宽度为百分比)、屏幕的宽高也不再是原来的宽高(计算图片偏移距离涉及到屏幕宽高)。
所以我们把初始化事件封装起来,供屏幕缩放时调用。同时动态获取banner宽度,而不是生硬地写入到各图片初始化的l参数中:
$(function(){
var win_w, win_h,b_w, b_h,
small_house, house, fish, info, pToW_w, pToW_h, $img,
temp_p_l, temp_p_t;
var $banner = $("#bannerWrap");
var picArray = "small_house,house,fish,info".split(",");
small_house = { l: 200, t: -140, s: 0.09, isFront: false },
house = { l: 70, t: -130, s: 0.05, isFront: false },
fish = { l: -160, t: -90, s: 0.02, isFront: true },
info = { l: -410, t: -110, s: 0.03, isFront: true };
var resetImg = function(){
b_w = $banner.width(); //初始化获取banner宽度
b_h = $banner.height(); //初始化获取banner高度
win_w = $(window).width();
win_h = $(window).height();
pToW_w = $banner.width()/win_w;
pToW_h = $banner.height()/win_h;
$.each( picArray, function(i ,id){ //初始化各图片的位置(相当于鼠标移到屏幕中间时图片的位置)
$img = $("#"+ id);
temp_p_l = pToW_w * eval(id+".s") * win_w/2 ;
temp_p_t = pToW_h * eval(id+".s") * win_h/2 ;
if(eval(id +".isFront")){
$img.css({"left": b_w/2 + eval(id +".l") + temp_p_l , "top": b_h/2 + eval(id +".t") + temp_p_t }); //动态加上banner宽高
}else{
$img.css({"left": b_w/2 + eval(id +".l") - temp_p_l , "top": b_h/2 + eval(id +".t") - temp_p_t });
}
})
}
resetImg();
$(window).on("resize",resetImg); //屏幕缩放时重新初始化数据
var changePst = function( pageX, pageY ){
$.each( picArray, function(i ,id){
$img = $("#"+ id);
temp_p_l = pToW_w * eval(id +".s") * pageX ;
temp_p_t = pToW_h * eval(id +".s") * pageY ;
if(eval(id +".isFront")){
$img.css({"left": b_w/2 + eval(id +".l") + temp_p_l , "top": b_h/2 + eval(id +".t") + temp_p_t });
}else{
$img.css({"left": b_w/2 + eval(id +".l") - temp_p_l , "top": b_h/2 + eval(id +".t") - temp_p_t });
}
})
}
$("body,html").mousemove(function(e){
changePst(e.pageX, e.pageY);
})
})
至此我们完成了我们所预期的功能。
眼尖的同学会发现,resetImg事件里的.each方法跟changePst事件里的非常相似。我们可以把它们整合起来提高复用、减少代码量:
$(function(){
var win_w, win_h,b_w, b_h,
small_house, house, fish, info, pToW_w, pToW_h, $img,
temp_p_l, temp_p_t;
var $banner = $("#bannerWrap");
var picArray = "small_house,house,fish,info".split(",");
small_house = { l: 200, t: -140, s: 0.09, isFront: false }, //smallhouse的参数
house = { l: 70, t: -130, s: 0.05, isFront: false }, //house的参数
fish = { l: -160, t: -90, s: 0.02, isFront: true }, //fish的参数
info = { l: -410, t: -110, s: 0.03, isFront: true }; //info的参数
var setPst = function(x, y){
x = x||win_w/2;
y = y||win_h/2;
$.each( picArray, function(i ,id){
$img = $("#"+ id);
temp_p_l = pToW_w * eval(id+".s") * x ;
temp_p_t = pToW_h * eval(id+".s") * y ;
if(eval(id +".isFront")){ //判断是否前景元素
$img.css({"left": b_w/2 + eval(id +".l") + temp_p_l , "top": b_h/2 + eval(id +".t") + temp_p_t }); //这里的b_w/2和b_h/2是为了保证窗口缩放时还能在相对位置
}else{
$img.css({"left": b_w/2 + eval(id +".l") - temp_p_l , "top": b_h/2 + eval(id +".t") - temp_p_t });
}
})
}
var resetImg = function(){
b_w = $banner.width(); //初始化获取banner宽度
b_h = $banner.height(); //初始化获取banner高度
win_w = $(window).width(); //初始化获取屏幕宽度
win_h = $(window).height(); //初始化获取屏幕高度
pToW_w = $banner.width()/win_w; //初始化获取banner宽度和屏幕宽度的比例
pToW_h = $banner.height()/win_h; //初始化获取banner高度和屏幕高度的比例
setPst();
}
resetImg();
$(window).on("resize",resetImg); //屏幕缩放时重新初始化数据
$("body,html").mousemove(function(e){
setPst(e.pageX, e.pageY);
})
})
最后还是为大家提供本案例的Demo,请到GitHub上下载:https://github.com/VaJoy/BlogDemo/tree/master/140809
祝周末愉快,共勉~
扒皮下GitHub 404的图片层次轴动特效的更多相关文章
- 元素视差方向移动jQuery插件-类似github 404页面效果
原文地址:http://www.xuanfengge.com/shake.html 前言: 视差滚动,大家也许并不陌生.但是对于视差方向移动,你是否有见过效果呢?看官请进来瞧瞧~ demo : 轩枫阁 ...
- 如何在github中插入图片,链接,图片链接(给图片加上链接),文字+图片链接,的实战分享!
如何在github中插入图片,链接,图片链接(给图片加上链接),文字+图片链接,的实战分享! markdown 1.文字链接: [link-Text](link-URL) [home](https:/ ...
- 一款基于css3的3D图片翻页切换特效
今天给大家分享一款基于css3的3D图片翻页切换特效.单击图片下方的滑块会切换上方的图片.动起你的鼠标试试吧,效果图如下: 在线预览 源码下载 实现的代码. html代码: <div id= ...
- CSS3实战开发: 纯CSS实现图片过滤分类显示特效
原文:CSS3实战开发: 纯CSS实现图片过滤分类显示特效 各位网友大家好,今天我要带领大家开发一个纯CSS的图片分类显示的网址导航,单纯看标题大家可能有些困惑,依照以往惯例,我先给大家演示一下实际运 ...
- 基于jQuery适合做图片类网站的特效
分享一款基于jquery适合做图片类网站的特效.这是一款鼠标经过图片滑动弹出标题效果代码.效果图如下: 在线预览 源码下载 实现的代码. html代码: <div class="c ...
- 基于jQuery图片弹出翻转特效代码
分享一款基于jQuery图片弹出翻转特效代码.这是一款基于jQuery+HTML5实现的,里面包含六款不同效果的鼠标点击图片弹出特效下载.效果图如下: 在线预览 源码下载 实现的代码. html代 ...
- 8行代码批量下载GitHub上的图片
[问题来源] 来打算写一个的小游戏,但是图片都在GitHub仓库中,GitHub网页版又没有批量下载图片的功能,只有单独一张一张的下载,所以自己就写了个爬虫脚本模拟人的操作把整个页面上需要的图片爬取下 ...
- 解决github pages和github .md文件图片不显示
博客园上传的图片,在github上无法显示. 在github项目下建立img文件夹,放上图片 两种方式 项目绝对路径 https://raw.githubusercontent.com/用户名/项目名 ...
- github局部不同图片合并插件
用于解决游戏开发时,一套图里有局部地区图片不同其他地方相同,导致资源重复过大的问题 地址:https://github.com/Elringus/SpriteDicing
随机推荐
- Javascript 截取2位小数
今天在处理数据时,前台界面金额需要保留两位小数,所以只能使用Javascript 来进行截取. var regex = /([0-9]+\.[0-9]{2})[0-9]*/; var localMon ...
- tmp
Hello 大家好,这次给大家带来的是Gear VR4代,首先我得感谢下我们的虎友Hide兄弟友情提供Gear给我们测评,感谢 感谢.之前我录的前哨战也说过,这次Gear VR 4代较3代变化并不是很 ...
- C# 并行编程 之 轻量级手动重置事件的使用
目录(?)[-] 简单介绍 使用超时和取消 跨进程或AppDomain的同步 简单介绍 如果预计操作的等待的时间非常短,可以考虑使用轻量级的手动重置事件,ManualResetEventSlim. ...
- C、C++、Java、go的语法区别
详细C++.Java比较:http://www.cnblogs.com/stephen-liu74/archive/2011/07/27/2118660.html 一.C.C++的区别 在很大程度上, ...
- APP审核被拒,原因总结
今天早上,突然看到上周末提交的APP,审核被拒了.原以为是因为IPV6审核没过,后来查看原因后发现是,app的3张展示图里面,有些内容显示的有:测试XX等字眼.苹果说提交的版本不能是含有 test,t ...
- 记一次FTP上传文件总是超时的解决过程
好久没写博,还是重拾记录一下吧. 背景:买了一个阿里云的云虚拟机用来搭建网站(起初不了解云虚拟主机和云服务器的区别,以为都是有SSH功能的,后来发现不是这样样子啊,云虚拟机就是FTP上传网页+MySQ ...
- 安卓奇葩问题之SQLite条件查找不到数据
今天真是日了狗了. 先说需求:要做一个累死支付宝首页的可自定义的栏目.栏目是动态从后台获取的,所以就会有一个本地数据和后台数据的同步问题.为了方便对本地数据的增删改查,首先想到SQLite. 然后就写 ...
- 【九度OJ】题目1202:排序
题目描述: 对输入的n个数进行排序并输出. 输入: 输入的第一行包括一个整数n(1<=n<=100). 接下来的一行包括n个整数. 输出: 可能有多组测试数据,对于每组数据,将排序后 ...
- gulp-rev-orig
给客户演示项目时,老是会出现由于缓存,造成的最新的样式或者效果出不来的情况,还得需要手动清除缓存操作,一方面呢,会给客户留下不好的印象,而且也会多了清缓存这一过程,和同事商量过后,决定使用在css或者 ...
- 置入式模型inclusion model和显示具现化
1.置入式模型 链接错误: 大多数非模板程序代码的组织如下:A,类声明在头文件中: B:全局变量和非inline函数在cpp文件中定义 但是,如果模板程序也这样组织,则会出错.原因在于:函数模板的定义 ...