【问题标题】:Line button animation线条按钮动画
【发布时间】:2019-09-12 03:59:10
【问题描述】:

我需要在按钮上悬停时制作动画线, 从顶线的中间开始,这条线应该朝不同的方向走并改变颜色。 关于应该像这样工作,但它从顶部中间开始:

codepen.io

 <section class="hero">
      <div class="svg-container">
         <a class="magic-link" href="#">
            <svg class="gradient" height="60" width="320" xmlns="http://www.w3.org/2000/svg">
              <defs>
                <linearGradient id="gradient">
                  <stop offset="0%" stop-color="#EB3349" />
                  <stop offset="95%" stop-color="#EB3349" />
                </linearGradient>
              </defs>
              <rect class="rect-shape" height="60" width="320" />
              <div class="text">Hover me</div>
            </svg>
         </a>
      </div>
    </section>

【问题讨论】:

    标签: javascript jquery css svg


    【解决方案1】:

    检查一下,现在这条线是顺时针方向的。

    只需使用.rect-shapestroke-dasharraystroke-dashoffset 属性即可获得您最满意的效果:

     stroke-dasharray: 140 620;
     stroke-dashoffset: 274;
    

    当然你可以设置正或负的 dashoffset 值,然后你就可以改变动画的方向

    在官方页面这里举一个更详细的例子:

    https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dasharray https://developer.mozilla.org/en-US/docs/Web/SVG/Attribute/stroke-dashoffset

    body {
      max-width: 100vh;
      margin: 0;
      color: #fff;
      font-size: 24px;
      background: #EB3349;
    }
    
    a, a:hover, a:focus, a:active, a:visited {
      color: #fff;
      text-decoration: none;
      font-size: 1em;
    }
    
    .hero {
      height: 100vh;
      width: 100vw;
    }
    
    .svg-container {
      position: relative;
      top: 50%;
      transform: translateY(-50%);
      margin: 0 auto;
      width: 320px;
      max-height: 60px;
      cursor: default;
    }
    
    .rect-shape {
      stroke-dasharray: 130 620;
      stroke-dashoffset: 274;
      stroke-width: 8px;
      fill: url(#gradient);
      /* modify this with the color you want */
      stroke: #fff;
      transition: stroke-width 1s, stroke-dashoffset 1s, stroke-dasharray 1s;
    }
    
    .text {
      font-family: serif;
      font-size: 22px;
      line-height: 32px;
      letter-spacing: 4px;
      color: #fff;
      top: -48px;
      position: relative;
      text-align: center;
    }
    
    .svg-container:hover .rect-shape {
      stroke-width: 2px;
      stroke-dashoffset: 0;
      stroke-dasharray: 760;
    }
    
    #gradient stop {
      transition: .5s all;
    }
    
    .svg-container:hover svg.gradient #gradient stop:first-child {
      stop-color: #EB3349;
    }
    
    .svg-container:hover svg.gradient #gradient stop:last-child {
      stop-color: #f45c43;
    }
    <section class="hero">
      <div class="svg-container">
         <a class="magic-link" href="#">
            <svg class="gradient" height="60" width="320" xmlns="http://www.w3.org/2000/svg">
              <defs>
                <linearGradient id="gradient">
                  <stop offset="0%" stop-color="#EB3349" />
                  <stop offset="95%" stop-color="#EB3349" />
                </linearGradient>
              </defs>
              <rect class="rect-shape" height="60" width="320" />
              <div class="text">Hover me</div>
            </svg>
         </a>
      </div>
    </section>

    【讨论】:

      【解决方案2】:

      要实现使用两条线同时为绘图设置动画的想法,您可以使用stroke-dasharray 属性。 stroke-dasharray 属性有几个参数对:

      stroke-dasharray =" dash space dash space "

      剩下的就是计算这些参数的必要值:

      按钮周长:320 + 60 + 320 + 60 = 760px

      周长的一半 - 这将是一条线的长度 - 380 像素

      要在绘制的初始阶段隐藏线条,请写stroke-dasharray = "0 380 0 380"

      也就是说,一个破折号是0,一个空格是380,一个破折号是0,一个空格是380

      总计:笔画长度 - 0,空格长度 - 760,即线条将被完全隐藏

      要完全显示两条闭合线:stroke-dasharray = "0 0 760 0"

      我们写动画公式:values = "0 380 0 380; 0 0 760 0"

      body {
        max-width: 100vh;
        margin: 0;
        color: #fff;
        font-size: 24px;
        background: #3A92CE;
      }
      
      a, a:hover, a:focus, a:active, a:visited {
        color: gold;
        text-decoration: none;
        font-size: 1em;
        
      }
      
      .hero {
        height: 100vh;
        width: 100vw;
       
      }
      
      .svg-container {
        position: relative;
        top: 50%;
        transform: translateY(-50%);
        margin: 0 auto;
        width: 320px;
        max-height: 60px;
        cursor: pointer;
        
        
      }
      
      .rect-shape {
        stroke:#E4E4E4;
        stroke-width:2;
        fill:transparent;
       }
      
      .text {
        font-family: serif;
        font-size: 26px;
        font-weight:bold;
        line-height: 32px;
        letter-spacing: 4px;
        color: #E4E4E4;
        top: -48px;
        position: relative;
        text-align: center;
      }
      <section class="hero">
        <div class="svg-container">
           <a class="magic-link" href="#">
              <svg class="gradient" id="svg1" height="60" width="320" xmlns="http://www.w3.org/2000/svg">
                <defs>
                  <linearGradient id="gradient">
                    <stop offset="0%" stop-color="#EB3349" />
                    <stop offset="95%" stop-color="#EB3349" />
                  </linearGradient>
                </defs>
                <rect class="rect-shape" id="rect1" height="60" width="320"   stroke-width="2"  />
      		  <polyline id="p1" points="0 0, 320 0, 320 60, 0 60, 0 0"  fill="transparent" stroke="#E4E4E4"
             		  stroke-width="8"   stroke-dashoffset="600" stroke-dasharray="0 380" >
      		   <animate id="an1"
      		    attributeName="stroke-dasharray"
      			values="0 380 0 380;0 0 760 0"
      			dur="1s"
      			begin="p1.mouseover"
      			fill="freeze"
      			restart="whenNotActive" /> 
      		<animate id="an2"
      		    attributeName="stroke-dasharray"
      			values="0 0 760 0;0 380 0 380"
      			dur="0.5s"
      			begin="an1.end"
      			fill="freeze"
      			restart="whenNotActive" /> 	
      			
      		 </polyline>	 
      		 
      		  
                <div class="text">Bottom middle</div>
              </svg>
           </a>
        </div>
      </section>

      中上

      要从另一个点开始动画,例如从按钮顶行的中间开始,你需要使用命令stroke-dashoffset = "220" 移动动画的起始点

      body {
        max-width: 100vh;
        margin: 0;
        color: #fff;
        font-size: 24px;
        background: #4A4A4A;
      }
      
      a, a:hover, a:focus, a:active, a:visited {
        color: gold;
        text-decoration: none;
        font-size: 1em;
        
      }
      
      .hero {
        height: 100vh;
        width: 100vw;
       
      }
      
      .svg-container {
        position: relative;
        top: 50%;
        transform: translateY(-50%);
        margin: 0 auto;
        width: 320px;
        max-height: 60px;
        cursor: pointer;
        
        
      }
      
      .rect-shape {
        stroke:#E4E4E4;
        stroke-width:2;
        fill:transparent;
       }
      
      .text {
        font-family: serif;
        font-size: 26px;
        font-weight:bold;
        line-height: 32px;
        letter-spacing: 4px;
        color: #E4E4E4;
        top: -48px;
        position: relative;
        text-align: center;
      }
      <section class="hero">
        <div class="svg-container">
           <a class="magic-link" href="#">
              <svg class="gradient" id="svg1" height="60" width="320" xmlns="http://www.w3.org/2000/svg">
                <defs>
                  <linearGradient id="gradient">
                    <stop offset="0%" stop-color="#EB3349" />
                    <stop offset="95%" stop-color="#EB3349" />
                  </linearGradient>
                </defs>
                <rect class="rect-shape" id="rect1" height="60" width="320"   stroke-width="2"  />
      		  <polyline id="p1" points="0 0, 320 0, 320 60, 0 60, 0 0"  fill="transparent" stroke="#E4E4E4"
             		  stroke-width="8"   stroke-dashoffset="220" stroke-dasharray="0 380" >
      		   <animate id="an1"
      		    attributeName="stroke-dasharray"
      			values="0 380 0 380;0 0 760 0"
      			dur="1s"
      			begin="p1.mouseover"
      			fill="freeze"
      			restart="whenNotActive" /> 
      		<animate id="an2"
      		    attributeName="stroke-dasharray"
      			values="0 0 760 0;0 380 0 380"
      			dur="0.5s"
      			begin="an1.end"
      			fill="freeze"
      			restart="whenNotActive" /> 	
      			
      		 </polyline>	 
      		 
      		  
                <div class="text">Top middle</div>
              </svg>
           </a>
        </div>
      </section>

      左上角

      body {
        max-width: 100vh;
        margin: 0;
        color: #fff;
        font-size: 24px;
        background: #4A4A4A;
      }
      
      a, a:hover, a:focus, a:active, a:visited {
        color: gold;
        text-decoration: none;
        font-size: 1em;
        
      }
      
      .hero {
        height: 100vh;
        width: 100vw;
       
      }
      
      .svg-container {
        position: relative;
        top: 50%;
        transform: translateY(-50%);
        margin: 0 auto;
        width: 320px;
        max-height: 60px;
        cursor: pointer;
        
        
      }
      
      .rect-shape {
        stroke:#E4E4E4;
        stroke-width:2;
        fill:transparent;
       }
      
      .text {
        font-family: serif;
        font-size: 26px;
        font-weight:bold;
        line-height: 32px;
        letter-spacing: 4px;
        color: #E4E4E4;
        top: -48px;
        position: relative;
        text-align: center;
      }
      <section class="hero">
        <div class="svg-container">
           <a class="magic-link" href="#">
              <svg class="gradient" id="svg1" height="60" width="320" xmlns="http://www.w3.org/2000/svg">
                <defs>
                  <linearGradient id="gradient">
                    <stop offset="0%" stop-color="#EB3349" />
                    <stop offset="95%" stop-color="#EB3349" />
                  </linearGradient>
                </defs>
                <rect class="rect-shape" id="rect1" height="60" width="320"   stroke-width="2"  />
      		  <polyline id="p1" points="0 0, 320 0, 320 60, 0 60, 0 0"  fill="transparent" stroke="#E4E4E4"
             		  stroke-width="8"   stroke-dashoffset="380" stroke-dasharray="0 380" >
      		   <animate id="an1"
      		    attributeName="stroke-dasharray"
      			values="0 380 0 380;0 0 760 0"
      			dur="1s"
      			begin="p1.mouseover"
      			fill="freeze"
      			restart="whenNotActive" /> 
      		<animate id="an2"
      		    attributeName="stroke-dasharray"
      			values="0 0 760 0;0 380 0 380"
      			dur="0.5s"
      			begin="an1.end"
      			fill="freeze"
      			restart="whenNotActive" /> 	
      			
      		 </polyline>	 
      		 
      		  
                <div class="text">Top left</div>
              </svg>
           </a>
        </div>
      </section>

      右上角

      body {
        max-width: 100vh;
        margin: 0;
        color: #fff;
        font-size: 24px;
        background: #3A92CE;
      }
      
      a, a:hover, a:focus, a:active, a:visited {
        color: gold;
        text-decoration: none;
        font-size: 1em;
        
      }
      
      .hero {
        height: 100vh;
        width: 100vw;
       
      }
      
      .svg-container {
        position: relative;
        top: 50%;
        transform: translateY(-50%);
        margin: 0 auto;
        width: 320px;
        max-height: 60px;
        cursor: pointer;
        
        
      }
      
      .rect-shape {
        stroke:#E4E4E4;
        stroke-width:2;
        fill:transparent;
       }
      
      .text {
        font-family: serif;
        font-size: 26px;
        font-weight:bold;
        line-height: 32px;
        letter-spacing: 4px;
        color: #E4E4E4;
        top: -48px;
        position: relative;
        text-align: center;
      }
      <section class="hero">
        <div class="svg-container">
           <a class="magic-link" href="#">
              <svg class="gradient" id="svg1" height="60" width="320" xmlns="http://www.w3.org/2000/svg">
                <defs>
                  <linearGradient id="gradient">
                    <stop offset="0%" stop-color="#EB3349" />
                    <stop offset="95%" stop-color="#EB3349" />
                  </linearGradient>
                </defs>
                <rect class="rect-shape" id="rect1" height="60" width="320"   stroke-width="2"  />
      		  <polyline id="p1" points="0 0, 320 0, 320 60, 0 60, 0 0"  fill="transparent" stroke="#E4E4E4"
             		  stroke-width="8"   stroke-dashoffset="60" stroke-dasharray="0 380" >
      		   <animate id="an1"
      		    attributeName="stroke-dasharray"
      			values="0 380 0 380;0 0 760 0"
      			dur="1s"
      			begin="p1.mouseover"
      			fill="freeze"
      			restart="whenNotActive" /> 
      		<animate id="an2"
      		    attributeName="stroke-dasharray"
      			values="0 0 760 0;0 380 0 380"
      			dur="0.5s"
      			begin="an1.end"
      			fill="freeze"
      			restart="whenNotActive" /> 	
      			
      		 </polyline>	 
      		 
      		  
                <div class="text">Top right</div>
              </svg>
           </a>
        </div>
      </section>

      左下

      body {
        max-width: 100vh;
        margin: 0;
        color: #fff;
        font-size: 24px;
        background: purple;
      }
      
      a, a:hover, a:focus, a:active, a:visited {
        color: gold;
        text-decoration: none;
        font-size: 1em;
        
      }
      
      .hero {
        height: 100vh;
        width: 100vw;
       
      }
      
      .svg-container {
        position: relative;
        top: 50%;
        transform: translateY(-50%);
        margin: 0 auto;
        width: 320px;
        max-height: 60px;
        cursor: pointer;
        
        
      }
      
      .rect-shape {
        stroke:#E4E4E4;
        stroke-width:2;
        fill:transparent;
       }
      
      .text {
        font-family: serif;
        font-size: 26px;
        font-weight:bold;
        line-height: 32px;
        letter-spacing: 4px;
        color: #E4E4E4;
        top: -48px;
        position: relative;
        text-align: center;
      }
      <section class="hero">
        <div class="svg-container">
           <a class="magic-link" href="#">
              <svg class="gradient" id="svg1" height="60" width="320" xmlns="http://www.w3.org/2000/svg">
                <defs>
                  <linearGradient id="gradient">
                    <stop offset="0%" stop-color="#EB3349" />
                    <stop offset="95%" stop-color="#EB3349" />
                  </linearGradient>
                </defs>
                <rect class="rect-shape" id="rect1" height="60" width="320"   stroke-width="2"  />
      		  <polyline id="p1" points="0 0, 320 0, 320 60, 0 60, 0 0"  fill="transparent" stroke="#E4E4E4"
             		  stroke-width="8"   stroke-dashoffset="440" stroke-dasharray="0 380" >
      		   <animate id="an1"
      		    attributeName="stroke-dasharray"
      			values="0 380 0 380;0 0 760 0"
      			dur="1s"
      			begin="p1.mouseover"
      			fill="freeze"
      			restart="whenNotActive" /> 
      		<animate id="an2"
      		    attributeName="stroke-dasharray"
      			values="0 0 760 0;0 380 0 380"
      			dur="0.5s"
      			begin="an1.end"
      			fill="freeze"
      			restart="whenNotActive" /> 	
      			
      		 </polyline>	 
      		 
      		  
                <div class="text">Bottom left</div>
              </svg>
           </a>
        </div>
      </section>

      右下角

      body {
        max-width: 100vh;
        margin: 0;
        color: #fff;
        font-size: 24px;
        background: purple;
      }
      
      a, a:hover, a:focus, a:active, a:visited {
        color: gold;
        text-decoration: none;
        font-size: 1em;
        
      }
      
      .hero {
        height: 100vh;
        width: 100vw;
       
      }
      
      .svg-container {
        position: relative;
        top: 50%;
        transform: translateY(-50%);
        margin: 0 auto;
        width: 320px;
        max-height: 60px;
        cursor: pointer;
        
        
      }
      
      .rect-shape {
        stroke:#E4E4E4;
        stroke-width:2;
        fill:transparent;
       }
      
      .text {
        font-family: serif;
        font-size: 26px;
        font-weight:bold;
        line-height: 32px;
        letter-spacing: 4px;
        color: #E4E4E4;
        top: -48px;
        position: relative;
        text-align: center;
      }
      <section class="hero">
        <div class="svg-container">
           <a class="magic-link" href="#">
              <svg class="gradient" id="svg1" height="60" width="320" xmlns="http://www.w3.org/2000/svg">
                <defs>
                  <linearGradient id="gradient">
                    <stop offset="0%" stop-color="#EB3349" />
                    <stop offset="95%" stop-color="#EB3349" />
                  </linearGradient>
                </defs>
                <rect class="rect-shape" id="rect1" height="60" width="320"   stroke-width="2"  />
      		  <polyline id="p1" points="0 0, 320 0, 320 60, 0 60, 0 0"  fill="transparent" stroke="#E4E4E4"
             		  stroke-width="8"   stroke-dashoffset="0" stroke-dasharray="0 380" >
      		   <animate id="an1"
      		    attributeName="stroke-dasharray"
      			values="0 380 0 380;0 0 760 0"
      			dur="1s"
      			begin="p1.mouseover"
      			fill="freeze"
      			restart="whenNotActive" /> 
      		<animate id="an2"
      		    attributeName="stroke-dasharray"
      			values="0 0 760 0;0 380 0 380"
      			dur="0.5s"
      			begin="an1.end"
      			fill="freeze"
      			restart="whenNotActive" /> 	
      			
      		 </polyline>	 
      		 
      		  
                <div class="text">Bottom right</div>
              </svg>
           </a>
        </div>
      </section>

      【讨论】:

        猜你喜欢
        • 2017-12-22
        • 1970-01-01
        • 2021-08-16
        • 2017-09-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多