我有一个 svg,它有一个形状,当我单击链接时,我想在这个形状上放置不同的图像,并且我想在图像更改时应用过渡。
我使用了 fill 属性,并使用 javascript 将图像的 url 放入填充中,图像出现了,但我无法在 fill 属性上应用转换。
HTML 代码:
<svg id="logo" viewbox="0 0 322 419.6">
<path class="st0"d="M289.9,234.5c31.4-37.8,41.3-91.4,22.8-140.8c-27.9-74.6-111-112.4-185.5-84.5c-48.8,18.3-79.9,60.7-90.9,108 C36.1,117.6,5.7,268,0.7,318.4c-1.1,10.9-0.6,28.5,5,43.4c17.4,46.6,69.5,69.4,116.1,52c16.1-6,29.4-16.6,39.3-29.2 c0,0,0.1-0.2,0.1-0.2S258.3,272.5,289.9,234.5z" />
<defs>
<pattern id="imageFill1" x="0" y="0" width="1"height="1" >
<image id = "patternImage "xlink:href="images-testing/production.jpg" height="100%"/>
</pattern>
<pattern id="imageFill2" x="0" y="0" width="1"height="1">
<image id = "patternImage "xlink:href="images-testing/branding.jpg"height="100%"/>
</pattern>
<pattern id="imageFill3" x="0" y="0" width="1"height="1">
<image id = "patternImage "xlink:href="images-testing/media.jpg" height="100%"/>
</pattern>
</defs>
</svg>
<h1 style="color:white"><a class="image-link" data-fill="#imageFill1">Production</a></h1>
<h1 style="color:white"><a class="image-link" data-fill="#imageFill2">Branding</a></h1>
<h1 style="color:white"><a class="image-link" data-fill="#imageFill3">Media</a></h1>
JS:
<script>
const rect = document.getElementById('logo');
const toggleLinks = document.querySelectorAll('.image-link');
toggleLinks.forEach(link => {
link.addEventListener('click', function() {
const fillAttribute = this.getAttribute('data-fill');
rect.style.setProperty('fill', `url(${fillAttribute})`);
});
});
</script>
CSS:
#logo{
transition: fill 0.5s ease;
}
Css 动画或过渡实际上只是插值属性值 – 前提是这些值可以插值:你不能在 URL 之间插值。
相反,您需要堆叠所有图像并更改它们的顺序和不透明度以获得交叉淡入淡出过渡。
const logo = document.getElementById("logo");
const shape = document.getElementById("shape");
const toggleLinks = document.querySelectorAll(".image-link");
const slides = document.querySelectorAll('.slide')
toggleLinks.forEach((link) => {
link.addEventListener("click", (e)=> {
const slideID = e.currentTarget.getAttribute("data-fill");
const slide = document.getElementById(slideID);
// reset previously acive
slides.forEach(slide=>{
slide.classList.remove('prev')
slide.classList.remove('active')
})
slide.previousElementSibling.classList.add('prev')
slide.classList.add('active')
// change stack order
logo.append(slide)
});
});
svg{
width:10em;
}
a{
cursor: pointer
}
.prev{
fill-opacity:1;
}
.active {
animation: fadeIn 1s forwards;
}
@keyframes fadeIn{
0%{
fill-opacity:0;
}
100% {
fill-opacity: 1;
}
}
<svg id="logo" viewbox="0 0 322 419.6">
<defs>
<path id="shape" class="st0" d="m289.9 234.5c31.4-37.8 41.3-91.4 22.8-140.8-27.9-74.6-111-112.4-185.5-84.5-48.8 18.3-79.9 60.7-90.9 108-.2.4-30.6 150.8-35.6 201.2-1.1 10.9-.6 28.5 5 43.4 17.4 46.6 69.5 69.4 116.1 52 16.1-6 29.4-16.6 39.3-29.2 0 0 .1-.2.1-.2s97.1-111.9 128.7-149.9z" />
<pattern id="imageFill1" x="0" y="0" width="1" height="1">
<image id="patternImage1" href="https://picsum.photos/id/237/200/300" width="100%" height="100%" preserveAspectRatio="xMinYMin slice" />
</pattern>
<pattern id="imageFill2" x="0" y="0" width="1" height="1">
<image id="patternImage2" href="https://picsum.photos/id/236/200/300" width="100%" height="100%" preserveAspectRatio="xMinYMin slice" />
</pattern>
<pattern id="imageFill3" x="0" y="0" width="1" height="1">
<image id="patternImage3" href="https://picsum.photos/id/230/200/300" width="100%" height="100%" preserveAspectRatio="xMinYMin slice" />
</pattern>
</defs>
<use id="slide1" class="slide" href="#shape" fill="url(#imageFill1)" />
<use id="slide2" class="slide" href="#shape" fill="url(#imageFill2)" />
<use id="slide3" class="slide active" href="#shape" fill="url(#imageFill3)" />
</svg>
<h2><a class="image-link" data-fill="slide1">Production</a></h2>
<h2><a class="image-link" data-fill="slide2">Branding</a></h2>
<h2><a class="image-link" data-fill="slide3">Media</a></h2>
我正在使用
<use>
元素克隆填充形状。 <use id="slide1" class="slide" href="#shape" fill="url(#imageFill1)" />
<use id="slide2" class="slide" href="#shape" fill="url(#imageFill2)" />
<use id="slide3" class="slide active" href="#shape" fill="url(#imageFill3)" />
我们可以通过
svg.append()
轻松地将当前图像移动到顶部。