d
o
t
-
l
i
n
e
-
f
o
r
m
Divide ClipPath Motion
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は複数重なると重いので、要素のサイズ・数に注意する事