yyamazaki0417
@yyamazaki0417

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

SVGでモーフィングアニメーションを実現させたい

解決したいこと

Snap.svgとjavascritpを使用して、SVGのモーフィングアニメーションを制作したいです。

例)
具体的には、以下のアニメーションを制作したいです。
https://codepen.io/givemocean/pen/mdyzJGy

発生している問題・エラー

私が、作成するSVGのパスだと以下のようなぎこちない動きになります。
https://codepen.io/banananan/pen/GRYxMvB

該当するソースコード

こちらが私が作成したパスの記述です。

  // ↓私が作成したパスが格納された配列
  let blamePathListTest = [
    "m122,.5c67.1,0,121.5,54.4,121.5,121.5s-54.4,121.5-121.5,121.5S.5,189.1.5,122,54.9.5,122,.5",
    "m16.06,16.06h211.89v211.89H16.06V16.06",
    "m122,.5c67.1,0,121.5,54.4,121.5,121.5s-54.4,121.5-121.5,121.5S.5,189.1.5,122,54.9.5,122,.5",
    "m16.06,16.06h211.89v211.89H16.06V16.06",
  ];

こちらがソース全体です。
コメントアウトしている、「↓オリジナルのパスが格納された配列」だと、滑らかに

  class Blame {
    /**
     * @param {Array} blamePathList Coordinates of each blames' modification
     */
    constructor(blamePathList) {
      this.blamePathList = this.getBlameAbsolutePathList(blamePathList);
      gsap.timeline().to("#js-blame-path", {
        duration: 0,
        attr: { d: Snap.path.toAbsolute(blamePathList[0]) },
      }); // transform the current path value from relative to absolute
    }

    /**
     * @description Convert path generated by design apps (relative path) to the plugin oriented path (absolute path). Also you can convert each path by using https://codepen.io/thednp/pen/EgVqLw/ or change svg through https://shapeshifter.design/
     * @param {Array} pathList Coordinates of each blames' modification
     */
    getBlameAbsolutePathList(pathList) {
      return pathList.map(function (path) {
        return Snap.path.toAbsolute(path).toString();
      });
    }

    /**
     * @description Morph the blame
     * @param {string} elementQuerySelector Reference to the path element should be animated
     * @param {Array} pathList Stages of the morphing
     */
    animateBlamePath(elementQuerySelector, pathList) {
      let duration = 1;
      this.blamePathTimeline = gsap.timeline({
        defaults: {
          duration: duration,
          ease: Elastic.easeInOut.config(0.7, 0.4),
        },
        repeat: "-1",
      });

      this.blamePathTimeline
        .to(elementQuerySelector, { attr: { d: pathList[1] } })
        .to(elementQuerySelector, { attr: { d: pathList[2] } })
        .to(elementQuerySelector, { attr: { d: pathList[3] } })
        .to(elementQuerySelector, { attr: { d: pathList[0] } });
    }

    /**
     * @description Start the blame morphing
     */
    startBlamePathAnimation() {
      this.animateBlamePath("#js-blame-path", this.blamePathList);
    }
  } // class blame

  /**
   * @description Declare array of the blames' path
   */
  // ↓オリジナルのパスが格納された配列
  // let blamePathListTest = [
  //   "M530.3 510.9c306-17 374-12 406-89 57.3-138-188-394-486-394-159.1 0-513.7 382.7-405 585 36 67 248-98 485-102z",
  //   "M330.5 501.6c379 5 246 118 355 118 99 0 391.9-387 240-543-111-114-940 27-924 314 4.5 80.8 14 112 329 111z",
  //   "M264.7 374.1c126 40-196 143-94 262 112.2 130.9 867-398 735.2-558.1C804.7-44.9 173.7-31.9 58.7 184.1c-29 54.4-8 146 206 190z",
  //   "M224.9 398.8c136 42-29.4 186.7 58 229 153 74 735.1-119.3 673-340-36-128-782.7-462.8-925-136-64 147 16 223 194 247z",
  // ];

  // ↓私が作成したパスが格納された配列
  let blamePathListTest = [
    "m122,.5c67.1,0,121.5,54.4,121.5,121.5s-54.4,121.5-121.5,121.5S.5,189.1.5,122,54.9.5,122,.5",
    "m16.06,16.06h211.89v211.89H16.06V16.06",
    "m122,.5c67.1,0,121.5,54.4,121.5,121.5s-54.4,121.5-121.5,121.5S.5,189.1.5,122,54.9.5,122,.5",
    "m16.06,16.06h211.89v211.89H16.06V16.06",
  ];

  window.onload = (function () {
    let blame = new Blame(blamePathListTest);
    blame.startBlamePathAnimation();
  })();

自分で試したこと

1

パスが、Snap.path.toAbsolute(path)の記述によって絶対座標になっていたので、Snap.path.toRelative(path)にして相対パスに変換しました。

2

パスの数やアンカーの数をモーフィングさせるSVGで合わせました。

0

1Answer

モーフィングさせたい複数のパス(つまりblamePathListTest内で定義されている4つのパス)は、頂点の数やパスの種類アンカーの数が完全に一致している必要があるかと思います。

0Like

Comments

  1. @yyamazaki0417

    Questioner

    ご回答いただきありがとうございます。

    >頂点の数やパスの種類アンカーの数が完全に一致している
    こちら、意識して作成していたと思っていましたが、再度確認してみます。

    半ば諦めて取り組まなくなっていましたが、ご助言をいただいたことを機にもう一度取り組んでみます。

Your answer might help someone💌