Jump to content
Search Community

Animating clip-path

tamlyn test
Moderator Tag

Go to solution Solved by Diaco,

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

I'm trying to convert a CSS transition to use GSAP because I need more control over it.

 

The CSS produces a triangular wipe from the outside to the centre:

    -webkit-clip-path: polygon(50% -150%, 170% 150%, -70% 150%);
    transition: -webkit-clip-path 3s;

    &.wipe {
        -webkit-clip-path: polygon(50% 50%, 50% 50%, 50% 50%);
    }

However when I port it to TweenMax (see Code Pen) I just get the first and last frames, no tweening. I know there is a policy of not supporting non-standardised properties but I would have expected it to just do string interpolation on the polygon spec. Am I doing something wrong?

See the Pen VYjPvE by tamlyn (@tamlyn) on CodePen

Link to comment
Share on other sites

  • Solution

Hi tamlyn  :)

 

i dont know that there's a native solution in CSSplugin for this type of webkit property or not ... anyway , you can handle that with this piece of code :

var arr1 = [50,-150,170,150,-70,150];
var arr2 = [50,50,50,50,50,50]; 

arr2.onUpdate = function() {
  TweenMax.set('#square', {webkitClipPath:'polygon('+arr1[0]+'%'+arr1[1]+'%,'+arr1[2]+'%'+arr1[3]+'%,'+arr1[4]+'%'+arr1[5]+'%)'});
};

TweenLite.to(arr1,3, arr2);

pls check this out :

See the Pen ogLZax by MAW (@MAW) on CodePen

 

and i think that's better to use SVG clip path ( browsers compatibility )

 

  • Like 7
Link to comment
Share on other sites

  • 2 months later...
  • 4 weeks later...
  • 5 weeks later...
  • 8 months later...

 

Hi tamlyn  :)

 

i dont know that there's a native solution in CSSplugin for this type of webkit property or not ... anyway , you can handle that with this piece of code :

var arr1 = [50,-150,170,150,-70,150];
var arr2 = [50,50,50,50,50,50]; 

arr2.onUpdate = function() {
  TweenMax.set('#square', {webkitClipPath:'polygon('+arr1[0]+'%'+arr1[1]+'%,'+arr1[2]+'%'+arr1[3]+'%,'+arr1[4]+'%'+arr1[5]+'%)'});
};

TweenLite.to(arr1,3, arr2);

pls check this out :

See the Pen ogLZax by MAW (@MAW) on CodePen

 

and i think that's better to use SVG clip path ( browsers compatibility )

 

 

Is it example can be converted for using in "timeline" with multiple elements?

I will be very thankful for the example.

Link to comment
Share on other sites

  • 1 month later...
  • 1 month later...

Just be to add my two cents that i would have to agree with Diaco about using an SVG clip path instead for cross browser compatibility.

 

Also webkitClipPath (-webkit-clip-path) will only work in Chrome and Safari. Since Firefox, IE, MS Edge do not widely support polygon yet for CSS clip-path. GSAP is still animating (interpolating the values) of the -webkit-clip-path polygon, but you just don't see it rendering in the Firefox browser, even with clip-path: polygon(..) with the webkit prefix.

 

if you don't use SVG clip path,, then instead you can use the W3C Standard of using CSS clip-path: url(#your-svg-path-definition). And animate the element that clip-path url is attached to, which will work in both Firefox and Chrome.
 

;)

Link to comment
Share on other sites

Hello Climber, and welcome to the GreenSock Forum!

 

If you need to add easing .. Using Blake's fork of Diaco's codepen from above you can simply just add that ease property:

 

See the Pen groRaL by jonathan (@jonathan) on CodePen


 

TweenLite.to(arr1, 3, { 
     endArray: arr2, 
     onUpdate: clipPath, 
     ease: Bounce.easeOut // adds bounce easing
});

I hope this helps!

 

:)

  • Like 3
Link to comment
Share on other sites

This seems to be a really popular thread, but it also seems cause a lot of confusion. If you want to do an animation like this, use the EndArrayPlugin.

 

I'm not trying knock Diaco's code. My hat's off to him for figuring this out. It was the first time I ever saw an array being tweened, and is what led me to figure out how to do more complicated things like path morphing, but it's also confusing.

 

Arrays are a special type of object, so this works. The easing is a just a property of the object. Make sense? If not, use the plugin.

var arr1 = { 0:150, 1:30,  2:177, 3:113, length: 4};
var arr2 = { 0:123, 1:113, 2:150, 3:30,  length: 4};

arr2.ease = Back.easeInOut;
arr2.onUpdate = setPoints;

TweenMax.to(arr1, 1.2, arr2);

See the Pen mPpLMK?editors=0010 by osublake (@osublake) on CodePen

  • Like 5
Link to comment
Share on other sites

  • 1 year later...

I built this helper function that can encapsulate all mentioned above, might be helpful to someone

 

    function polygonClipToArray(polygonString){
        return polygonString.match(/\d+/g).map(Number);
    }

    /**
     * 
     * @param element- Element to animate
     * @param fromClip- e.g 'polygon(0 100%, 100% 100%, 0 100%, 0 100%)'
     * @param toClip - e.g ''polygon(0 100%, 100% 100%, 0 100%, 0 100%)'
     * @param duration - time to preform the animation
     * @returns {TimelineMax}
     */
    function clipPathAnimation(element,fromClip,toClip,duration){
        let clipPathTimeline = new TimelineMax();
        let fromPath = polygonClipToArray(fromClip);
        let toPath = polygonClipToArray(toClip);

        let clipPath = function(){
            let valuesString = '';
            fromPath.forEach((element,index)=>{
                let postFix = (index % 2 === 1 && index !== fromPath.length -1)? ',':'';
                valuesString += `${element.toString()}%${postFix}`
            });
             TweenMax.set(element, {clipPath:`polygon(${valuesString})`});
        };


        clipPathTimeline
            .to(fromPath,duration,{endArray:toPath,onUpdate:clipPath})

        return clipPathTimeline;
    }



Used like this:
 

let timeline = new TimelineMax();
const FIRST_MASK_CLIPS = [
            'polygon(0 100%, 100% 100%, 0 100%, 0 100%)','polygon(0 100%, 100% 100%, 0 0, 0 0)','polygon(0 100%, 50% 100%, 50% 0, 0 0)'];

timeline
	.add( clipPathAnimation(masks[0],FIRST_MASK_CLIPS[0],FIRST_MASK_CLIPS[1],17/25), 1 +6/25);
 	.add( clipPathAnimation(masks[0],FIRST_MASK_CLIPS[1],FIRST_MASK_CLIPS[2],1 + 9/25),1 + 23/25);

 

  • Like 1
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...