1

在 CSS 中,我们有transformfilter,我们也有backdrop-filter. 但据我所知,我们没有backdrop-transform,或类似的东西。

解释我的意思:backdrop-filter允许您过滤某些特定元素后面的东西,例如,您可以通过将 a 定位div在该区域上,然后应用backdrop-filter: hue-rotate(90deg)到它来调整背景图像的特定区域的色调,就像这样:

背景过滤器

backdrop-transform财产的类似物也是如此transform。您可以transform作为背景图像的一部分,如下所示:

背景变换

您也可以使用单个嵌入式 youtube 视频(或任何其他 iframe)执行类似的操作,例如:

背景变换 iframe

请注意,如果您尝试使用两个单独的 iframe 来模拟这一点,您需要以某种方式保持彼此同步(关于滚动、视频播放等),如果 iframe 是,这可能很难/不可能跨域。更不用说为您要转换的每个片段嵌入新的 iframe/视频的成本。

也许我对 Houdini 的惊人承诺太醉了,但我认为这样的东西会非常强大并且非常有用(至少对我来说!)。例如,您可以嵌入一个视频元素,但将其分成四份,甚至使用 CSS 将这些四份混杂在一起!用 4 个不同的蒙版视频来做这件事会很乏味,并且试图让它们逐帧完美同步可能会很麻烦(尤其是考虑到 HTML5 视频 API 的时间分辨率低),并且在服务器上剪切视频 -只是看起来不必要的艰巨。

对于我的特定用例,我什至无法控制视频(它位于跨域 iframe 中),因此 CSS 是实现我想做的唯一方法。backdrop-filter让我走到了一半,但我还需要能够独立地转换这些片段。


可能的解决方案#1:element()

CSSelement(...)可以在url(..)函数可以使用的任何地方使用。它允许您将页面上任何元素的完整快照(包括跨域内容)用作图像(令人惊叹)。对于那些感兴趣的人,这里有一些演示。唯一的问题是它目前只被 Firefox 支持,但它是在标准轨道上,所以它很有可能在未来被其他浏览器支持。如果我们获得了该函数的跨浏览器版本,我们可以通过假设属性element()实现一切可能。backdrop-transform我们只需在该区域上放置一个 div,然后获取它的实时快照,并根据需要对其进行转换。性能可能是一个问题,具体取决于element()幕后的实现方式。这是铬的element()问题。

4

1 回答 1

0

您可以通过自己组合不同的功能来创建它。基本上,您使用两个元素,在其中一个元素中删除您使用另一个元素重新创建的部分,然后您可以轻松应用任何类型的转换。

这是一个带有透明度的基本想法:

.box {
  width:300px;
  height:200px;
  margin:50px;
  background:
    /*I hide a part of the image using a white gradient*/
    linear-gradient(#fff,#fff) 50px 50px/100px 100px,
    /*the main image*/
    url(https://picsum.photos/300/200?image=1069);
  background-repeat:no-repeat;
  position:relative;
}
.box:before {
  content:"";
  position:absolute;
  top:0;
  left:0;
  right:0;
  bottom:0;
  box-sizing:border-box;
  /*I get the same background*/
  background:inherit;
  /*I make the gradient with 0 size*/
  background-size:0 0,auto;
  /*I clip the background to only the content*/
  background-clip:content-box;
  padding:50px 150px 50px 50px;
  /*Apply what you want here*/
  transform:perspective(100px) rotateY(-20deg) skewX(10deg);
}
<div class="box">

</div>

主要技巧是两者的背景相同,并依靠剪辑和渐变来模拟所需的效果。

除了剪裁,您还可以调整背景大小/位置:

.box {
  width:300px;
  height:200px;
  margin:50px;
  background:
    /*I hide a part of the image using a white gradient*/
    linear-gradient(#fff,#fff) 50px 50px/100px 100px,
    /*the main image*/
    url(https://picsum.photos/300/200?image=1069);
  background-repeat:no-repeat;
  position:relative;
}
.box:before {
  content:"";
  position:absolute;
  top:50px;
  left:50px;
  width:100px;
  height:100px;
  background:inherit;
  background-size:0 0,300px 200px;
  background-position:-50px -50px;
  /*Apply what you want here*/
  transform:perspective(100px) rotateY(-20deg) skewX(15deg);
  transform-origin:right;
}
<div class="box">

</div>


另一个想法是使用clip-path具有完美的透明度,但找到不同的值可能有点棘手:

.container {
  display:inline-block;
  position:relative;
  margin:50px;
}

.box {
  width:300px;
  height:200px;
  background:
    url(https://picsum.photos/300/200?image=1069);
  background-repeat:no-repeat;
clip-path: polygon(0% 0%, 0% 100%, 
  50px 100%, 50px 50px, 150px 50px, 150px 150px, 50px 150px, 50px 100%, 100% 100%, 100% 0%);
}
.container:before {
  content:"";
  position:absolute;
  top:50px;
  left:50px;
  width:100px;
  height:100px;
  box-sizing:border-box;
  background:
    url(https://picsum.photos/300/200?image=1069) -50px -50px/300px 200px no-repeat;

  /*Apply what you want here*/
  transform:perspective(100px) rotateY(-20deg) scale(0.8);
}

body {
  background:linear-gradient(to right,pink,red);
}
<div class="container">
<div class="box">

</div>
</div>

为了更容易处理,您可以考虑使用 CSS 变量来轻松调整您想要定位的区域:

.container {
  display:inline-block;
  position:relative;
  z-index:0;
  margin:5px;
  /*we set background here for inheritance*/
  background-image:var(--img);
  background-size:0 0; /*don't show here*/
  width:200px;
  height:200px;
}

.container:before,
.container:after{
  content:"";
  position:absolute;
  background-image:inherit;
}
.container:before {
  top:0;
  left:0;
  right:0;
  bottom:0;
  clip-path: polygon(0% 0%, 0% 100%, 
  var(--l) 100%, var(--l) var(--t), calc(var(--l) + var(--w)) var(--t), calc(var(--l) + var(--w)) calc(var(--t) + var(--h)), var(--l) calc(var(--t) + var(--h)), var(--l) 100%, 100% 100%, 100% 0%);
}
.container:after {
  top:var(--t);
  left:var(--l);
  width:var(--w);
  height:var(--h);
  background-position:calc(-1*var(--l)) calc(-1*var(--t));
  transform:var(--transform,none);
}

body {
  background:linear-gradient(to right,pink,red);
}
<div class="container"
  style="--img:url(https://picsum.photos/200/200?image=1069);
         --t:50px;--l:50px;
         --w:100px;--h:100px;
         --transform:perspective(100px) rotateY(-20deg) scale(0.8)">
</div>

<div class="container"
  style="--img:url(https://picsum.photos/200/200?image=1052);
         --t:10px;--l:50px;
         --w:100px;--h:150px;
         --transform:perspective(100px) rotate(-20deg) scale(0.8)">
</div>
<div class="container"
  style="--img:url(https://picsum.photos/200/200?image=1055);
         --t:5px;--l:5px;
         --w:80px;--h:80px;
         --transform:perspective(100px) skew(25deg) scale(0.8)">
</div>
<div class="container"
  style="--img:url(https://picsum.photos/200/200?image=1049);
         --t:100px;--l:100px;
         --w:100px;--h:100px;
         --transform:translate(50px,50px)">
</div>

如您所见,代码被简化为只有一个容器,您可以在其中轻松设置图像、区域的顶部/左侧位置及其宽度/高度,然后是您需要应用的转换。

于 2019-02-24T12:01:04.340 回答