在CSS中,我们有transform
和filter
,还有backdrop-filter
。但据我所知,我们没有backdrop-transform
或类似的东西。
解释一下我的意思:backdrop-filter
允许您过滤某些特定元素后面的,例如,您可以调整背景图像特定区域的色相通过在该区域上放置一个div
,然后对其应用backdrop-filter: hue-rotate(90deg)
,如下所示:
因此backdrop-transform
是transform
属性的类似物。您可以transform
部分背景图片,如下所示:
您还可以对单个嵌入式youtube视频(或任何其他iframe)执行类似的操作,例如:
请注意,如果您尝试使用两个独立的iframe进行模拟,则需要以某种方式使其保持同步(关于滚动,视频播放等),如果iframe是跨域的。更不用说为要转换的每个细分嵌入新的iframe /视频的成本了。
也许我对Houdini的惊人承诺太醉了,但是我认为类似这样的事情真的很强大而且非常有用(至少对我而言!)。例如,您可以嵌入视频元素,但将其分解为四分之一,甚至使用CSS 将这些四分之一弄乱!使用4个不同的蒙版视频进行处理比较麻烦,并且尝试使它们完美地逐帧同步可能会很麻烦(特别是考虑到HTML5视频API的时间分辨率较低),并在服务器上剪切视频,似乎只是不必要的繁琐。
对于我的特定用例,我什至没有对视频的控制(它在跨域iframe中),因此CSS是实现我想做的唯一方法。 backdrop-filter
将我带到了一半,但我还需要能够独立地对片段进行一些转换。
element()
CSS element(...)
可以在url(..)
函数可以使用的任何地方使用。它使您可以将页面上任何元素的完整快照(包括跨域内容)用作图像(令人兴奋)。 Here's a good into以及一些感兴趣的演示。唯一的问题是,Firefox目前仅支持它,但是它处于标准轨道上,因此将来很有可能会被其他浏览器支持。如果我们得到了element()
函数的跨浏览器版本,则可以使用假设的backdrop-transform
属性来实现所有可能的事情。我们将在该区域上放置一个div,然后获取它的实时快照,并根据需要对其进行转换。根据幕后如何实施element()
,性能可能会成为问题。 Here is the chromium issue代表element()
。
答案 0 :(得分:1)
您可以自己组合不同的功能来创建它。基本上,您使用两个元素,在其中一个元素中,删除要用另一个元素重新创建的零件,然后可以轻松地应用任何类型的变换。
这是一个具有 fake 透明性的基本概念:
.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>
如您所见,代码被简化为一个容器,您可以在其中轻松设置图像,区域的顶部/左侧位置及其宽度/高度,然后进行转换。