【问题标题】:Split background image with 3D thickness effect具有 3D 厚度效果的分割背景图像
【发布时间】:2017-02-13 20:35:31
【问题描述】:

我想分割背景图片。例如像这样的原始图像

我想要这样的效果:

这是我的代码

<style>
    div{

    -webkit-transform: skewY(175deg); 
    padding: 10px;
    margin: 10px;
    border: 10px;
    background-image: url(Chrysanthemum.jpg);
    width: 200px;
    height: 200px;
    background-origin: content-box;
    }
</style>
<div></div> 

但我找不到任何方法如何使用 CSS 或 jQuery 以相同的厚度效果分割此背景。

【问题讨论】:

标签: jquery css css-shapes css-transforms


【解决方案1】:

这是一种将图像分成3部分并制作厚度效果的3D方法。 它具有响应性并依赖于:

  • 图像旋转和厚度效果的 3d 变换
  • 保持元素纵横比的“填充技术”
  • 伪元素,使图像的每个部分的厚度
  • 背景图片和背景位置

3d rotated and thick image的演示。

输出:

body{perspective:1000px;}
.imgWrap{
  position:relative;
  width:90%;
  margin:5% auto;
  padding-bottom:39%;
  transform: rotateY(25deg);
  transform-style:preserve-3d;
}
.imgWrap > div{
  position:absolute;
  top:0;
  width:30.3%;height:100%;
  float:left;
  background-image:url('http://i.imgur.com/FhZxJJp.jpg');
  background-size:auto 100%;
  transform-style:preserve-3d;
  outline: 1px solid transparent; /* prevent jagged edges in firefox */
}
.imgWrap .left  { left: 0;     background-position:   3% 0; }
.imgWrap .center{ left:34.83%; background-position: -97% 0; }
.imgWrap .right { left:69.66%; background-position:-197% 0; }
.imgWrap > div:before{
  content:'';
  position:absolute;
  top:0;right:100%;
  width:10%; height:100%;
  background:inherit;
  transform-origin:100% 50%;
  transform:rotateY(-90deg);
}
.imgWrap .left:before  { background-position:     0%   0; }
.imgWrap .center:before{ background-position: -1001.3% 0; }
.imgWrap .right:before { background-position: -2001.4% 0; }
<div class="imgWrap">
  <div class="left"></div>
  <div class="center"></div>
  <div class="right"></div>
</div>

请注意,您需要添加供应商前缀以支持浏览器。如需更多信息,请参阅canIuse

【讨论】:

    【解决方案2】:

    此答案仅提供单元素解决方案

    2D 解决方案是仅使用伪元素 :before:after 来模拟间隙。你只需要position他们并用calc()给他们与边界的适当距离。

    要使其看起来更 3D,您可以将 transform perspective()rotateY() 结合使用,而不是 skewY()

    div {
      position: relative;
      -webkit-transform: perspective(1000px) rotateY(30deg);
      transform: perspective(1000px) rotateY(30deg);
      margin: 50px 10px;
      background-image: url(http://placekitten.com/g/600/200);
      width: 600px;
      height: 200px;
    }
    div:before,
    div:after {
      content: "";
      position: absolute;
      top: 0;
      width: 10px;
      height: 100%;
      background: white;
    }
    div:before {
      left: calc(33% - 5px);
    }
    div:after {
      right: calc(33% - 5px);
    }
    &lt;div&gt;&lt;/div&gt;

    要实现非常简单的 3D 效果,可以在 div 中添加 border-left,在伪元素中添加 border-right。再加上白色的上下边框和右边框半透明,伪元素甚至给人一种3D的感觉。不幸的是,这对于主要元素是不可能的。但在这里你至少可以玩转边框透明度。

    div {
      position: relative;
      -webkit-transform: perspective(1000px) rotateY(30deg);
      transform: perspective(1000px) rotateY(30deg);
      margin: 50px 10px;
      background-image: url(http://placekitten.com/g/600/200);
      width: 600px;
      height: 200px;
      background-origin: border-box;
      border-left: 5px solid rgba(0, 0, 0, 0.5);
    }
    div:before,
    div:after {
      content: "";
      position: absolute;
      top: 0;
      width: 0;
      height: 100%;
      box-sizing: border-box;
      background: transparent;
      border-top: 4px solid white;
      border-bottom: 4px solid white;
      border-left: 10px solid white;
      border-right: 6px solid rgba(0, 0, 0, 0.5);
    }
    div:before {
      left: calc(33% - 7px);
    }
    div:after {
      right: calc(33% - 7px);
    }
    &lt;div&gt;&lt;/div&gt;

    【讨论】:

    • 看起来不错..如果您查看图像,则只想多做一件事,每个分割图像也采用边宽。我们如何才能做到这一点?
    • 厚度将很难创建......也许你可以做类似this tutorial的事情。但是你需要大量的 HTML 元素和 CSS 操作...
    【解决方案3】:

    这是另一种依赖一个元素的解决方案。

    这个想法是使用多个背景在初始图像上方创建不同的层,以便:

    • 使用白色(或与主背景相同的颜色)在图像的每个部分之间创建间隙。
    • 为每个部分创建阴影。
    • 使用透明色创建粗细效果。

    然后我们使用透视进行旋转以获得 3D 错觉。

    body {
      perspective: 1000px;
      max-width:600px;
    }
    
    .box {
      margin: 20px;
      width:400px;
      height:200px;
      border-left:20px solid transparent;
      transform: rotateY(25deg);
      transform-style: preserve-3d;
      background:
      /*
        1: The bottom shadow
        2: A small triangle at the bottom left corner for the 3D effect
        3: A small triangle at the top    left corner for the 3D effect
        4: The left side shadow
        5: White color to create the separation between each part
      */
      
      /* First part */
      /*1*/ linear-gradient(24deg,transparent 54%,#aaa 57%)          0px  100%/30px 16px border-box border-box,
      /*2*/ linear-gradient(to bottom left,transparent 50%,#fff 52%) 10px 100%/8px 3px,
      /*3*/ linear-gradient(to top left,transparent 50%,#fff 52%)    10px 0   /8px 3px,
      /*4*/ linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5))         10px 0   /8px 100%,
      /*5*/ linear-gradient(#fff,#fff)                               0 0      /10px 100%,
      /* Second part */
      /*1*/ linear-gradient(30deg,transparent 35%,#aaa 51%)          130px 100%/10px 16px,
      /*2*/ linear-gradient(to bottom left,transparent 50%,#fff 52%) 140px 100%/8px  3px,
      /*3*/ linear-gradient(to top left,transparent 50%,#fff 52%)    140px 0   /8px  3px,
      /*4*/ linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5))         140px 0   /8px  100%,
      /*5*/ linear-gradient(#fff,#fff)                               130px 0   /10px 100%,
      /* Third part */
      /*1*/ linear-gradient(30deg,transparent 35%,#aaa 51%)          260px 100%/10px 16px,
      /*2*/ linear-gradient(to bottom left,transparent 50%,#fff 52%) 270px 100%/8px  3px,
      /*3*/ linear-gradient(to top left,transparent 50%,#fff 52%)    270px 0   /8px  3px,
      /*4*/ linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5))         270px 0   /8px  100%,
      /*5*/ linear-gradient(#fff,#fff)                               260px 0   /10px 100%,
      /* Main background */
      url(https://picsum.photos/400/200/?image=1015) 0 0/cover;
     background-repeat:no-repeat;
    }
    <div class="box" >
    </div>

    为了更好地理解谜题,为每个渐变使用不同的颜色:

    body {
      perspective: 1000px;
      max-width:600px;
    }
    
    .box {
      margin: 20px;
      width:400px;
      height:200px;
      border-left:20px solid transparent;
      transform: rotateY(25deg);
      transform-style: preserve-3d;
      background:
      /*
        1: The bottom shadow
        2: A small triangle at the bottom left corner for the 3D effect
        3: A small triangle at the top    left corner for the 3D effect
        4: The left side shadow
        5: White color to create the separation between each part
      */
      
      /* First part */
      /*1*/ linear-gradient(24deg,transparent 54%,red 57%)           0px  100%/30px 16px border-box border-box,
      /*2*/ linear-gradient(to bottom left,transparent 50%,blue 52%) 10px 100%/8px 3px,
      /*3*/ linear-gradient(to top left,transparent 50%,black 52%)   10px 0   /8px 3px,
      /*4*/ linear-gradient(pink,pink)                               10px 0   /8px 100%,
      /*5*/ linear-gradient(green,green)                             0 0      /10px 100%,
      /* Second part */
      /*1*/ linear-gradient(30deg,transparent 35%,red 51%)           130px 100%/10px 16px,
      /*2*/ linear-gradient(to bottom left,transparent 50%,blue 52%) 140px 100%/8px  3px,
      /*3*/ linear-gradient(to top left,transparent 50%,black 52%)   140px 0   /8px  3px,
      /*4*/ linear-gradient(pink,pink)                               140px 0   /8px  100%,
      /*5*/ linear-gradient(green,green)                             130px 0   /10px 100%,
      /* Third part */
      /*1*/ linear-gradient(30deg,transparent 35%,red 51%)           260px 100%/10px 16px,
      /*2*/ linear-gradient(to bottom left,transparent 50%,blue 52%) 270px 100%/8px  3px,
      /*3*/ linear-gradient(to top left,transparent 50%,black 52%)   270px 0   /8px  3px,
      /*4*/ linear-gradient(pink,pink)                               270px 0   /8px  100%,
      /*5*/ linear-gradient(green,green)                             260px 0   /10px 100%,
      /* Main background */
      url(https://picsum.photos/400/200/?image=1015) 0 0/cover;
     background-repeat:no-repeat;
    }
    <div class="box" >
    </div>

    您可以使用mask 优化代码以获得透明度:

    body {
      perspective: 1000px;
      max-width:600px;
      background:linear-gradient(to right,pink,yellow);
    }
    
    .box {
      margin: 20px;
      width:400px;
      height:200px;
      border-left:30px solid transparent;
      transform: rotateY(25deg);
      transform-style: preserve-3d;
      background:
      /* */
      linear-gradient(30deg,transparent 65%,#aaa 67%)   0  100%/30px 16px border-box border-box,
      linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5))  0 0   /8px 100%,
      /* */
      linear-gradient(30deg,transparent 35%,#aaa 51%)   130px 100%/10px 16px,
      linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5))  140px 0   /8px  100%,
      linear-gradient(#fff,#fff)                        130px 0   /10px 100%,
      /* */
      linear-gradient(30deg,transparent 35%,#aaa 51%)   260px 100%/10px 16px,
      linear-gradient(rgba(0,0,0,0.5),rgba(0,0,0,0.5))  270px 0   /8px  100%,
      linear-gradient(#fff,#fff)                        260px 0   /10px 100%,
      
      url(https://picsum.photos/id/1015/400/200) center/cover;
     background-repeat:no-repeat;
      -webkit-mask:
         linear-gradient(30deg,transparent 35%,#fff 51%)  160px 100%/10px 16px,
         linear-gradient(30deg,transparent 35%,#aaa 51%)  290px 100%/10px 16px,
         
         linear-gradient(#fff,#fff) 0     50%/160px calc(100% - 16px),
         linear-gradient(147deg,transparent 21px,#fff 22px) 0 0/160px 8px,
         linear-gradient(30deg,transparent 19px,#fff 20px) 0 100%/160px 8px,
         
         linear-gradient(#fff,#fff) 170px 50%/120px calc(100% - 16px),
         linear-gradient(147deg,transparent 21px,#fff 22px) 140px 0/150px 8px,
         linear-gradient(30deg,transparent 19px,#fff 20px) 140px 100%/150px 8px,
         
         linear-gradient(#fff,#fff) 300px 50%/130px calc(100% - 16px),
         linear-gradient(147deg,transparent 21px,#fff 22px) 270px 0/160px 8px,
         linear-gradient(30deg,transparent 19px,#fff 20px) 270px 100%/160px 8px;
      mask:
         linear-gradient(30deg,transparent 35%,#fff 51%)  160px 100%/10px 16px,
         linear-gradient(30deg,transparent 35%,#aaa 51%)  290px 100%/10px 16px,
         
         linear-gradient(#fff,#fff) 0     50%/160px calc(100% - 16px),
         linear-gradient(147deg,transparent 21px,#fff 22px) 0 0/160px 8px,
         linear-gradient(30deg,transparent 19px,#fff 20px) 0 100%/160px 8px,
         
         linear-gradient(#fff,#fff) 170px 50%/120px calc(100% - 16px),
         linear-gradient(147deg,transparent 21px,#fff 22px) 140px 0/150px 8px,
         linear-gradient(30deg,transparent 19px,#fff 20px) 140px 100%/150px 8px,
         
         linear-gradient(#fff,#fff) 300px 50%/130px calc(100% - 16px),
         linear-gradient(147deg,transparent 21px,#fff 22px) 270px 0/160px 8px,
         linear-gradient(30deg,transparent 19px,#fff 20px) 270px 100%/160px 8px;
      -webkit-mask-repeat:no-repeat;
      mask-repeat:no-repeat;
    }
    <div class="box" >
    </div>

    【讨论】:

    • 请在 sn-p 代码中添加(如果可能)cmets \ 在第一条评论中,我的意思是人们不喜欢这个答案,因为它是值得的
    猜你喜欢
    • 1970-01-01
    • 2021-09-18
    • 1970-01-01
    • 2020-01-23
    • 1970-01-01
    • 2021-01-02
    • 2016-06-03
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多