在链接悬停时为 SVG 设置动画

Posted

技术标签:

【中文标题】在链接悬停时为 SVG 设置动画【英文标题】:Animate SVG on link hover 【发布时间】:2022-01-10 09:00:06 【问题描述】:

我在一组菜单项下有这个 SVG。我想在选择的任何菜单项下为拱形位设置动画。

然后当单击菜单项时,拱门应保留为页面标记。我尝试过使用背景图像,并为位置设置动画,或者为每个链接使用伪状态,但问题总是没有落在菜单项的中心,并且出现边界线,因为它需要是一个带有切口的拱门有道理吗?

CODEPEN

.site-header 
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 10001;
    transition: all 0.3s ease 0.3s;


.inner-header 
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  


.drawer-menu 
    width:50%;


.inner-menu 
    position:relative;
    padding:0 40px;


ul.menu-nav 
    display:flex;
    flex-wrap:wrap;
    width:100%;
    justify-content:space-between;
  margin:0;
  padding:0;
  list-style:none;


ul.menu-nav li 
  padding:30px 0 60px;
  position:relative;
  


ul.menu-nav li a 

<header id="masthead" class="site-header">
        <div class="inner-header">

            <div class="drawer-menu">
                <div class="inner-menu">
                    <ul class="menu-nav">
                        <li><a href="#work">Work</a></li>
                        <li><a href="#interesting">Interesting</a></li>
                        <li><a href="#useful">Useful</a></li>
                        <li><a href="#about">About</a></li>
                        <li><a href="#contact">Contact</a></li>
                    </ul>
                </div>
            </div>
            
            <!-- #site-navigation -->

            <div class="site-branding">
                <a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"></a>
            </div><!-- .site-branding -->

        </div>

  <?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 26.0.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
     viewBox="0 0 1190.55 52.22" style="enable-background:new 0 0 1190.55 52.22;" xml:space="preserve">
<style type="text/css">
    .st0fill:none;stroke:#000000;stroke-miterlimit:10;
</style>
<line class="st0" x1="0" y1="43.48" x2="581.13" y2="43.48"/>
<line class="st0" x1="609.42" y1="43.48" x2="1190.49" y2="43.48"/>
<path class="st0" d="M580.64,43.48V21.53c0-8.08,6.55-14.63,14.63-14.63s14.63,6.55,14.63,14.63v21.95"/>
</svg>

    </header><!-- #masthead -->

我尝试使用 css 或 jquery 定位路径,但它不起作用。谁能指出我正确的方向?

非常感谢!!

【问题讨论】:

如果你想用 svg 做,你可以试试这个:keith-wood.name/svg.html 【参考方案1】:

这是一种解决方案。我已将 cmets 添加到描述我所做的一切的代码中。

// Get a list of the <li><a> elements
var menuItems = document.querySelectorAll(".menu-nav li a");
// Get a reference to the <g id="arch"> group in the SVG
var arch = document.getElementById("arch");

// For each meny item, attach to it a "mouseenter" event handler
menuItems.forEach(item => 
  item.addEventListener("mouseenter", moveArchTo);
);


function moveArchTo(evt) 
  // Get the bounding box of the link element
  var pos = evt.target.getBoundingClientRect();
  // Calculate the horizontal position of the centre of the link element
  var linkCentreX = pos.x + pos.width / 2;
  // Work out how far we need to move the arch (and lines) so that it is under the centre of the link.
  // 594 is found by experimentation. It's the 580.64, from the <path d="">, plus a bit more to the centre of the arch.
  var dx = linkCentreX - 594;
  // Add a translation transform to the "arch" group of elements to shift them to the desited position
  arch.setAttribute("transform", "translate("+dx+", 0)");
.site-header 
    position: fixed;
    top: 0;
    left: 0;
    width: 100%;
    z-index: 10001;
    transition: all 0.3s ease 0.3s;


.inner-header 
    display: flex;
    flex-wrap: wrap;
    align-items: center;
  


.drawer-menu 
    width:50%;


.inner-menu 
    position:relative;
    padding:0 40px;


ul.menu-nav 
    display:flex;
    flex-wrap:wrap;
    width:100%;
    justify-content:space-between;
  margin:0;
  padding:0;
  list-style:none;


ul.menu-nav li 
  padding:30px 0 60px;
  position:relative;
  


ul.menu-nav li a 

<header id="masthead" class="site-header">
        <div class="inner-header">

            <div class="drawer-menu">
                <div class="inner-menu">
                    <ul class="menu-nav">
                        <li><a href="#work">Work</a></li>
                        <li><a href="#interesting">Interesting</a></li>
                        <li><a href="#useful">Useful</a></li>
                        <li><a href="#about">About</a></li>
                        <li><a href="#contact">Contact</a></li>
                    </ul>
                </div>
            </div>
            
            <!-- #site-navigation -->

            <div class="site-branding">
                <a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home"></a>
            </div><!-- .site-branding -->

        </div>

    <!-- I've removed unnecessary header attributes from the SVG to tidy things up -->
    <!-- I've also forced the width to the same as the viewBox width, so that the SVG is forced to be at 1:1 scale.
         Otherwise the transform we add later won't move the right amount. -->
    <svg id="Layer_1"  viewBox="0 0 1190 52">
      <style type="text/css">
        .st0fill:none;stroke:#000000;stroke-miterlimit:10;
      </style>
      <!-- Group the three elements together so we can move them all as one with a transform later -->
      <g id="arch">
        <line class="st0" x1="0" y1="43.48" x2="581.13" y2="43.48"/>
        <!-- note I've increased the x2 attribute here so we don't see the end of the line when we move these elements to the left later -->
        <line class="st0" x1="609.42" y1="43.48" x2="3000" y2="43.48"/>
        <path class="st0" d="M580.64,43.48V21.53c0-8.08,6.55-14.63,14.63-14.63s14.63,6.55,14.63,14.63v21.95"/>
      </g>
    </svg>

    </header><!-- #masthead -->

【讨论】:

以上是关于在链接悬停时为 SVG 设置动画的主要内容,如果未能解决你的问题,请参考以下文章

tailwind css - 在悬停时为另一个元素设置动画

css 链接和按钮的通用过渡样式为悬停上的链接设置动画

悬停链接并在 SVG 中更改颜色 [重复]

逐渐为 SVG 设置动画

仅在将鼠标悬停在圆圈上时才沿文本路径为 SVG 文本设置动画

无限 SVG 动画在悬停时平滑地检索初始状态