精华内容
下载资源
问答
  • Hadoop Trash回收站使用指南

    千次阅读 2017-12-22 09:37:49
    我们在删除一个文件时,遇到如下问题,提示我们不能删除文件放回回收站:sudo -uxiaosi hadoop fs -rm -r tmp/data_group/test/employee/employee_salary.txt17/12/06 16:34:48 INFO fs.TrashPolicyDefault: Namenode...

    我们在删除一个文件时,遇到如下问题,提示我们不能删除文件放回回收站:

    sudo -uxiaosi hadoop fs -rm -r tmp/data_group/test/employee/employee_salary.txt
    17/12/06 16:34:48 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 72000000 minutes, Emptier interval = 0 minutes.
    17/12/06 16:34:48 WARN fs.TrashPolicyDefault: Can't create trash directory: hdfs://cluster/user/xiaosi/.Trash/Current/user/xiaosi/tmp/data_group/test/employee
    rm: Failed to move to trash: hdfs://cluster/user/xiaosi/tmp/data_group/test/employee/employee_salary.txt. Consider using -skipTrash option

    去回收站对应目录下观察一下,得出的结论是:无法创建目录employee,因为employee文件已经存在,自然导致employee_salary.txt文件不能放回收回站:

    -rw-r--r--   3 xiaosi xiaosi  352 2017-12-06 16:18 hdfs://cluster/user/xiaosi/.Trash/Current/user/xiaosi/tmp/data_group/test/employee

    跟如下是同样的道理:

    xiaosi@yoona:~$ ll employee
    -rw-rw-r-- 1 xiaosi xiaosi 0 12月 6 16:56 employee
    xiaosi@yoona:~$
    xiaosi@yoona:~$
    xiaosi@yoona:~$ mkdir employee
    mkdir: 无法创建目录"employee": 文件已存在

    借此机会,详细研究了一下HDFSTrash回收站机制。

    1. 配置

    HDFS的回收站就像Windows操作系统中的回收站一样。它的目的是防止你无意中删除某些东西。你可以通过设置如下属性来启用此功能(默认是不开启的):

    <property>  
    <name>fs.trash.interval</name>
    <value>1440</value>
    <description>Number of minutes after which the checkpoint gets deleted. If zero, the trash feature is disabled.</description>
    </property>

    <property>
    <name>fs.trash.checkpoint.interval</name>
    <value>0</value>
    <description>Number of minutes between trash checkpoints. Should be smaller or equal to fs.trash.interval. If zero, the value is set to the value of fs.trash.interval.</description>
    </property>

    属性说明
    fs.trash.interval分钟数,当超过这个分钟数后检查点会被删除。如果为零,回收站功能将被禁用。
    fs.trash.checkpoint.interval检查点创建的时间间隔(单位为分钟)。其值应该小于或等于fs.trash.interval。如果为零,则将该值设置为fs.trash.interval的值。

    2. Trash

    启用回收站功能后,使用rm命令从HDFS中删除某些内容时,文件或目录不会立即被清除,它们将被移动到回收站Current目录中(/user/${username}/.Trash/current)。如果检查点已经启用,会定期使用时间戳重命名Current目录。.Trash中的文件在用户可配置的时间延迟后被永久删除。回收站中的文件和目录可以简单地通过将它们移动到.Trash目录之外的位置来恢复:

    sudo -uxiaosi hadoop fs -rm tmp/data_group/test/employee/employee_salary.txt
    17/12/06 17:24:32 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 72000000 minutes, Emptier interval = 0 minutes.
    Moved: 'hdfs://cluster/user/xiaosi/tmp/data_group/test/employee/employee_salary.txt' to trash at: hdfs://cluster/user/xiaosi/.Trash/Current

    说明:

    • Deletion interval表示检查点删除时间间隔(单位为分钟)。这里是fs.trash.interval的值。NameNode运行一个线程来定期从文件系统中删除过期的检查点。
    • Emptier interval表示在运行线程来管理检查点之前,NameNode需要等待多长时间(以分钟为单位),即检查点创建时间间隔。NameNode删除超过fs.trash.interval的检查点,并为/user/${username}/.Trash/Current创建一个新的检查点。该频率由fs.trash.checkpoint.interval的值确定,且不得大于Deletion interval。这确保了在emptier窗口内回收站中有一个或多个检查点。

    例如,可以设置如下:

    fs.trash.interval = 360 (deletion interval = 6 hours)
    fs.trash.checkpoint.interval = 60 (emptier interval = 1 hour)

    这导致NameNodeCurrent目录下的垃圾文件每小时创建一个新的检查点,并删除已经存在超过6个小时的检查点。

    在回收站生命周期结束后,NameNodeHDFS命名空间中删除该文件。删除文件会导致与文件关联的块被释放。请注意,用户删除文件的时间与HDFS中相应增加可用空间的时间之间可能存在明显的时间延迟,即用户删除文件,HDFS可用空间不会立马增加,中间有一定的延迟。

    3. 检查点

    检查点仅仅是用户回收站下的一个目录,用于存储在创建检查点之前删除的所有文件或目录。如果你想查看回收站目录,可以在/user/${username}/.Trash/{timestamp_of_checkpoint_creation}处看到:

    hadoop fs -ls hdfs://cluster/user/xiaosi/.Trash/
    Found 3 items
    drwx------ - xiaosi xiaosi 0 2017-12-05 08:00 hdfs://cluster/user/xiaosi/.Trash/171205200038
    drwx------ - xiaosi xiaosi 0 2017-12-06 01:00 hdfs://cluster/user/xiaosi/.Trash/171206080038
    drwx------ - xiaosi xiaosi 0 2017-12-06 08:00 hdfs://cluster/user/xiaosi/.Trash/Current

    最近删除的文件被移动到回收站Current目录,并且在可配置的时间间隔内,HDFS会为在Current回收站目录下的文件创建检查点/user/${username}/.Trash/<日期>,并在过期时删除旧的检查点。

    4. 清空回收站

    首先想到的是只要删除整个回收站目录,将会清空回收站。诚然,这是一个选择。但是我们有更好的选择。HDFS提供了一个命令行工具来完成这个工作:

    hadoop fs -expunge

    该命令使NameNode永久删除回收站中比阈值更早的文件,而不是等待下一个emptier窗口。它立即从文件系统中删除过期的检查点。

    5. 注意点

    回收站功能默认是禁用的。对于生产环境,建议启用回收站功能以避免意外的删除操作。启用回收站提供了从用户操作删除或用户意外删除中恢复数据的机会。但是为fs.trash.intervalfs.trash.checkpoint.interval设置合适的值也是非常重要的,以使垃圾回收以你期望的方式运作。例如,如果你需要经常从HDFS上传和删除文件,则可能需要将fs.trash.interval设置为较小的值,否则检查点将占用太多空间。

    当启用垃圾回收并删除一些文件时,HDFS容量不会增加,因为文件并未真正删除。HDFS不会回收空间,除非文件从回收站中删除,只有在检查点过期后才会发生。

    回收站功能默认只适用于使用Hadoop shell删除的文件和目录。使用其他接口(例如WebHDFSJava API)以编程的方式删除的文件或目录不会移动到回收站,即使已启用回收站,除非程序已经实现了对回收站功能的调用。

    有时你可能想要在删除文件时临时禁用回收站,也就是删除的文件或目录不用放在回收站而直接删除,在这种情况下,可以使用-skipTrash选项运行rm命令。例如:

    sudo -uxiaosi hadoop fs -rm -skipTrash tmp/data_group/test/employee/employee_salary.txt

    这会绕过垃圾回收站并立即从文件系统中删除文件。

    资料:

    https://developer.ibm.com/hadoop/2015/10/22/hdfs-trash/

    https://my.oschina.net/cloudcoder/blog/179381

    http://debugo.com/hdfs-trash/

    http://hadoop.apache.org/docs/r2.7.3/hadoop-project-dist/hadoop-hdfs/HdfsDesign.html#File_Deletes_and_Undeletes

    展开全文
  • 前言   相信大家在开发中,对于final修饰符都比较常见,它会将修饰的变量固定不可重复赋值。但是我们是否思考过被它所修饰属性变量或类存储在哪里呢?...究竟final修饰的数据被存储在什么位置呢?

    前言 



          相信在开发中,对于 final 修饰符大家都比较常见,它会将修饰的变量固定不可重复赋值。但是我们是否思考过被它所修饰属性变量或类存储在哪里呢?下面已我将用比较有趣的问答形式,让大家对final有一个全面的认识。为了更好认识Final,我们首先来复习一下Java的内存分配存储的知识,可以先看一下 内存如何分配(简单普及知识)。内存分配区域常见如下:
    • 堆区heap(存储对象)
    • 栈区stack(存储引用)
    • 静态方法区static storage(存储静态的)
    • 常量区constant storage(存储不变的)

    例如:String s1 = "abc";  // 引用对象 s1  ,值 abc 在常量池中。为什么呢?

        因为,基本数据类型存在栈(stack), String的对象实例存在堆(heap)。基础数据类型在栈里面直接分配内存 ,而引用数据则是通过堆里的对象来对栈中的内容进行引用。在 java 中 String 是个对象,是引用类型不是基本数据类型,判断是否相等,不能使用==,而使用equals方法。java中对 String 对象特殊对待,在堆区域给分成了两块,一块是 String constant pool(存储java字符串常量对象),另一块用于存储普通对象及字符串对象。另外,

    展开全文
  • 很少有文章做到将知识形成一个体系,于是需要翻阅很多资料,但这篇文章做到了!共34815字数。

    写在开头

    大家好,这里是 lionLoveVue,基础知识决定了编程思维,学如逆水行舟,不进则退。金三银四,为了面试也还在慢慢积累知识,Github上面可以直接查看所有前端知识点梳理, github传送门,觉得不错,点个Star★,好运连连,Offer终究鼠于你,持续更新中。另外,也可以关注微信公众号: 小狮子前端Vue,源码以及资料今后都会放在里面。
    一直想着成为一个up主,正值时间挺多的,4月份左右面试的面经我会制作视频去分享,赶快捧个场吧。 哔哩哔哩:一百个Chocolate

    展开全文
  • 『HTML5梦幻之旅』-滚动播放的幻灯片效果

    万次阅读 多人点赞 2013-10-20 14:46:13
    很久又没写博客了,一者是因为要上课,平时没有什么零碎的时间研究新东西;二者最近在开发一款塔防游戏,有整块的时间都拿去开发这个项目了。因此最近没有什么好的东西和大家分享。这周末看在游戏快完工的份上,抽出...

    很久又没写博客了,一者是因为要上课,平时没有什么零碎的时间研究新东西;二者最近在开发一款塔防游戏,有整块的时间都拿去开发这个项目了。因此最近没有什么好的东西和大家分享。这周末看在游戏快完工的份上,抽出了半天的时间研究了一下html5幻灯片制作,效果还不错,展示如下:

    首先是一张《真三国无双7》关云长的头像


    其次是《真三国无双7》貂蝉的头像


    切换时的效果


    怎么样?效果还是很不错,对吧~

    测试链接:http://www.cnblogs.com/yorhom/articles/html5_dream_trip_slideshowsample1.html

    接下来就来讲一讲制作过程。


    一,准备工作

    首先,需要下载html5开源引擎lufylegend.js,它是完全免费+开源的,可以下载下来学习一下。

    下载地址:http://lufylegend.com/lufylegend

    API文档:http://lufylegend.com/lufylegend/api


    二,设计原理

    要搞清楚本次开发的原理,我们不妨先画一张示意图:


    假设绿色方框内的区域为显示区域,那么,我们可以用到lufylegend中的mask的方法来将整个红色方框裁减为绿色方框的大小,这时,我们只能看到A区域,而B,C被遮盖住了。然后如果我们要显示B区域,我们可以直接将红框区域往左移动一格的距离,绿色区域不动,就能将B显示出来了,就像放映机一样。

    但是如果一直播放下去,那么我们播放到C区域时,红色区域再往左移动,那就会显示为空白。解决措施是又移回A区域,但是出现的问题又在于红色区域如果要移到A处,那应该右移动才能到达,但是我们要的是红色区域往左移动,因此就不能直接移回。那该怎么办呢?我想的解决措施就是把最前面的那个区域移动到最后的那个区域的右边。如果是刚才那种情况,那就让A接到C后方,这时候,A变成了最后一个。这时红色区域又往左移动时,取到的就是B,然后将B移动到A后面。

    当然,上面我们只提到了向左移动时的处理方式,其实向右也是一样的,只是取的是最后一个区域,然后把这个区域移动到第一个区域的前面罢了。

    光说原理只能算是纸上谈兵,接下来就来看看代码。


    三,代码讲解

    首先我们为了方便起见,建立一个LSlideshowSample1类,因为以后万一要拓展别的幻灯片效果,所以就在这个类的名字后面写上了"Sample1”,名字只是一种代号,我们主要看代码,构造器如下:

    function LSlideshowSample1(width,height,isLoop,loopData){
    	var self = this;
    	base(self,LSprite,[]);
    	
    	self._slideshowList = new Array();
    	self._slideshowIndex = 0;
    	self._currentIndex = self._slideshowIndex;
    	
    	self.rangeWidth = width;
    	self.rangeHeight = height;
    	self.isLoop = isLoop;
    	
    	self._toX = 0;
    	
    	self.nextChildList = new Array();
    	self.previousChildList = new Array();
    	
    	self.borderLayer = new LSprite();
    	self.borderLayer.graphics.drawRect(0,"",[0,0,width,height],true,"transparent");
    	
    	self.contentLayer = new LSprite();
    	self.contentLayer.mask = self.borderLayer;
    	self.addChild(self.contentLayer);
    	
    	if(self.isLoop == true){
    		self.loopData = loopData;
    		self.frameIndex = 0;
    		self.maxFrame = Math.floor(self.loopData.delay*1000/LGlobal.speed);
    		self.addEventListener(LEvent.ENTER_FRAME,self.loopPlay);
    	}
    }

    这个类有4个参数,意思分别是:[显示宽度,显示高度,是否自动播放,自动播放方式],如果第三个参数填false,就可以不用添第4个参数。

    接下来解释一下构造器中的代码:
    self._slideshowList原先是用来装每一帧的数据的,后来直接在LSprite的childList中取了,所以它没有什么用,直接忽略掉。

    接下来看_slideshowIndex属性,这个属性很怪异,主要用于取出要显示的帧,以后慢慢解释。_currentIndex是用来表示显示位置的,如果往左移动,表示显示位置增加1格,往右移动,表示显示位置减少1格。

    self.rangeWidth,self.rangeHeight,self.isLoop是将参数存放起来的属性,后面会用到的。

    然后是self._toX,这个表示要移动到的位置,和_currentIndex联用,以后也会提到,到时候慢慢讲。接下来是self.nextChildList和self.previousChildList属性,这两个属性和_slideshowIndex联用,_slideshowIndex主要负责作为这两个数组的取值下标。接下来,我们初始化显示层:

    self.borderLayer = new LSprite();
    self.borderLayer.graphics.drawRect(0,"",[0,0,width,height],true,"transparent");
    	
    self.contentLayer = new LSprite();
    self.contentLayer.mask = self.borderLayer;
    self.addChild(self.contentLayer);

    borderLayer等于上面我们讲解原理时的绿色区域,contentLayer代表红色区域。borderLayer要作为contentLayer的遮罩,因此在contentLayer中写道:

    self.contentLayer.mask = self.borderLayer;
    然后进入判断是否自动播放:

    if(self.isLoop == true){
    	self.loopData = loopData;
    	self.frameIndex = 0;
    	self.maxFrame = Math.floor(self.loopData.delay*1000/LGlobal.speed);
    	self.addEventListener(LEvent.ENTER_FRAME,self.loopPlay);
    }
    代码很简单,值得注意的是,我们实例化构造器时,第4个参数是一个json对象,如下格式:

    {delay:每帧停留时间(单位s),order:出现时滚动的样式(向右或者向左)}

    ok,构造器就讲完了,接下来看看设置帧的setFrame:

    LSlideshowSample1.prototype.setFrame = function(o){
    	var self = this;
    	var cl = self.contentLayer.childList;
    	o.x = self.contentLayer.childList.length * self.rangeWidth;
    	o.y = 0;
    	self.contentLayer.addChild(o);
    	
    	self._sortChild();
    };
    这个函数也有一个参数,是一个LDisplayObject对象。其中代码很简单,就是将加入的这一帧放到最后面。其中调用到一个_sortChild函数,这个函数十分重要,如下:

    LSlideshowSample1.prototype._sortChild = function(){
    	var self = this;
    	
    	self.nextChildList = new Array();
    	self.previousChildList = new Array();
    	var duplicate = new Array();
    	for(var i=0; i<self.contentLayer.childList.length; i++){
    		self.nextChildList.push(i);
    		duplicate.push(i);
    	}
    	self.nextChildList = self.nextChildList.sort();
    	duplicate.splice(0,1);
    	var sortedList = duplicate.sort(function(a,b){
    		return b - a;
    	});
    	self.previousChildList.push(0);
    	for(var key in sortedList){
    		self.previousChildList.push(sortedList[key]);
    	}
    };
    我们能看到,主要是对self.nextChildList和self.previousChildList两个属性进行操作。也许有朋友不理解为什么要将他们排续,这个就设计到显示时的原理,还是用刚才那张图来讲解:


    我们加入ABC后,A在contentLayer中的成员序号是0,B是1,C是2。在self.nextChildList我们将其加入先后顺序排列为[0,1,2],如果我们要显示B区域,那我们就要在contentLayer中取B对象,B对象的序号是1,因此我们要将显示位置往后调一格,于是self._slideshowIndex+=1; self._currentIndex += 1; 然后通过self._slideshowIndex的值来取出contentLayer的成员列表中对应的对象,正好self._slideshowIndex初始值是0,+1后变为1,取出的刚好是B对象。

    但是,我们的红色区域如果往右移动时,按理说要显示最后的那一个对象C,C的序号是2,但是self._slideshowIndex - 1 != 2,因此我们要在新建self.previousChildList这个属性来确保往右移动时,能正常地取出对象的序号,因此我们对self.previousChildList里的成员排列做了特殊处理,将其变成了[0,2,1]。但是还是不对啊,self._slideshowIndex - 1 = -1时,应该显示C对象,但是C对象序号在self.previousChildList中对应的下标是1不是-1,怎么办呢?其实很简单,取的时候用self._slideshowIndex的绝对值就ok啦。

    比如说我们F5一下界面,回到第一格的位置,然后,我们将红色部分向有移动一格,self._slideshowIndex -= 1; self._currentIndex -= 1; 现在按理说要显示C,这时我们在self.previousChildList中用self._slideshowIndex的绝对值取出要找的对象,self._slideshowIndex这时的值是-1,绝对值就是1,在[0,2,1]中对应的值正好是2,也就是C在contentLayer的成员列表中对应的序号,然后用这个序号取出contentLayer的成员列表中对应的成员,位置移动到响应的地方,然后将其通过LTweenLite缓动类缓缓地显示出来,达到想要的效果。

    有了上面的介绍,我们就来看看显示部分的代码next()和previous():

    LSlideshowSample1.prototype.next = function(){
    	var self = this;
    	
    	self._currentIndex += 1;
    	self._slideshowIndex += 1;
    	
    	if(self._slideshowIndex >= self.contentLayer.childList.length){
    		self._slideshowIndex = 0;
    	}
    	
    	if(self._slideshowIndex < 0){
    		var obj = self.contentLayer.getChildAt(self.previousChildList[Math.abs(self._slideshowIndex)]);
    	}else{
    		var obj = self.contentLayer.getChildAt(self.nextChildList[Math.abs(self._slideshowIndex)]);
    	}
    	obj.x = self.rangeWidth*self._currentIndex;
    			
    	self._toX = -(self._currentIndex*self.rangeWidth);
    	
    	var tweenObj = LTweenLite.to(self.contentLayer,1,{
    		x:self._toX
    	});
    };
    LSlideshowSample1.prototype.previous = function(){
    	var self = this;
    	
    	self._currentIndex -= 1;
    	self._slideshowIndex -= 1;
    	
    	if(self._slideshowIndex < -(self.contentLayer.childList.length-1)){
    		self._slideshowIndex = 0;
    	}
    	
    	if(self._slideshowIndex < 0){
    		var obj = self.contentLayer.getChildAt(self.previousChildList[Math.abs(self._slideshowIndex)]);
    	}else{
    		var obj = self.contentLayer.getChildAt(self.nextChildList[Math.abs(self._slideshowIndex)]);
    	}
    	obj.x = self.rangeWidth*self._currentIndex;
    		
    	self._toX = -(self._currentIndex*self.rangeWidth);
    	
    	var tweenObj = LTweenLite.to(self.contentLayer,1,{
    		x:self._toX
    	});
    };
    其中用到了LTweenLite,这个是Lufylegend中给的一个用于实现缓动的类,具体方法请移步API文档。

    还有一个getChildAt,这是lufylegend中LSprite类的一个成员函数,用于取出参数值在LSprite成员列表中相应的对象。

    这个类在设计时为了方便大家使用,还提供了showFrameAt函数,可以直接跳到播放某一帧:

    LSlideshowSample1.prototype.showFrameAt = function(index,order){
    	var self = this;
    	if(self._slideshowIndex < 0){
    		if(self.previousChildList[Math.abs(self._slideshowIndex)] == index)return;
    	}else{
    		if(self.nextChildList[Math.abs(self._slideshowIndex)] == index)return;
    	}
    	if(order == LSlideshow.LEFTWARD){
    		self._currentIndex -= 1;
    	}else if(order == LSlideshow.RIGHTWARD){
    		self._currentIndex += 1;
    	}else{
    		self._currentIndex += 1;
    	}
    	self._slideshowIndex = index;
    	
    	var obj = self.contentLayer.getChildAt(index);
    	obj.x = self.rangeWidth*self._currentIndex;
    	
    	self._toX = -(self._currentIndex*self.rangeWidth);
    	
    	var tweenObj = LTweenLite.to(self.contentLayer,1,{
    		x:self._toX
    	});
    };
    在上面也提到过自动播放这个功能,我们不妨温习一下调用自动播放的地方:

    if(self.isLoop == true){
    	self.loopData = loopData;
    	self.frameIndex = 0;
    	self.maxFrame = Math.floor(self.loopData.delay*1000/LGlobal.speed);
    	self.addEventListener(LEvent.ENTER_FRAME,self.loopPlay);
    }
    在时间轴事件ENTER_FRAME中,我们调用了loopPlay函数,这个函数的代码如下:

    LSlideshowSample1.prototype.loopPlay = function(self){
    	if(self.contentLayer.childList.length == 0)return;
    	if(self.frameIndex++ < self.maxFrame)return;
    	self.frameIndex = 0;
    	if(self.loopData.order == LSlideshow.RIGHTWARD){
    		self.next();
    	}else if(self.loopData.order == LSlideshow.LEFTWARD){
    		self.previous();
    	}else if(self.loopData.order == LSlideshow.RANDOM){
    		var index = Math.floor(Math.random()*(self.contentLayer.childList.length-1));
    		var order = Math.random() > 0.5 ? LSlideshow.LEFTWARD : LSlideshow.RIGHTWARD;
    		self.showFrameAt(index,order);
    	}
    };
    其中我们能看到了LSlideshow.RIGHTWAR,LSlideshow.LEFTWARD,LSlideshow.RANDOM这几种播放方式,它们分别是在LSlideshow静态类中得到定义的。如下:

    var LSlideshow = function(){throw "LSlideshow cannot be instantiated";};
    LSlideshow.type = "LSlideshow";
    LSlideshow.RIGHTWARD = "rightward";
    LSlideshow.LEFTWARD = "leftward";
    LSlideshow.RANDOM = "random";
    LSlideshow.RIGHTWAR代表向右滚动,LSlideshow.LEFTWARD代表向左滚动,LSlideshow.RANDOM代表随机滚动。

    最后还加了一个getFrameIndex的函数,是用于取当前帧的序号的:

    LSlideshowSample1.prototype.getFrameIndex = function(){
    	var self = this;
    	if(self._slideshowIndex < 0){
    		var v = self.previousChildList[Math.abs(self._slideshowIndex)];
    	}else{
    		var v = self.nextChildList[Math.abs(self._slideshowIndex)];
    	}
    	return v;
    };

    ok,幻灯片类就搞定了~只要搞清楚原理,其实还是挺简单的,不是吗?接下来是使用举例:

    <!DOCTYPE html>
    <html>
    <head>
    <meta charset="UTF-8">
    <title>幻灯片效果</title>
    </head>
    <body>
    <div id="mylegend">loading......</div>
    <script type="text/javascript" src="./lufylegend-1.8.0.min.js"></script>
    <script type="text/javascript" src="./lufylegend.ui-0.2.0.min.js"></script>
    <script type="text/javascript" src="./LSlideshow.js"></script>
    <script type="text/javascript" src="./LSlideshowSample1.js"></script>
    <script>
    init(50,"mylegend",980,609,main);
    var backLayer,slideshowObj;
    var loadData = [
    	{name:"caocao",path:"./images/cao_cao.jpg"},
    	{name:"diaochan",path:"./images/diao_chan.jpg"},
    	{name:"guanyu",path:"./images/guan_yu.jpg"},
    	{name:"zhaoyun",path:"./images/zhao_yun.jpg"},
    	{name:"sunshangxiang",path:"./images/sun_shang_xiang.jpg"}
    ];
    var datalist = {};
    function main(){
    	LStage.setDebug(true);
    	if(LGlobal.canTouch){
    		LGlobal.stageScale = LStageScaleMode.EXACT_FIT;
    		LSystem.screen(LStage.FULL_SCREEN);
    	}
    	
    	var loadingLayer = new LoadingSample5();
    	addChild(loadingLayer);
    	
    	LLoadManage.load(
    		loadData,
    		function(p){
    			loadingLayer.setProgress(p);
    		},
    		function(r){
    			datalist = r;
    			removeChild(loadingLayer);
    			initPage();
    		}
    	);
    }	
    function initPage(){
    	backLayer = new LSprite();
    	addChild(backLayer);
    	
    	slideshowObj = new LSlideshowSample1(971,609,true,{delay:3,order:LSlideshow.RANDOM});
    	backLayer.addChild(slideshowObj);
    	
    	slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["caocao"])));
    	slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["diaochan"])));
    	slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["guanyu"])));
    	slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["zhaoyun"])));
    	slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["sunshangxiang"])));
    	
    	addButton();
    }
    function addButton(){
    	var next_btn = new LButtonSample2(">",20,"黑体","white");
    	next_btn.backgroundCorl = "#008800";
    	next_btn.x = LStage.width-next_btn.getWidth()-40;
    	next_btn.y = (LStage.height-next_btn.getHeight())*0.5;
    	backLayer.addChild(next_btn);
    	next_btn.addEventListener(LMouseEvent.MOUSE_DOWN,function(){
    		slideshowObj.next();
    	});
    	
    	var last_btn = new LButtonSample2("<",20,"黑体","white");
    	last_btn.backgroundCorl = "#008800";
    	last_btn.x = 20;
    	last_btn.y = (LStage.height-last_btn.getHeight())*0.5;
    	backLayer.addChild(last_btn);
    	last_btn.addEventListener(LMouseEvent.MOUSE_DOWN,function(){
    		slideshowObj.previous();
    	});
    	
    	for(var i=0; i<5; i++){
    		var page_btn = new LButtonSample2(i+1,20,"黑体","white");
    		page_btn.backgroundCorl = "#008800";
    		page_btn.x = 50*i+600;
    		page_btn.y = LStage.height-page_btn.getHeight()-40;
    		backLayer.addChild(page_btn);
    		page_btn.addEventListener(LMouseEvent.MOUSE_DOWN,function(event,o){
    			var textObj = o.getChildAt(1).getChildAt(0);
    			var toIndex = parseInt(textObj.text)-1;
    			slideshowObj.showFrameAt(toIndex,LSlideshow.LEFTWARD);
    		});
    	}
    }
    function ondown(event){
    	if(event.offsetX <= 100){
    		slideshowObj.previous();
    	}else if(event.offsetX >= LStage.width-100){
    		slideshowObj.next();
    	}
    }
    </script> 
    </body>
    </html>

    运行代码后,就得到了本文最上面展示的效果。


    四,源代码

    上面讲解得有些乱,大家可以把源代码下载下来看看。

    最后,奉上源代码:http://files.cnblogs.com/yorhom/Slideshow_source.zip



    本章就到此为止,以上就是本篇所有内容,欢迎大家交流。

    ----------------------------------------------------------------

    欢迎大家转载我的文章。

    转载请注明:转自Yorhom's Game Box

    http://blog.csdn.net/yorhomwang

    欢迎继续关注我的博客

    展开全文
  • 1、材料入塔吉锅,开火. 不用加油 (为更适合亚洲人口味,或加少许油),食材堆成金字塔型,最好是蔬菜放在锅底,肉类放在上面  2、用大火(煤气炉6-7分钟)加热后,等它沸腾后,塔吉锅的盖子缝隙中有水溢出来,之后再...
  • 我的变量引用不到我说明的位置上的内容导致了错误; 解决方法:确认引用是否正确(找不找得到你要引用的东西)。 我要引用的图片放回了工程下面,解决了问题。
  • 成为编程大牛很简单,这些书看个八成就OK

    万次阅读 多人点赞 2015-05-28 21:38:23
    本文程序员所需掌握的关键知识总结为三大类19个关键概念,然后给出了掌握每个关键概念所需的入门书籍,必读书籍,以及延伸阅读。旨在成为最好最全面的程序员必读书单。 前言 Reading makes a full man;
  • 很多初学者对于JavaScript中的offset、scroll、client一直弄不明白,虽然网上到处都可以看一张图(图1),但这张图太... 既然我认为上图太多太乱,那么我就offset、scroll、client分开说,希望能让大家彻底弄清楚,
  • java学习写的第一个东西《飞机大战》

    万次阅读 多人点赞 2016-04-26 23:27:27
    java学习写的第一个东西《飞机大战》
  • 在开发的过程中,我们的一期项目开发完了,二期项目要开始了,但是我们的项目二期和一期差别很大,老大又让在SVN上保存一份原来的项目。以前没做过头大呀,上网找了半天没照出来。最后自己各种 各种尝试,终于在SVN...
  • Web Components 是个什么样的东西

    万次阅读 2016-08-31 11:01:33
    React 的components 等等,无一不是前端组件化的一种实现和探索,但是提上议程的 Web Components 标准是个怎样的东西,相关的一些框架或者类库,如 React,Angular2,甚至是 x-tag,polymer 现在实
  • CPU指令集是什么东西

    万次阅读 多人点赞 2017-02-16 09:37:09
    后面的A8-A11同样被送入寄存器选择电路,接通R2寄存器,然后R2就值送出来,到ALU的第二个数据接口上。 ALU开始运算,两个接口电路上的数据加起来,然后输出。 最后结果又被送R1。 基本上简单的运算计算机...
  • 最简单的视音频播放示例5:OpenGL播放RGB/YUV

    万次阅读 多人点赞 2014-10-27 12:35:41
    看人家OGL,哪里要这个东西? D3D有好多版本,要是显卡不支持就废柴一垛了。而OGL从几年前就一直没变过,所以大部分显卡都支持。 还有,我发现D3D的半透明功能有很大的问题!!就是两个半透明的物体前后顺序的问题...
  • 几个有趣的哲学命题,带你去了解哲学是什么东西

    千次阅读 多人点赞 2011-04-10 00:44:00
    几个有趣的哲学命题,带你去了解哲学是什么东西 由衷的建议你看这篇文章,并它看完,我想看过之后你绝对会有所收获的。 很偶然的机会,让我接触了哲学知识,理科生一般离这方面很远的,由于好奇吧...
  • 网上找的好东西

    万次阅读 2010-05-21 13:30:00
    fc one.txt two.txt > 3st.txt 对比二个文件并不同之处输出到3st.txt文件中,"> "和"> >" 是重定向命令 at id号 开启已注册的某个计划任务 at /delete 停止所有计划任务,用参数/yes则不需要确认就直接停止 ...
  • 请思考 小结: 三、Manacher原理 假设遍历到位置i,如何操作呢 四、代码及复杂度分析 前缀树 后缀树/后缀数组 后缀树:后缀树,就是一串字符的所有后缀保存并且压缩的字典树。 相对于字典树来说,后缀树并不是针对...
  • 网络爬虫是个什么东西(一)

    万次阅读 多人点赞 2017-04-08 17:01:19
     你输入网址请求的页面,其实是以html格式返回给你,也就是先给你右侧这一坨东西,再转化成左侧比较和谐的东西,你的浏览器可以解析出这个格式,并将其对应内容,到页面对应位置上,查看这个右侧文字与左侧文字...
  • 1小时1篇文学会python再做个飞机大战游戏

    万次阅读 多人点赞 2021-04-30 16:02:07
    作者简介 作者名:1_bit 简介:CSDN博客专家,2020年博客之星TOP5,蓝桥签约作者。15-16年曾在网上直播,带领一批程序小白走上程序员之...系列教程将会在流量降低时转为付费位置,流量多时将不会,各位抓紧时间学习哟~
  • 【Unity3D插件】视频播放插件AVPro Video的研究

    万次阅读 多人点赞 2018-06-15 09:53:03
    应用/数据文件夹 Android - 除非你手动构建APK,否则无法访问APK 3.3.4 相对于资源文件夹 数据文件夹是由Unity指定的: http://docs.unity3d.com/ScriptReferencelApplication-dataPath.html 视频文件直接到这个...
  • 能吃的东西还有多少!!!!

    千次阅读 2011-06-28 14:08:00
    能不吃的最好别吃,推荐看完吃鱼的话 最好吃本地产的 新鲜鱼常温下高密度运输的存活时间是8小时。跨地域运输的时间少说要...这个东西基本上是行业的潜规则,没办法的。所以最好吃本地的鱼,越近越好。外地的水产品还是
  • php最基础的东西,面试必备<2>

    万次阅读 2017-05-07 14:39:06
    字符串翻转过来,然后去第一个点之前的所有字符串,再翻转 strrev() strstr($str," ." ,true) 第三个参数取之前的字符串,用点连接即可 function fun2($str) { $str=strrev($str); $str=strstr($str,...
  • 漫画:什么是JVM的垃圾回收?

    千次阅读 多人点赞 2021-06-08 00:14:35
    需要注意的是:所谓的清除,并不需要真正地整个内存的字节进行清零操作,只需要空闲对象的起始结束地址记录下来入空闲列表里,表示这段内存是空闲的就行。 优点速度快,只需要做个标记就能知道哪一块需要被...
  • 超硬核!数据结构学霸笔记,考试面试吹牛就靠它

    万次阅读 多人点赞 2021-03-26 11:11:21
    主要内容: 1、函数传数组就是传了个指针,这个大家都知道,所以传的时候你写arr[],里面写多少,或者不写,都是没关系的,那你后面一定要一个变量来数组长度传进来。 2、还有就是,定义:int arr[5],你访问...
  • Android的定位策略

    千次阅读 2016-06-17 18:15:48
    获取用户的地理位置信息能够让你的应用程序显得更加智能,借此能够分发更合适的信息给用户。为android开发地理位置相关的应用程序,你可以利用GPS或者android的网络定位数据源来获取用户的地理位置。尽管GPS的定位...
  • 或许很多Winodws的程序员都不知道这个东西,因为那些Windows的IDE都为你做了这个工作,但我觉得要作一个好的和professional的程序员,makefile还是要懂。这就好像现在有这么多的HTML的编辑器,但如果你想成为一个...
  • 超硬核!小白读了这篇文章,就能在算法圈混了

    万次阅读 多人点赞 2021-03-29 10:21:58
    4.4一、分析枚举的效率 4.4二、初步优化 4.4三、Manacher原理 假设遍历到位置i,如何操作呢 4.4四、代码及复杂度分析 第一节 1.1bogo排序 Bogo排序(Bogo-sort),又被称为猴子排序,是一种恶搞排序算法。 将元素随机...
  • intellij idea在运行web项目时部署的位置(tomcat)

    万次阅读 多人点赞 2017-09-19 15:47:17
    在idea中运行tomcat,项目部署运行起来,然后我去tomcat目录下去看,找不到我部署的项目 那我的项目是怎么运行起来的? 说明一下:这里是使用tomcat 部署成war exploded 而不是war包。 war exploded模式是直接
  • C语言(调函数)

    千次阅读 多人点赞 2016-03-09 09:53:01
    调函数在程序开发中是一个非常重要的概念,所谓的调其实就是不同程序模块之间的接口和约定,是软件分层设计的基本方式。   拓展: 调(callback)是一种非常重要的机制,主要可以用来实现软件的分层...
  • 牛逼!Java 从入门到精通,超全汇总版

    万次阅读 多人点赞 2021-05-06 19:40:33
    面向过程与面向对象的区别,由“如何大象装进冰箱”来看: 一、面向过程 为了大象装进冰箱,需要3个过程。 思路: 1、冰箱门打开(得到打开门的冰箱)。 2、大象装进去(打开门后,得到里面装着大象的冰箱...
  • 对于链接器,一种普遍情景是由多个子程序来构建一个程序,并生成一个链接好的起始地址为0的输出程序,各个子程序通过重定位在大程序中确定位置。具体来说:利用第一遍扫描得到的数据,链接器将相似段合并,计算出...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 118,428
精华内容 47,371
关键字:

把东西放回原来位置