将div定位在可变高度图像的特定区域上

问题描述 投票:8回答:4

我正在努力将div放在一个可变高度的图像上,我想知道如何最好地处理这种情况。例如,在下面的示例中,我试图将红色方块放在图像中注册的商标符号上:Fiddle

我的HTML / CSS看起来像这样:

<img src="http://cisloandthomas.com/wp-content/uploads/2015/12/Shrunken-Banner-Wide-Ends-1140x200.jpg" class="background">
<div class="overlay"></div>

.background {
  height: 100%;
  position: absolute;
  margin-top: -61px;
}

.overlay {
  position: absolute;
  height: 20px;
  width: 20px;
  background: red;
}

我用以下JS将红色div放在图像上:

var resizeOverlay = function() {
  var windowHeight = $(window).height();

  var left = windowHeight * 1.07;
  var bottom = (windowHeight * .63) + 61;

  $(".overlay").css({
    "left": left,
    "bottom": bottom
  });
};

$(document).ready(resizeOverlay);
$(window).resize(resizeOverlay);

结果并不理想,因为我只是构建两个线性模型来计算x和y偏移量。其他人如何处理这项任务?

javascript html css position css-position
4个回答
8
投票

This can be achieved with CSS and a few changes to your markup

示例中的图像相对于视口的高度进行缩放 - 高度始终为100%,浏览器动态计算宽度以保持纵横比。

要定位叠加层,需要应用相同的缩放比例。为此,可以添加一个容器,该容器适合视口高度并缩放到图像的宽度,这将允许叠加层相对于它定位并按比例缩放到图像。

需要进行以下修改:

  • .background.overlay包装在一个容器中(在本例中称为#container
  • 使用以下属性设置#containerheight: 100vh; - 这将使它填满整个视口高度 margin-top: -61px; - 从你的榜样中结束 position: relative; - 确保.overlay与此容器相关 width: 570vh; - 这将确保容器以与图像相同的速率缩放。这是通过查找现有图像的纵横比来计算的 - 1140 x 200是57:10的纵横比,因此200(px)* 5.7 = 1140(px)转换为100(vh)* 5.7 = 570(vh)
  • 使用以下属性设置.backgroundheight: 100%; - 为了确保它以与您的示例类似的方式调整大小,它将填充视口的整个高度。宽度将相对于此缩放
  • 使用以下属性设置.overlaybackground: red; - 从你的榜样中结束 height: 6vh; - 当图像相对于视口高度缩放时,这将确保叠加以相同的速率缩放 left: 18.3%; - 将叠加层定位在注册符号上方的指定区域 position: absolute; - 相对于容器定位叠加层 top: 29%; - 将叠加层定位在注册符号上方的指定区域 width: 6vh; - 当图像相对于视口高度缩放时,这将确保叠加以相同的速率缩放

$(".overlay").click(function() {
  alert("Clicked")
});
#container {
  height: 100vh;
  margin-top: -61px;
  position: relative;
  width: 570vh;
}
.background {
  height: 100%;
}
.overlay {
  background: red;
  height: 6vh;
  left: 18.3%;
  position: absolute;
  top: 29%;
  width: 6vh;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="container">
  <img alt="" class="background" src="http://cisloandthomas.com/wp-content/uploads/2015/12/Shrunken-Banner-Wide-Ends-1140x200.jpg">
  <div class="overlay"></div>
</div>

JS Fiddle - 更改结果窗口高度,叠加层应相应地重新定位。


2
投票

昨天回家我发现这个问题其实很简单。

图像的比例是恒定的,叠加层有两个值:x位置和y位置。 x位置只是图像宽度的一部分,y位置是图像高度的一部分。

因此,可以使用两个浮点值{0,1}来表示叠加层的位置:一个用于叠加在x轴上的位置,另一个用于y轴。然后将这些值乘以图像的宽度和高度(分别),以找到叠加层的适当x,y位置。

为了使叠加层始终位于感兴趣的点上(即{0:max-image-x},{0:max-image-y}),只需要从x中减去叠加div的宽度的一半,y位置计算。


1
投票

这是fiddle,我在发布你问题的结尾后意识到......无论如何,我在这里留下了答案,因为至少它是精确定位的。我认为没有比你已经尝试过的更好的方法了。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
    <style type="text/css">
        html, body, div, span, object, iframe,h1, h2, h3, h4, h5, h6, p, blockquote, pre,a, abbr, acronym, address, code,del, dfn, em, img, q, dl, dt, dd, ol, ul, li,fieldset, form, label, legend,table, caption, tbody, tfoot, thead, tr, th, td{margin:0;padding:0;border:0;font-weight:inherit;font-style:inherit;font-size:100%;font-family:inherit;vertical-align:baseline;}
        body{line-height:1.5;}
        table{border-collapse:separate;border-spacing:0;}caption, th, td{text-align:left;font-weight:normal;}
        table, td, th{vertical-align:middle;}
        blockquote:before, blockquote:after, q:before, q:after{content:"";}blockquote, q{quotes:"" "";}
        a img{border:none;}

        .background {
            height: 100%;
            position: absolute;
            margin-top: -61px;
        }

        .overlay {
            position: absolute;
            background: red;
            -moz-border-radius:100%;
            -webkit-border-radius:100%;
            border-radius:100%;
        }
    </style>
</head>
<body>
<script type="text/javascript">
    var resizeOverlay = function() {
        var l=515,
                t=145,
                $b=$('.background'),
                $o=$('.overlay'),
                o_w=25,
                o_h=25;
        var b_h=$b.height();
        var ratio=$b.width()/2800;
        $o.css({
            left:parseInt(l*ratio,10)+'px',
            top:parseInt(t*ratio-61,10)+'px',
            width:parseInt(o_w*ratio,10)+'px',
            height:parseInt(o_h*ratio,10)+'px'
        });
        console.log('background_height',b_h);
    };

    $(document).ready(resizeOverlay);
    $(window).resize(resizeOverlay);
</script>
<img src="http://cisloandthomas.com/wp-content/uploads/2015/12/Shrunken-Banner-Wide-Ends-1140x200.jpg" class="background">
<div class="overlay"></div>
</body>
</html>

0
投票

多年以后,我意识到将元素定位在图像的特定区域上的最佳方式是使用SVG,将图像添加到SVG,并将SVG元素定位在图像中的感兴趣点上。

This site has an example,其中建筑物的图像堆叠在其上面,以便悬停在地板(例如地板22)上突出显示该地板:

enter image description here

这是相关的标记:

<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewbox="4.5 0 980.9 545.9" x="0px" y="0px">
<g>
    <image height="546" overflow="visible" transform="matrix(0.9999 0 0 0.9999 4.4815 -0.9215)" width="981" href="https://www.360statestreet.com/wp-content/themes/statestreet360/images/floorplans/bg-floor_plans.jpg"/>
</g>
<g id="Floors">
    <polygon class="floor Floor7" fill="rgba(102,199,198,0.8)" id="Floor7" opacity="0" points="424,309 450,319 449,320 624,385 632,383 663,394 715,376 715,389 665,409 629,398 624,398 449,333 450,332 424,321" values="th"/>
    <polygon class="floor Floor8" fill="rgba(102,199,198,0.8)" id="Floor8" opacity="0" points="424,297 450,307 449,310 624,373 632,372 663,383 715,364 715,376 666,396 629,384 624,385 450,323 450,320 424,310" values="th"/>
    <polygon class="floor Floor9" fill="rgba(102,199,198,0.8)" id="Floor9" opacity="0" points="424,287 450,297 450,299 625,361 633,360 665,371 715,352 715,365 667,382 630,372 624,374 450,311 450,308 424,299" values="th"/>
    <polygon class="floor Floor10" fill="rgba(102,199,198,0.8)" id="Floor10" opacity="0" points="424,275 450,284 450,287 627,349 634,345 668,358 715,340 715,353 668,372 630,359 628,361 450,300 450,296 424,287" values="th"/>
    <polygon class="floor Floor11" fill="rgba(102,199,198,0.8)" id="Floor11" opacity="0" points="424,263 450,271 450,275 627,337 634,334 667,345 715,327 715,340 667,358 635,346 627,349 450,287 450,284 424,275" values="th"/>
    <polygon class="floor Floor12" fill="rgba(102,199,198,0.8)" id="Floor12" opacity="0" points="424,252 450,261 450,264 627,324 635,322 667,332 715,315 715,327 668,346 635,334 627,337 450,276 450,274 424,265" values="th"/>
    <polygon class="floor Floor13" fill="rgba(102,199,198,0.8)" id="Floor13" opacity="0" points="424,240 451,249 451,251 628,310 635,308 668,319 715,301 715,315 668,333 635,322 628,325 450,265 450,263 424,254" values="th"/>
    <polygon class="floor Floor14" fill="rgba(102,199,198,0.8)" id="Floor14" opacity="0" points="424,228 451,237 451,240 628,297 635,296 668,307 715,289 715,302 668,320 634,309 628,310 450,252 450,250 424,241" values="th"/>
    <polygon class="floor Floor15" fill="rgba(102,199,198,0.8)" id="Floor15" opacity="0" points="424,216 451,225 451,227 628,284 634,284 668,295 715,277 715,290 670,307 634,295 628,298 450,240 450,238 424,229" values="th"/>
    <polygon class="floor Floor16" fill="rgba(102,199,198,0.8)" id="Floor16" opacity="0" points="424,203 451,213 451,216 628,272 634,271 668,282 715,265 715,277 669,295 634,284 628,286 450,228 450,225 424,216" values="th"/>
    <polygon class="floor Floor17" fill="rgba(102,199,198,0.8)" id="Floor17" opacity="0" points="424,192 451,203 451,205 628,260 634,259 668,270 715,253 715,265 669,282 634,271 628,273 450,216 450,213 424,204" values="th"/>
    <polygon class="floor Floor18" fill="rgba(102,199,198,0.8)" id="Floor18" opacity="0" points="424,182 451,191 451,193 629,248 634,246 668,257 715,240 715,253 669,270 634,258 628,261 450,205 450,202 424,194" values="th"/>
    <polygon class="floor Floor19" fill="rgba(102,199,198,0.8)" id="Floor19" opacity="0" points="424,171 451,179 451,181 629,235 630,233 668,245 715,228 715,240 669,257 634,246 628,249 450,193 450,190 424,183" values="th"/>
    <polygon class="floor Floor20" fill="rgba(102,199,198,0.8)" id="Floor20" opacity="0" points="424,160 451,167 451,170 629,224 632,222 668,232 715,215 715,228 669,245 634,234 628,237 450,182 450,179 424,171" values="th"/>
    <polygon class="floor Floor21" fill="rgba(102,199,198,0.8)" id="Floor21" opacity="0" points="424,148 450,156 451,160 629,212 633,209 668,220 715,204 715,216 669,233 634,222 628,225 450,172 450,168 424,160" values="st"/>
    <polygon class="floor Floor22" fill="rgba(102,199,198,0.8)" id="Floor22" opacity="0" points="424,138 450,144 451,147 629,200 633,198 668,207 715,191 715,205 669,221 634,212 628,214 450,162 450,158 424,150" values="nd"/>
    <polygon class="floor Floor23" fill="rgba(102,199,198,0.8)" id="Floor23" opacity="0" points="424,126 452,135 451,136 629,187 633,185 668,195 715,181 715,194 669,211 634,200 628,202 450,149 450,147 424,139" values="rd"/>
    <polygon class="floor Floor24" fill="rgba(102,199,198,0.8)" id="Floor24" opacity="0" points="424,116 452,124 451,125 629,176 633,173 668,183 715,166 715,180 669,195 634,187 628,189 450,137 450,135 424,129" values="th"/>
    <polygon class="floor Floor25" fill="rgba(102,199,198,0.8)" id="Floor25" opacity="0" points="424,103 452,111 451,113 629,162 633,160 668,170 715,155 715,168 669,183 634,173 628,176 450,127 450,125 424,117" values="th"/>
    <polygon class="floor Floor26" fill="rgba(102,199,198,0.8)" id="Floor26" opacity="0" points="424,91 452,99 451,101 629,150 633,148 668,157 715,142 715,156 669,171 634,161 628,164 450,115 450,112 424,105" values="th"/>
    <polygon class="floor Floor27" fill="rgba(102,199,198,0.8)" id="Floor27" opacity="0" points="424,80 452,88 451,90 629,138 634,135 668,144 715,130 715,143 669,158 634,149 628,151 450,103 450,100 424,93" values="th"/>
    <polygon class="floor Floor28" fill="rgba(102,199,198,0.8)" id="Floor28" opacity="0" points="425,69 452,76 451,78 629,126 634,123 668,132 715,118 715,131 669,145 634,136 628,139 450,91 450,88 424,81" values="th"/>
    <polygon class="floor Floor29" fill="rgba(102,199,198,0.8)" id="Floor29" opacity="0" points="449,59 449,63 448,65 513,81 525,78 557,86 557,92 622,108 632,109 681,95 681,94 681,104 715,112 664,128 630,120 622,121 449,76 446,72 426,66" values="th"/>
    <polygon class="floor Floor30" fill="rgba(102,199,198,0.8)" id="Floor30" opacity="0" points="451,54 513,70 527,67 556,73 557,79 623,95 681,81 680,95 632,109 622,109 556,93 555,85 526,79 513,82 451,66" values="th"/>
    <polygon class="floor Floor31" fill="rgba(102,199,198,0.8)" id="Floor31" opacity="0" points="451,40 513,55 527,52 556,59 557,65 623,81 680,68 681,81 632,94 622,96 556,79 555,73 526,67 513,70 451,53" values="st"/>
</g>
</svg>

建筑图像存储在image标签中,每个楼层都有一个位于图像上方的polygon。 SVG调整大小规则处理SVG大小调整,所有子元素都使用重新缩放的图像进行缩放!

© www.soinside.com 2019 - 2024. All rights reserved.