将全尺寸图像的大小和比例与 SVG 视图框匹配
Posted
技术标签:
【中文标题】将全尺寸图像的大小和比例与 SVG 视图框匹配【英文标题】:Match size and scale of fullsize image to SVG viewbox 【发布时间】:2018-06-25 18:45:31 【问题描述】:我有一份团队成员名单。每个成员元素都由一个在白色框内裁剪成圆形的图像组成。当您将鼠标悬停在框上时,图像将变为全尺寸。它的灵感来自this website:
我用 SVG 实现了同样的动画。但是,在上面的网站中,每张图片都是 300X350 - 与白色容器盒的大小相同。这创建了从蒙版图像到全尺寸图像的完美过渡 - 似乎没有任何东西跳跃或移动。 另一方面,我的图片有多种尺寸。结果,SVG 的可见部分要么放大要么缩小图像,当你将鼠标悬停时,整个图像似乎会跳跃:
如何使全尺寸图像的比例和大小与 SVG 视图框中的大小相匹配,使其看起来不会移动?
JSFiddle:http://jsfiddle.net/mzechar/afnxkt2h/2/
html:
<li>
<a href="#">
<article>
<div>
<!-- The masked image -->
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 100 100">
<defs>
<clipPath id="circle">
<circle cx="50" cy="50" r="35"/>
</clipPath>
</defs>
<image preserveAspectRatio="xMinYMin slice" xlink:href="team/finishedBW/CCK.jpg__.jpg" clip-path="url(#circle)"/>
</svg>
</div>
<!-- The full revealed image -->
<img class="img-full" src="team/finishedBW/CCK.jpg__.jpg" >
<!-- The circle ring -->
<svg viewBox="0 0 100 100" class="circle-ring">
<circle cx="50" cy="50" r="35" stroke="white" stroke- fill="transparent" />
</svg>
<div class="bio">
<h2>Chun-Kang Chen</h2>
<h4>Article Subtitle</h4>
</div>
</article>
</a>
</li>
<li>
CSS:
.team-listing
position:relative;
margin-top:40px;
margin-right:auto;
margin-left:auto;
.team-listing li
display:inline-block;
overflow: hidden;
float:left;
height: 340px;
list-style-position:inside;
margin: 1px 1px 1px 1px;
background-color:#fff;
.team-listing ul
display: flex;
flex-wrap: wrap;
justify-content: center;
flex-direction: row;
flex-flow: row wrap;
flex-shrink: 1;
flex-grow: 1;
float: left;
min-width: 0;
max-width: 100%;
position: relative;
filter: drop-shadow(5px 5px 5px rgba(2,2,22,0.1));
a
display: inline-block;
article
position: relative;
width: 300px;
height: 350px;
/* prevent scaled circle ring from triggering hover */
overflow: hidden;
/* create the colour overlay */
article:after
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: none;
background: rgba(0, 255, 255, .2);
z-index: 3;
/* place full image above SVG */
.img-full
position: absolute;
top: 0;
right:0;
z-index: 2;
/* hide the full image initially */
display: none;
.circle-ring
position: absolute;
top: 0;
z-index: 3;
/* initially hidden with opacity so it can be animated */
opacity: 0;
transform-origin: 50% 50%;
transform: scale(1.8);
transition: transform .3s ease, opacity .4s ease;
a:hover .img-full,
a:hover article:after
position:absolute;
display: block;
a:hover .circle-ring
opacity: 1;
transform: scale(1);
.bio
position: absolute;
bottom: 0;
padding: 1rem 2rem;
color: #000;
/* keep text above SVG, full image and overlay */
z-index: 4;
a:hover .bio
color: #FFF;
/* general */
h2,
h4
margin: 0;
font-family: sans-serif;
h4
font-weight: 300;
【问题讨论】:
当您可以将一个元素用于标准视图和悬停视图(如我们的灵感 360i.com)时,为什么要加载同一张图片两次? 我最初尝试过这样做,但我不知道如何在悬停时获得圆形轮廓(请参阅此处的原始代码:jsfiddle.net/mzechar/em5yh164 和此处发布:***.com/questions/50937186/…) 【参考方案1】:对 SVG 内容有信心。无需在其间定义两个 <svg>
元素和 HTML <img>
。只需将图像放置在<svg>
父级内的<image>
标记中,然后根据悬停状态设置/删除剪辑路径。
剪辑路径本身保留在单独但隐藏的<svg>
中,因此它可以重复用于多个图像。
如果图像尺寸和位置都不同,因此它们显示正确的剪辑内容,最好不要依赖preserveAspectRatio
,而是绝对设置它们。 (在 <svg>
元素上设置 overflow:hidden
更多的是一种预防措施,因为规范已经改变了一点,无论这是否是默认值。)
a
display: inline-block;
article
position: relative;
width: 300px;
height: 350px;
overflow: hidden;
article::after
content: '';
position: absolute;
top: 0;
right: 0;
bottom: 0;
left: 0;
display: none;
background: rgba(0, 255, 255, .2);
z-index: 3;
.portrait
position: relative;
width: 300px;
height: 300px;
overflow: hidden;
.portrait image
clip-path: url(#circle);
a:hover .portrait image
clip-path: none;
a:hover article:after
position: absolute;
display: block;
.ring
fill: none;
stroke: white;
stroke-width: 1;
opacity: 0;
transform-origin: 50% 50%;
transform: scale(1.8);
transition: transform .3s ease, opacity .4s ease;
a:hover .ring
opacity: 1;
transform: scale(1);
.bio
position: absolute;
bottom: 0;
padding: 1rem 2rem;
color: #000;
h2
font-size: 1.5em;
font-weight: bold;
h4
font-weight: 300;
h2, h4
margin: 0;
font-family: sans-serif;
<svg >
<clipPath id="circle">
<circle cx="150" cy="150" r="100"/>
</clipPath>
</svg>
<a href="#">
<article>
<svg class="portrait" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 300">
<!-- no automatic sizing for SVG image, width and height must be set -->
<image x="-100" y="0"
xlink:href="http://api.leafsnap.com/v1/team/images/columbia/Neeraj.jpg?h=300"/>
<circle class="ring" cx="150" cy="150" r="100" />
</svg>
<div class="bio">
<h2>Chun-Kang Chen</h2>
<h4>Article Subtitle</h4>
</div>
</article>
</a>
【讨论】:
您对如何让图像也填充白色容器框有什么建议吗? 将<svg>
的宽度和高度设置为100%(如果<article>
是您的意思。)显然,您还必须调整<image>
的尺寸。两种选择:绝对定位和手动找到正确的纵横比,或者像你一样,将宽度/高度设置为 100% 和 preserveAspectRatio="... slice"
我愿意接受这个答案 - 但我不知道如何像在 OP 中那样添加背景颜色和背景图像(线性渐变)
我已经用article::after
重新添加了覆盖,它仍然像以前一样工作。你的问题在哪里有梯度? - 如果您想知道为什么看不到图像,那是一个安全问题。请参阅jsfiddle.net/0wa65etj,它可以工作。【参考方案2】:
剪裁你的图片,扔掉那些无用的标签,每张图片只使用一次。 希望这会有所帮助:
section.team
margin: auto;
background: #fefefe;
.team-listing
position: relative;
margin: 40px auto 0;
display: flex;
filter: drop-shadow(5px 5px 5px rgba(2, 2, 22, 0.1));
.team-listing li
overflow: hidden;
height: 350px;
list-style: none;
margin: 1px;
background-color: #fff;
article
position: relative;
top: 0;
width: 300px;
height: 300px;
overflow: hidden;
display: flex;
align-items: center;
justify-content: center;
.img-full
-webkit-clip-path: circle(30% at 50% 50%);
clip-path: circle(30% at 50% 50%);
width: 500px;
a:hover .img-full
-webkit-clip-path: none;
clip-path: none;
filter: sepia(100%);
.circle-ring
position: absolute;
top: 0;
z-index: 3;
opacity: 0;
transform-origin: 50% 50%;
transform: scale(1.8);
transition: transform 0.3s ease, opacity 0.4s ease;
a:hover .circle-ring
opacity: 1;
transform: scale(1);
.bio
position: absolute;
bottom: 0;
margin: 2rem;
color: #000;
a:hover .bio > h2
color: #fff;
h2,
h4
margin: 0;
font-family: sans-serif;
h4
font-weight: 300;
<section class="content-wrapper team">
<ul class="team-listing">
<li>
<a href="#">
<article>
<img class="img-full" src="https://i.imgur.com/6eRLJ4I.jpg" >
<svg viewBox="0 0 100 100" class="circle-ring">
<circle cx="50" cy="50" r="35" stroke="white" stroke- fill="transparent" />
</svg>
</article>
<div class="bio">
<h2>Article Title</h2>
<h4>Article Subtitle</h4>
</div>
</a>
</li>
<li>
<a href="#">
<article>
<img class="img-full" src="https://i.imgur.com/6eRLJ4I.jpg" >
<svg viewBox="0 0 100 100" class="circle-ring">
<circle cx="50" cy="50" r="35" stroke="white" stroke- fill="transparent" />
</svg>
</article>
<div class="bio">
<h2>Article Title</h2>
<h4>Article Subtitle</h4>
</div>
</a>
</li>
</ul>
</section>
【讨论】:
以上是关于将全尺寸图像的大小和比例与 SVG 视图框匹配的主要内容,如果未能解决你的问题,请参考以下文章