码迷,mamicode.com
首页 > 其他好文 > 详细

LED跑马灯之二

时间:2015-06-19 18:49:25      阅读:190      评论:0      收藏:0      [点我收藏+]

标签:

   这是上一篇文章的地址:http://blog.csdn.net/pandeng4639088/article/details/46550257

   上一篇对跑马灯的原理及规律进行了一次分析,虽然本来故事会在那里结束的,但结果我在中午去吃饭途中,又想了想,既然都给A对象加了一个假想长度,那为什么不将这个假想长度映射回A本身呢?而且现实生活中也有这样的效果,就是当B超出A长度时,超出的部份,直接在A开始的位置出现,类似效果如下:

技术分享技术分享

    好,这种效果又如何实现呢?同样,我们也是通过事实的表面来分析得出事物的规律,利用规律来解决问题。

   (1)如下图所示,当B对象刚超出A时的情景,我们把刚超出的部份B0映射到A0上去,那如何知道计算这个下标映射关系?如图所示,假设映射的起始下标位置为S1,那么就有S1 = S%A.len,A.len表示A数组的长度,所进行的操作是A[i].style.backgroundColor = B[j]。

技术分享

   但这个仍然得不到合理的头绪,因为接下来的循环没法做了,因为问题在于I这个下标身上,I的值为0的话,那相当于这个循环结束了!但我们又想到,I=S1=S%A.len,那,为什么不用S来表示I?,让I=S,执行操作为A[i%A.len].style.backgroundColor = B[j]。

   所示得到一个过程如下:

for( var i= S, j=0; i>=0; i--, j++ ){

   if( j < B.len ){

A[ i%A.len ].style.backgroundColor = B[j];

   }else{

       A[ i%A.len ].style.backgroundCOlor = ‘#ccc‘; //默认颜色

}


(2)那如果B数组遍历完后如下图所示:

技术分享

经过分析得出,当S > ( A.len + B.len - 1 ) ,即S增长到A和B两者的长度之和时,映射刚好把B全部映射完毕,说明这一轮就结束了。

于是得出:

if( S > ( A.len + B.len - 1 ){

    //结束,重新开始新的一轮

     S = S%A.len;

}

似乎,分析就到此结束了,但运行后我发现,走完一轮后,发现并没有得到正确的运行结果,为什么?因为i的值是一直递减的,一直减到为0为止,所以我们映射过去的颜色又被默认色覆盖了。那我们怎么知道在哪里停下?即我们怎么知道哪一部份被映射了?上面两张图中都有一个E的标记,这个E就是表示I结束的位置。而E的计算公式如下:

当在(1)图状态时,E = S%A.len + 1 = 5%5+1 = 1

当在(2)时,E=0,为什么是=0,而不是同(1)一样?答案是已经到了结尾而重新开始的地方,那E当然是归0啦!

但是你们也许还有疑惑,那正常情况下的呢?公式是不是仍然正确?正常情况下,E的值仍然是0,因为S并未超出A数组的长度,当只有S超出A的长度时,即进行映射的时候,这个时候,E才会进行移动,当映射结束的时,即最终状态,E也需要回归到正常状态下,即0。

所以,代码如下,这里我还添加了一个控制按钮,方便进行查看各个过程:

<pre name="code" class="html"><!DOCTYPE html>
<html>

<head>
	<title>Test4</title>
	<meta http-equiv="Content-type" content="text/html;charset=utf-8" />
	<style type='text/css'>
		.box{ width:500px; margin:20px auto; }
		.box ul{list-style: none;}
		.box ul li { width:20px; height: 20px; background-color: #ccc; float:left; text-align:center;}		
	</style>
</head>

<body>
	<input type="button" value='Start/Stop' onclick="switchLED()" />
	<div id='box' class='box'>
		<ul>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li> 
			<li></li>
			<li></li>
			<li></li>
			<li></li>
			<li></li>
		</ul>
	</div>
</body>
<script type="text/javascript">
	
	//颜色数组(简称B)
	var objB = [ '#FF0000', '#FF3300', '#FF6600', '#FF9900', '#FFCC00' ];
	var startPos = 0; //这里是一个数组游标,标记当前从哪个位置开始变化设置颜色
	var objA = undefined; //进行变化的对象
	var timer = undefined;

	init();

	//初始化
	function init(){
		
		//我这里用的是li标签,如果你的是div,则将所有需要变化的div存在在一个变量中,我这里放的是objA这个变量.
		objA = document.getElementById('box').children[0].children; //简称A对象

		//调用跑马灯函数
		fLEDScrollerB();
	}

	function fLEDScrollerB(){

		var endPos = 0;

		//当开始进行映射
		if( startPos >= objA.length ){
			endPos = startPos%objA.length+1;
		}

		//映射结束状态,归0操作
		if( startPos > ( objA.length + objB.length - 1 ) ){
			startPos = startPos%objA.length;
			endPos = 0;
		}

		//i下标的值不能超过endPos
		for( var i= startPos, j=0; i>=endPos; i--, j++ ){
			if( j<objB.length ){
				objA[i%objA.length].style.backgroundColor = objB[j];
			}else{
				objA[i%objA.length].style.backgroundColor = '#ccc';
			}
		}

		startPos++;
		
		//间隔100毫秒进行一次变化
		timer = setTimeout( 'fLEDScrollerB()', 100 );
	}

	//开关函数
	function switchLED(){
		if( null == timer ){
			fLEDScrollerB();
		}
		else{
			clearTimeout( timer );
			timer = null;
		}
	}

</script>
</html>




效果如下:

技术分享技术分享

注意,这种映射方式有其限制,就是A数组的长度不能小于B数组的长度,不然,映射的长度都不够,会造成重复覆盖的后果!


LED跑马灯之二

标签:

原文地址:http://blog.csdn.net/pandeng4639088/article/details/46561991

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!