Jump to content
Search Community

adamoc

Members
  • Posts

    27
  • Joined

  • Last visited

Everything posted by adamoc

  1. Hi @aok, I think you might be having the same problem I was with markers moving around and triggering the animation at different stages on reload of page. I made out a Test example to showcase this problem and actually I think (well it works for me ), came up with a solution as I noticed it was adding more markers on reload and then gsap was taking these new markers as the triggers which were being pushed down by the old markers . I explained it much better and came up with a solution I hope to your problem -
  2. No I know that , but do you know of any I meant like because I couldn't find any anywhere when I searched.
  3. Hi @ZachSaucier , nope I'm not using the markers but the markers are indicating from what i gather anyway where the animation starts so getting them in the right position is key and then turn them off . So I was just using them as a guide really , oh hahahah I found a workaround so but I'll try that either if I run into this very problem again hahaha . No I completely understand the honus is not on you as that is not your problem really , if i ever run into Barba problem again , do you have any forums I could use ? Thanks a million for your help over last few days , think I'll just about be able to launch it in large part thanks to you . Youre a sound man , see ya again i imagine lol ?? Cheers Adam
  4. Decided I should leave this here and contribute for once lol ?. Update : For anyone who might be coming to this in the future , I observed that when I resized the window the markers updated their position idk why but this is absolutely unreal because what I did was basically simulate a window resize to get the markers back to their desired locations So for anyone who comes to this and observes your scroll markers are in a different position after a Barba page transition , this is what I did I have my afterEnter hook calling a function called aboutInit to handle all page onboarding issues I'm facing, in the function what it does first is what I mentioned above checks all the classes in the DOM for gsap one's against a regex and then finds these gsap markers and removes them so now you're only left with no markers . Then I call my actual function to do the horizontal scroll effect and give me a brand new set of markers and now you're left with that set of markers in the wrong positions (as stated above - read that before continuing ). So then just simulate a window resize event to kick the markers back into their original positions then everything is in order and your animation should start and end in the right place . What I did was check the top position on just reload of the page in the right original position , then do a barba transition let all this happen above and bam left with the same top positions for the markers. Hope that makes sense . ? Here is the code - aboutInit // About Page Functions const aboutInit = () => { let horizontalscrollAnim, cleanGSAP() if(typeof horizontalscrollAnim === "undefined") { scroll_facts_tl_func(); } window.dispatchEvent(new Event('resize')); } const cleanGSAP = () => { const allClasses = [...document.querySelectorAll('[class]')] let gsapArray = [] if(allClasses.length <= 134) return for (var i = 0; i < allClasses.length; i++) { if (/gsap-/.test(allClasses[i].className)) { gsapArray.push(allClasses[i].className); } else break } gsapArray.map(tag => document.querySelector(`.${tag}`).remove()) } //You don't need this but it's just so you know what I'm calling const scroll_facts_tl_func = () => { const facts = [...document.querySelectorAll('.fact')], factsContainer = document.querySelector('.factsContainer'); let xPercent window.matchMedia("(max-width: 600px)").matches ? xPercent = -85 : xPercent = -115 horizontalscrollAnim = gsap.to(facts, { xPercent: xPercent * (facts.length - 1), ease: "none", scrollTrigger: { trigger: ".factsContainer", pin: true, pinSpacing: true, // markers: true, scrub: 1, snap: 1 / (facts.length - 1), start: "top top", // base vertical scrolling on how wide the container is so it feels more natural. end: `+=${factsContainer.offsetWidth}` //4320 } }); } Helper Methods // Helper Functions const delay = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); } Barba Initialization barba.init({ sync: true, transitions: [{ name: 'transition-base', async leave() { const done = this.async(); pageTransition(); await delay(1000); done(); }, async enter() { window.scrollTo(0, 0); }, }], views: [ { namespace: 'about', afterEnter() { aboutInit() } } ], }); Here's also a Test Site I put to show what I mean just do exactly as stated to see the effect and discreptancy in the markers positions due to Barba transition 1. Go to https://testbarba.netlify.app/ 2. Click the about page - this will trigger barba transition - take note of the markers positions(end and start in the inspect element) 3. Then just reload the about page and you will notice the different positions of your markers upon load (again in the inspect element) 4. You can use above to fix this , if this is your problem Cheers Adam
  5. Right @ZachSaucier , I know you're sick of seeing my name pop up talking about GSAP and Barba Combination. The problem is BarbaJs doesn't really have a forum (well from what I could find anyway), but what I will confess to and start trying to do is debug my problems more before coming to this forum that's why yesterday I basically spent the day trying to debug my actual first problem I still can't get. I turned off all functions bar one and stepped through all variable values at all stages of DOM loading and manipulation through the Barba hooks , I identified the places I needed to add a setTimeout and also I found out which hooks come first(enter , DOM load , etc... ) and that the afterEnter hook is probably the best place to initialize anything you want because if you place a function call in there it gets called whether or not you're transitioning through Barba. As I said before I really did try to debug this time as much as possible and identified my problem I think . As I said in a earlier post , markers are added every time by GSAP on page load (which I'm guessing is how ye make the pinning possible starting at the start marker pin until the end marker and then the other two are to do with the scroll position on the page. So what I observed in the inspect element is that when you transition to a page with Barba the amount of markers doubles and so pushes down the start marker and end marker down the page causing my animation to start at a different place which is what I'm observing is happening in my site now if i go to homepage and click about , to counteract this what I have done is got rid of all the markers on page load so that GSAP can add it's new markers and not be pushed down , however I don't know how but the markers added are still getting pushed down even though they're only ones there now , what's happening is lets take this problem for example, On Normal page Load my Start Marker top - 2371px Height Of my Container that pins - 4320px End Marker top - 6691px - This works without a hitch perfectly After Barba Transition Page Load Start Marker top - 7175px Height Of my Container that pins - 4320px End Marker top - 11495px - This works at the wrong position therefore doesn't perform properly (overlapping other elements and what not) So to be clear If i didn't remove some of the markers page would look like this like it does now 2371 +4320 6691 7175 +4320 11495 Now when I clear it takes care of the first one's so you're left with this now 7175 +4320 11495 Now What I want is to move these positions to the same as page load normal that being 2371 +4320 6691 But when I tried to do this the actual top value changed / updated as the tag jumped up but seems GSAP somewhere has it defined that the animation is still getting set at the marker at 7175 so when I scroll to that position this is when it actually works but at the wrong position as already stated , further down the page . Wondering how are those markers position set and/or the way you use to identify where to start animation and how would I go about changing these positions to my desired ones on page load after barba transition. So now to your post above Zach , I intentially left out Barba Script and Barba wrapper data properties on the homepage as you said you wanted a simple but effective test case so you could see what I was on about that animation with Barba and without is different so I set Homepage as page without the Barba and the about page as page with it, as for not including all the resources you needed to carry out the experiment yourself stupidly I thought you were going to just look at my code , at the live version and work it out from there , I didn't think you were going to reverse engineer it so sorry for that in the future I will most definitely be more thorough with providing all resources if i'm asking a question on this forum. I'm sorry , this is all pretty new to me writing in forums as I haven't wrote questions before on forums as I'm normally a hard worker 100% never give up until you got it don't show someone else they are better than you guy and you'll get this . But taking a step backward from this over this year I have identified that asking for help is not a form of weakness but strength as you it's through help you get better and learn more things , otherwise you stuck in a rut for a long time leading to unfinished projects. So I have taken the leap to ask for more help I do agree however I should have debugged this issue above a bit better but I'm trying that's all I can do ?‍♂️. Okay what I will say and acknowledge is a huge thank you to you and the team at GSAP who work tirelessly to help us create spectacular animations and ScrollTrigger is another amazing addition to this outstanding library. Personally thank you for sorting the stupid bug I missed yesterday ? Cheers Adam
  6. Looking into this further I have happened upon the reason I think my situation above arises , but I have no clue how to fix it (is it a manual clearout job of the tags)?? So When on the home page I looked in the inspect element and saw that there's the elements for the tags(end marker , start marker , end scroller marker , start scroller marker and then pin spacer). Then went on the About page and observed that it seems the first elements don't get cleared out and new one's for the second page are added , thing is pin spacer element gets added with a different height altogether therefore you can only scroll halfway across the page like I observed above. So wondering how to go about solving my problem , any thoughts would be appreciated ?. I've attached the relevant screenshots of the inspect element below , note the page domain name in the grey bar at the top to see which screenshot belongs to which page. Cheers Adam
  7. Hi there, okay so thank you @ZachSaucier for your advice on what to do next with my situation. So I've made a little test , minimal and I think complete which shows the difference in the reaction of scrollTrigger with and without BarbaJS enabled on the page. So I have a homepage which has horizontal scroll perfectly available and working then I include a button to click the about page , click the button and brought to the about page (same animation but doesn't give you the same result) only able to scroll halfway across and not able to reach the footer. Wondering why this is the case and what can I do to combat the differences in the adjustment of the dimensions of the page made by Barba. Here's the site - https://testbarba.netlify.app/ Here's the code - index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/ScrollTrigger.min.js"></script> <script defer src="main.js"></script> <title>Document</title> </head> <body> <div class="container"> <div class="page one">One</div> <div class="page two">Two</div> <div class="page three">Three</div> </div> <div class="about_btn_container"> <a href="about.html">About</a> </div> <footer> All Rights Reserved &copy; Adamoc 2020 </footer> </body> </html> about.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <link rel="stylesheet" href="style.css"> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/gsap.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.3.4/ScrollTrigger.min.js"></script> <script defer src="https://unpkg.com/@barba/core"></script> <script defer src="main.js"></script> <title>Document</title> </head> <body data-barba="wrapper"> <div class="container" data-barba="container" data-barba-namespace="about"> <div class="page one">One</div> <div class="page two">Two</div> <div class="page three">Three</div> </div> <div class="about_btn_container"> <a href="about.html">About</a> </div> <footer> All Rights Reserved &copy; Adamoc 2020 </footer> </body> </html> main.js const scrollAnimation = () => { let pages = [...document.querySelectorAll('.page')] gsap.to(pages, { xPercent: -100 * (pages.length - 1), ease: "none", scrollTrigger: { trigger: ".container", pin: true, markers: true, scrub: 1, snap: 1 / (pages.length - 1), // base vertical scrolling on how wide the container is so it feels more natural. end: () => "+=" + document.querySelector(".container").offsetWidth } }); } scrollAnimation() barba.init({ sync: true, transitions: [{ name: 'transition-base', async leave() { const done = this.async(); await delay(1000); done(); }, async enter() { window.scrollTo(0, 0); }, }], views: [ { namespace: 'about', beforeEnter(data) { }, afterEnter() { scrollAnimation(); }, } ], }); Cheers Adam
  8. Okay , thank you sm @mdelp, I followed all the steps you suggested and the website is running a lot smoother now. Followed all those cutting down on code steps and cut down my JS code into one file called main.js as suggested by you and @Yannis Yannakopoulos. This works a lot better than multiple JS files , so thank you . I've fixed my actual problem it was Barba acting up so just had to reclare variables on a beforeEnter hook to the next container . Now I'm just having a minor issue with pinning and using horizontal scrollTrigger . My aim is to scroll until the .factsContainer , create a timeline like i've done before , then have the heading fade in and then scroll little more and pin the .factsContainer_sm container containing the facts , then create a smooth snapping horizontal scroll for the offsetWidth of that container , then unpin and continue . I have created a codepen of what I want and copied the code directly into my actual website as is and it's not working as desired , just wondering could anyone help me please. main.js const scroll_facts_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.factsContainer', start: "top center", // pin: true, scrub: true, end: "+=300", // markers: true, } }), facts = [...document.querySelectorAll('.fact')] scroll_tl.to('.factsContainer h2', { scale: 1.5, duration: 1, ease: "slow" }) gsap.to(facts, { xPercent: -85 * (facts.length - 1), scrollTrigger: { trigger: ".factsContainer_sm", start: "center center", end: `+=${factsContainer_sm.offsetWidth}`, // 414 pin: true, pinSpacing:false, markers: true, scrub: 1, snap: 1 / (facts.length - 1), // // base vertical scrolling on how wide the container is so it feels more natural. // end: `+=${factsContainer_sm.offsetWidth}` } }); } Codepen - https://codepen.io/Adamoc/pen/RwrgyRv Website - https://adamoceallaigh.netlify.app/about.html but to get extent of what i'm working with you have to go https://adamoceallaigh.netlify.app/index.html and click 'About' Cheers Adam
  9. Hi there , I'm definitely having the same issue and thank god I found this forum because I was thinking i was going insane trying to find the bug. So basically as I'm guessing this is why my ScrollTrigger is not working as expected with BarbaJS as I navigate from the homepage to about page on my portfolio site everything else works as expected but sometimes the markers are out of their places . Which is even more weird is that sometimes the behaviour is actually perfect when viewed on mobile and then other times not on mobile but i'm guessing it has something to do with the Barba Removing of my elements so basically what you advise me to do is make reference variables to the elements I want to animate with GSAP and then call a function in beforeAfter () hook to redeclare those variables to new elements that Barba has swapped in and then pass them to the gsap animations. Or what do ye( @GreenSock @Yannis Yannakopoulos, @2malH) mean kill the scrollTrigger instance , why do I need to do that , is that just an easier way of doing what I've just implied above?? homepage.js //Variable Declarations and Function Definitions let viewBox = "" heading_Pos = [0, 0] displayState = "" hamburger_display_button = Array.from($('.mobile_nav_sticky'))[0] opened_nav_buttons = document.querySelector('.options') logo = $(".Actual_Logo_Svg") // Morphing Circles and ellipses to paths to be able to morph them and checking the viewbox for device size MorphSVGPlugin.convertToPath("ellipse"); shapes = Array.from($('.Logo_In_Shapes path')) const homeInit = () => { viewBox = "", heading_Pos = [0, 0], displayState = "" hamburger_display_button = Array.from($('.mobile_nav_sticky'))[0] opened_nav_buttons = document.querySelector('.options') logo = $(".Actual_Logo_Svg"); // Morphing Circles and ellipses to paths to be able to morph them and checking the viewbox for device size MorphSVGPlugin.convertToPath("ellipse"); shapes = Array.from($('.Logo_In_Shapes path')) } const logo_tl_func = () => { let logo_tl = gsap.timeline({ onComplete: moveLogo, }) // Morphing into the Logo logo_tl.from(shapes, 1, { y: -600, autoAlpha: 0, ease: "bounce", stagger: 0.15 }) logo_tl.to(shapes, 1, { fill: '#F0C368', stagger: 0.05 }) let firstAnimation = gsap.to('.shapes', { duration: 2, morphSVG: ".Logo_Proper_Background" }); let secondAnimation = gsap.to('.textShape', { duration: 2, fill: '#1D373F', morphSVG: ".Logo_Proper_Text" }); logo_tl.add([firstAnimation, secondAnimation]) } const changeViewBox = media_query => { media_query.matches ? viewBox = "-150 -180 2495 890" : viewBox = "-150 -350 3574 880" media_query.matches ? heading_Pos = [-511, -15] : heading_Pos = [-1540, 40]; media_query.matches ? displayState = "none" : displayState = "block" } const moveLogo = () => { gsap.to(logo, { attr: { viewBox: viewBox }, duration: 3 }) fadeInHeadingAndLinks(); } const fadeInHeadingAndLinks = () => { gsap.to('.nav_links', { display: displayState, scale: 1, duration: 3 }) gsap.to('.logo_heading', { display: "block", x: heading_Pos[0], y: heading_Pos[1], // scale:1, duration: 3 }) gsap.to('.mobile_nav_sticky', { display: "block", scale: 1, duration: 5 }, "+=.7") } const pageTransition = () => { var tl = gsap.timeline(); tl.set('.loading_container img', { scale: 0.3 }) tl.to('.loading_container', { duration: 1.2, width: "100%", left: "0%", ease: "circ.out", }) .to('.loading_container img', { scale: 0.6, duration: 1 }, "-=1.2") .to('.loading_container', { duration: 1.2, width: "0%", right: "0%", ease: "circ.out", }) .to('.loading_container img', { scale: 0.3, duration: 1.2 }, "-=1.3") } // Helper Functions const delay = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); } // Initialization Methods $(document).ready(() => { window.matchMedia("(max-width: 600px)").matches ? logo.attr('viewBox', '-350 -700 1274 1680') : logo.attr('viewBox', '-680 -380 2074 1080') var viewbox = window.matchMedia("(max-width: 600px)") changeViewBox(viewbox) }) hamburger_display_button.onclick = () => { opened_nav_buttons.classList.toggle('open') } barba.init({ sync: true, transitions: [{ name: 'transition-base', preventRunning: true, timeout: 5000, async leave() { const done = this.async(); pageTransition(); await delay(1000); done(); }, async enter() { window.scrollTo(0, 0); }, }], views: [ { namespace: 'home', afterEnter() { homeInit() window.matchMedia("(max-width: 600px)").matches ? logo.attr('viewBox', '-350 -700 1274 1680') : logo.attr('viewBox', '-680 -380 2074 1080') let viewbox = window.matchMedia("(max-width: 600px)") changeViewBox(viewbox) logo_tl_func(); hamburger_display_button.onclick = () => { opened_nav_buttons.classList.toggle('open') } }, }, { namespace: 'about', afterEnter() { aboutInit() face_tl_func() scroll_p_tl_func() scroll_skills_tl_func() scroll_facts_tl_func() }, } ], }); // //Global Hooks // barba.hooks.leave(() => { // const done = this.async(); // pageTransition(); // await delay(1000); // done(); // }) // barba.hooks.enter(() => { // window.scrollTo(0, 0); // }) about.js // Variable Declarations and Function Definitions let factsContainer_sm = document.querySelector(".factsContainer_sm") const aboutInit =() => { factsContainer_sm = document.querySelector(".factsContainer_sm") let head = document.getElementsByTagName('head')[0], link = document.createElement('link') link.rel = 'stylesheet' link.href= "../../Resources/CSS/about.css" head.appendChild(link); } const face_tl_func = () => { let face_tl = gsap.timeline(), paths = document.querySelectorAll('.My_Face path'), filledYellowElements = ['.Main_Hair_Part', '.Eyeball_2', '.Eyeball_1', '.Nostril_1', '.Nostril_2', '.Tongue_Part'], filledNavyElements = ['.Pupil_2', '.Pupil_1']; face_tl.set(filledNavyElements, { fill: 'unset' }), face_tl.set(filledYellowElements, { fill: 'unset' }), face_tl.fromTo(paths, { drawSVG: "0%" }, { duration: 1, drawSVG: "100% ", stagger: 0.15 }) let firstAnimation = gsap.to(filledYellowElements, { duration: 2, ease: "slow", fill: '#F0C368' }, "-=.7"), secondAnimation = gsap.to(filledNavyElements, { duration: 2, ease: "bounce", fill: '#1D373F' }, "-=.7") face_tl.add([firstAnimation, secondAnimation]) } const scroll_p_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.content', start: "top center", end: "+=1000", markers: true, scrub: true // pin: true } }) scroll_tl.to('.first', { transform: "rotateX(50deg) rotateZ(331deg) translateX(42px)", duration: .5, }), scroll_tl.to('.flag', { scale: 1 }, '-=.1'), scroll_tl.addLabel("first_down") scroll_tl.to('.second', { transform: "rotateX(50deg) rotateZ(331deg) translateX(42px)", duration: 2, }, "first_down-=.1") scroll_tl.addLabel("second_down") scroll_tl.to('.third', { transform: "rotateX(50deg) rotateZ(331deg) translateX(42px)", duration: 2, }, "second_down-=.01") } const scroll_skills_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.skillsContainer', start: "top center", markers: true, } }), barWidth = "", bars = [...document.querySelectorAll('.bar')] bars.map(bar => { barWidth = bar.dataset.width; let barAnimation = gsap.to(bar, { width: barWidth, duration: 1, delay : .2 }), percentageAniamtion = gsap.to('.percentage', { scale: 1, }) scroll_tl.add([barAnimation, percentageAniamtion]); }) } const scroll_facts_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.factsContainer', start: "top center", // pin: true, scrub: true, end: "+=300", markers: true, } }), facts = [...document.querySelectorAll('.fact')] scroll_tl.to('.factsContainer h2', { scale: 1.5, duration: 1, ease: "slow" }) scroll_tl.to(facts, { xPercent: -85 * (facts.length - 1), scrollTrigger: { trigger: ".factsContainer_sm", start: "center center", pin: true, // pinSpacing:false, markers: true, scrub: 1, snap: 1 / (facts.length - 1), // base vertical scrolling on how wide the container is so it feels more natural. end: () => `+=${factsContainer_sm.offsetWidth}` } }); } // //Initialization Methods // aboutInit() // face_tl_func() // scroll_p_tl_func() // scroll_skills_tl_func() // scroll_facts_tl_func() Here's my homepage - https://adamoceallaigh.netlify.app/ and here's my about page - https://adamoceallaigh.netlify.app/about.html
  10. I'm having a problem and i'm unsure as to whether it's either with Barba or Gsap ScrollTrigger itself I have no clue . So in my website , when I go from the homepage to the about page everything works as normal except the horizontal scroll part that I have put in (Facts Section) , thing is I do this very same action on mobile and it works perfectly sometimes and then other times it does the same as it does with the Desktop Version , so it's either my code and the way I have implemented the horizontal scroll but thing is when I go directly to the page as in not through the homepage and just initiate all the functions in about.js independently , everything including the horizontal scroll works as desired and perfectly , so I don't know which is causing the problem , could ye have a look maybe ?? So here is my homepage.js (Barba Init code) //Variable Declarations and Function Definitions let viewBox = "" heading_Pos = [0, 0] displayState = "" hamburger_display_button = Array.from($('.mobile_nav_sticky'))[0] opened_nav_buttons = document.querySelector('.options') logo = $(".Actual_Logo_Svg") // Morphing Circles and ellipses to paths to be able to morph them and checking the viewbox for device size MorphSVGPlugin.convertToPath("ellipse"); shapes = Array.from($('.Logo_In_Shapes path')) const homeInit = () => { viewBox = "", heading_Pos = [0, 0], displayState = "" hamburger_display_button = Array.from($('.mobile_nav_sticky'))[0] opened_nav_buttons = document.querySelector('.options') logo = $(".Actual_Logo_Svg"); // Morphing Circles and ellipses to paths to be able to morph them and checking the viewbox for device size MorphSVGPlugin.convertToPath("ellipse"); shapes = Array.from($('.Logo_In_Shapes path')) } const logo_tl_func = () => { let logo_tl = gsap.timeline({ onComplete: moveLogo, }) // Morphing into the Logo logo_tl.from(shapes, 1, { y: -600, autoAlpha: 0, ease: "bounce", stagger: 0.15 }) logo_tl.to(shapes, 1, { fill: '#F0C368', stagger: 0.05 }) let firstAnimation = gsap.to('.shapes', { duration: 2, morphSVG: ".Logo_Proper_Background" }); let secondAnimation = gsap.to('.textShape', { duration: 2, fill: '#1D373F', morphSVG: ".Logo_Proper_Text" }); logo_tl.add([firstAnimation, secondAnimation]) } const changeViewBox = media_query => { media_query.matches ? viewBox = "-150 -180 2495 890" : viewBox = "-150 -350 3574 880" media_query.matches ? heading_Pos = [-511, -15] : heading_Pos = [-1540, 40]; media_query.matches ? displayState = "none" : displayState = "block" } const moveLogo = () => { gsap.to(logo, { attr: { viewBox: viewBox }, duration: 3 }) fadeInHeadingAndLinks(); } const fadeInHeadingAndLinks = () => { gsap.to('.nav_links', { display: displayState, scale: 1, duration: 3 }) gsap.to('.logo_heading', { display: "block", x: heading_Pos[0], y: heading_Pos[1], // scale:1, duration: 3 }) gsap.to('.mobile_nav_sticky', { display: "block", scale: 1, duration: 5 }, "+=.7") } const pageTransition = () => { var tl = gsap.timeline(); tl.set('.loading_container img', { scale: 0.3 }) tl.to('.loading_container', { duration: 1.2, width: "100%", left: "0%", ease: "circ.out", }) .to('.loading_container img', { scale: 0.6, duration: 1 }, "-=1.2") .to('.loading_container', { duration: 1.2, width: "0%", right: "0%", ease: "circ.out", }) .to('.loading_container img', { scale: 0.3, duration: 1.2 }, "-=1.3") } // Helper Functions const delay = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); } // Initialization Methods $(document).ready(() => { window.matchMedia("(max-width: 600px)").matches ? logo.attr('viewBox', '-350 -700 1274 1680') : logo.attr('viewBox', '-680 -380 2074 1080') var viewbox = window.matchMedia("(max-width: 600px)") changeViewBox(viewbox) }) hamburger_display_button.onclick = () => { opened_nav_buttons.classList.toggle('open') } barba.init({ sync: true, transitions: [{ name: 'transition-base', preventRunning: true, timeout: 5000, async leave() { const done = this.async(); pageTransition(); await delay(1000); done(); }, async enter() { window.scrollTo(0, 0); }, }], views: [ { namespace: 'home', afterEnter() { homeInit() window.matchMedia("(max-width: 600px)").matches ? logo.attr('viewBox', '-350 -700 1274 1680') : logo.attr('viewBox', '-680 -380 2074 1080') let viewbox = window.matchMedia("(max-width: 600px)") changeViewBox(viewbox) logo_tl_func(); hamburger_display_button.onclick = () => { opened_nav_buttons.classList.toggle('open') } }, }, { namespace: 'about', afterEnter() { aboutInit() face_tl_func() scroll_p_tl_func() scroll_skills_tl_func() scroll_facts_tl_func() }, } ], }); // //Global Hooks // barba.hooks.leave(() => { // const done = this.async(); // pageTransition(); // await delay(1000); // done(); // }) // barba.hooks.enter(() => { // window.scrollTo(0, 0); // }) and here's my about.js // Variable Declarations and Function Definitions let factsContainer_sm = document.querySelector(".factsContainer_sm") const aboutInit =() => { factsContainer_sm = document.querySelector(".factsContainer_sm") let head = document.getElementsByTagName('head')[0], link = document.createElement('link') link.rel = 'stylesheet' link.href= "../../Resources/CSS/about.css" head.appendChild(link); } const face_tl_func = () => { let face_tl = gsap.timeline(), paths = document.querySelectorAll('.My_Face path'), filledYellowElements = ['.Main_Hair_Part', '.Eyeball_2', '.Eyeball_1', '.Nostril_1', '.Nostril_2', '.Tongue_Part'], filledNavyElements = ['.Pupil_2', '.Pupil_1']; face_tl.set(filledNavyElements, { fill: 'unset' }), face_tl.set(filledYellowElements, { fill: 'unset' }), face_tl.fromTo(paths, { drawSVG: "0%" }, { duration: 1, drawSVG: "100% ", stagger: 0.15 }) let firstAnimation = gsap.to(filledYellowElements, { duration: 2, ease: "slow", fill: '#F0C368' }, "-=.7"), secondAnimation = gsap.to(filledNavyElements, { duration: 2, ease: "bounce", fill: '#1D373F' }, "-=.7") face_tl.add([firstAnimation, secondAnimation]) } const scroll_p_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.content', start: "top center", end: "+=1000", markers: true, scrub: true // pin: true } }) scroll_tl.to('.first', { transform: "rotateX(50deg) rotateZ(331deg) translateX(42px)", duration: .5, }), scroll_tl.to('.flag', { scale: 1 }, '-=.1'), scroll_tl.addLabel("first_down") scroll_tl.to('.second', { transform: "rotateX(50deg) rotateZ(331deg) translateX(42px)", duration: 2, }, "first_down-=.1") scroll_tl.addLabel("second_down") scroll_tl.to('.third', { transform: "rotateX(50deg) rotateZ(331deg) translateX(42px)", duration: 2, }, "second_down-=.01") } const scroll_skills_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.skillsContainer', start: "top center", markers: true, } }), barWidth = "", bars = [...document.querySelectorAll('.bar')] bars.map(bar => { barWidth = bar.dataset.width; let barAnimation = gsap.to(bar, { width: barWidth, }), percentageAniamtion = gsap.to('.percentage', { scale: 1, }) scroll_tl.add([barAnimation, percentageAniamtion]); }) } const scroll_facts_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.factsContainer', start: "top center", // pin: true, scrub: true, end: "+=300", markers: true, } }), facts = [...document.querySelectorAll('.fact')] scroll_tl.to('.factsContainer h2', { scale: 1.5, duration: 1, ease: "slow" }) scroll_tl.to(facts, { xPercent: -85 * (facts.length - 1), scrollTrigger: { trigger: ".factsContainer_sm", start: "center center", pin: true, // pinSpacing:false, markers: true, scrub: 1, snap: 1 / (facts.length - 1), // base vertical scrolling on how wide the container is so it feels more natural. end: () => `+=${factsContainer_sm.offsetWidth}` } }); } // //Initialization Methods aboutInit() face_tl_func() scroll_p_tl_func() scroll_skills_tl_func() scroll_facts_tl_func() Here's the website homepage - https://adamoceallaigh.netlify.app/ Here's the about page - https://adamoceallaigh.netlify.app/about.html Appreciate all the help ye can give , if ye can , can ye check both mobile and desktop versions. ? Cheers Adam
  11. Omg thanks for this @akapowl and @mdelp , this is exactly what I was looking for . Thanks so much didn't see these responses until now. Now unfortunately I have a new problem and it's either with Barba or Gsap ScrollTrigger itself I have no clue . So in my website , when I go from the homepage to the about page everything works as normal except the horizontal scroll part that I have put in (Facts Section) , thing is I do this very same action on mobile and it works perfectly sometimes and then other times it does the same as it does with the Desktop Version , so it's either my code and the way I have implemented the horizontal scroll but thing is when I go directly to the page as in not through the homepage and just initiate all the functions in about.js independently , everything including the horizontal scroll works as desired and perfectly , so I don't know which is causing the problem , could ye have a look maybe ?? Also I just have a few questions about your code above @mdelp , You define the function barbaInit() but where is this called and when ?? , also are those anim_about_in() and other view specific functions your initializers for the page or just animating the page in?? . Just want to clarify aswell , like i mentioned above if someone clicks a link that loads the about page again or something or goes directly to the about page the Barba animations are gone so therefore if you're reliant on Barba to initialize your scripts upon that specific page load then your scripts are not going to be initialized so do you call them independently like above in their seperate JS files too?? Last thing I want to clarify if i have a seperate stylesheet for each page , do I even need to include it in the seperate pages( about etc) as they will be redundant if barba is just gonna use my homepage as the one page for my application so would I be better off loading in all my stylesheets for all my seperate pages on the homepage or just put them to load in dynamically once the view with namespace ?? occurs??. So here is my homepage.js (Barba Init code) //Variable Declarations and Function Definitions let viewBox = "" heading_Pos = [0, 0] displayState = "" hamburger_display_button = Array.from($('.mobile_nav_sticky'))[0] opened_nav_buttons = document.querySelector('.options') logo = $(".Actual_Logo_Svg") // Morphing Circles and ellipses to paths to be able to morph them and checking the viewbox for device size MorphSVGPlugin.convertToPath("ellipse"); shapes = Array.from($('.Logo_In_Shapes path')) const homeInit = () => { viewBox = "", heading_Pos = [0, 0], displayState = "" hamburger_display_button = Array.from($('.mobile_nav_sticky'))[0] opened_nav_buttons = document.querySelector('.options') logo = $(".Actual_Logo_Svg"); // Morphing Circles and ellipses to paths to be able to morph them and checking the viewbox for device size MorphSVGPlugin.convertToPath("ellipse"); shapes = Array.from($('.Logo_In_Shapes path')) } const logo_tl_func = () => { let logo_tl = gsap.timeline({ onComplete: moveLogo, }) // Morphing into the Logo logo_tl.from(shapes, 1, { y: -600, autoAlpha: 0, ease: "bounce", stagger: 0.15 }) logo_tl.to(shapes, 1, { fill: '#F0C368', stagger: 0.05 }) let firstAnimation = gsap.to('.shapes', { duration: 2, morphSVG: ".Logo_Proper_Background" }); let secondAnimation = gsap.to('.textShape', { duration: 2, fill: '#1D373F', morphSVG: ".Logo_Proper_Text" }); logo_tl.add([firstAnimation, secondAnimation]) } const changeViewBox = media_query => { media_query.matches ? viewBox = "-150 -180 2495 890" : viewBox = "-150 -350 3574 880" media_query.matches ? heading_Pos = [-511, -15] : heading_Pos = [-1540, 40]; media_query.matches ? displayState = "none" : displayState = "block" } const moveLogo = () => { gsap.to(logo, { attr: { viewBox: viewBox }, duration: 3 }) fadeInHeadingAndLinks(); } const fadeInHeadingAndLinks = () => { gsap.to('.nav_links', { display: displayState, scale: 1, duration: 3 }) gsap.to('.logo_heading', { display: "block", x: heading_Pos[0], y: heading_Pos[1], // scale:1, duration: 3 }) gsap.to('.mobile_nav_sticky', { display: "block", scale: 1, duration: 5 }, "+=.7") } const pageTransition = () => { var tl = gsap.timeline(); tl.set('.loading_container img', { scale: 0.3 }) tl.to('.loading_container', { duration: 1.2, width: "100%", left: "0%", ease: "circ.out", }) .to('.loading_container img', { scale: 0.6, duration: 1 }, "-=1.2") .to('.loading_container', { duration: 1.2, width: "0%", right: "0%", ease: "circ.out", }) .to('.loading_container img', { scale: 0.3, duration: 1.2 }, "-=1.3") } // Helper Functions const delay = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); } // Initialization Methods $(document).ready(() => { window.matchMedia("(max-width: 600px)").matches ? logo.attr('viewBox', '-350 -700 1274 1680') : logo.attr('viewBox', '-680 -380 2074 1080') var viewbox = window.matchMedia("(max-width: 600px)") changeViewBox(viewbox) }) hamburger_display_button.onclick = () => { opened_nav_buttons.classList.toggle('open') } barba.init({ sync: true, transitions: [{ name: 'transition-base', preventRunning: true, timeout: 5000, async leave() { const done = this.async(); pageTransition(); await delay(1000); done(); }, async enter() { window.scrollTo(0, 0); }, }], views: [ { namespace: 'home', afterEnter() { homeInit() window.matchMedia("(max-width: 600px)").matches ? logo.attr('viewBox', '-350 -700 1274 1680') : logo.attr('viewBox', '-680 -380 2074 1080') let viewbox = window.matchMedia("(max-width: 600px)") changeViewBox(viewbox) logo_tl_func(); hamburger_display_button.onclick = () => { opened_nav_buttons.classList.toggle('open') } }, }, { namespace: 'about', afterEnter() { aboutInit() face_tl_func() scroll_p_tl_func() scroll_skills_tl_func() scroll_facts_tl_func() }, } ], }); // //Global Hooks // barba.hooks.leave(() => { // const done = this.async(); // pageTransition(); // await delay(1000); // done(); // }) // barba.hooks.enter(() => { // window.scrollTo(0, 0); // }) and here's my about.js // Variable Declarations and Function Definitions let factsContainer_sm = document.querySelector(".factsContainer_sm") const aboutInit =() => { factsContainer_sm = document.querySelector(".factsContainer_sm") let head = document.getElementsByTagName('head')[0], link = document.createElement('link') link.rel = 'stylesheet' link.href= "../../Resources/CSS/about.css" head.appendChild(link); } const face_tl_func = () => { let face_tl = gsap.timeline(), paths = document.querySelectorAll('.My_Face path'), filledYellowElements = ['.Main_Hair_Part', '.Eyeball_2', '.Eyeball_1', '.Nostril_1', '.Nostril_2', '.Tongue_Part'], filledNavyElements = ['.Pupil_2', '.Pupil_1']; face_tl.set(filledNavyElements, { fill: 'unset' }), face_tl.set(filledYellowElements, { fill: 'unset' }), face_tl.fromTo(paths, { drawSVG: "0%" }, { duration: 1, drawSVG: "100% ", stagger: 0.15 }) let firstAnimation = gsap.to(filledYellowElements, { duration: 2, ease: "slow", fill: '#F0C368' }, "-=.7"), secondAnimation = gsap.to(filledNavyElements, { duration: 2, ease: "bounce", fill: '#1D373F' }, "-=.7") face_tl.add([firstAnimation, secondAnimation]) } const scroll_p_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.content', start: "top center", end: "+=1000", markers: true, scrub: true // pin: true } }) scroll_tl.to('.first', { transform: "rotateX(50deg) rotateZ(331deg) translateX(42px)", duration: .5, }), scroll_tl.to('.flag', { scale: 1 }, '-=.1'), scroll_tl.addLabel("first_down") scroll_tl.to('.second', { transform: "rotateX(50deg) rotateZ(331deg) translateX(42px)", duration: 2, }, "first_down-=.1") scroll_tl.addLabel("second_down") scroll_tl.to('.third', { transform: "rotateX(50deg) rotateZ(331deg) translateX(42px)", duration: 2, }, "second_down-=.01") } const scroll_skills_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.skillsContainer', start: "top center", markers: true, } }), barWidth = "", bars = [...document.querySelectorAll('.bar')] bars.map(bar => { barWidth = bar.dataset.width; let barAnimation = gsap.to(bar, { width: barWidth, }), percentageAniamtion = gsap.to('.percentage', { scale: 1, }) scroll_tl.add([barAnimation, percentageAniamtion]); }) } const scroll_facts_tl_func = () => { let scroll_tl = gsap.timeline({ scrollTrigger: { trigger: '.factsContainer', start: "top center", // pin: true, scrub: true, end: "+=300", markers: true, } }), facts = [...document.querySelectorAll('.fact')] scroll_tl.to('.factsContainer h2', { scale: 1.5, duration: 1, ease: "slow" }) scroll_tl.to(facts, { xPercent: -85 * (facts.length - 1), scrollTrigger: { trigger: ".factsContainer_sm", start: "center center", pin: true, // pinSpacing:false, markers: true, scrub: 1, snap: 1 / (facts.length - 1), // base vertical scrolling on how wide the container is so it feels more natural. end: () => `+=${factsContainer_sm.offsetWidth}` } }); } // //Initialization Methods aboutInit() face_tl_func() scroll_p_tl_func() scroll_skills_tl_func() scroll_facts_tl_func() Here's the website homepage - https://adamoceallaigh.netlify.app/ Here's the about page - https://adamoceallaigh.netlify.app/about.html Appreciate all the help ye can give , if ye can , can ye check both mobile and desktop versions. ? Cheers Adam
  12. Thanks @ZachSaucier That's fair , just thought since you might know but yeah i'll definitely look into it. Cheers , Adam
  13. Whoop whoop , after a little bit of tweaking and yere help she's working perfectly. Thanks a million lads ( @ZachSaucier @akapowl @mdelp) . I do have a question though as this hook runs after each transition say if I wanted to start a timeline on the projects page - using anotherJS file. First of all , would I have to initialize Barba again in this file considering i'm using it already to get onto this page ?? Secondly the fact that these elements aren't on the homepage, so when I then initilize and create references to them on the second JS file if i transition to another page and back to this page how do I reference them in this page without barba or the hook. I just think that if i do it on the homepage.js it would all get very cluttered and this page wouldn't have access to the objects on the other page (or maybe it would as it's just swapped in so now the DOM does have access to it ) I really don't know. I'm just looking for clarity as to how to expand my program i guess , and when i do so, do i keep needing to rereferencing objects and functions in that same hook on that JS file or can i spread it out to other JS files ?? Cheers Adam Finished Product - https://adamoceallaigh.netlify.app/
  14. Like this: let viewBox = "", heading_Pos = [0, 0], displayState = "" hamburger_display_button = Array.from($('.mobile_nav_sticky'))[0] opened_nav_buttons = document.querySelector('.options') logo = $(".Actual_Logo_Svg"); // Morphing Circles and ellipses to paths to be able to morph them and checking the viewbox for device size MorphSVGPlugin.convertToPath("ellipse"); shapes = Array.from($('.Logo_In_Shapes path')) const init = () => { viewBox = "", heading_Pos = [0, 0], displayState = "" hamburger_display_button = Array.from($('.mobile_nav_sticky'))[0] opened_nav_buttons = document.querySelector('.options') logo = $(".Actual_Logo_Svg"); // Morphing Circles and ellipses to paths to be able to morph them and checking the viewbox for device size MorphSVGPlugin.convertToPath("ellipse"); shapes = Array.from($('.Logo_In_Shapes path')) } barba.hooks.afterEnter(() => { logo_tl_func() init() hamburger_display_button.onclick = () => { opened_nav_buttons.classList.toggle('open') }; }); ??
  15. Just thought of something there, as it's basically not a new DOM and the elements have been replaced and/ or removed , the variable declarations at the start become abundant no?? So if i was to put a function to redeclare these variables and basically allow DOM to refind these elements and call it in the hook then it might work ?? Adam
  16. Thank you so much for your quick and informative replies . Okay I get what you are saying @mdelp and @akapowl and have updated my JS code to use a function to restart the timeline upon call in the hook all at once but it doesn't seem to be working and I can't tell why , it appears the individual tweens ( gsap.to) is working as the heading is being pushed in upon homepage revisit after navigating with barba , and this is enabled by using a seperate tweens and not a timeline , so is it a problem with the timeline ??. But then I have tried to use a hamburger button in the phone version it pops up and i tried to click it and i'm able in the first instance but seems that script stops working upon return after barba navigation . I've tried putting the code back into the hook (beforeAfter as indicated above) and to no avail , and as indicated above I think if i put another script in to tod something subsequent to the gsap it probably wouldn't work either so how do i get around this issue or fix my existing code to basically refresh all the scripts, like the function window.load or $(document).ready(()=>{}) would do ?? //Variable Declarations and Function Definitions let viewBox = "", heading_Pos = [0, 0], displayState = "" hamburger_display_button = Array.from($('.mobile_nav_sticky'))[0] opened_nav_buttons = document.querySelector('.options') logo = $(".Actual_Logo_Svg"); // Morphing Circles and ellipses to paths to be able to morph them and checking the viewbox for device size MorphSVGPlugin.convertToPath("ellipse"); shapes = Array.from($('.Logo_In_Shapes path')) const logo_tl_func = () => { let logo_tl = gsap.timeline({ onComplete: moveLogo, }) // Morphing into the Logo logo_tl.staggerFrom(shapes, 1, { y: -600, autoAlpha: 0, ease: "bounce" }, 0.15) logo_tl.staggerTo(shapes, 1, { fill: '#F0C368', }, 0.05) let firstAnimation = gsap.to('.shapes', { duration: 2, morphSVG: ".Logo_Proper_Background" }); let secondAnimation = gsap.to('.textShape', { duration: 2, fill: '#1D373F', morphSVG: ".Logo_Proper_Text" }); logo_tl.add([firstAnimation, secondAnimation]) console.log('Well you should have animated rn') } const changeViewBox = media_query => { media_query.matches ? viewBox = "-150 -180 2495 890" : viewBox = "-150 -350 3574 880" media_query.matches ? heading_Pos = [-511, -15] : heading_Pos = [-1540, 40]; media_query.matches ? displayState = "none" : displayState = "block" } const moveLogo = () => { gsap.to(logo, { attr: { viewBox: viewBox }, duration: 3 }) fadeInHeadingAndLinks() } const fadeInHeadingAndLinks = () => { gsap.to('.nav_links', { display: displayState, scale: 1, duration: 3 }) gsap.fromTo('.logo_heading', { x: 1340, y: 20 }, { display: "block", x: heading_Pos[0], y: heading_Pos[1], // scale:1, duration: 3 }) gsap.to('.mobile_nav_sticky', { display: "block", scale: 1, duration: 5 }, "+=.7") } const pageTransition = () => { var tl = gsap.timeline(); tl.to('.loading_container', { duration: 1.2, width: "100%", left: "0%", ease: "Expo.easeInOut", }) .to('.loading_container', { background: "#f0c368" }) .to('.loading_container', { duration: 1.2, width: "0%", right: "0%", ease: "Expo.easeInOut", }) } // Helper Functions const delay = (ms) => { return new Promise(resolve => setTimeout(resolve, ms)); } // Initialization Methods $(document).ready(() => { window.matchMedia("(max-width: 600px)").matches ? logo.attr('viewBox', '-350 -700 1274 1680') : logo.attr('viewBox', '-680 -380 2074 1080') var viewbox = window.matchMedia("(max-width: 600px)") changeViewBox(viewbox) }) hamburger_display_button.onclick = () => { opened_nav_buttons.classList.toggle('open') }; barba.init({ sync: true, transitions: [{ async leave(data) { const done = this.async(); pageTransition(); await delay(1000); done(); }, async enter(data) { window.scrollTo(0, 0); }, }] }); // barba.hooks.enter(() => { // }); barba.hooks.afterEnter(() => { logo_tl_func() hamburger_display_button.onclick = () => { opened_nav_buttons.classList.toggle('open') }; }); https://adamoceallaigh.netlify.app/ Cheers , Adam
  17. Hi there , I have read this thread as I have come back into this problem too . My problem is before transitioning the timeline loads perfectly and executes as i want however after transitioning to another page and then clicking back to the home screen the timeline doesn't play half the tweens specifically the part animating my logo. I believe after reading the thread it might come down to the fact as @mdelp has implied that elements targeted with a timeline inside the barba container are removed or replaced but I have no clue how to go about fixing this problem as i need all this content withing barba container. Here's a link to my website where you will find the problem occuring if you follow the steps outlined above -> Move to different page and then back to homepage again - https://adamoceallaigh.netlify.app/ Cheers, Adam
  18. Hi Zach , i've taken all these things onboard and suppose the reason why i was using the two svg's was that i thought it morphed into the other but reading through some documentation as stated by you it's not actually morphing into the SVG it just takes the path of the other SVG and goes into that path but actually is the same SVG , therefore i moved the actual logo part into the original SVG as a group so it's still able to morph into the desired paths. I've updated my code to GSAP 3 per your recommendations I think all of it is in order so now to my problem , what can i do to achieve the effect i want. Below is a pic of the end result i want to achieve just for your understanding (after the animation ends like). https://cdpn.io/Adamoc/debug/pojYrNE https://codepen.io/Adamoc/pen/pojYrNE?editors=1010
  19. Hi there, I nearly have this short animation finished , the problem i'm having is working with the viewbox . So when the logo is made i want to move it to the position it ends up which is perfect the problem i'm having is in order to move the object into the center at the start i make the svg width almost 100vw and height respevctively almost 100vh but then as it's animating back into it's position in the corner it has to change these width and height values to scale down the logo and also in order for me to put other elements alongside the SVG in the top section so I'm wondering it almost works perfectly but you can see as it's changing it's width and height values it becomes enormous rather than smaller at the start and i'm just wondering is there a way to make it scale smaller as it moves rather than large and then to the exact position and dimensions i need ? Thanks Adam
  20. It's grand i figured it out , I don't need it to repeat so therefore won't see square coming back , thanks so much . Until next time Craig ?
  21. Just one more question any way I could hide the square so that it's not visible to human eye that the square is morphing ? Even only on the way out ? Is what you said what I need to do with the square?
  22. @PointC Ahh sound , now i get you . So although i actually positioned the shapes in HTML in the order i wanted it to render it doesn't matter what order those shapes are in because it's math so the renderer will follow the paths unlike normal HTML where stack order does matter. I updated the synthax to the GSAP 3 and moved the square instead to the end so that the text comes in the middle which is perfect , would never have thought of this thanks so much Craig. See the actual resulting animation below: https://cdpn.io/Adamoc/debug/pojYrNE https://codepen.io/Adamoc/pen/pojYrNE?editors=1010 Just one more question anyway I could hide the square so that it's not visible to human eye that the square is morphing ? Even only on the way out ?
  23. Also I have the text element path at the bottom of the SVG i want it to morph to already
×
×
  • Create New...