【openlayers】CSS3樣式的Popups


 一直覺得ol自帶的Popup的樣式太難看,后來也換了一套自己的皮膚,感覺展示效果還是不怎么地。

看到leafet上的樣式挺不錯的:

就自己搞個了個,popup主體加個圓角和陰影:

  border-radius: 1.2em 1.2em 1.2em 1.2em;
  box-shadow: 0 3px 14px rgba(0, 0, 0, 0.35);

popup的那個小箭頭:矩形旋轉45度,使用transform: rotate(45deg)來實現。另外針對不同的瀏覽器還需要添加不同的hack,例如Opera的-o-transform、Firefox的-moz-transform。

具體效果如下:

 實現的過程如下:

  1. 我在OpenLayers.Popup.Framed基礎上另寫了一個類如下:
    View Code
    OpenLayers.Popup.CSSFramedCloud = OpenLayers.Class(OpenLayers.Popup.Framed, {
        autoSize: true,
        panMapIfOutOfView: true,
        fixedRelativePosition: false,
    
      positionBlocks: {
            "tl": {
                'offset': new OpenLayers.Pixel(44, -6),
                'padding': new OpenLayers.Bounds(5, 14, 5, 5),
                'blocks': [
                    { 
                        className: 'olwidgetPopupStemTL',
                        size: new OpenLayers.Size(20, 20),
                        anchor: new OpenLayers.Bounds(null, 4, 32, null),
                        position: new OpenLayers.Pixel(0, -28)
                    }
                ]
            },
            "tr": {
                'offset': new OpenLayers.Pixel(-44, -6),
                'padding': new OpenLayers.Bounds(5, 14, 5, 5),
                'blocks': [
                    { 
                        className: "olwidgetPopupStemTR",
                        size: new OpenLayers.Size(20, 20),
                        anchor: new OpenLayers.Bounds(32, 4, null, null),
                        position: new OpenLayers.Pixel(0, -28)
                    }
                ]
            },
            "bl": {
                'offset': new OpenLayers.Pixel(44, 6),
                'padding': new OpenLayers.Bounds(5, 5, 5, 14),
                'blocks': [
                    { 
                        className: "olwidgetPopupStemBL",
                        size: new OpenLayers.Size(20,20),
                        anchor: new OpenLayers.Bounds(null, null, 32, 4),
                        position: new OpenLayers.Pixel(0, 0)
                    }
                ]
            },
            "br": {
                'offset': new OpenLayers.Pixel(-44, 6),
                'padding': new OpenLayers.Bounds(5, 5, 5, 14),
                'blocks': [
                    { 
                        className: "olwidgetPopupStemBR",
                        size: new OpenLayers.Size(20, 20),
                        anchor: new OpenLayers.Bounds(32, null, null, 4),
                        position: new OpenLayers.Pixel(0, 0)
                    }
                ]
            }
        },
    
        initialize: function(id, lonlat, contentSize, contentHTML, anchor, closeBox,
                        closeBoxCallback, relativePosition, separator) {
            if (relativePosition && relativePosition != 'auto') {
                this.fixedRelativePosition = true;
                this.relativePosition = relativePosition;
            }
            if (separator === undefined) {
                this.separator = ' of ';
            } else {
                this.separator = separator;
            }
    
            this.olwidgetCloseBox = closeBox;
            this.olwidgetCloseBoxCallback = closeBoxCallback;
            this.page = 0;
            OpenLayers.Popup.Framed.prototype.initialize.apply(this, [id, lonlat,
                contentSize, contentHTML, anchor, false, null]);
        },
    
        /*
         * 構造popup內部容器。
         */
        setContentHTML: function(contentHTML) {
            if (contentHTML !== null && contentHTML !== undefined) {
                this.contentHTML = contentHTML;
            }
      
            if (this.contentDiv !== null)  {
                var popup = this; 
    
                // 清空舊數據
                this.contentDiv.innerHTML = "";
    
                // 創建內部容器
                var containerDiv = document.createElement("div");
                containerDiv.innerHTML = this.contentHTML;
                containerDiv.className = 'olwidgetPopupContent';
                this.contentDiv.appendChild(containerDiv);
    
                // 創建關閉按鈕
                if (this.olwidgetCloseBox) {
                    var closeDiv = document.createElement("div");
                    closeDiv.className = "olwidgetPopupCloseBox";
                    closeDiv.innerHTML = "close";
                    closeDiv.onclick = function(event) {
                        popup.olwidgetCloseBoxCallback.apply(popup, arguments);
                    };
                    this.contentDiv.appendChild(closeDiv);
                }
                if (this.autoSize) {
                    this.registerImageListeners();
                    this.updateSize();
                }
            }
        },
    
        /*
         * 重寫createBlocks:使用CSS樣式而不是特定的img圖片
         */
        createBlocks: function() {
            this.blocks = [];
    
            // since all positions contain the same number of blocks, we can
            // just pick the first position and use its blocks array to create
            // our blocks array
            var firstPosition = null;
            for(var key in this.positionBlocks) {
                firstPosition = key;
                break;
            }
    
            var position = this.positionBlocks[firstPosition];
            for (var i = 0; i < position.blocks.length; i++) {
    
                var block = {};
                this.blocks.push(block);
    
                var divId = this.id + '_FrameDecorationDiv_' + i;
                block.div = OpenLayers.Util.createDiv(divId,
                    null, null, null, "absolute", null, "hidden", null
                );
                this.groupDiv.appendChild(block.div);
            }
        },
        /*
         * 重寫updateBlocks
         */
        updateBlocks: function() {
            if (!this.blocks) {
                this.createBlocks();
            }
            if (this.size && this.relativePosition) {
                var position = this.positionBlocks[this.relativePosition];
                for (var i = 0; i < position.blocks.length; i++) {
    
                    var positionBlock = position.blocks[i];
                    var block = this.blocks[i];
    
                    // adjust sizes
                    var l = positionBlock.anchor.left;
                    var b = positionBlock.anchor.bottom;
                    var r = positionBlock.anchor.right;
                    var t = positionBlock.anchor.top;
    
                    // note that we use the isNaN() test here because if the
                    // size object is initialized with a "auto" parameter, the
                    // size constructor calls parseFloat() on the string,
                    // which will turn it into NaN
                    //
                    var w = (isNaN(positionBlock.size.w)) ? this.size.w - (r + l)
                                                          : positionBlock.size.w;
    
                    var h = (isNaN(positionBlock.size.h)) ? this.size.h - (b + t)
                                                          : positionBlock.size.h;
    
                    block.div.style.width = (w < 0 ? 0 : w) + 'px';
                    block.div.style.height = (h < 0 ? 0 : h) + 'px';
    
                    block.div.style.left = (l !== null) ? l + 'px' : '';
                    block.div.style.bottom = (b !== null) ? b + 'px' : '';
                    block.div.style.right = (r !== null) ? r + 'px' : '';
                    block.div.style.top = (t !== null) ? t + 'px' : '';
    
                    block.div.className = positionBlock.className;
                }
    
                this.contentDiv.style.left = this.padding.left + "px";
                this.contentDiv.style.top = this.padding.top + "px";
            }
        },
        updateSize: function() {
            
                return OpenLayers.Popup.prototype.updateSize.apply(this, arguments);
        
        },
    
        CLASS_NAME: "OpenLayers.Popup.CSSFramedCloud"
    });

     

  2. 然后是css樣式:
    .olPopupContent {
        overflow: visible !important;
        padding: 0 !important;
    }
    .olPopup {
        z-index: 1005 !important;
    }
    .olwidgetPopupContent {
        background: none repeat scroll 0 0 #FFFFFF;
        border-radius: 1.2em 1.2em 1.2em 1.2em;
        box-shadow: 0 3px 14px rgba(0, 0, 0, 0.35);
        overflow: auto;
        padding: 10px 8px 8px;
    }
    .olwidgetPopupCloseBox {
        background: url("img/popup_icons.png") no-repeat scroll -80px 0 #FFFFFF;
        cursor: pointer;
        height: 0;
        overflow: hidden;
        padding-top: 16px;
        position: absolute;
        right: 10px;
        top: 10px;
        width: 16px;
    }
    .olwidgetPopupCloseBox:hover {
        background-position: -64px 0;
    }
    .olwidgetPopupStemTL,.olwidgetPopupStemTR {
        -moz-transform: rotate(45deg);
        -webkit-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
        -o-transform: rotate(45deg);
        transform: rotate(45deg);
        background: none repeat scroll 0 0 #FFFFFF;
        z-index: 1;
    }
    
    .olwidgetPopupStemBL,.olwidgetPopupStemBR {
        -moz-transform: rotate(45deg);
        -webkit-transform: rotate(45deg);
        -ms-transform: rotate(45deg);
        -o-transform: rotate(45deg);
        transform: rotate(45deg);
        background: none repeat scroll 0 0 #FFFFFF;
        z-index: 1;
    }

     

    使用方法和OL自帶的一樣:
     function onFeatureSelect(feature) {
                selectedFeature = feature;
                popup = new OpenLayers.Popup.CSSFramedCloud("chicken", 
                                         feature.geometry.getBounds().getCenterLonLat(),
                                         null,
                                         "<div style='font-size:.8em'>Feature: " + feature.id +"<br>Area: " + feature.geometry.getArea()+"</div>",
                                         null, true, onPopupClose);
                feature.popup = popup;
                map.addPopup(popup);
            }

     源碼:https://github.com/shitao1988/OL_CSSPopups

 在線示例:http://www.fenglgis.com/github/OL_CSSPopups/select-feature-openpopup.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM