zoukankan      html  css  js  c++  java
  • 【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

  • 相关阅读:
    iaure学习网站
    linux下环境搭建比较
    微信分享jsdk接口
    微信接口开发遇到的问题
    Centos7.6部署k8s(v1.14.2)集群
    k8s简介
    nginx配置ssl证书
    kafka zookeeper介绍
    mysql数据库的备份与还原
    centos7 部署jumpserver
  • 原文地址:https://www.cnblogs.com/shitao/p/2695135.html
Copyright © 2011-2022 走看看