【问题标题】:Position popover on center of element将弹出框定位在元素的中心
【发布时间】:2015-07-31 10:50:20
【问题描述】:

我正在使用 SVG 构建资源地图。当用户单击单个元素时,我想在该元素的中心放置一个弹出框。然而,由于地图是通过 CSS 旋转的,技术like this one 一直不成功。

这是我的javascript:

Map.popup = function(e) {
    var rect = $(this);
    var offset = $(this).offset();

    var rectWidth = $(this).attr('width').replace(/[^-\d\.]/g, '');
    var rectHeight = $(this).attr('height').replace(/[^-\d\.]/g, '');

    var centerX = offset.left - rectWidth/2;
    var centerY = offset.top - rectHeight/2;

    $('.popup').css({
       'top' : centerY,
       'left' : centerX,
    });
}

这是标记:

    <div id="map">
    <svg width="1088px" height="1088px" xmlns="http://www.w3.org/2000/svg">
        <g transform="translate(288.0 32.0) rotate(45 256.0 512.0)">
            <rect id="0" x="8px" y="8px" width="51px" height="230px"></rect>
            <rect id="1" x="67px" y="8px" width="112px" height="38px"></rect>
            <rect id="2" x="187px" y="8px" width="144px" height="38px"></rect>
            <rect id="3" x="339px" y="8px" width="165px" height="38px"></rect>
            <rect id="4" x="67px" y="54px" width="112px" height="44px"></rect>
            <rect id="5" x="187px" y="54px" width="144px" height="75px"></rect>
            <rect id="6" x="339px" y="54px" width="35px" height="24px"></rect>
            <rect id="7" x="382px" y="54px" width="122px" height="51px"></rect>
            <rect id="8" x="339px" y="86px" width="35px" height="204px"></rect>
            <rect id="9" x="67px" y="106px" width="52px" height="132px"></rect>
            <rect id="10" x="127px" y="106px" width="52px" height="132px"></rect>
            <rect id="11" x="382px" y="113px" width="122px" height="78px" class=""></rect>
            <rect id="12" x="187px" y="137px" width="144px" height="70px"></rect>
            <rect id="13" x="382px" y="199px" width="122px" height="91px"></rect>
            <rect id="14" x="187px" y="215px" width="144px" height="65px"></rect>
            <rect id="15" x="8px" y="246px" width="171px" height="58px" class="selected"></rect>
            <rect id="16" x="187px" y="288px" width="144px" height="70px"></rect>
            <rect id="17" x="339px" y="298px" width="165px" height="60px" class=""></rect>
            <rect id="18" x="8px" y="312px" width="171px" height="50px"></rect>
            <rect id="19" x="187px" y="366px" width="144px" height="74px"></rect>
            <rect id="20" x="339px" y="366px" width="165px" height="28px"></rect>
            <rect id="21" x="8px" y="370px" width="171px" height="58px"></rect>
            <rect id="22" x="339px" y="402px" width="165px" height="38px"></rect>
            <rect id="23" x="8px" y="436px" width="171px" height="70px"></rect>
            <rect id="24" x="187px" y="448px" width="87px" height="58px"></rect>
            <rect id="25" x="282px" y="448px" width="49px" height="58px"></rect>
            <rect id="26" x="339px" y="448px" width="165px" height="58px"></rect>
            <rect id="27" x="8px" y="514px" width="171px" height="67px"></rect>
            <rect id="28" x="187px" y="514px" width="87px" height="67px"></rect>
            <rect id="29" x="282px" y="514px" width="49px" height="67px"></rect>
            <rect id="30" x="339px" y="514px" width="19px" height="44px"></rect>
            <rect id="31" x="366px" y="514px" width="46px" height="44px"></rect>
            <rect id="32" x="420px" y="514px" width="84px" height="22px"></rect>
            <rect id="33" x="420px" y="544px" width="84px" height="69px"></rect>
            <rect id="34" x="339px" y="566px" width="73px" height="53px"></rect>
            <rect id="35" x="8px" y="589px" width="171px" height="55px"></rect>
            <rect id="36" x="187px" y="589px" width="24px" height="36px"></rect>
            <rect id="37" x="219px" y="589px" width="112px" height="36px"></rect>
            <rect id="38" x="420px" y="621px" width="84px" height="71px"></rect>
            <rect id="39" x="339px" y="627px" width="73px" height="99px"></rect>
            <rect id="40" x="187px" y="633px" width="24px" height="105px"></rect>
            <rect id="41" x="219px" y="633px" width="112px" height="105px"></rect>
            <rect id="42" x="8px" y="652px" width="103px" height="36px"></rect>
            <rect id="43" x="119px" y="652px" width="60px" height="179px"></rect>
            <rect id="44" x="8px" y="696px" width="103px" height="49px"></rect>
            <rect id="45" x="420px" y="700px" width="84px" height="26px"></rect>
            <rect id="46" x="339px" y="734px" width="165px" height="46px"></rect>
            <rect id="47" x="187px" y="746px" width="24px" height="85px"></rect>
            <rect id="48" x="219px" y="746px" width="112px" height="34px"></rect>
            <rect id="49" x="8px" y="753px" width="103px" height="122px"></rect>
            <rect id="50" x="219px" y="788px" width="112px" height="43px"></rect>
            <rect id="51" x="339px" y="788px" width="165px" height="43px"></rect>
            <rect id="52" x="119px" y="839px" width="92px" height="177px"></rect>
            <rect id="53" x="219px" y="839px" width="46px" height="177px"></rect>
            <rect id="54" x="273px" y="839px" width="58px" height="53px"></rect>
            <rect id="55" x="339px" y="839px" width="58px" height="53px"></rect>
            <rect id="56" x="405px" y="839px" width="99px" height="53px"></rect>
            <rect id="57" x="8px" y="883px" width="103px" height="39px"></rect>
            <rect id="58" x="273px" y="900px" width="124px" height="116px"></rect>
            <rect id="59" x="405px" y="900px" width="19px" height="116px"></rect>
            <rect id="60" x="432px" y="900px" width="72px" height="116px"></rect>
            <rect id="61" x="8px" y="930px" width="103px" height="86px"></rect>
        </g>
    </svg>
</div>

您可以在此处查看地图的一个版本(及其不完美的定位):http://cityasacampus.org/map/

关于如何更好地瞄准每个中心的任何想法?

【问题讨论】:

  • 因为你使用了transform="translate(288.0 32.0) rotate(45 256.0 512.0),所以你真正的height 不是你height=XX 上的值。所以你需要计算你的真实身高,然后你就可以设置中心了:)

标签: javascript jquery html css


【解决方案1】:

正如@sjm 指出的那样,您可以使用getBoundingCliendRect() 来获取您的“真实”高度/宽度,但它不适用于$(this)

Map.popup = function(e) {    
  var rect          = $(this);
      offset        = $(this).offset(),
      canvas        = document.getElementById(rect.prop('id')),
      rectWidth     = canvas.getBoundingClientRect().width,
      rectHeight    = canvas.getBoundingClientRect().height,
      popoverWidth  = 250,
      popoverHeight = $('.popup').height(),
      centerX       = offset.left - popoverWidth + rectWidth/2,
      centerY       = offset.top + rectHeight/2;

  $('.popup').css({
     'top' : centerY,
     'left' : centerX,
  });
}

还有你的centerXcenterY 错了,我已经更正了。

干杯!

【讨论】:

  • 是的,很好的发现,$(this)[0].getBoundingClientRect() 可以代替,我已经更新了完整的答案
【解决方案2】:

首先需要使用 getBoundingClientRect() 来获取单击的 SVG 元素自旋转以来边界区域的实际宽度。然后,您需要将其中的一半添加到偏移量而不是减量,这将使您的弹出窗口左上角位于 SVG 单击元素的中心。

如果您还从 centerX 计算中取出 250px(弹出元素的宽度),弹出箭头点(即右上角)应该很好地居中于您点击的元素的中间。

新代码:

Map.popup = function(e) {
 var rect = $(this);
 var offset = $(this).offset();

 var rectWidth = $(this)[0].getBoundingClientRect().width;
 var rectHeight = $(this)[0].getBoundingClientRect().height;

 var centerX = offset.left + rectWidth/2 - 250;
 var centerY = offset.top + rectHeight/2;

 $('.popup').css({
   'top' : centerY,
   'left' : centerX,
 });
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-09
    • 2014-07-12
    • 2016-11-22
    • 1970-01-01
    • 2018-08-09
    • 2022-06-16
    • 2022-01-04
    • 1970-01-01
    相关资源
    最近更新 更多