模仿Google Maps的MapViewer

<div class="quote_title">sheva.wen 写道</div><div class="quote_div"><p>下面要写的东西是一个使用GWT编写的在有限区域内通过拖动查看整个地图的简单实现。</p><p> <strong>一些细节:</strong></p><ol style="margin-right: 0px"><li>为什么能拖? <p><span style="font-family: Arial"><a href="http://code.google.com/webtoolkit/documentation/com.google.gwt.user.client.ui.MouseListener.html">com.google.gwt.user.client.ui.MouseListener</a> 通过实现这个接口,可以实现UI对象对鼠标的Enter,Down,Leave,Move,Up动作的支持。</span></p><p><span style="font-family: Arial"><span style="font-family: Arial"><a href="http://code.google.com/webtoolkit/documentation/com.google.gwt.user.client.ui.FocusPanel.html">com.google.gwt.user.client.ui.FocusPanel</a> 并不是每个UI对象都能够实现MouseListener接口的,可以通过添加到FocusPanel来实现。</span></span></p><span style="font-family: Arial"></span></li><li>怎么才能显示地图的局部,或者说怎么把其他部分藏起来? </li></ol><blockquote dir="ltr" style="margin-right: 0px"><p dir="ltr">通过样式:</p><div class="code_title">java 代码</div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span>DOM.setStyleAttribute(viewPortArea.getElement(), </span><span class="string">"overflow"</span><span>, </span><span class="string">"hidden"</span><span>);   </span></span> </li><li><span>  </span> </li><li class="alt"><span>DOM.setStyleAttribute(viewPortArea.getElement(), </span><span class="string">"position"</span><span>,</span><span class="string">"relative"</span><span>);  </span> </li></ol></div><p>设置显示区域的"overflow"属性为"hidden"及"position"属性为"relative",图片可以实现局部显示显示框内。</p></blockquote><p dir="ltr"><strong>代码:</strong></p><blockquote dir="ltr" style="margin-right: 0px"><div class="code_title">java 代码</div><div class="dp-highlighter"><ol class="dp-j"><li class="alt"><span><span class="keyword">package</span><span> cn.gov.imwb.client;   </span></span> </li><li><span>  </span> </li><li class="alt"><span class="keyword">import</span><span> com.google.gwt.user.client.DOM;   </span> </li><li><span class="keyword">import</span><span> com.google.gwt.user.client.Event;   </span> </li><li class="alt"><span class="keyword">import</span><span> com.google.gwt.user.client.ui.AbsolutePanel;   </span> </li><li><span class="keyword">import</span><span> com.google.gwt.user.client.ui.Composite;   </span> </li><li class="alt"><span class="keyword">import</span><span> com.google.gwt.user.client.ui.FocusPanel;   </span> </li><li><span class="keyword">import</span><span> com.google.gwt.user.client.ui.Image;   </span> </li><li class="alt"><span class="keyword">import</span><span> com.google.gwt.user.client.ui.MouseListener;   </span> </li><li><span class="keyword">import</span><span> com.google.gwt.user.client.ui.Widget;   </span> </li><li class="alt"><span>  </span> </li><li><span class="comment">/** </span>  </li><li class="alt"><span><span class="comment"> * @author sheva.wen </span> </span> </li><li><span><span class="comment"> * </span> </span> </li><li class="alt"><span><span class="comment"> */</span><span>  </span></span> </li><li><span class="keyword">public</span><span> </span><span class="keyword">class</span><span> MapViewerPanel </span><span class="keyword">extends</span><span> Composite {   </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> areaHeight;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> areaWidth;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> centerLeft;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> centerTop;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> imageHeight;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> String imageUrl;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> imageWidth;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> maxLeft;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> maxTop;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> minLeft;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">int</span><span> minTop;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">private</span><span> Image image;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">private</span><span> FocusPanel mouseListenerContainer;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">double</span><span> showPositionLeftRatio;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> </span><span class="keyword">double</span><span> showPositionTopRatio;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">private</span><span> </span><span class="keyword">int</span><span> startLeft;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">private</span><span> </span><span class="keyword">int</span><span> startTop;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">private</span><span> </span><span class="keyword">int</span><span> startX;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">private</span><span> </span><span class="keyword">int</span><span> startY;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">private</span><span> </span><span class="keyword">int</span><span> state = </span><span class="number">0</span><span>;</span><span class="comment">//用于判断当前用户的鼠标动作 </span><span>  </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">private</span><span> AbsolutePanel viewArea;   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="keyword">private</span><span> AbsolutePanel viewPortArea = </span><span class="keyword">new</span><span> AbsolutePanel();   </span> </li><li><span>  </span> </li><li class="alt"><span>    </span><span class="comment">/** </span>  </li><li><span><span class="comment">     *  </span> </span> </li><li class="alt"><span><span class="comment">     * @param areaWidth 显示区域的宽 </span> </span> </li><li><span><span class="comment">     * @param areaHeight 显示区域的高 </span> </span> </li><li class="alt"><span><span class="comment">     * @param imageUrl 地图的链接 </span> </span> </li><li><span><span class="comment">     * @param imageWidth 地图的宽 </span> </span> </li><li class="alt"><span><span class="comment">     * @param imageHeight 地图的高 </span> </span> </li><li><span><span class="comment">     * @param showPositionLeftRatio 地图初始显示的位置 最左占宽度的比例 </span> </span> </li><li class="alt"><span><span class="comment">     * @param showPositionTopRatio 地图初始显示的位置 最上占宽度的比例 </span> </span> </li><li><span><span class="comment">     */</span><span>  </span></span> </li><li class="alt"><span>    </span><span class="keyword">public</span><span> MapViewerPanel(</span><span class="keyword">int</span><span> areaWidth, </span><span class="keyword">int</span><span> areaHeight, String imageUrl,   </span> </li><li><span>            </span><span class="keyword">int</span><span> imageWidth, </span><span class="keyword">int</span><span> imageHeight, </span><span class="keyword">double</span><span> showPositionLeftRatio,   </span> </li><li class="alt"><span>            </span><span class="keyword">double</span><span> showPositionTopRatio) {   </span> </li><li><span>        mouseListenerContainer = </span><span class="keyword">new</span><span> FocusPanel(viewPortArea);   </span> </li><li class="alt"><span>        viewArea = </span><span class="keyword">new</span><span> AbsolutePanel();   </span> </li><li><span>        </span><span class="comment">/** </span>  </li><li class="alt"><span><span class="comment">         * 将地图(图片)上的默认浏览器行为除去。 </span> </span> </li><li><span><span class="comment">         */</span><span>  </span></span> </li><li class="alt"><span>        image = </span><span class="keyword">new</span><span> Image(){   </span> </li><li><span>            </span><span class="comment">/** </span>  </li><li class="alt"><span><span class="comment">             * 这个部分必须紧跟在实例化过程的后面,不然就不起作用,没有在官方文档里找到原因。 </span> </span> </li><li><span><span class="comment">             */</span><span>  </span></span> </li><li class="alt"><span>                 </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> onBrowserEvent (Event event)   </span> </li><li><span>                 {   </span> </li><li class="alt"><span>                     DOM.eventPreventDefault(event);   </span> </li><li><span>                     </span><span class="keyword">super</span><span>.onBrowserEvent(event);   </span> </li><li class="alt"><span>                 }   </span> </li><li><span>  </span> </li><li class="alt"><span>        };   </span> </li><li><span>        viewArea.add(image);   </span> </li><li class="alt"><span>        image.setPixelSize(imageWidth, imageHeight);   </span> </li><li><span>        image.setUrl(imageUrl);   </span> </li><li class="alt"><span>  </span> </li><li><span>        viewPortArea.setPixelSize(areaWidth, areaHeight);   </span> </li><li class="alt"><span>        viewPortArea.addStyleName(</span><span class="string">"viewportViewer"</span><span>);   </span> </li><li><span>        DOM.setStyleAttribute(viewPortArea.getElement(), </span><span class="string">"overflow"</span><span>, </span><span class="string">"hidden"</span><span>);   </span> </li><li class="alt"><span>  </span> </li><li><span>        DOM.setStyleAttribute(viewPortArea.getElement(), </span><span class="string">"position"</span><span>,   </span> </li><li class="alt"><span>                        </span><span class="string">"relative"</span><span>);   </span> </li><li><span>        initWidget(mouseListenerContainer);   </span> </li><li class="alt"><span>           </span> </li><li><span>           </span> </li><li class="alt"><span>           </span> </li><li><span>        </span><span class="keyword">this</span><span>.showPositionLeftRatio = showPositionLeftRatio;   </span> </li><li class="alt"><span>        </span><span class="keyword">this</span><span>.showPositionTopRatio = showPositionTopRatio;   </span> </li><li><span>        </span><span class="keyword">this</span><span>.areaWidth = areaWidth;   </span> </li><li class="alt"><span>        </span><span class="keyword">this</span><span>.areaHeight = areaHeight;   </span> </li><li><span>        </span><span class="keyword">this</span><span>.imageUrl = imageUrl;   </span> </li><li class="alt"><span>        </span><span class="keyword">this</span><span>.imageWidth = imageWidth;   </span> </li><li><span>        </span><span class="keyword">this</span><span>.imageHeight = imageHeight;   </span> </li><li class="alt"><span>           </span> </li><li><span>        </span><span class="comment">/** </span>  </li><li class="alt"><span><span class="comment">         * 设置图片可被拖放的极限,防止图片被拖出边界 </span> </span> </li><li><span><span class="comment">         */</span><span>  </span></span> </li><li class="alt"><span>           </span> </li><li><span>        maxLeft = imageWidth - areaWidth;   </span> </li><li class="alt"><span>        maxTop = imageHeight - areaHeight;   </span> </li><li><span>        minLeft = -(imageWidth - areaWidth);   </span> </li><li class="alt"><span>        minTop = -(imageHeight - areaHeight);   </span> </li><li><span>           </span> </li><li class="alt"><span>        </span><span class="comment">/** </span>  </li><li><span><span class="comment">         * 地图初始应该在的位置 </span> </span> </li><li class="alt"><span><span class="comment">         */</span><span>  </span></span> </li><li><span>        centerLeft = (</span><span class="keyword">int</span><span>) ((areaWidth - imageWidth) * showPositionLeftRatio);   </span> </li><li class="alt"><span>        centerTop = (</span><span class="keyword">int</span><span>) ((areaHeight - imageHeight) * showPositionTopRatio);   </span> </li><li><span>           </span> </li><li class="alt"><span>        viewPortArea.add(viewArea, centerLeft, centerTop);   </span> </li><li><span>        </span><span class="comment">/** </span>  </li><li class="alt"><span><span class="comment">         * 鼠标拖放的行为 </span> </span> </li><li><span><span class="comment">         */</span><span>  </span></span> </li><li class="alt"><span>        MouseListener listener = </span><span class="keyword">new</span><span> MouseListener(){   </span> </li><li><span>  </span> </li><li class="alt"><span>            </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> onMouseDown(Widget sender, </span><span class="keyword">int</span><span> x, </span><span class="keyword">int</span><span> y) {   </span> </li><li><span>                state = </span><span class="number">1</span><span>;   </span> </li><li class="alt"><span>                startX = x;   </span> </li><li><span>                startY = y;   </span> </li><li class="alt"><span>                startLeft = viewPortArea.getWidgetLeft(viewArea);   </span> </li><li><span>                startTop = viewPortArea.getWidgetTop(viewArea);   </span> </li><li class="alt"><span>                   </span> </li><li><span>            }   </span> </li><li class="alt"><span>  </span> </li><li><span>            </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> onMouseEnter(Widget sender) {   </span> </li><li class="alt"><span>                   </span> </li><li><span>            }   </span> </li><li class="alt"><span>  </span> </li><li><span>            </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> onMouseLeave(Widget sender) {   </span> </li><li class="alt"><span>                state = </span><span class="number">0</span><span>;   </span> </li><li><span>                DOM.setStyleAttribute(mouseListenerContainer.getElement(), </span><span class="string">"cursor"</span><span>, </span><span class="string">"default"</span><span>);   </span> </li><li class="alt"><span>            }   </span> </li><li><span>  </span> </li><li class="alt"><span>            </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> onMouseMove(Widget sender, </span><span class="keyword">int</span><span> x, </span><span class="keyword">int</span><span> y) {   </span> </li><li><span>                </span><span class="keyword">if</span><span>(state == </span><span class="number">1</span><span>){   </span> </li><li class="alt"><span>                    DOM.setStyleAttribute(mouseListenerContainer.getElement(), </span><span class="string">"cursor"</span><span>, </span><span class="string">"move"</span><span>);   </span> </li><li><span>                    </span><span class="keyword">if</span><span>(viewPortArea.getWidgetLeft(viewArea) >= minLeft   </span> </li><li class="alt"><span>                            && viewPortArea.getWidgetLeft(viewArea) <= maxLeft   </span> </li><li><span>                            && viewPortArea.getWidgetTop(viewArea) >= minTop   </span> </li><li class="alt"><span>                            && viewPortArea.getWidgetTop(viewArea) <= maxTop){   </span> </li><li><span>                        viewPortArea.setWidgetPosition(viewArea,startLeft + (x - startX), startTop + (y - startY));   </span> </li><li class="alt"><span>                    }   </span> </li><li><span>                }   </span> </li><li class="alt"><span>            }   </span> </li><li><span>  </span> </li><li class="alt"><span>            </span><span class="keyword">public</span><span> </span><span class="keyword">void</span><span> onMouseUp(Widget sender, </span><span class="keyword">int</span><span> x, </span><span class="keyword">int</span><span> y) {   </span> </li><li><span>                </span><span class="comment">// TODO 缺报当拖放结束时,地图还在显示框内 </span><span>  </span> </li><li class="alt"><span>                </span><span class="keyword">if</span><span>(viewPortArea.getWidgetLeft(viewArea) < minLeft){   </span> </li><li><span>                    viewPortArea.setWidgetPosition(viewArea, minLeft, viewPortArea.getWidgetTop(viewArea));   </span> </li><li class="alt"><span>                }   </span> </li><li><span>                </span><span class="keyword">if</span><span>(viewPortArea.getWidgetTop(viewArea) < minTop){   </span> </li><li class="alt"><span>                    viewPortArea.setWidgetPosition(viewArea, viewPortArea.getWidgetLeft(viewArea), minTop);   </span> </li><li><span>                }   </span> </li><li class="alt"><span>                </span><span class="keyword">if</span><span>(viewPortArea.getWidgetLeft(viewArea) > </span><span class="number">0</span><span>){   </span> </li><li><span>                    viewPortArea.setWidgetPosition(viewArea, </span><span class="number">0</span><span>, viewPortArea.getWidgetTop(viewArea));   </span> </li><li class="alt"><span>                }   </span> </li><li><span>                </span><span class="keyword">if</span><span>(viewPortArea.getWidgetTop(viewArea) > </span><span class="number">0</span><span>){   </span> </li><li class="alt"><span>                    viewPortArea.setWidgetPosition(viewArea, viewPortArea.getWidgetLeft(viewArea), </span><span class="number">0</span><span>);   </span> </li><li><span>                }   </span> </li><li class="alt"><span>                state = </span><span class="number">0</span><span>;   </span> </li><li><span>                DOM.setStyleAttribute(mouseListenerContainer.getElement(), </span><span class="string">"cursor"</span><span>, </span><span class="string">"default"</span><span>);   </span> </li><li class="alt"><span>            }   </span> </li><li><span>               </span> </li><li class="alt"><span>        };   </span> </li><li><span>        mouseListenerContainer.addMouseListener(listener);   </span> </li><li class="alt"><span>  </span> </li><li><span>    }   </span> </li><li class="alt"><span>  </span> </li><li><span>}   </span> </li></ol></div><p>代码很容易理解,这只是一个很简易的实现,至少还有以下需要完善:</p><ol><li>地图分块载入 </li><li>支持鼠标滚轮的缩放 </li><li>“鹰眼”功能。 </li></ol><p>感兴趣的跟进一下:)</p></blockquote></div>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值