与上一篇分块运动不同的是,上一篇是一行一行的一块一块的运动直到最后一个。而斜三角分块运动是从左上角开始,只要是斜对角在一条线上的都会同时显示,透明度从0到1开始运动。
两种运动的大部分代码一样,由于for循环瞬间就可以完成,只需要改变需要同时运动的元素在定时器开启时的延时时间而已;
<style>
.box{
width: 800px;
height: 400px;
margin: 50px auto;
position: relative;
background: url(image/0.jpg) no-repeat;
}
</style>
<body>
<input type="button" name="btn" id="btn" value="换一张" />
<div class="box" id="box">
</div>
</body>
<script>
//封装获取非行间样式函数;写运动框架做必须的;
function getStylecss(obj,oStyle){
if(obj.currentStyle){
return obj.currentStyle[oStyle];
}else{
return getComputedStyle(obj,false)[oStyle];
}
}
//封装运动函数 有另外一篇文章专门写了运动框架详解;
function motion(obj,json,options){
options=options || {};
options.time=options.time || 1000;
options.easing=options.easing || 'linear';
clearInterval(obj.timer);
var start={};
var distance={};
for(var name in json){
start[name]=parseFloat(getStylecss(obj,name));
if(isNaN(start[name])){
switch(name){
case 'left':
start[name]=obj.offsetLeft;
break;
case 'top':
start[name]=obj.offsetTop;
break;
case 'right':
start[name]=obj.offsetRight;
break;
case 'bottom':
start[name]=obj.offsetBottom;
break;
}
}
distance[name]=json[name]-start[name];
}
var n=0;
var count=Math.floor(options.time/30);
obj.timer=setInterval(function(){
n++;
for(var name in json){
switch(options.easing)
{
case 'linear':
var a=n/count;
var cur=start[name]+distance[name]*a;
break;
case 'ease-in':
var a=n/count;
var cur=start[name]+distance[name]*(a*a*a);
break;
case 'ease-out':
var a=1-n/count;
var cur=start[name]+distance[name]*(1-a*a*a);
break;
}
if(name == 'opacity'){
obj.style[name]=start[name]+n*distance[name]/count;
}else{
obj.style[name]=start[name]+n*distance[name]/count+'px';
}
}
if(n==count){
clearInterval(obj.timer);
options.complete && options.complete();
}
},30);
};//运动函数封装完成;
//页面加载完成的时候执行此一下代码;
window.onload=function(){
var oBtn=document.getElementByID('btn');
var oBox=document.getElementByID('box');
var R=4; //在这里我定义分4行运动;
var C=8; //我定义每行分为8列;大家可以视情况而定;
//下面用两次for循环来创建和添加我们想到的元素,并设置样式;
for(var r=0;r<R;r++){
for(var c=0;c<C;c++){
var oSpan=docunment.createElement('span'); //创建‘span’标签;一共创建R*C个元素;
oSpan.style.width=oBox.offsetWidth/C+'px';
oSpan.style.height=oBox.offsetHeight/R+'px';
oBox.appendChild(oSpan);
oSpan.style.position='abosolute';
oSpan.style.left=c*oSpan.offsetWidth+'px';
oSpan.style.top=r*oSpan.offsetHeight+'px';
oSpan.style.backgroundPosition='-'+c*oSpan.offsetWidth+'px -'+r*oSpan.offsetHeight+'px';
//给每个span元素定义属性和属性值
oSpan.r=r; //每行元素的r值相同;
oSpan.c=c; //每列元素的c值相同;
//可以根据每个元素的属性值来定义一个独有的坐标,详解见顶部图片
}
}
var aSpan=oBox.getElementsByTagName('span');
var iNow=0; //图片的名称从0开始;
var moving=true; //如果在一张图片运动未完成时点击换图应该是不执行的,不然图片会很混乱,所以定义一个值来判断是否可以换下一张;
oBtn.onclick=function(){
if(moving){
moving=false; //此时让moving为false那么再怎么点击也不会执行if里面的代码,也不会更换图片;
iNow++; //点击事件触发的时候换下一张图片;
for(var i=0;i<aSpan.length;i++){
//用封闭空间写可以解决定时器里面i的值得问题;
(function(index){
setTimeout(function(){
oSpan.style.opacity=0;
aSpan[index].style.backgroundImage='url(image/'+iNow%3+'.jpg)'; //用iNow%3是为了让图片始终在0、1、2三张图片之间转换;
motion(aSpan[index],{opacity:1},{complete:function(){ //当一张图片最后一块运动完成时,让此时box的背景图成为当前显示的图片;并且此时再点击换图便会继续执行if里面的代码;
if(index==aSpan.length-1){
moving=true;
oBox.style.backgroundImage='url(image/'+iNow%3+'.jpg)';
}
}});//运动函数结束
},(aSpan[index].r+aSpan[index].c)*100);//由于斜对角延迟的时间相等,所以会同时执行定时器内的代码,同时运动,所以同时显示;
)(i);
};//for循环结束
};//if结束
};//点击事件结束
}
</script>