📖

フェードアニメ(VanillaJS)

2024/01/21に公開

フェードアニメVanillaJSバージョンです

フェードアニメクラスバージョンはこちらをご覧ください
https://zenn.dev/icchicw/articles/5a6968f5daee9c

script.js
fadeAnime({
  top: "-10%",
  bottom: "-10%",
  once: false //アニメーション継続
});

function fadeAnime(obj) {
  obj.top ? obj.top : obj.top = "0px"; //rootMargin top
  obj.bottom ? obj.bottom : obj.bottom = "0px"; //rootMargin bottom
  obj.threshold ? obj.threshold : 0; //threshold
  typeof obj.once == "undefined" ? obj.once = true : obj.once; //アニメーション継続するか否か
  let addCls; //クラス付与用
  let removeCls; //クラス除去用

  let DOM = [];
  let dom;

  dom = document.querySelectorAll(".js-fadeIn");
  DOM.push(dom);
  dom = document.querySelectorAll(".js-fadeOut");
  DOM.push(dom);
  dom = document.querySelectorAll(".js-fadeRight");
  DOM.push(dom);
  dom = document.querySelectorAll(".js-fadeLeft");
  DOM.push(dom);

  //フラグ設定
  let fadeFlags = [];
  DOM.forEach(d => {
    d.length != 0 ? fadeFlags.push(true) : fadeFlags.push(false);
  });
  //フェード系のDOMが存在しない場合は終了
  if (fadeFlags.every(fade => fade === false)) return;

  function addClassFunc(target) {
    const targetClass = target.classList;
    targetClass.forEach(t => {
      if (t.indexOf("js-fade") == 0) addCls = `u-${t.split("js-")[1]}`;
    });
    targetClass.add(addCls);
  }

  function removeClassFunc(target) {
    const targetClass = target.classList;
    targetClass.forEach(t => {
      if (t.indexOf("js-fade") == 0) removeCls = `u-${t.split("js-")[1]}`;
    });
    targetClass.remove(removeCls);
  }

  //オブザーバー
  const callback = (entries) => {
    entries.forEach(entry => {
      if (entry.isIntersecting) {
        log(entry.target)
        //交差したらクラス付与
        addClassFunc(entry.target);
        if (obj.once) {
          //onceがtrueの場合は監視終了
          observer.unobserve(entry.target);
        }
      } else {
        //交差しない場合はクラス除去
        removeClassFunc(entry.target);
      }
    });
  }

  const options = {
    root: null, //ビューポートをルート要素とする
    rootMargin: `${obj.top} 0px ${obj.bottom} 0px`, //判定基準:ビューポート
    threshold: 0, //閾値
    once: obj.once,
  };

  const observer = new IntersectionObserver(callback, options);

  DOM.forEach(fade => {
    fade.forEach(item => observer.observe(item));
  });
}

Discussion