GWT实现平滑移动图片效果
在一些网站的首页上,顶部总会存在一些平滑移动的图片,一般用来投放广告或者业务介绍。多个图片只在一个区域展示,仅通过一些方法来不停的移动这个区域的图片来达到展示多个图片的目的。如果是普通的网页,使用Jquery是很好实现的,那么在GWT上该怎么实现呢?当然,GWT也存在“GQuery”,意思是在GWT上使用的Jquery。闲空的时候,我用纯GWT试了一下,发现一样能达到这样的效果。如下图显示效果:
实现这样的效果,其中有两个要点,第一,什么样的Panel支持平滑移动;第二,实现自动移动需要怎么做。翻阅了下资料,发现LayoutPanel支持上下、左右移动,并且其中它其中有一个animate()方法,支持动画效果。自动移动在Jquery中可以用setTimeOut实现,在GWT存在一个Timer类,功能类似于Jquery中的settimeout,它可以实现自动延时调用方法。
在可视化界面下的结构如下图:
几个按钮放在一个HorizontalPanel下,在AbsolutePanel下,我放置了两个控件,一个是ap,即是一个LayoutPanel,里面是一个水平Panel,根据LayoutPanel的特点,在移动的时候,就移动内部的水平Panel就行。水平panel里面我放了四张图片作为测试。
关于底下的dots,它也是一个水平Panel,里面放的是四个FocusPanel,对应那四个可点击的点。并给它们设置的样式。在此处,我使用的图片是140*100px的,所以内部的数值是调试过的。布局代码如下:
1 VerticalPanel rootPanel = new VerticalPanel(); 2 rootPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); 3 initWidget(rootPanel); 4 5 HorizontalPanel horizontalPanel = new HorizontalPanel(); 6 rootPanel.add(horizontalPanel); 7 albumWidth=510; 8 9 Button next = new Button("Next"); 10 horizontalPanel.add(next); 11 next.addClickHandler(new ClickHandler() { 12 13 @Override 14 public void onClick(ClickEvent event) { 15 offsetAlbum(); 16 } 17 }); 18 19 auto = new Button("Auto"); 20 horizontalPanel.add(auto); 21 auto.addClickHandler(new ClickHandler() { 22 23 @Override 24 public void onClick(ClickEvent event) { 25 auto.setEnabled(false); 26 timer = new Timer() { 27 28 @Override 29 public void run() { 30 offsetAlbum(); 31 } 32 }; 33 34 timer.scheduleRepeating(2500); 35 // timer.schedule(100); 36 } 37 }); 38 39 stop = new Button("Stop"); 40 stop.addClickHandler(new ClickHandler() { 41 @Override 42 public void onClick(ClickEvent event) { 43 auto.setEnabled(true); 44 timer.cancel(); 45 } 46 }); 47 48 horizontalPanel.add(stop); 49 50 AbsolutePanel absolutePanel = new AbsolutePanel(); 51 rootPanel.add(absolutePanel); 52 53 ap = new LayoutPanel(); 54 absolutePanel.setSize("520px", "130px"); 55 absolutePanel.add(ap); 56 ap.setStyleName("scrollStyle"); 57 rootPanel.setCellVerticalAlignment(ap, HasVerticalAlignment.ALIGN_MIDDLE); 58 rootPanel.setCellHorizontalAlignment(ap, HasHorizontalAlignment.ALIGN_CENTER); 59 ap.setSize("289px", "108px"); 60 album = new HorizontalPanel(); 61 album.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); 62 album.setVerticalAlignment(HasVerticalAlignment.ALIGN_MIDDLE); 63 ap.add(album); 64 65 album.setSpacing(3); 66 album.setSize("510px", "101px"); 67 68 69 70 Image i1 = new Image("images/01.png"); 71 Image i2 = new Image("images/02.png"); 72 Image i3 = new Image("images/03.png"); 73 Image i4 = new Image("images/04.png"); 74 album.add(i1); 75 album.add(i2); 76 album.add(i3); 77 album.add(i4); 78 79 dots = new HorizontalPanel(); 80 dots.setSpacing(3); 81 dots.setVerticalAlignment(HasVerticalAlignment.ALIGN_BOTTOM); 82 dots.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_CENTER); 83 absolutePanel.add(dots,235,110); 84 85 dot1 = new FocusPanel(); 86 dot1.addClickHandler(new ClickHandler() { 87 public void onClick(ClickEvent event) { 88 offset=0; 89 offsetAlbum(); 90 changeDotStyle(0); 91 } 92 }); 93 dot1.setStyleName("dotSelected"); 94 dots.add(dot1); 95 dot1.setSize("10px", "10px"); 96 97 dot2 = new FocusPanel(); 98 dot2.addClickHandler(new ClickHandler() { 99 public void onClick(ClickEvent event) { 100 offset = LENGTH*1; 101 offsetAlbum(); 102 changeDotStyle(1); 103 } 104 }); 105 dot2.setStyleName("dotUnSelected"); 106 dots.add(dot2); 107 dot2.setSize("10px", "10px"); 108 109 dot3 = new FocusPanel(); 110 dot3.addClickHandler(new ClickHandler() { 111 public void onClick(ClickEvent event) { 112 offset=2*LENGTH; 113 offsetAlbum(); 114 changeDotStyle(2); 115 } 116 }); 117 dot3.setStyleName("dotUnSelected"); 118 dots.add(dot3); 119 dot3.setSize("10px", "10px"); 120 121 dot4 = new FocusPanel(); 122 dot4.addClickHandler(new ClickHandler() { 123 public void onClick(ClickEvent event) { 124 offset=LENGTH*3; 125 offsetAlbum(); 126 offset-=143; 127 changeDotStyle(3); 128 } 129 }); 130 dot4.setStyleName("dotUnSelected"); 131 dots.add(dot4); 132 dot4.setSize("10px", "10px"); 133
上面的是布局,我在类定义了两个变量和一个常量,分别是private int offset=-143; private final static int LENGTH=-143; private int albumWidth = 0;
其中有三个方法,offsetAlbum(),用于移动album,代码如下:
1 public void offsetAlbum(){ 2 if((Math.abs(offset))>=albumWidth){ 3 offset=0; 4 } 5 6 ap.setWidgetLeftRight(album, offset, Unit.PX, 0,Unit.PX); 7 ap.animate(500); 8 int num =offset/LENGTH; 9 changeDotStyle(num); 10 offset-=143; 11 }
其中6、7行是设置Layout的移动方式和移动完成是动画时间。offset变量会随着每次移动增加位移量,当位移量超过album的宽度的时候,代码2、3行做出判断,将offset设为0,让其从头开始位移。
每次移动图片,下面的几个点也要跟着“移动”,实际是更改它们是显示样式。用一个方法来改变样式changeDotStyle():
1 public void changeDotStyle(int num){ 2 if(num==0){ 3 dot1.setStyleName("dotSelected"); 4 dot2.setStyleName("dotUnSelected"); 5 dot3.setStyleName("dotUnSelected"); 6 dot4.setStyleName("dotUnSelected"); 7 } 8 if(num==1){ 9 dot2.setStyleName("dotSelected"); 10 dot1.setStyleName("dotUnSelected"); 11 dot3.setStyleName("dotUnSelected"); 12 dot4.setStyleName("dotUnSelected"); 13 } 14 if(num==2){ 15 dot3.setStyleName("dotSelected"); 16 dot1.setStyleName("dotUnSelected"); 17 dot2.setStyleName("dotUnSelected"); 18 dot4.setStyleName("dotUnSelected"); 19 } 20 if(num==3){ 21 dot4.setStyleName("dotSelected"); 22 dot1.setStyleName("dotUnSelected"); 23 dot2.setStyleName("dotUnSelected"); 24 dot3.setStyleName("dotUnSelected"); 25 } 26 }
两个样式如下:
1 .dotSelected{ 2 background-color: #ff0000; 3 } 4 5 .dotUnSelected{ 6 background-color: #00ff00; 7 }
并且在每个点上面设置了点击事件,来配合调用offsetAblum和changeDotStyle方法,以此达到图片和点同步。
这里我只是做了一个简单的演示,为了说明GWT也可以实现此功能而已。所以此处使用的图片都是固定的,当然,也可以把图片地址放在一个集合中,通过集合传送,再来决定album的宽度设定多少,以及该显示多少个dot,那样会更灵活一些。