用 url 填充 SVG 并在其上应用过渡

问题描述 投票:0回答:1

我有一个 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 svg transition fill
1个回答
0
投票

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()
轻松地将当前图像移动到顶部。

© www.soinside.com 2019 - 2024. All rights reserved.