GSAP/SVG 根据活动选项卡设置 x/y 来源,并循环事件侦听器

GSAP/SVG setting x/y origin based on active tab, and looping through event listeners

我正在制作带有扩展选项卡的甜甜圈圈 svg。截至昨晚,扩展选项卡功能齐全,正确的 x/y 转换应用于 mouseenter/mouseleave。 (x/y 对于正确的变换原点在鼠标进入和鼠标离开时都是必不可少的 - 这很难让每个选项卡扩展显示在中心,因为它是一个圆圈)。

今天,我尝试通过创建一个额外的循环来进一步推进该项目,该循环根据活动选项卡索引显示相应的内容。 (这是有效的)。

现在我想更进一步,使当前选项卡保持展开状态,直到将鼠标悬停在另一个选项卡上。现在,事件监听器 mouseleave 在我的鼠标离开选项卡时应用(很明显)。除非将鼠标悬停在另一个选项卡上,否则我该怎么做才能使当前选项卡保持“活动状态”? (而不是 mouseleave?)。我对 JS 仍然相当缺乏经验,如果有人能把我送到正确的方向,我会很满足

CodePen

const subTabs = gsap.utils.toArray(".subtab");
const expandTabs = gsap.utils.toArray(".expandtab");

// Timeline set default duration to .025
const tl = gsap.timeline({ defaults: { duration: 0.025 } });

tl.set(expandTabs, {
    opacity: 0,
    scale: 0.5,
    x: "0%",
    y: "0%",
});

// display corresponding content based on active tab
// Set expand tab x/y when inactive
let tabIndex = 1;
    tabExcerpt(tabIndex);


function currentTab(n) {
    tabExcerpt(tabIndex = n);
}

function tabExcerpt(n) {
    let i;
    let expandTab = document.querySelectorAll(".expandtab");
    let tabExcerpts = document.querySelectorAll(".tab-excerpt");

    if (n > tabExcerpts.length) {tabIndex = 1}
    if (n < 1) {tabIndex = tabExcerpts.length}
    for (i = 0; i < tabExcerpts.length; i++) {
        tabExcerpts[i].style.display = "none";
    }
    for (i = 0; i < expandTab.length; i++) {
        // Need to set expand tab to default x/y when not active
        expandTab[i] = (num) => {
            tl.set(expandTab, {
                scale: 0.5,
                opacity: 0,
                x: "25%",
                y: "25%",
            });
        }
    }
    tabExcerpts[tabIndex-1].style.display = "block";
    // expandTab[tabIndex-1].className.baseVal += " active";
}

subTabs.forEach((subTab, index) => {
    let expandTab = expandTabs[index];

    // Event Listener Hover On
    // If index[0]
    if (index === 0) {
        subTabs[0].addEventListener("mouseenter", (event) => {
            console.log("you entered region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "30%",
                    y: "25%",
                },
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                }
            );
        });
    } else if (index === 1) {
        subTabs[1].addEventListener("mouseenter", (event) => {
            console.log("you entered region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "24%",
                    y: "39%",
                },
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                }
            );
        });
    } else if (index === 2) {
        subTabs[2].addEventListener("mouseenter", (event) => {
            console.log("you entered region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "25%",
                    y: "25%",
                },
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                }
            );
        });
    } else if (index === 3) {
        subTabs[3].addEventListener("mouseenter", (event) => {
            console.log("you entered region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "25%",
                    y: "25%",
                },
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                }
            );
        });
    } else if (index === 4) {
        subTabs[4].addEventListener("mouseenter", (event) => {
            console.log("you entered region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "25%",
                    y: "25%",
                },
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                }
            );
        });
    }

    // Event Listener Hover off
    // if index[0]
    if (index === 0) {
        subTabs[0].addEventListener("mouseleave", (event) => {
            console.log("you exited region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                },
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "35%",
                    y: "25%",
                }
            );
        });
    } else if (index === 1) {
        subTabs[1].addEventListener("mouseleave", (event) => {
            console.log("you exited region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                },
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "24%",
                    y: "39%",
                }
            );
        });
    } else if (index === 2) {
        subTabs[2].addEventListener("mouseleave", (event) => {
            console.log("you exited region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                },
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "25%",
                    y: "25%",
                }
            );
        });
    } else if (index === 3) {
        subTabs[3].addEventListener("mouseleave", (event) => {
            console.log("you exited region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                },
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "25%",
                    y: "25%",
                }
            );
        });
    } else if (index === 4) {
        subTabs[4].addEventListener("mouseleave", (event) => {
            console.log("you exited region number " + index);
            tl.fromTo(
                expandTab,
                {
                    scale: 1,
                    opacity: 1,
                    x: "0%",
                    y: "0%",
                },
                {
                    scale: 0.5,
                    opacity: 0,
                    x: "25%",
                    y: "25%",
                }
            );
        });
    }
});

您必须在此处使用“自定义事件”,而不是使用 mouseout 事件。

是的,您可以创建事件...阅读更多内容 here 并发送它们。这使您可以触发一些特殊的事情,而不会干扰任何其他常规事件的“正常行为”。

下面,我将事件称为“撤回”。耶!也可以随意命名!

函数如下:

function unhover(exceptIndex){
  subTabs[exceptIndex].classList.add("expanded")
  subTabs.forEach((subTab, index) => {
    if(index != exceptIndex && subTab.classList.contains("expanded")){
      let event = new Event('retract');
      subTab.dispatchEvent(event);
      subTab.classList.remove("expanded");
    }
  })
}

Andd 你会在每个 mouseenter 回调结束时调用它,传递当前悬停的索引(因为那个不应该收回)。

unhover(index);

这是你的CodePen forked and edited

顺便说一句,关于扩展的工作做得很好(而且很快!)!继续做好工作。 ;)