d
o
t
-
l
i
n
e
-
f
o
r
m
Divide ClipPath Motion
GSAP + CSS

1.画像ブロック要素を複製して追加する処理

		
const copyImgElements = (imgArea, cloneLen) => {
    const elementToClone = imgArea.querySelector(".image");
    const fragment = document.createDocumentFragment();
    for (let i = 0; i < cloneLen - 1; i++) {
      const clone = elementToClone.cloneNode(true);
      fragment.appendChild(clone);
    }
    imgArea.appendChild(fragment);
  }
		
	

2.複製した画像グループにclip-pathプロパティを付与する

		
//縦ラインのclip-pathを付与する
const setVerticalClipPath = (imgArea) => {
    const imgs = imgArea.querySelectorAll(".image"), unit = 100 / imgs.length;
    imgs.forEach((img, index) => {
      const x = unit * index, x2 = 100 - (x + unit + 0.05);
      img.style.clipPath = `inset(0% ${x2}% 0% ${x}%)`;
    });
  }


//横ラインのclip-pathを付与する
const setHorizonClipPath = (imgArea) => {
    const imgs = imgArea.querySelectorAll(".image"), unit = 100 / imgs.length;
    imgs.forEach((img, index) => {
      const y = unit * index, y2 = 100 - (y + unit + 0.06);
      img.style.clipPath = `inset(${y}% 0% ${y2}%)`;
    });
  }


//円形のclip-pathをスケーリングしながら付与する
const setCircleClipPath = (imgArea) => {
    const imgs = imgArea.querySelectorAll(".image"), unit = 100 / imgs.length;
    imgs.forEach((img, index) => {
      const size = unit * index * 0.82;
      img.style.clipPath = `circle(${size}% at 50% 50%)`;
      img.style.zIndex = imgs.length - index;
    });
  }


//斜線のclip-pathを付与する
const setLineClipPath = (imgArea, angle) => {
    const imgs = imgArea.querySelectorAll(".image"), ratio = (100 + angle) / 100, unit = 100 / imgs.length * ratio;
    imgs.forEach((img, index) => {
      const x = unit * index - angle, x2 = x + unit + 0.04, x3 = unit * index, x4 = x3 + unit + 0.04;
      img.style.clipPath = `polygon(${x3}% 0%, ${x4}% 0%, ${x2}% 100%, ${x}% 100%)`;
    });
  }


//矩形のclip-pathをスケーリングしながら付与する
const setRectClipPath = (imgArea) => {
    const imgs = imgArea.querySelectorAll(".image"), unit = 50 / imgs.length;
    imgs.forEach((img, index) => {
      const size = 50 - unit * index - unit;
      img.style.clipPath = `inset(${size}%)`;
      img.style.zIndex = imgs.length - index;
    });
  }
		
	

3.GSAPのstagger属性を使い、clip-pathの中の画像に一律のアニメーションを実行

		
//例:拡大とフェードインのアニメーション
const gsapAnimation = (imgArea) => {
    const imgs = imgArea.querySelectorAll("img");
    const stagger = { each: 0.025 };
    gsap.fromTo(
      imgs,
      {
        scaleY: 1.8,
        scaleX: 2,
        opacity: 0
      },
      {
        scaleY: 1,
        scaleX: 1,
        opacity: 1,
        ease: Expo.easeOut,
        duration: 1.5,
        stagger
      }
    );
  }
codepenデモ:https://codepen.io/pujwrmui-the-flexboxer/pen/JjVmPKZ?editors=0010
		
	

実装例

		
const doClipPathAnim = () => {
    const imgArea = document.getElementById("img-area_01");
    copyImgElements(imgArea, 16);
    setVerticalClipPath(imgArea);
    imgArea.addEventListener("click", () => {
      doClipPathAnim();
    });
  }

//注意点:
//clip-pathは複数重なると重いので、要素のサイズ・数に注意する事