如何在JavaScript/CSS中简单地创建一个图像反射效果?
How to simply create an image reflection effect in JavaScript/CSS?
我花了一些时间查找如何最好地创建动态图像反射效果。
我找到的选项是:
非标准浏览器标签,例如-webkit-reflect
、
添加来自 <2012 的库,这些库都具有过时的依赖关系,并且在与例如结合时失败。最新 JQuery 3,或
放弃动态图像反射的想法并依赖GIMP/Photoshop。
大多数现有解决方案在非纯色背景(即纹理)上也会失败。
上面的缺点就在眼前。不幸的是,我没有网络博客 post 我想出了什么,但我认为它值得分享(见下面的自我回答)。
- 将图片添加到您的 HTML:
<img class="reflect" src="some/image.png" />
- 添加以下 CSS 规则:
img.reflect {
width: calc(100% - 20px); /* not sure how else to allow for margin */
margin-left: 10px;
}
img.reflection {
position: absolute;
opacity: 0.4;
margin-top: 4px;
width: calc(100% - 20px);
-webkit-mask-image: -webkit-linear-gradient(transparent 75%, black 100%);
mask-image: linear-gradient(transparent 75%, black 100%);
-webkit-transform: translateX(calc(-100% - 10px)) translateY(100%) scaleY(-1) ;
transform: translateX(calc(-100% - 10px)) translateY(100%) scaleY(-1);
}
如果您不想依赖任何 JavaScript,您现在可以通过在 (1) 中的图像标签之后插入反射标签来简单地添加反射:
<img class="reflection" src="some/image.png" />
否则
- 例如,使用以下函数扩展 JQuery:
$.fn.reflect = function() {
var reflection = this.clone();
this.after(reflection);
reflection.addClass("reflection");
};
- 然后镜像:
$(".reflect").reflect();
这是一个纯粹的 CSS 解决方案,不需要 jQuery 或 JS:
.reflect {
display:inline-block;
vertical-align:top;
width:150px;
height:300px;
background:
linear-gradient(#000,#000) center/100% 1px no-repeat, /*a separation*/
var(--img) top/100% 50% no-repeat;
position:relative;
}
.reflect::before {
content:"";
position:absolute;
bottom:0;
left:0;
right:0;
top:0;
background:inherit;
transform:scale(1,-1);
-webkit-mask-image: -webkit-linear-gradient(transparent 25%, #ccc 50%);
mask-image: linear-gradient(transparent 25%, #ccc 50%)
}
.right {
width:300px;
height:150px;
background-position:center,left;
background-size:1px 100%,50% 100%;
}
.right:before {
transform:scale(-1,1);
-webkit-mask-image: -webkit-linear-gradient(left,transparent 25%, #ccc 50%);
mask-image: linear-gradient(to left,transparent 25%, #ccc 50%)
}
<div class="reflect" style="--img:url(https://picsum.photos/200/200?image=0)"></div>
<div class="reflect right" style="--img:url(https://picsum.photos/200/200?image=1069)"></div>
我花了一些时间查找如何最好地创建动态图像反射效果。
我找到的选项是:
非标准浏览器标签,例如
-webkit-reflect
、添加来自 <2012 的库,这些库都具有过时的依赖关系,并且在与例如结合时失败。最新 JQuery 3,或
放弃动态图像反射的想法并依赖GIMP/Photoshop。
大多数现有解决方案在非纯色背景(即纹理)上也会失败。
上面的缺点就在眼前。不幸的是,我没有网络博客 post 我想出了什么,但我认为它值得分享(见下面的自我回答)。
- 将图片添加到您的 HTML:
<img class="reflect" src="some/image.png" />
- 添加以下 CSS 规则:
img.reflect {
width: calc(100% - 20px); /* not sure how else to allow for margin */
margin-left: 10px;
}
img.reflection {
position: absolute;
opacity: 0.4;
margin-top: 4px;
width: calc(100% - 20px);
-webkit-mask-image: -webkit-linear-gradient(transparent 75%, black 100%);
mask-image: linear-gradient(transparent 75%, black 100%);
-webkit-transform: translateX(calc(-100% - 10px)) translateY(100%) scaleY(-1) ;
transform: translateX(calc(-100% - 10px)) translateY(100%) scaleY(-1);
}
如果您不想依赖任何 JavaScript,您现在可以通过在 (1) 中的图像标签之后插入反射标签来简单地添加反射:
<img class="reflection" src="some/image.png" />
否则
- 例如,使用以下函数扩展 JQuery:
$.fn.reflect = function() {
var reflection = this.clone();
this.after(reflection);
reflection.addClass("reflection");
};
- 然后镜像:
$(".reflect").reflect();
这是一个纯粹的 CSS 解决方案,不需要 jQuery 或 JS:
.reflect {
display:inline-block;
vertical-align:top;
width:150px;
height:300px;
background:
linear-gradient(#000,#000) center/100% 1px no-repeat, /*a separation*/
var(--img) top/100% 50% no-repeat;
position:relative;
}
.reflect::before {
content:"";
position:absolute;
bottom:0;
left:0;
right:0;
top:0;
background:inherit;
transform:scale(1,-1);
-webkit-mask-image: -webkit-linear-gradient(transparent 25%, #ccc 50%);
mask-image: linear-gradient(transparent 25%, #ccc 50%)
}
.right {
width:300px;
height:150px;
background-position:center,left;
background-size:1px 100%,50% 100%;
}
.right:before {
transform:scale(-1,1);
-webkit-mask-image: -webkit-linear-gradient(left,transparent 25%, #ccc 50%);
mask-image: linear-gradient(to left,transparent 25%, #ccc 50%)
}
<div class="reflect" style="--img:url(https://picsum.photos/200/200?image=0)"></div>
<div class="reflect right" style="--img:url(https://picsum.photos/200/200?image=1069)"></div>