【问题标题】:Saw an interesting effect for the button看到按钮的有趣效果
【发布时间】:2019-04-26 14:05:39
【问题描述】:

我想在将鼠标悬停在 svg 对象上时创建与此站点 http://animejs.com/ 上完全相同的效果。

为此,我打开了 inkscape 并绘制了一条路径并保存了悬停前后的两种状态。

第一个状态:

<svg viewBox="0 0 210 297" xmlns="http://www.w3.org/2000/svg">

 <path d="m11 103c64-2.5 123-1.5 178 0v42c-61 3.5-120 0.43-178 0z"
 style="fill:none; stroke:#ff17ff;"/>
</svg>

第二个状态

<svg viewBox="0 0 210 297" xmlns="http://www.w3.org/2000/svg">

 <path d="m11 103c62-7.8 121-6.3 178 0v42c-61 9.7-120 6.3-178 0z" 
       style="fill:none;stroke:#ff17ff"/>
</svg>

很可能需要在js/jquery中完成,告诉我如何实现这个效果?我怎样才能以如此灵活的方式改变路径?

【问题讨论】:

    标签: jquery animation svg smil


    【解决方案1】:

    要对按钮的轮廓进行动画处理,需要对参数d补丁进行动画处理

    <animate attributeName="d" values="path1;path2" dur="2s" begin="btn.mouseover" /> 
    

    .container {
    width:25%;
    height:25%;
    }
    <div class="container">
    <svg   viewBox="0 0 210 297" xmlns="http://www.w3.org/2000/svg">
    
     <path id="btn"  d="m11 103c64-2.5 123-1.5 178 0v42c-61 3.5-120 0.43-178 0z"
     style="fill:none; stroke:#ff17ff;">
     <animate attributeName="d" values="m11 103c64-2.5 123-1.5 178 0v42c-61 3.5-120 0.43-178 0z;m11 103c62-7.8 121-6.3 178 0v42c-61 9.7-120 6.3-178 0z" dur="1s" begin="btn.mouseover" />
     </path>
     <text x="23" y="136" font-size="36" >mouseover</txt>
    </svg>
    </div>

    【讨论】:

    • 它似乎以另一种方式存在 - 更有弹性......但作为一个合适的例子......谢谢......
    • 是的......我的评分很低,我不能举手
    • 但还有另一个问题——我在 ruSo 看到过这个问题,但没有人给出答案……只是从网站上偷了代码……
    【解决方案2】:

    我看到已经有答案了,但是因为我已经准备好了,所以我将其发布。我使用的是 Javascript 而不是 SMIL 动画。

    我首先准备好了路径。如果您看一下,我已将每个命令都转换为C

    let rid = null;
    let ry = [];
    let speed = 1 / 10;
    
    class pathsPair {
      constructor(thePath, yes, no) {
        this.path = thePath;
        this.yes = yes;
        this.no = no;
        this.vals = this.getArgsRy(yes);
        this.target = this.getArgsRy(no);
        this.targetAlp = 0;
        this.alp = 1;
        this.light = 70;
      }
    
      getArgsRy(path) {
        let d = path.getAttribute("d").replace(/\r?\n|\r/g, ""); //remove breaklines
        if (d.charAt(0) == "m") {
          d = "M" + d.slice(1);
        }
        let argsRX = /(?=[a-zA-Z])/;
        let args = d.split(argsRX);
    
        let ArgsRy = [];
    
        args.map(arg => {
          let argRy = arg
            .slice(1)
            .replace(/\-/g, " -")
            .split(/[ ,]+/);
          argRy.map((p, i) => {
            if (p == "") {
              argRy.splice(i, 1);
            }
          });
    
          for (let i = 0; i < argRy.length; i++) {
            argRy[i] = parseFloat(argRy[i]);
          }
    
          argRy.unshift(arg[0]);
          ArgsRy.push(argRy);
        });
    
        return ArgsRy;
      }
    
      morph() {
        let newD = "";
    
        this.vals.map((v, vi) => {
          let newStr = v[0];
          for (let i = 1; i < v.length; i++) {
            this.updateProp(vi, i);
    
            newStr += v[i].toFixed(3) + " ";
          }
          newD += newStr + " ";
        }); //
        this.path.setAttributeNS(null, "d", newD);
      }
    
      updateProp(vi, i) {
        let dist = this.target[vi][i] - this.vals[vi][i];
        let vel = dist / 10;
        this.vals[vi][i] += vel;
      }
    
      sayNO() {
        this.target = this.getArgsRy(this.no);
        this.targetAlp = 0;
      }
    
      sayYES() {
        this.target = this.getArgsRy(this.yes);
        this.targetAlp = 1;
      }
    }
    
    let the_pair = new pathsPair(morphingPath, _2, _1);
    console.log(the_pair);
    svg.addEventListener("mouseover", function() {
      console.log(rid);
      if (rid) {
        window.cancelAnimationFrame(rid);
        rid = null;
      }
      the_pair.sayYES();
      Frame();
    });
    svg.addEventListener("mouseleave", function() {
      
      if (rid) {
        window.cancelAnimationFrame(rid);
        rid = null;
      }
      the_pair.sayNO();
      Frame();
    });
    
    function Frame() {
      rid = window.requestAnimationFrame(Frame);
      the_pair.morph();
    }
    
    window.addEventListener("load", function() {
      Frame();
    });
    svg{border:1px solid}
    #morphingPath{fill:transparent; stroke:black;}
    <svg id="svg" viewBox="0 90 210 70" xmlns="http://www.w3.org/2000/svg">
    <defs>
     <path id="_1" d="M11.000, 103.000 C75.000, 100.500 134.000, 101.500 189.000, 103.000 C189.000, 117.000 189.000, 131.000 189.000, 145.000 C128.000, 148.500 69.000, 145.430 11.000, 145.000 z"
    />
      
       <path id="_2" d="M11.000, 103.000 C73.000, 95.200 132.000, 96.700 189.000, 103.000 C189.000, 117.000 189.000, 131.000 189.000, 145.000 C128.000, 154.700 69.000, 151.300 11.000, 145.000 z" 
           />
      </defs>
      
      <path id="morphingPath" d=""
     style="fill:none; stroke:#ff17ff;" />
    </svg>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-08
      • 2017-10-04
      • 2023-03-31
      • 2014-02-14
      • 2012-11-05
      • 2011-05-25
      • 1970-01-01
      • 2014-02-27
      相关资源
      最近更新 更多