Search code examples
javascriptanimationsvgtransformgsap

GSAP/CSS transform origin and glitchy hover effect/ SVG Regions


I am attempting to animate an svg doughnut circle with gsap. After much testing with code and layering, I am stumped with a glitchy hover effect (which I tried to resolve with pointer events) and the transform origin is only applied to a few of the expanded tabs. I am wondering if this might be that the tabs may have a different bounding box?

Comments added per request:

Side Note: I've tried applying fill-box to entire svg instead, I'm wondering if I need a parent layer thats an exact square so I can apply the transform origin for the child "expandtabs" to the center of that?

I assumed I needed to iterate through an array of both to have the tabs correspond. Unless the tabs were children of each other?

TLDR; Tabs are not scaling from center of circle, and glitchy hover effect

CodePen Example

.expandtab {
    pointer-events: none;
    transform: fill-box;
    transform-origin: -15px 25%;
}

Javascript:

const subTabs = gsap.utils.toArray(".subtab");
const expandTabs = gsap.utils.toArray(".expandtab");
const tl = gsap.timeline({ defaults: { duration: .05, } });

tl.set(expandTabs, {
    visibility: "hidden",
    opacity: 0,
    scale: 0,
});

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

    // Event Listener Hover on
    subTabs[index].addEventListener("mouseover", (event) => {
        console.log("you clicked region number " + index);
        tl.to(expandTab, {
            visibility: "visible",
            opacity: 1,
            scale: 1,
        });
    });

    // Event Listener Hover off
    subTabs[index].addEventListener("mouseout", (event) => {
        console.log("you exited region number " + index);
        tl.to(expandTab, {
            opacity: 0,
            scale: 0,
            visibility: "hidden",
        });
    });
});

Solution

  • About the glitchy hover effect, the mouseenter and mouseleave will do the job better. mouseover is firering way to much...

    For the "growing" effect, it is more complex. The transform-origin CSS property won't be enought. Any way, you will need different values for each five parts of the circle.

    Additionnaly, you will need to adjust a transition to "fit" or "keep" the inner part of the circle in place. I suggest you to look at the fromTo method of GSAP. That will allow you to specify explicitely the starting and the landing coordinates.

    Be patient! ;)