Jump to content
GreenSock

Search In
  • More options...
Find results that contain...
Find results in...

Leaderboard


Popular Content

Showing content with the highest reputation on 11/12/2019 in all areas

  1. 3 points
    Forward Ref can be a little confusing if you're relatively new to React, but is quite simple actually. In the same way that in my sample I send the close method from the parent to the modal component, the modal component creates a ref of the content <ModalContent ref={e => (modalContent = e)} />, the thing is that the value of modalContent is going to be a react object and not a DOM element. Basically forwardRef is a higher order function that takes a functional component and takes the ref passed as a prop in ModalContent and looks where exactly in the JSX code of that component you're using that reference and returns the DOM node to the parent, just like the close method works in this: <Modal visible={isModalVisible} close={closeModal} />, the only difference is that in the case of forwardRef that is executed when the component is mounted and not on a specific event handler, like a button. This is just the way I see and understand how this works, perhaps the official explanation could be different. Just personal preference, the code is easier to read for me like that Happy Tweening!!!
  2. 3 points
    Hi, I was actually working on a sample, it took longer than expected due to some work stuff and the fact that I'm getting up-to-speed in the API of V3 (all my current projects are still on 2.x. I believe that the best approach is to use forwardRef (https://reactjs.org/docs/forwarding-refs.html) in order to pass a reference of the modal content to it's parent element and include all in that particular timeline. Here is a live sample: https://codesandbox.io/s/gsap-react-modal-timeline-783bk Happy Tweening!!!
  3. 2 points
    To be completely honest I've never worked a lot with forwardRef and specially in such a case. Javascript-wise the solution in the SO post is quite correct and elegant. Keep in mind that you're just passing a reference (hence the name) to a specific object (DOM node). If that ref resides inside another object or an array, or a factory function or whatever you want, is just what JS allows you to do. If that approach works in your case then go ahead and use it. If you want you could ask around in Reactiflux discord channel. There are quite a few very talented React guys there, including people that contribute to major React projects like React Transition Group, Styled Components, React Router, etc., so you can be sure that you'll find a very accurate and correct answer there. Just click the Join Reactiflux button. Happy Tweening!!!
  4. 2 points
    Updated it. There are a lot of demos, so we haven't gotten around to updating all of them yet
  5. 2 points
    When I type into the help search I can no results (for anything). http://greensock.com/docs#/HTML5/
  6. 2 points
    Oops, thanks for pointing that out. I updated the ease visualizer to include the correct value. Thanks for bringing it to our attention!
  7. 2 points
    Hey @Loque, Welcome to the GreenSock Forum. You could use the stagger property together with function-based values ... https://codepen.io/mikeK/pen/BaaOjEP Happy tweening ... Mikel
  8. 2 points
    Ok I think I have found a solution. myTimeline.labels returns an object whose keys are the label name and whose properties are their time. E.g. {labelName:12, otherLabelName: 23} So if you want the parent timeline to play from the child timeline's previous label you could write something like: parentTl.play( childTl.labels[childTl.previousLabel()] );
  9. 2 points
    You can still search your project for strings. That's what this big button is for. And you don't have to use strings for eases. The old way still works. And you can use .parseEase if you need an actual reference. https://greensock.com/docs/v3/GSAP/gsap.parseEase()
  10. 2 points
    Hey IntouchGroup and welcome to the forums. In GSAP 3, eases are super simple: A linear/no ease is just ease: "none" (or ease: "linear", both work)! Thanks for the reduced demo
  11. 2 points
    Here's a fully random version in GSAP 3.0 using the new each, wrap and repeatRefresh: https://codepen.io/chrisgannon/pen/eedc13af50b6269167c85a2667d522dc
  12. 2 points
    It's now called InertiaPlugin. It's even more streamlined and capable, but it does exactly what ThrowPropsPlugin did - it just has a more intuitive name now
  13. 1 point
    GSAP 3 is the most significant upgrade we have ever had. With 50+ new features, there's a lot to be excited about. Here are a few of the highlights: Check out the full demo collection for more. A special shout-out to @dsenneff who created the animation at the top of this page! Jump right in - here's a starter codepen: See the Pen Try GSAP 3 on CodePen by GreenSock (@GreenSock) on CodePen. More ways to play: GSAP 3 Starter Pen - Fork the CodePen and away you go. Download the files to use locally. Using a build tool? npm install gsap will get you the files. If you're a Club GreenSock user, there's a gsap-bonus.tgz tarball file in download that you can simply drop into your project's folder and then npm install ./gsap-bonus.tgz and BOOM, it'll be installed just like any other package! See the installation docs for more information. The GSAP 3 docs Tell us what you think! Feel free to post in the our forums about what you like and any questions that you have. Or you can contact us directly if a public forum isn't your style. Are you interested in having a GreenSock representative teach your team about the new version or speak at your next conference? Contact us and we'll do our best to make it happen! Happy tweening!
  14. 1 point
    Looks awesome! Super excited for keyframes and editing motion paths in browser! Mind blown... Thank you for the awesome tool!
  15. 1 point
    Didn't see you were using a foreignObject. Don't do that.
  16. 1 point
    Great, I really appreciate all of the assistance and hope you have a great rest of the day!
  17. 1 point
    Yeah, that's totally unrelated to GSAP (which doesn't do any rendering). I'm on Catalina as well, and I don't see any of those artifacts. Could be a video card thing or driver. Tough to say for sure. Thanks for reporting it, but I don't think there's anything we can do about it unfortunately.
  18. 1 point
    Hey ueno and welcome to the GreenSock forums. Thanks for being a Business Green member! As the GSAP 3 release notes say, support for scrollLeft and scrollTop on Draggable have been removed because they can be reproduced without it. We try to keep the code as small as we (reasonably) can! Try just using type: 'x' in your project. Let us know (and potentially create another minimal demo) if you run into issues!
  19. 1 point
    I think having "center" like that is invalid for backgroundPosition according to MDN. But even with correct values the callstack is exceeded in GSAP 2 @GreenSock. The good news is it works in GSAP 3! That should be reason to upgrade https://codepen.io/GreenSock/pen/VwwGKWK?editors=0010
  20. 1 point
    Hey Chris, This should be fixed now. Thanks for bringing it to our attention!
  21. 1 point
    Here is your answer: import { FormsModule } from '@angular/forms'; [...] @NgModule({ imports: [ [...] FormsModule ], [...] }) Through you can resolve your errors, Here I am sharing with you some resource you can follow them: 1. https://stackoverflow.com/questions/38892771/cant-bind-to-ngmodel-since-it-isnt-a-known-property-of-input 2. Learn Angular
  22. 1 point
    It only kills this.tl. Yeah, sorry. There is are no magic tricks when it comes to memory management. You just have to be mindful of what you're doing, and where you are creating references.
  23. 1 point
    No. GSAP is just JavaScript, so the same rules apply to tweens as normal JavaScript objects. https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/ You can clean up after yourself to limit memory leaks. let tl = new TimelineMax().to(...) ... tl.kill(); tl = null; I do this for classes. class Foo { constructor() { this.tl = new TimelineMax().to(...) } destroy() { this.tl.kill(); this.tl = null; } } let foo = new Foo(); ... foo.destroy(); foo = null; Using breakpoints is an easy way to see what's in memory. https://developers.google.com/web/tools/chrome-devtools/javascript/breakpoints/
  24. 1 point
    Hello @jdw and Welcome to the GreenSock Forum! I noticed that in to() tween, your syntax for text-shadow has a typo with 2 semi-colons. You have this with 2 semi-colons: textShadow: "0px 0px 0px black;, 2px 2px 8px deeppink;", But it should be like this with just your comma separated values, no semi-colons: textShadow: "0px 0px 0px black, 2px 2px 8px deeppink", CSS text-shadow: https://developer.mozilla.org/en-US/docs/Web/CSS/text-shadow Happy Tweening
  25. 1 point
    Hey unvs, Thanks! I'm guessing you're running these if checks immediately after the timeline is being created and plays? I was able to get it to work with a very short delayedCall. I'm guessing it's because the timeline doesn't become active until the next animation frame? @GreenSock can check me on that. Not sure if it's meant to be that way given it wasn't that way in v2. v3: https://codepen.io/GreenSock/pen/wvvxYoZ?editors=0010 v2: https://codepen.io/GreenSock/pen/MWWBPpy?editors=0010 Thanks for bringing this to our attention!
  26. 1 point
    Hey Violetta and welcome to the GreenSock forums. With this sort of use case, you might want to use a clip-path rather than a mask. See this article for more info on why. There are several ways to do this sort of effect. The first is to not use SVG/CSS at all and just use CSS clip paths: https://codepen.io/GreenSock/pen/KKKBRMG?editors=1000 Another option would be to position the circle with GSAP/JS on resize: https://codepen.io/GreenSock/pen/MWWBGOd?editors=0010 You could also move the HTML outside of the foreignObject (duplicating it using .cloneNode(true) in JS) and then apply the SVG mask/clip path to that content. I'm not sure which method is the best supported across different browsers. The best way may depend on who your clients are. You can check support for this sort of thing.
  27. 1 point
    I agree with Zach in this, I think you're over-complicating things a bit (something we all have done to be honest ). You can easily create an empty timeline using useState() and later in the initial render you can add child instances, labels, callbacks, etc. to it, in order to avoid errors: const [tl] = useState(gsap.timeline({paused: true)); useEffect(()=>{ // here add instances to the timeline }, []); You're right about adding paused timelines to a parent one. Normally in that scenario I create the child timelines paused and when I add them to the parent I un-pause them: const masterTl = gsap.timeline({ paused: true }); const childTl = gsap.timeline({ paused: true }); // add child instance masterTl.add(childTl.paused(false)); // later on your code you only control the parent Timeline Finally, avoid adding instances to a timeline because of a state update using useEffect, this will keep adding instances and callbacks to your timeline on every state update and at the end you could end up with a lot of unwanted callbacks and instances inside your timeline. As suggested create the timeline at runtime and then, if possible, add all the instances to the timeline on the initial render. Then control the timeline using useEffect. Here is a simple example of creating and controlling a timeline using Hooks: https://stackblitz.com/edit/gsap-react-hooks-timeline-instance-toggle Happy Tweening!!!
  28. 1 point
    Hey Rhaffaele, There's multiple ways to do this. One would be to keep track of the order as the user drags them around. Another way is to just detect the order at the end (when they're submitting). It'd probably be good to use an ID for the parent instead, but you could do something like this one liner: let answerOrder = []; document.querySelector(".col").querySelectorAll(".tile").forEach(answer => answerOrder.push(answer.id)); // Do what you need to with answerOrder
  29. 1 point
    Ok, delved in (read) the docs and throwprops is inertia, and realised I needed to register them...
  30. 1 point
    Note: TimelineMax has been deprecated in GSAP 3 (but GSAP 3 is still compatible with TimelineMax). We highly recommend using the gsap.timeline() object instead. While GSAP 3 is backward compatible with most GSAP 2 features, some parts may need to be updated to work properly. Please see the GSAP 3 release notes for details. TimelineMax extends TimelineLite, offering exactly the same functionality plus useful (but non-essential) features like repeat, repeatDelay, yoyo, currentLabel(), tweenTo(), tweenFromTo(), getLabelAfter(), getLabelBefore(), getActive() (and probably more in the future). It is the ultimate sequencing tool that acts like a container for tweens and other timelines, making it simple to control them as a whole and precisely manage their timing. Its easy to make complex sequences repeat with TimelineMax and there are plenty of methods and events that give you complete access to all aspects of your animation as shown in the demo below. See the Pen Burger Boy Finished / TimelineMax page by GreenSock (@GreenSock) on CodePen. Interesting note: The animation in the banner above is a mere 11 lines of TimelineMax code. The next demo illustrates many of the things TimelineLite and TimelineMax handle with ease, such as the ability to: insert multiple tweens with overlapping start times into a timeline create randomized bezier tweens control the entire set of tweens with a basic UI slider repeat the animation any number of times dynamically adjust the speed at runtime. Notice how the play / pause buttons smoothly accelerate and deccelerate? See the Pen Burger Boy Finished / TimelineMax page by GreenSock (@GreenSock) on CodePen Be sure to check out TimelineLite for more info on all the capabilities TimelineMax inherits. The chart below gives a birds-eye look at the methods these tools provide. ul.chart { width:360px; float:left; margin-right:30px; } ul.chart li:nth-child(1){ font-weight:700; list-style:none; margin-left:-20px; font-size:20px; margin-bottom:20px; } TimelineLite and TimelineMax Methods add() addLabel() addPause() call() clear() delay() duration() eventCallback exportRoot() from() fromTo() getChildren() getLabelTime() getTweensOf() invalidate() isActive() kill() pause() paused() play() progress() remove() removeLabel() render() restart() resume() reverse() reversed() seek() set() shiftChildren() staggerFrom() staggerFromTo() staggerTo() startTime() time() timeScale() to() totalDuration() totalProgress() totalTime() useFrames() Methods exclusive to TimelineMax currentLabel() getActive() getLabelAfter() getLabelBefore() getlLabelsArray() repeat() repeatDelay() tweenFromTo() tweenTo() yoyo()
  31. 1 point
    Hey jdw, Your tween is a bit misformatted. It seems you have two values for the textShadow in the tween. GSAP does its best at interpreting it, ending up going to the second value, it would be better to use a .fromTo() if you want to animate from one value to another. Secondly, browsers that I know of don't do sub-pixel text-shadows. So that's likely why your animation is "jumpy". GSAP has no control over that. If you look at a demo like the one below, you'll notice their going between larger values so that the animation looks more smooth. https://codepen.io/FelixRilling/pen/qzfoc?editors=0100 Also note that animating shadows like text-shadow are performance intensive, so it's likely to not perform well no matter what you're doing If you're going to do something like this in production, it might be a good use case for using <canvas> with something like pixi.js or just using a spritesheet of images.
  32. 1 point
    Hey @jdw, Welcome to the GreenSock Forum. Your code is working as expected. Should it flicker? Or what ... Examples of how 'neon font' can be implemented you can find on CodePen. https://codepen.io/mikeK/pen/ae5576e80f4f8d25a946fc4c657d8810 Happy tweening ... Mikel
  33. 1 point
    Hey kohlej, A few things here: You're using document.querySelector('.btn'), but this only select the first button. You want to be using querySelectorAll() instead. One you make the change above, you will see errors appear because you can't add event listeners to a node list (which is what querySelectorAll() returns). So yes, you will have to iterate through each of the buttons to add event listeners to each. There are many ways to do this, but I included one way in the demo below. Your tween selects every element with the .one and .two classes on the page (because GSAP automatically uses document.querySelectorAll() for selector strings in the target position). You aren't wanting that, so you need to provide a scoped selector as the target. It's generally better to use .addEventListener() rather than .onsomething because that way your listener can't be overwritten by some other JS on the page. Altogether it should look something like this: https://codepen.io/GreenSock/pen/JjjrmWK?editors=0010
  34. 1 point
    Note: This page was created for GSAP version 2. We have since released GSAP 3 with many improvements. While it is backward compatible with most GSAP 2 features, some parts may need to be updated to work properly. Please see the GSAP 3 release notes for details. Have you ever wondered why GreenSock doesn't use a more common open source license like MIT? Sometimes our licensing model is misunderstood but hopefully after reading this article you'll see why it is so foundational to the success of our tools and why it ultimately benefits users too. Open source is awesome! If you had to write and maintain your own jQuery or React or GSAP, could you do it? Would it be as refined and reliable? Probably not. How many times have you found a library or chunk of code on github that saved you hours of development time? Open source can be a quick path to great results. It also serves as a jumping-off point for up-and-coming developers to share their innovation, inspiring others to write better code. Open source is easily one of the most influential movements in the entire development community. We're certainly not anti-open-source. Quite the contrary. Open source is *not* always awesome Despite its strengths, there are some dark sides to open source. Many projects are riddled with bugs, poorly documented, and sometimes even dangerous to use. The web is littered with abandoned projects that once seemed promising. It's like a clearance bin you'd find at a discount store; there may be some treasures in there, but you'll have to dig through a lot of undesirables to find the gems. In an industry that's inundated weekly with "hot new" libraries, all just a click away for free, it can be tough to figure out which ones to gamble on. Commitment required(?) Some libraries are one-trick ponies that don't require ongoing commitment. For example, a math library that performs matrix operations or a formatting library. If the author abandons the project, it's no big deal. Other projects, like a full-featured animation library, are much more complex and leverage browser-level optimizations that are moving targets. Vendor-specific bugs need to be worked around or new browser features get introduced that beg to be animated. Plus, animation is the most performance-sensitive aspect of the user experience, so a commitment to ongoing optimization pays dividends. Beyond the code itself, what about community, documentation and examples? These become increasingly important as a library's feature set expands and companies standardize on it, needing to train new staff. Again, some projects have very little need for ongoing support but for GreenSock, it seemed essential. Hampered by success Paradoxically, success is the very thing that kills many open source projects because they don't have a funding mechanism to underwrite all the demands. The project that was once the twinkle in the author's eyes often ends up being a thorn in their side. They can't afford (or don't really want) to keep up with the demands. That's not to say that all open source projects suffer this fate. We have the utmost respect for open source authors, and we don't mean to diminish anyone's hard work or generosity. But there are some common frailties of open source projects in general that GreenSock aims to avoid. Having built and maintained a popular library for over a decade, we've learned that one of the most important factors in keeping a complex project like GSAP vibrant is the licensing model. Our goal was to make GreenSock tools not only accessible (which MIT does a great job of), but also sustainable, business-friendly, consistent, and respectful. We needed a license that would have the best chance of facilitating those goals, as described below: Sustainable Scores of animation libraries have come and gone over the years. We didn't want to be just another flash in the pan that ultimately leaves users feeling abandoned. Trust is paramount for us. We wanted the GreenSock brand to be associated with an exceptionally high level of commitment and reliability. Earning that trust requires a consistent, full-time effort so we considered these funding models: Self-funded - most open source projects are self-funded, meaning that the authors cover all the costs themselves, typically by donating their time and resources. It's noble and perfectly adequate for many projects. An MIT (or similar) license is a great fit because it allows an author to share code with almost zero strings attached. However, the commitment level tends to be unreliable and self-funded projects are rarely sustained long-term. With our particular project and goals, this wasn't a good fit. Corporate sponsorship - sometimes huge companies like Adobe, Microsoft, Facebook, or Google are willing to contribute funds to encourage a project. They usually have a vested interest in its success. For example, Adobe helps fund CreateJS which is a set of libraries that its very own Adobe Animate (formerly Flash) relies on. React is underwritten by Facebook. This can be a great way to offload development costs onto some deep-pocketed corporations, keeping it totally free for end users. The risk, however, is that if the project goals don't line up with the corporation's agenda (which can shift), funding gets yanked or the developers get pressured to go in a direction that may not be good for end users. If the company has a bad year, they may re-allocate resources. The project is ultimately beholden to a few key sponsors with potentially conflicting objectives. This wasn't something we were comfortable with although we acknowledge that it's a great solution for certain projects. Private investors - famo.us is probably the most well-known example of an "open source" project that took on private investors. A few years and $30,000,000+ later, it stopped development of its open source library and laid off a large chunk of its staff, deciding to "pivot" in a more profitable commercial direction. Private investors want a return on their investment (which is completely understandable) but an MIT license can make that very difficult because it leaves the IP (intellectual property) wide open for anyone to steal, including competitors. Similar to corporate sponsorship, projects who get their funding this way are beholden to a few key stakeholders who may have a very different agenda than end users. Again, this wasn't an ideal fit for GreenSock. User-funded - when funding comes directly from end users, it creates a wider base (more stable) and incentivizes the kind of innovation that end users actually care about, otherwise funding naturally dries up. That's a healthy dynamic for aligning agendas. Rather than serving a small set of outside investors looking for a return or a corporation with profit centers to bolster, end users play the central role. The downside, of course, is that certain features or use cases involve a fee. That can be a tough pill to swallow for some, especially when "free" MIT-licensed options abound. And it takes time to build up a wide base of users who literally "buy in". Trust and longevity are key. But a surprising number of users embrace this model because it allows them to "vote" with their dollars and participate in making a product they love continue to thrive. While this model certainly isn't for everyone, it has been a good fit for GreenSock. Accessible Sometimes we hear comments like "you can't use GreenSock in commercial projects without a license." WRONG. [loud buzzer noise]. Our license was designed to make the tools extremely accessible, even permitting usage in one-off commercial projects (where you get paid a one-time fee by a single client). And of course it's free to use in non-commercial projects (see licensing page for details). That way, a certain breed of power-user provides the funding that benefits everyone. An estimated 95%+ of our users never pay us a dime. So while a rare type of commercial project does require a "Business Green" Club GreenSock membership (which covers an unlimited number of projects while active), the vast majority of users never need that special license. This accessibility was a cornerstone of our approach. We didn't want to hide all the tools behind an intimidating paywall or make all commercial uses trigger a fee. Yet it couldn't be as unrestrained as MIT because that would create vulnerabilities for us and our users (as described in this article). Another way we keep the core tools accessible is by freely exposing the raw source code both on github and in our downloads. Users can peek under the hood and see how things work. That makes troubleshooting and learning much easier. We tried to strike a balance of openness and healthy insulation from the frailties of MIT. Business-friendly Most businesses are very concerned about IP infringement, lawsuits, and indemnification. The "no strings attached and no warranties" nature of MIT is both a strength and a weakness. It simplifies sharing, but what if an open source library leverages someone else's IP? What if it uses "copyleft" code that infects anything it touches, requiring that all projects using it be open-sourced as well? That could be a huge problem for businesses with proprietary tools in a competitive market. GreenSock's license doesn't have any attribution requirements, nor does it impose share-alike rules like GNU and Creative Commons. Furthermore, it contains warranties that aren't found in MIT-like licenses, making GreenSock more business-friendly. It survived the software audits and legal review process at reputable companies like Google, Sony, EA, Intel, every major ad network, and many others. This vetting is necessary in the business world where there is so much at stake. The license also allows for code edits to be made for bug fixes. Typically that's not necessary because we handle it as a part of our ongoing support efforts, but businesses appreciate knowing that if we relaxed those efforts, they'd still be able to get their project working if they ran into a bug and needed to squash it themselves. Consistent MIT-licensed projects spread on github where it's trivial to fork them and start making custom flavors. That's ideal for authors whose goal is to start something and then step back to let the community run with it. But that can lead to a lot of confusion as different flavors start popping up with incongruent feature sets and incompatibilities. Focus and direction are easily lost. If there's no driver (or too many drivers), it can be a scary ride for the passengers. We wanted the GreenSock brand to convey a certain level of consistency and reliability. That's part of the reason we don't generally accept pull requests - we keep a tight reign on the codebase so that we are intimately aware of every piece. That allows us to not only support it, but also stand behind our IP warranties. Respectful We believe that if we respect our users, they'll generally reciprocate that respect. Most people want to do the right thing. So we don't inject "phone home" code that reports usage or causes things to suddenly stop working when a membership expires. We don't force business customers register each user or enter serial numbers to activate seats. We don't limit installations or the number of projects that the license covers. We don't burn extra energy policing usage. We've never sued anyone. We funnel our energy into refining the tools, innovating, educating, and supporting our users. We put a lot of effort into creating a positive, respectful culture in the forums which boast over 50,000 members and 80,000 posts. We don't charge a dime for support there, and we don't shamelessly promote Club GreenSock memberships. Again, we trust that if we keep trying to provide value, people will notice and gladly sign up to support the efforts at some point. An unintended benefit of our licensing model has been that it naturally weeds out users who expect everything for free and don't recognize the substantial effort that goes into these projects. We're left with users who tend to be very respectful and trustworthy (exactly who we like to serve). Conclusion GreenSock isn't the typical open source project. Our licensing model reflects that. It offers a blend of sustainability, accessibility, business-friendliness, consistency, and respect that'd be very difficult (or impossible) to accomplish with an MIT-like license. It's not necessarily "better" (open source is fantastic, really) but in our particular case it aligned more closely with the project goals. In fact, many companies have chosen GreenSock because of the license, not in spite of it. They wanted to invest in a platform that had a certain level of commitment behind it that's rare in the open source world. After a decade, the experiment seems to be working and we have our supporters to thank for that. We've been humbled and inspired by Club GreenSock members throughout the years. It's a privilege to create these tools and serve the community. We're grateful for their partnership which makes it all possible.
  35. 1 point
    Hi and welcome to the GreenSock forums. Thank you for the demo. I think you understand that the transformOrigin allows you to provide the x/y coordinates for the point the object will rotate around. With SVG you need to get those coordinates based on its native size. Your SVG has a viewBox of 0 0 58 58 but it is being scaled up to fill a container of 300x300. To get the SVG to display at its native (normal) size I changed your container's css to 58x58: .svgContainer{ width: 58px; height: 58px; } I then selected the needle in Chrome Dev tools to see its bounding box. I took a screenshot of the svg at its normal size with the needle highlighted so that I could see its true dimensions. I then opened that screenshot in photoshop I measured to where the center of the needle is and got the values from width:4px height: 12px for the transformOrigin tl.to(needle, 5, {rotation: 360, transformOrigin:"4px 12px"}); See it here: http://codepen.io/GreenSock/pen/eBOdYY SVG ORIGIN GSAP also has a feature called svgOrigin which allows you to find a point on the SVG container that child elements can spin around. This demo: http://codepen.io/GreenSock/pen/waKrNj illustrates the difference between transformOrigin and svgOrigin. Since your svg is normally 58 x 58 the center will be at x:29, y:29. I think your needle may be off just a touch I found that 29 / 28 worked fine as svgOrigin tl.to(needle, 5, {rotation: 360, svgOrigin:"29px 28px"}); http://codepen.io/GreenSock/pen/vyBXYe Hopefully this helps. Let us know if you have any more questions.
×