模仿Google Maps的MapViewer

下面要写的东西是一个使用GWT编写的在有限区域内通过拖动查看整个地图的简单实现。

 一些细节:

  1. 为什么能拖?

    com.google.gwt.user.client.ui.MouseListener 通过实现这个接口,可以实现UI对象对鼠标的Enter,Down,Leave,Move,Up动作的支持。

    com.google.gwt.user.client.ui.FocusPanel 并不是每个UI对象都能够实现MouseListener接口的,可以通过添加到FocusPanel来实现。

  2. 怎么才能显示地图的局部,或者说怎么把其他部分藏起来?

通过样式:

java 代码
  1. DOM.setStyleAttribute(viewPortArea.getElement(), "overflow""hidden");   
  2.   
  3. DOM.setStyleAttribute(viewPortArea.getElement(), "position","relative");  

设置显示区域的"overflow"属性为"hidden"及"position"属性为"relative",图片可以实现局部显示显示框内。

代码:

java 代码
  1. package cn.gov.imwb.client;   
  2.   
  3. import com.google.gwt.user.client.DOM;   
  4. import com.google.gwt.user.client.Event;   
  5. import com.google.gwt.user.client.ui.AbsolutePanel;   
  6. import com.google.gwt.user.client.ui.Composite;   
  7. import com.google.gwt.user.client.ui.FocusPanel;   
  8. import com.google.gwt.user.client.ui.Image;   
  9. import com.google.gwt.user.client.ui.MouseListener;   
  10. import com.google.gwt.user.client.ui.Widget;   
  11.   
  12. /**  
  13.  * @author sheva.wen  
  14.  *  
  15.  */  
  16. public class MapViewerPanel extends Composite {   
  17.     public int areaHeight;   
  18.   
  19.     public int areaWidth;   
  20.   
  21.     public int centerLeft;   
  22.   
  23.     public int centerTop;   
  24.   
  25.     public int imageHeight;   
  26.   
  27.     public String imageUrl;   
  28.   
  29.     public int imageWidth;   
  30.   
  31.     public int maxLeft;   
  32.   
  33.     public int maxTop;   
  34.   
  35.     public int minLeft;   
  36.   
  37.     public int minTop;   
  38.   
  39.     private Image image;   
  40.   
  41.     private FocusPanel mouseListenerContainer;   
  42.   
  43.     public double showPositionLeftRatio;   
  44.   
  45.     public double showPositionTopRatio;   
  46.   
  47.     private int startLeft;   
  48.   
  49.     private int startTop;   
  50.   
  51.     private int startX;   
  52.   
  53.     private int startY;   
  54.   
  55.     private int state = 0;//用于判断当前用户的鼠标动作   
  56.   
  57.     private AbsolutePanel viewArea;   
  58.   
  59.     private AbsolutePanel viewPortArea = new AbsolutePanel();   
  60.   
  61.     /**  
  62.      *   
  63.      * @param areaWidth 显示区域的宽  
  64.      * @param areaHeight 显示区域的高  
  65.      * @param imageUrl 地图的链接  
  66.      * @param imageWidth 地图的宽  
  67.      * @param imageHeight 地图的高  
  68.      * @param showPositionLeftRatio 地图初始显示的位置 最左占宽度的比例  
  69.      * @param showPositionTopRatio 地图初始显示的位置 最上占宽度的比例  
  70.      */  
  71.     public MapViewerPanel(int areaWidth, int areaHeight, String imageUrl,   
  72.             int imageWidth, int imageHeight, double showPositionLeftRatio,   
  73.             double showPositionTopRatio) {   
  74.         mouseListenerContainer = new FocusPanel(viewPortArea);   
  75.         viewArea = new AbsolutePanel();   
  76.         /**  
  77.          * 将地图(图片)上的默认浏览器行为除去。  
  78.          */  
  79.         image = new Image(){   
  80.             /**  
  81.              * 这个部分必须紧跟在实例化过程的后面,不然就不起作用,没有在官方文档里找到原因。  
  82.              */  
  83.                  public void onBrowserEvent (Event event)   
  84.                  {   
  85.                      DOM.eventPreventDefault(event);   
  86.                      super.onBrowserEvent(event);   
  87.                  }   
  88.   
  89.         };   
  90.         viewArea.add(image);   
  91.         image.setPixelSize(imageWidth, imageHeight);   
  92.         image.setUrl(imageUrl);   
  93.   
  94.         viewPortArea.setPixelSize(areaWidth, areaHeight);   
  95.         viewPortArea.addStyleName("viewportViewer");   
  96.         DOM.setStyleAttribute(viewPortArea.getElement(), "overflow""hidden");   
  97.   
  98.         DOM.setStyleAttribute(viewPortArea.getElement(), "position",   
  99.                         "relative");   
  100.         initWidget(mouseListenerContainer);   
  101.            
  102.            
  103.            
  104.         this.showPositionLeftRatio = showPositionLeftRatio;   
  105.         this.showPositionTopRatio = showPositionTopRatio;   
  106.         this.areaWidth = areaWidth;   
  107.         this.areaHeight = areaHeight;   
  108.         this.imageUrl = imageUrl;   
  109.         this.imageWidth = imageWidth;   
  110.         this.imageHeight = imageHeight;   
  111.            
  112.         /**  
  113.          * 设置图片可被拖放的极限,防止图片被拖出边界  
  114.          */  
  115.            
  116.         maxLeft = imageWidth - areaWidth;   
  117.         maxTop = imageHeight - areaHeight;   
  118.         minLeft = -(imageWidth - areaWidth);   
  119.         minTop = -(imageHeight - areaHeight);   
  120.            
  121.         /**  
  122.          * 地图初始应该在的位置  
  123.          */  
  124.         centerLeft = (int) ((areaWidth - imageWidth) * showPositionLeftRatio);   
  125.         centerTop = (int) ((areaHeight - imageHeight) * showPositionTopRatio);   
  126.            
  127.         viewPortArea.add(viewArea, centerLeft, centerTop);   
  128.         /**  
  129.          * 鼠标拖放的行为  
  130.          */  
  131.         MouseListener listener = new MouseListener(){   
  132.   
  133.             public void onMouseDown(Widget sender, int x, int y) {   
  134.                 state = 1;   
  135.                 startX = x;   
  136.                 startY = y;   
  137.                 startLeft = viewPortArea.getWidgetLeft(viewArea);   
  138.                 startTop = viewPortArea.getWidgetTop(viewArea);   
  139.                    
  140.             }   
  141.   
  142.             public void onMouseEnter(Widget sender) {   
  143.                    
  144.             }   
  145.   
  146.             public void onMouseLeave(Widget sender) {   
  147.                 state = 0;   
  148.                 DOM.setStyleAttribute(mouseListenerContainer.getElement(), "cursor""default");   
  149.             }   
  150.   
  151.             public void onMouseMove(Widget sender, int x, int y) {   
  152.                 if(state == 1){   
  153.                     DOM.setStyleAttribute(mouseListenerContainer.getElement(), "cursor""move");   
  154.                     if(viewPortArea.getWidgetLeft(viewArea) >= minLeft   
  155.                             && viewPortArea.getWidgetLeft(viewArea) <= maxLeft   
  156.                             && viewPortArea.getWidgetTop(viewArea) >= minTop   
  157.                             && viewPortArea.getWidgetTop(viewArea) <= maxTop){   
  158.                         viewPortArea.setWidgetPosition(viewArea,startLeft + (x - startX), startTop + (y - startY));   
  159.                     }   
  160.                 }   
  161.             }   
  162.   
  163.             public void onMouseUp(Widget sender, int x, int y) {   
  164.                 // TODO 缺报当拖放结束时,地图还在显示框内   
  165.                 if(viewPortArea.getWidgetLeft(viewArea) < minLeft){   
  166.                     viewPortArea.setWidgetPosition(viewArea, minLeft, viewPortArea.getWidgetTop(viewArea));   
  167.                 }   
  168.                 if(viewPortArea.getWidgetTop(viewArea) < minTop){   
  169.                     viewPortArea.setWidgetPosition(viewArea, viewPortArea.getWidgetLeft(viewArea), minTop);   
  170.                 }   
  171.                 if(viewPortArea.getWidgetLeft(viewArea) > 0){   
  172.                     viewPortArea.setWidgetPosition(viewArea, 0, viewPortArea.getWidgetTop(viewArea));   
  173.                 }   
  174.                 if(viewPortArea.getWidgetTop(viewArea) > 0){   
  175.                     viewPortArea.setWidgetPosition(viewArea, viewPortArea.getWidgetLeft(viewArea), 0);   
  176.                 }   
  177.                 state = 0;   
  178.                 DOM.setStyleAttribute(mouseListenerContainer.getElement(), "cursor""default");   
  179.             }   
  180.                
  181.         };   
  182.         mouseListenerContainer.addMouseListener(listener);   
  183.   
  184.     }   
  185.   
  186. }   

代码很容易理解,这只是一个很简易的实现,至少还有以下需要完善:

  1. 地图分块载入
  2. 支持鼠标滚轮的缩放
  3. “鹰眼”功能。

感兴趣的跟进一下:)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值