看到了按钮的有趣效果

时间:2018-11-24 05:44:31

标签: jquery animation svg smil

当我将鼠标悬停在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中完成,告诉我如何实现此效果?如何以这种灵活的方式更改路径?

2 个答案:

答案 0 :(得分:2)

要对按钮的轮廓进行动画处理,您需要对参数<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>
unordered_map<int, unordered_map<int, int>> graph

答案 1 :(得分:1)

我看到已经有一个答案,但是由于我已经准备好了,所以我将其发布。我使用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>