• Openlayers2卷帘功能的实现


    概述:

    在WebGIS开发中,经常会有用户提需求,要实现卷帘功能,卷帘功能主要是实现两张图之间的对比。在前文中,讲到了openlayers3以及Arcgis for js中卷帘的实现,在本文讲述如何在openlayers2中实现卷帘功能。


    结果展示:



    实现代码:

    在此,扩展了一个名为Swipe的Control,Swipe的代码如下:

    /*
     *
     * @requires OpenLayers/Control.js
     */
    
    /* The following globals are for JSLint */
    /* jslint browser: true, vars: true */
    /* global OpenLayers, escape */
    
    /** api: (define)
     *  module =  OpenLayers.Control
     *  class = Swipe
     *  base_link = `OpenLayers.Control <http://dev.openlayers.org/apidocs/files/OpenLayers/Control-js.html>`_
     */
    
    /** api: example
     *  Sample code to add a swipe control
     *
     *  .. code-block:: javascript
     *
     *     var map = new new OpenLayers.Map("mymap");
     *     var Swipe = new OpenLayers.Control.Swipe({map: map});
     *     map.addControls([swipe]);
     *     Swipe.activate();
     *
     */
    
    /** api: constructor
     *  .. class:: Swipe(options)
     *
     *  :param options: ``Object`` options
     *
     *  :return:  ``OpenLayers.Control.Swipe``
     *
     *  Add a swipe control in the map
     */
    OpenLayers.Control.Swipe = OpenLayers.Class(OpenLayers.Control, {
    
        /** api: config[map]
         *  ``OpenLayers.Map``
         *  A `OpenLayers.Map <http://dev.openlayers.org/docs/files/OpenLayers/Map-js.html>`_ instance
         */
        map: null,
    
         32,
    
        /** api: config[swipeRatio]
         *  ``Number``
         *  A number between 0 and 1 defining the position of the swipe relative to the map (from right to left)
         */
        swipeRatio: null,
    
        swipeLayer: null,
    
        isTitleVisible: false,
    
        isDragging: false,
    
        mouseDragStart: null,
    
    
        /**
         * Property: divEvents
         * {<OpenLayers.Events>}
         */
        divEvents: null,
    
        initialize: function (options) {
            "use strict";
            OpenLayers.Control.prototype.initialize.apply(
                this,
                arguments
            );
            // Manage position of swipe
            if (this.map && this.map.swipeRatio) {
                // Swipe ratio can be set in the map (in order to manage permalink)
                this.setSwipeRatio(this.map.swipeRatio);
            } else {
                if (!this.swipeRatio) {
                    // Default swipe ratio is 0.5
                    this.setSwipeRatio(0.5);
                } else {
                    // Swipe ratio can be set to the control
                    this.setSwipeRatio(this.swipeRatio);
                }
            }
        },
    
        /**
         * Method: activate
         * Activates the control.
         *
         * Returns:
         * {Boolean} The control was effectively activated.
         */
        activate: function () {
            this.map.swipeActive = true;
            this.map.events.triggerEvent("changelayer", {
                layer: this.swipeLayer,
                property: "name"
            });
            OpenLayers.Control.prototype.activate.apply(this, arguments);
            this.map.events.on({
                "addlayer": this.handleAddLayer,
                "removelayer": this.handleRemoveLayer,
                "changelayer": this.handleChangeLayer,
                "updatesize": this.handleUpdateSize,
                "move": this.handleMove,
                "scope": this
            });
    
            if (this.isLayersInLayerSwitcher()) {
                this.div.style.display = 'block';
                this.viewBigArrow();
            }
            this.resize();
    
            return true;
        },
    
        /**
         * Method: deactivate
         * Deactivates the control.
         *
         * Returns:
         * {Boolean} The control was effectively deactivated.
         */
        deactivate: function () {
            this.map.swipeActive = false;
            this.map.events.triggerEvent("changelayer", {
                layer: this.swipeLayer,
                property: "name"
            });
            this.map.events.un({
                "addlayer": this.handleAddLayer,
                "removelayer": this.handleRemoveLayer,
                "changelayer": this.handleChangeLayer,
                "updatesize": this.handleUpdateSize,
                "move": this.handleMove,
                "scope": this
            });
            this.hideBigArrow();
            this.hideLayerTitle();
            this.div.style.display = 'none';
            if (this.swipeLayer) {
                if (this.swipeLayer.layers) {
                    for (var i = this.swipeLayer.layers.length - 1; i >= 0; i--) {
                        var layer = this.swipeLayer.layers[i];
                        if (layer.div) {
                            layer.div.style.clip = 'auto';
                        }
                    }
                } else {
                    this.swipeLayer.div.style.clip = 'auto';
                }
                this.swipeLayer = null;
            }
    
            return OpenLayers.Control.prototype.deactivate.apply(
                this, arguments
            );
        },
    
        /**
         * Method: destroy
         * Destroy control.
         */
        destroy: function() {
            this.map.events.un({
                "addlayer": this.handleAddLayer,
                "removelayer": this.handleRemoveLayer,
                "changelayer": this.handleChangeLayer,
                "updatesize": this.handleUpdateSize,
                "scope": this
            });
            OpenLayers.Control.prototype.destroy.apply(this, arguments);
        },
    
        /**
         * Method: draw
         * Initialize control.
         *
         * Returns:
         * {DOMElement} A reference to the DIV DOMElement containing the control
         */
        draw: function() {
            OpenLayers.Control.prototype.draw.apply(this, arguments);
    
            this.elementLayer = document.createElement("div");
            this.div.appendChild(this.elementLayer);
            OpenLayers.Element.addClass(
                this.elementLayer,
                'olControlSwipeLayerHide'
            );
            this.elementLayerSpan = document.createElement("span");
            this.div.appendChild(this.elementLayerSpan);
            OpenLayers.Element.addClass(
                this.elementLayerSpan,
                'olControlSwipeLayerSpan'
            );
            this.elementLeft = document.createElement("div");
            this.div.appendChild(this.elementLeft);
            OpenLayers.Element.addClass(
                this.elementLeft,
                'olControlArrowLeft'
            );
    
            this.elementRight = document.createElement("div");
            this.div.appendChild(this.elementRight);
            OpenLayers.Element.addClass(
                this.elementRight,
                'olControlArrowRight'
            );
    
            OpenLayers.Control.prototype.draw.apply(this, arguments);
    
            this.divEvents = new OpenLayers.Events(this, this.div, null, true, {includeXY: true});
    
            this.divEvents.on({
                "touchstart": this.divDown,
                "touchmove": this.divDrag,
                "touchend": this.divUp,
                "mousedown": this.divDown,
                "mousemove": this.divDrag,
                "mouseup": this.divUp,
                "mouseover": this.divMouseOver,
                "mouseout": this.divMouseOut,
                scope: this
            });
    
            return this.div;
        },
    
        /*
         * Method: divMouseOver
         * event listener for onmouseover event
         *
         * Parameters:
         * evt - {<OpenLayers.Event>}
         */
        divMouseOver: function(ev) {
            OpenLayers.Element.addClass(
                this.div,
                'olControlSwipeHover'
            );
            //this.viewLayerTitle();
        },
    
        hideBigArrow: function() {
            if (!this.isDragging) {
                this.elementLeft.style.display = "none";
                this.elementRight.style.display = "none";
            }
        },
    
        viewBigArrow: function() {
            if (!this.isDragging) {
                this.elementLeft.style.display = "block";
                this.elementRight.style.display = "block";
            }
        },
    
        /*
         * Method: divMouseOut
         * event listener for onmouseout event
         *
         * Parameters:
         * evt - {<OpenLayers.Event>}
         */
        divMouseOut: function(ev) {
            OpenLayers.Element.removeClass(
                this.div,
                'olControlSwipeHover'
            );
            this.hideLayerTitle();
            this.viewBigArrow();
        },
    
        /**
         * Method: passEventToDiv
         * This function is used to pass events that happen on the map,
         * through to the div, which then does its moving thing.
         *
         * Parameters:
         * evt - {<OpenLayers.Event>}
         */
        passEventToDiv:function(evt) {
            this.divEvents.handleBrowserEvent(evt);
        },
    
        /*
         * Method: divDown
         * event listener for clicks on the div
         *
         * Parameters:
         * evt - {<OpenLayers.Event>}
         */
        divDown:function(evt) {
            if (!OpenLayers.Event.isLeftClick(evt) && !OpenLayers.Event.isSingleTouch(evt)) {
                return;
            }
            this.map.events.on({
                "touchmove": this.passEventToDiv,
                "mousemove": this.passEventToDiv,
                "mouseup": this.passEventToDiv,
                scope: this
            });
            this.mouseDragStart = evt.xy.clone();
            OpenLayers.Event.stop(evt);
            //this.viewLayerTitle();
            this.hideBigArrow();
            this.isDragging = true;
            return false;
        },
    
        /*
         * Method: divDrag
         * This is what happens when a click has occurred, and the client is
         * dragging.  Here we must ensure that the div doesn't go beyond the
         * bottom/top of the zoombar div, as well as moving the div to its new
         * visual location
         *
         * Parameters:
         * evt - {<OpenLayers.Event>}
         */
        divDrag:function(evt) {
            if (this.mouseDragStart && this.isDragging) {
                var deltaX = this.mouseDragStart.x - evt.xy.x;
                var left = parseInt(this.div.style.left, 10);
                if ((left - deltaX) >= 0 &&
                    (left - deltaX) <= (this.map.size.w - this.width)) {
                    var delta = 0;
                    if (OpenLayers.BROWSER_NAME === "msie" || OpenLayers.BROWSER_NAME === "safari") {
                        delta = -1;
                    }
                    this.setSwipeRatio((left - deltaX) / (this.map.size.w - this.width + delta));
                    this.moveTo(this.computePosition());
                    this.clipFirstLayer();
                    this.mouseDragStart = evt.xy.clone();
                }
                OpenLayers.Event.stop(evt);
            }
            return false;
        },
    
        /*
         * Method: divUp
         * Perform cleanup when a mouseup event is received
         *
         * Parameters:
         * evt - {<OpenLayers.Event>}
         */
        divUp:function(evt) {
            this.map.events.un({
                "touchmove": this.passEventToDiv,
                "mousemove": this.passEventToDiv,
                "mouseup": this.passEventToDiv,
                scope: this
            });
            if (!OpenLayers.Event.isLeftClick(evt) && evt.type !== "touchend") {
                return;
            }
            if (this.mouseDragStart) {
                this.mouseDragStart = null;
            }
            this.isDragging = false;
            this.viewBigArrow();
            if (evt.type === "touchend") {
                this.hideLayerTitle();
            }
            OpenLayers.Event.stop(evt);
            return false;
        },
    
        /*
         * Method: clipFirstLayer
         * Clip the first layer present in the layer switcher
         */
        clipFirstLayer: function() {
            var newFirstLayer = this.getFirstLayerInLayerSwitcher();
            if (this.swipeLayer) {
                if (newFirstLayer.id !== this.swipeLayer.id) {
                    if (this.swipeLayer.layers) {
                        for (var i = this.swipeLayer.layers.length - 1; i >= 0; i--) {
                            var layer = this.swipeLayer.layers[i];
                            if (layer.div) {
                                layer.div.style.clip = 'auto';
                            }
                        }
                    } else {
                        this.swipeLayer.div.style.clip = 'auto';
                    }
                }
            }
    
            if (newFirstLayer) {
                var width = this.map.getCurrentSize().w;
                var height = this.map.getCurrentSize().h;
                // slider position in pixels
                var s = parseInt(width * this.getSwipeRatio() * ((this.map.getCurrentSize().w - this.width) / this.map.getCurrentSize().w), 10);
                // cliping rectangle
                var top = -this.map.layerContainerOriginPx.y;
                var bottom = top + height;
                var left = -this.map.layerContainerOriginPx.x;
                var right = left + s + Math.ceil((this.width - 1) / 2);
                //Syntax for clip "rect(top,right,bottom,left)"
                var clip = "rect(" + top + "px " + right + "px " + bottom + "px " + left + "px)";
                this.swipeLayer = newFirstLayer;
                if (this.swipeLayer.layers) {
                    for (var i = this.swipeLayer.layers.length - 1; i >= 0; i--) {
                        var layer = this.swipeLayer.layers[i];
                        if (layer.div) {
                            layer.div.style.clip = clip;
                        }
                    }
                } else {
                    this.swipeLayer.div.style.clip = clip;
                }
            }
    
        },
    
        /*
         * Method: handleAddLayer
         * Triggered when a new layer is added
         *
         * Parameters:
         * object - {<OpenLayers.Event>}
         */
        handleAddLayer: function (object) {
            if (this.isLayersInLayerSwitcher()) {
                this.div.style.display = 'block';
                this.moveTo(this.computePosition());
                this.clipFirstLayer();
            } else {
                this.div.style.display = 'none';
                this.swipeLayer = null;
            }
        },
    
        viewLayerTitle: function() {
            if (!this.isTitleVisible && !this.isDragging) {
                if (this.swipeLayer) {
                    var content = "     " + this.swipeLayer.name;
                    this.elementLayer.innerHTML = content;
                    this.elementLayerSpan.innerHTML = content;
                    OpenLayers.Element.addClass(
                        this.elementLayer,
                        'olControlSwipeLayerView'
                    );
                    OpenLayers.Element.removeClass(
                        this.elementLayer,
                        'olControlSwipeLayerHide'
                    );
                    var width = parseInt(this.elementLayerSpan.offsetWidth) + 5;
                    this.elementLayer.style.width = width + "px";
                    this.elementLayer.style.marginLeft = "-" + width + "px";
    
                }
    
            }
            this.isTitleVisible = true;
        },
    
        hideLayerTitle: function() {
            if (!this.isDragging) {
                this.elementLayer.innerHTML = '';
                this.isTitleVisible = false;
                OpenLayers.Element.addClass(
                    this.elementLayer,
                    'olControlSwipeLayerHide'
                );
                OpenLayers.Element.removeClass(
                    this.elementLayer,
                    'olControlSwipeLayerView'
                );
            }
        },
    
        /*
         * Method: handleRemoveLayer
         * Triggered when a new layer is removed
         *
         * Parameters:
         * object - {<OpenLayers.Event>}
         */
        handleRemoveLayer: function (object) {
            if (this.isLayersInLayerSwitcher()) {
                this.div.style.display = 'block';
                this.moveTo(this.computePosition());
                this.clipFirstLayer();
            } else {
                this.div.style.display = 'none';
                this.swipeLayer = null;
            }
        },
    
        /*
         * Method: handleChangeLayer
         * Triggered when the layer order is changed
         *
         * Parameters:
         * object - {<OpenLayers.Event>}
         */
        handleChangeLayer: function (object) {
            if (object.property === 'order') {
                if (this.isLayersInLayerSwitcher()) {
                    this.div.style.display = 'block';
                    this.moveTo(this.computePosition());
                    this.clipFirstLayer();
                } else {
                    this.div.style.display = 'none';
                    this.swipeLayer = null;
                }
            }
        },
    
        /*
         * Method: handleUpdateSize
         * Triggered when the map size changed. In this case the swipe control is updated accordingly.
         *
         * Parameters:
         * object - {<OpenLayers.Event>}
         */
        handleUpdateSize: function (object) {
            //we have to delay this on Android devices
            if (navigator.userAgent.toLowerCase().indexOf("android") > 0) {
                var self = this;
                setTimeout(function() {
                    self.resize();
                }, 10);
            } else {
                this.resize();
            }
        },
    
        /*
         * Method: handleMove
         * Triggered when the map is moved. In this case, the clip ares has to be updated
         *
         * Parameters:
         * object - {<OpenLayers.Event>}
         */
        handleMove: function (object) {
            this.clipFirstLayer();
        },
    
        /*
         * Method: resize
         * Resize the swipe and update the first layer clipping
         */
        resize: function() {
            this.div.style.height = this.map.getCurrentSize().h + 'px';
            this.div.style.width = this.width + 'px';
            this.moveTo(this.computePosition());
            this.clipFirstLayer();
            var topPosition = (this.map.getCurrentSize().h / 2) - 32;
            this.elementLeft.style.marginTop = topPosition + 'px';
            this.elementRight.style.marginTop = topPosition + 'px';
        },
    
        /*
         * Method: computePosition
         * Recompute the position of the swipe acording  to swipeRatio and the size of the map
         */
        computePosition: function() {
            var y = 0;
            var x = this.getSwipeRatio() * (this.map.size.w - this.width);
            return new OpenLayers.Pixel(x, y);
        },
    
        /*
         * Method: getFirstLayerInLayerSwitcher
         * Get the first layer visible in the layer switcher
         */
        getFirstLayerInLayerSwitcher: function() {
            for (var i = this.map.layers.length - 1; i >= 0; i--) {
                var layer = this.map.layers[i];
                if (layer.displayInLayerSwitcher) {
                    return layer;
                }
            }
            return null;
        },
    
        /*
         * Method: isLayersInLayerSwitcher
         * Check the presence of a layer in the layer switcher
         */
        isLayersInLayerSwitcher: function() {
            for (var i = 0, len = this.map.layers.length; i < len; i++) {
                var layer = this.map.layers[i];
                if (layer.displayInLayerSwitcher) {
                    return true;
                }
            }
            return false;
        },
    
        setSwipeRatio: function(ratio) {
            this.map.events.triggerEvent("changelayer", {
                layer: this.swipeLayer,
                property: "name"
            });
            this.map.swipeRatio = ratio;
            this.map.swipeActive = this.active;
        },
    
        getSwipeRatio: function() {
            return this.map.swipeRatio;
        },
    
        /*
         * Method: updateRatio
         * Update the swipeRatio and update the swipe control accordingly
         */
        updateRatio: function(ratio) {
            this.setSwipeRatio(ratio);
            if (this.isLayersInLayerSwitcher()) {
                this.div.style.display = 'block';
                this.moveTo(this.computePosition());
                this.clipFirstLayer();
            } else {
                this.div.style.display = 'none';
                this.swipeLayer = null;
            }
        },
    
        CLASS_NAME: "OpenLayers.Control.Swipe"
    });


    这个js文件里面引用到了一些样式,样式文件的内容如下:
    .olControlSwipe {
        background:url("../img/line.png") repeat;
        display: none;
    }
    
    .olControlSwipeHover {
        cursor: w-resize;
    }
    
    .olControlSwipeLayerView {
        background-color: white;
        height: 16px;
         220px;
        margin-top: 23px;
        margin-left: -230px;
        display: block;
        font-size: 11px;
        font-family: Tahoma, Arial;
        font-weight: 700;
        padding-top: 2px;
        background-image: url("../img/bigarrow_left.png");
        background-repeat: no-repeat;
        position: absolute;
    }
    
    .olControlSwipeLayerSpan {
        visibility: hidden;
        font-size: 11px;
        font-family: Tahoma, Arial;
        font-weight: 700;
        white-space: pre;
        position: absolute;
    }
    
    .olControlSwipeLayerHide {
        display: none;
    }
    
    .olControlArrowLeft {
         16px;
        height: 32px;
        margin-left: -1px;
        background-image: url("../img/bigarrow_left.png");
        background-repeat: no-repeat;
        position: absolute;
    }
    .olControlArrowRight {
         16px;
        height: 32px;
        margin-left: 19px;
        background-image: url("../img/bigarrow_right.png");
        background-repeat: no-repeat;
        position: absolute;
    }

    最后,调用展示,代用代码如下:

    			$("#swipebutton").on("click",function(){
    				if(flag){
    					swipe.deactivate();
    					flag=false;
    				}
    				else{
    					swipe.activate();
    					flag=true;
    				}
    			});


    Arcgis for js基础教程




  • 相关阅读:
    原来四五年没有写过什么东西了
    Spark难道比oracle性能还差?百万级数据测试性能
    程序人常去的网站(转)
    Android中关于dip和px以及转换的总结
    padding与margin的区别
    Python装饰器探究——装饰器参数
    Python 装饰器执行顺序迷思
    Python CSV模块简介
    理解线程3 c语言示例线程基本操作
    Python 外部函数调用库ctypes简介
  • 原文地址:https://www.cnblogs.com/lzugis/p/6539789.html
Copyright © 2020-2023  润新知