简体   繁体   English

将单个背景图像划分到多个 div 以创建“窗口化”效果的方法?

[英]Way to divide a single background image across multiple divs to create “windowed” effect?

I was wondering if there is an easy way to "tile" or "window" a single background image across multiple divs.我想知道是否有一种简单的方法可以在多个 div 中“平铺”或“窗口化”单个背景图像。 I want to create a sort of punched out window look.我想创造一种打孔的窗户外观。

Keep in mind that I want to dynamically add these boxes.请记住,我想动态添加这些框。 There will be a maximum of 16, but I could have 9.最多有 16 个,但我可以有 9 个。

I have a fiddle here: link to fiddle我在这里有一个小提琴:链接到小提琴

What I want to do is instead of the background image showing, it would just be white.. And instead of the divs being white, they contain that section of the background image.我想要做的是而不是显示背景图像,它只是白色.. 而不是白色的 div,它们包含背景图像的那部分。 Sorry if this is not a very good description, but basically I want to swap the white with the background.对不起,如果这不是一个很好的描述,但基本上我想用背景交换白色。

so something like:所以像:

<div id="blocks">
  <div class="block" style=" background: some-section-of-image ;"></div>
  <div class="block" style=" background: some-section-of-image2;"></div>
  <div class="block" style=" background: some-section-of-image3;"></div>
  <div class="block" style=" background: some-section-of-image4;"></div>
</div>

I'd like to do this with as little jQuery as possible... but maybe that is not feasible.我想用尽可能少的 jQuery 来做到这一点......但也许那是不可行的。

I fiddled around some with setting我摆弄了一些设置

opacity:0.0;

on just the blocks, but can't figure out how to not display the image elsewhere.仅在块上,但无法弄清楚如何不在其他地方显示图像。 Thanks!谢谢!

A CSS-only solution仅使用 CSS 的解决方案

What you are describing is basically a table with a background image and white borders.您所描述的基本上是一张带有背景图像和白色边框的表格。 A simple solution can be achieved by creating a table-like layout with CSS only.一个简单的解决方案可以通过仅使用 CSS 创建类似表格的布局来实现。

#background-container { 
    display:table;
    width:100%;
    border-collapse:collapse;
    box-sizing:border-box;
     /**/
    background: url(path-to-background-image) no-repeat center center;
    background-size: cover;
     /* Vendor specific hacks */
    -webkit-background-size: cover;
    -moz-background-size: cover;
    -o-background-size: cover;
}

.blocks {
    display:table-row;
}

.block {
    display:table-cell;
    height:100px;
    border:10px solid #FFF;
}

See jsFiddle Demo参见jsFiddle 演示

I came into something that's nearly a 100%.我进入了接近 100% 的东西。 Feel free (anyone) to edit the answer.随意(任何人)编辑答案。

CSS CSS

#blocks {
    width:100%;
    height:100px;
}
.block {
    float: left;
    overflow: hidden;
    margin: 2%;
    width: 20%;
    height: 100%;
    background: transparent url(http://www.designmyprofile.com/images/graphics/backgrounds/background0172.jpg) no-repeat top left;
}

jQuery (JS) jQuery (JS)

$(function () {
    var posX = 0;
    var posY = 0;
    var i = 0;

    $(".block").each(function (ind, el) {
        $(this).css("background-position", posX.toString() + "% " + posY.toString() + "%");

        posX += 20;
        i++;

        if (i == 4) {
            i = 0;
            posX = 0;
            posY += 25;
        }
    });
});

Demo (to be improved): http://jsfiddle.net/bzCNb/33/演示(有待改进): http : //jsfiddle.net/bzCNb/33/

Try putting the background on the blocks instead of the page with fixed attachment and alignment of left top.尝试将背景放在块上而不是带有固定附件和左上对齐的页面上。 Unfortunately with this option if the page scrolls the background appears fixed.不幸的是,如果页面滚动背景显示固定,则使用此选项。

.block{
    float: left;
    overflow: hidden;
    margin: 2%;
    width: 20%;
    height: 100%;
    background-image: url(http://www.designmyprofile.com/images/graphics/backgrounds/background0172.jpg);
    background-repeat: no-repeat;
    background-position: left top;
    background-attachment: fixed;
}

http://jsfiddle.net/bzCNb/28/ http://jsfiddle.net/bzCNb/28/

I found the question interesting and wondered how hard it would be to do this with vanilla JavaScript nowadays, for any tile shapes or positions.我发现这个问题很有趣,并想知道现在用普通的 JavaScript 来做这件事有多难,对于任何瓷砖形状或位置。

Answer: it's not so hard.回答:没那么难。

Snippet below illustrates that with 3 different ways of laying out tiles for a tiled image, all handled by the same JavaScript code.下面的片段说明了使用 3 种不同的方式为平铺图像布置平铺,所有这些都由相同的 JavaScript 代码处理。

It works with the following algorithm:它适用于以下算法:

  1. find an element with class tiled-image .找到一个类tiled-image的元素。 Use this frame's dimensions for image layout使用此框架的尺寸进行图像布局
  2. find the first <img> element inside it: use it's src as tiled image.找到其中的第一个<img>元素:使用它的src作为平铺图像。 Remove it去掉它
  3. For all elements with class tile inside it, find their position, set their background as the image, with background-position offset so it always matches the frame's upper-left, and background-size set to the frame's size对于其中包含类tile所有元素,找到它们的位置,将它们的background设置为图像,使用background-position偏移使其始终与框架的左上角匹配,并将background-size设置为框架的大小

Current limitation: the frame's size must match the image's aspect ratio.当前限制:框架的大小必须与图像的纵横比匹配。 Could easily be improved for dynamic image sizes可以轻松改进动态图像大小

 window.addEventListener('load', _e=> { const tFrames = document.querySelectorAll('.tiled-image');//Find tiled frames tFrames.forEach(frame => { //For each one const img = frame.querySelector('img'); //Retrieve first img if (!img || !img.src) return; img.remove(); //Remove it const src = img.src; //Store its src const fBounds = frame.getBoundingClientRect(); //Store position of frame frame.querySelectorAll('.tile').forEach(tile => { //For each tile tile.style.backgroundImage = `url('${src}')`; //Set bg image to img's src const tBounds = tile.getBoundingClientRect(); //Find position //Position background to frame's upperleft corner const bx = tBounds.left - fBounds.left; const by = tBounds.top - fBounds.top; tile.style.backgroundPosition = `left ${-bx}px top ${-by}px`; //Set background size to frame's size tile.style.backgroundSize = `${fBounds.width}px ${fBounds.height}px`; }); }); });
 /*General positioning */ .tiled-image { box-sizing: content-box; width: 800px; height: 600px; } /* fallback to regular image if javascript doesn't run */ .tiled-image img { display: block; width: 100%; height: 100%; } /* DONE. The rest is decoration and specific tile positioning for the 3 examples */ body { background: linear-gradient(164deg, rgba(0,0,0,1) 0%, rgba(145,145,167,1) 35%, rgba(70,80,82,1) 100%); } .light-text { color: gainsboro; } .tiled-image + .tiled-image { margin-top: 1em; } /* debugging help */ /* .tiled-image { outline: 1px solid blue; } .tiled-image .tile { outline: 1px solid red; } */ /* regular grid */ #ti-1 { display: grid; grid-template-columns: repeat(3, 1fr); grid-template-rows: repeat(3, 1fr); grid-gap: 10px; } /* irregular grid */ #ti-3 { display: grid; grid-template-areas: "aacccc" "bbcccc" "bbddee" "bbddee"; grid-gap: 10px; } #ti-3 .ta { grid-area: a; } #ti-3 .tb { grid-area: b; } #ti-3 .tc { grid-area: c; } #ti-3 .td { grid-area: d; } #ti-3 .te { grid-area: e; } /* position absolute */ #ti-2 { position: relative; } #ti-2 .tile { position: absolute; } #ti-2 .t0-0 { left: 0; top: 10px; width: 150px; height: 200px; } #ti-2 .t0-1 { left: 180px; top: 0; width: 220px; height: 400px; } #ti-2 .t0-2 { left: 410px; top: 30px; width: 380px; height: 510px; } #ti-2 .t1-0 { left: 20px; top: 220px; width: 150px; height: 380px; } #ti-2 .t1-1 { left: 180px; top: 420px; width: 210px; height: 170px; } #ti-2 .t1-2 { top: 560px; left: 400px; height: 40px; width: 400px; }
 <h4 class="light-text">With regular grid</h4> <div class="tiled-image" id="ti-1"> <img src="http://avante.biz/wp-content/uploads/800x600-Wallpapers/800x600-Wallpapers-048.jpg" /> <div class="tile t0-0"></div> <div class="tile t0-1"></div> <div class="tile t0-2"></div> <div class="tile t1-0"></div> <div class="tile t1-1"></div> <div class="tile t1-2"></div> <div class="tile t2-0"></div> <div class="tile t2-1"></div> <div class="tile t2-2"></div> </div> <!-- DONE. Next examples use the same code with different numbers of tiles --> <h4>With irregular grid</h4> <div class="tiled-image" id="ti-3"> <img src="http://avante.biz/wp-content/uploads/800x600-Wallpapers/800x600-Wallpapers-042.jpg" /> <div class="tile ta"></div> <div class="tile tb"></div> <div class="tile tc"></div> <div class="tile td"></div> <div class="tile te"></div> </div> <h4>With position: absolute</h4> <div class="tiled-image" id="ti-2"> <img src="http://avante.biz/wp-content/uploads/800x600-Wallpapers/800x600-Wallpapers-047.jpg" /> <div class="tile t0-0"></div> <div class="tile t0-1"></div> <div class="tile t0-2"></div> <div class="tile t1-0"></div> <div class="tile t1-1"></div> <div class="tile t1-2"></div> </div>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM