Jump to content
Search Community

Robert Wildling

Members
  • Posts

    120
  • Joined

  • Last visited

Everything posted by Robert Wildling

  1. @Rodrigo Thank you very much for your insights! Always an eye-opener! (And sorry for replying so late.) I ams till trying to figure put what "updateScales" would look like. And if that solution wouldn't apply the same scale amount to all cubes already existing... But first and foremost I do understand your argument of the 2 loop-run-throughs on each iteration and that the difference in architecture makes my approach rather impossible. I will look for options in Three itself. If a follow-up question comes along, I will post again. Thank you and, as you say: Happy tweening!
  2. Hello, @akapowl ! Thank you for your investigation, research and answer - very much appreciated! As a matter of fact I did find all those examples, too, and there are more out there. But none that uses v0.157.0. And with that version I keep getting errors in the source code on all those platforms I listed. I could use an older version, true, but there are enough situations where an answer would be like "Have you tried with the latest version?". And I want to prevent that. (This might not be the case here, since this is an exceptional forum; but I keep experiencing things like that in other forums, so it became second nature to work with the version I use in my projects.) – Eventually all I wanted to add to this post is that there are rare situations where a minimal demo is not really possible, even though some try hard to provide one. But since @Rodrigo now says that he wants to move the post, I don't even know if it is welcome to post here. Maybe the comment function should be set to "non possible", if there is anything like that?. Anyway, @Rodrigo: I did post this comment because I experienced problems when trying to post my other question. But the posts are not related. I think it should not be moved, because this comment here is more of a universal nature pointing out one specific situation where a minimal demo would perhaps indeed not be possible. In that sense I understand my post as indeed very much related to creating a demo. It is of no great importance to me, though, so if you prefer to keep this post without comments, please feel free to delete them. Happy tweening to you all, too! And thank you very much for your feedbacks!
  3. May I first say that I tried countless examples and templates for three and vue on codepen, stackblitz, jsfiddle and codesandbox, but to no avail. GLTFLoader (and OrbitControls) make problems when imported from somewhere else, at least with the latest versions. After 2 days I decided to move on and ask my question and provide a github repo. Of course I do understand, if you won't look at it. But, as I said: I couldn't make it work anywhere, so this is really all I can do... for what's it worth here ti is: https://github.com/rowild/three-and-gsap-and-gltf I'll try to explain my problem anyway, maybe a codepen is not necessary. I import a gltf model successfully into a three scene. The gltf model contains many little cubes that I would eventually like to manipulate with gsap. (There is a post with an image on stackexchange: https://blender.stackexchange.com/questions/301825/how-to-convert-separate-linked-faces-to-individual-meshes/301828#301828) The essential code for importing that model is: const gltfLoader = new GLTFLoader() gltfLoader.load( '/models/ball.gltf', (gltf) => { scene.add(gltf.scene) const allCubes = [] gltf.scene.children.forEach(cube => { cube.castShadow = true cube.receiveShadow = true cube.scale.set(0.2, 0.2, 0.2) allCubes.push(cube) }) console.log('allCubes =', allCubes); // gsap.to( gltf.scene.children, { // duration: 2, // "scale.x": 1, // stagger: { // amount: 0.1, // grid: "auto", // from: "center" // } // }) } ) The result of logging `gltf.scene` to the console is shown in the screenshot. In order to get hold of the cubes, I save the to a new array `allCubes`, which is meant for GSAP, but this might not be necessary, since they can be accessed directly via `gsap.scene.children` if I am not mistaken. However, neither of those work when the gsap object is created (it is meant to scale the cubes to Vector3(1, 1, 1) again after having been set to 0.2). Instead I get this error in the console: ``` gsap-core.js:732 Uncaught (in promise) TypeError: a[(wrapAt++)].getBoundingClientRect is not a function at gsap-core.js:732:41 at new Tween2 (gsap-core.js:3254:48) at Object.to (gsap-core.js:3618:12) at Index.vue:168:9 at GLTFLoader.js:228:6 at GLTFLoader.js:2553:5 ``` What do I have to do to be able to let gsap operate on each of the cubes sequentially? Thank you!
  4. Thank you for providing all these templates! I took some time the last 2 days and tried out most of them (those using three). Unfortunately there is a problem with importing three GLTFLoader or OrbitControls in all of them. Things like "GLTFLoader is not a constructor" are shown as error in the console or even right within the code (Codepen). I am aware that this is not a GSAP problem, and by no means do I expect that Greensock should fix the three importing problems. But I thought I should point out the problems, because not in all cases it will possible to post a minimal demo.
  5. I am trying to find out how, in Vue (here with Quasar 2 / Vite 2) transitions between layouts can be solved. The stackblitz example has to layout "contexts", `home`and `main`. A very important factor is that the routes all have a `meta.layoutKey`, which is set on the `router-view` component as `:key`, so reload only happens, when this context changes. If such a change is detected, the `parent` var in the pinia store is set to true in `router.beforeEach()` – that way a transition can be initialised. Transitions works - kind'a... but there is a flickering happening, when "main" is revisited. I assume this has to do with things like (e.g.) `vue-if="navItems"`, where gsap's `.set(obj, { autoAlpha: 0 })` is set just not right away... How can I solve this? Stackblitz Example: https://stackblitz.com/edit/quasarframework-vy4eiw (The Readme of the example also contains the problem description. Please understand that I really worked hard to strip down the example; but it needs a certain amount of features and files, otherwise this whole layout transition problem cannot be show-cased. Thank you in advance, if you take your time to look at this!)
  6. Yes, Jack, you are totally right! I actually wanted to mention that, but than I was so overwhelmed with the result that I forgot all about it! Thanks for bringing it up!
  7. @SteveS I posted an update before I read you comment. Yes, makes very much sense what you say. Thank you again! Also thank you again, @tomcatbuzz, for participating and finding solutions! ?
  8. @tomcatbuzz I appreciate your feedback, but, as written above, I am not using API mode, but script setup, and the things you refer to (onLeave etc) have to be used on a page, where the route-view is defined (a layout page, e.g.). The code I have to deal with, however, lives in a component that is loaded and unloaded. Meaning the router-view does not have access to that component's DOM (well, it does at some point, but that would make things really complicated). It is not a difficult or unusual setup and it is totally ok to be done on router guards. All that I want to know (and where I obviousely make thinks complicated, even though it shouldn't be, since it would be short, very readable and performant code) is if there is a way to call a router guard's "next()", when using "tl.reverse()" on a "globally" defined "tl". @SteveS Thank you for your input! I have not tried yet what you suggested (pause, reverse...), but shouldn't "tk.reverse(0)" - "0" being the indicator to play the tl from the very end - do all that automatically? When the animation starts, it is only played forward, so a"onReverseComplete" has not yet been fired... unless something else it happening that I do not know about... UPDATE: @SteveS Indeed, your suggestion is the solution. Added this: onBeforeRouteLeave((to, from, next) => { tl.pause() tl.reversed() tl.eventCallback('onReverseComplete', () => { console.log('reverse complete') next() }) tl.timeScale(2).reverse(0) } Thank you! ?
  9. Thank you for your feedback, @tomcatbuzz and your example! Very nice! (Are you working in a Three.js project there?) However, I really want to know a solution for my setup, which uses router guards.
  10. Building a separate animation for the "onLeave" animation is one way to go and would solve the callback problem. However, I would like not to create extra code and instead use the existing timeline in `reverse` mode. But, as mentioned, this does create a callback problem, for which I am seeking a solution...
  11. Hi, GSAPlers! Let me start by apologizing for not providing a codepen. I do not know how to setup a vue 3 / vite project on codepen. (I think this is only possible in the pro version?) And I spent my day so far to try to get a codesandbox working, but to no avail (I have to admit that I have never been successful on codesandbox). All I can do is provide a github link for those who are willing to download and have a look into it on their local machine (which, of course, i do not expect, but at the moment it is the most I can do): https://github.com/rowild/jvds-vue3 That said I think the problem itself might not even need a codepen. This is what I have: In a Vue 3 Composition API ScriptSetup & Vite & GSAP project, a timeline is created. Items are added to the timeline in the `onMounted` hook and eventually `play`ed. The result - appearing letters - works fine. Once the enter button is clicked, a new route is called. But before that the timeline should be played in reverse (letters should disappear), which to my knowledge happens in a "Vue Router Guard", `onBeforeRouteLeave`, which comes with 3 params (`to, from, next`). `next` would eventually fire the route change, and it should be called, when the animation is completed, in this case, when `onReverseComplete` is fired. // <script setup> import { ref, onMounted } from 'vue' import { onBeforeRouteLeave, onBeforeRouteUpdate } from 'vue-router' import gsap from 'gsap' // [...] const tl = gsap.timeline({ paused: true, onComplete: () => { console.log('TL onComplete invoked')}, onCompleteScope: this }) /* Life cycles hooks */ onMounted(() => { tl.set('.letter', { opacity: 0 }) tl.set('.line', { opacity: 0, scaleY: 0 }) tl.set('.intro-container', { autoAlpha: 1 }) tl.to('.letter', { autoAlpha: 1, duration: 0.5, stagger: 0.035 }, 0) tl.to('.line', { opacity: .7, scaleY: 1, duration: 1.25 }, 0.25) tl.to('.btn-ui-show', { autoAlpha: 1, duration: 0.5 }, '>-.5') tl.play() }) /* Router Guards */ onBeforeRouteLeave((to, from, next) => { console.log('IndexPage onBeforeRouteLeave'); tl.eventCallback('onReverseComplete', console.log('reverse complete')) tl.timeScale(1) tl.reverse(0) }) However, I have no idea how to properly implement that event callback. While the reverse.played animation works fine, the callback in the shown solution is called right away instead of at the end of the animation. Assigning the `onReverseCallback` in the timeline setup (where there is also `onComplete`) won't work, because there is no access to the router guard's `next()` function. How can I solve this problem? Thank you!
  12. @Greensock No, I have not installed inertia yet. And my last post was indeed only a question concerning the docu. I looked at your changes in the docu – and I must admit I am still a bit confused. "snap" (like "onThrowUpdate" and "onThrowComplete") is now on the main list level, but other functions, that are only available with inertia, are only listed within the "inertia" list level. This seems a bit arbitrary. Wouldn't it make more sense to either put **all** functions on the main level OR **group all inertia-related functions** within the inertia list level? Or maybe even put the inertia API below the main "Config Properties" as a separate list? Just thinking out loud... personally I would prefer a separate "Inertia Config Properties" section below the "Main Config Properties" that has a comment like "Only available with inertia"; ideally with a jump menu above the "Main Config Properties". Or in the "Main Config Properties" "inertia" could be mentioned, but the text would say sth like "See below" or maybe offer a jump link... What do you think?
  13. @Greensock I started experimenting with "snap", which I couldn' get to work yet ("liveSnap" works, though). This is a very minor issue, but since I didn't know, where to post it, I do it right here: While reading through the api: https://greensock.com/docs/v3/Plugins/Draggable I realised that there is no "snap" under "Config object properties" (main text). Also, "inertia" is not listed alphabetically. The same is true, when clicking in "Draggable.create", where I can find "bounds", "edgeResistence", "liveSnap" etc, but no "snap" (and inertia before "t"). To y understanding "snap" is only available with "inertia", right? If so, shouldn't "onThrowComplete" and "onThrowUpdate" also go into the "inertia" block ONLY? (Currently they are on both "levels"). (The anchor link on "See the snapping section" does not work either.)
  14. Excellent! Thank you very much, @GreenSock, this is incredibly helpful for me! (I think you are not `@ J a c k`, right? Sorry for that. I'll fix that in the previous posts.)
  15. @GreenSock Thank you very much for the "quickTo" example! (Indeed, I thought it was just meant as a replacement of ".to"... will look into the docu now.) Draggable's "onDragEnd" only fires, when the mouse button is released. What I am asking is, if there is a way to detect a "onMoveEnd" without releasing the mouse button. In my example this would mean: - drag the sprocket - move the sprocket - stop moving the sprocket, but do not release the button (because I might continue moving after a while) -- if that happens, invoke a function that causes the pedal to move to it's proper position The reason, why a user might not release the mouse button, has to do with the (not yet implemented) idea that at various positions there will be some kind of reactions (e.g. some item, that is only a dot, but expands, when the sprocket is at a specific angle...) But OSUBlake already mentioned that I have to be implement some kind of check on my own. May I ask you for your advice on the "timeline" solution?
  16. @OSUblake @GreenSock Thanks again for your feedbacks! Sorry for not posting the link to the demo again; it is still in the first post (which I adapted): https://codepen.io/rowild/pen/eYVmJdE There I added the "quickTo", which I cannot get to work. And yes, when talking about "onMoveEnd", I actually mean Draggable – sorry for being so unclear! About my performance question: since I cannot get "quickTo" to work, I define the tween that is frequently called in "onDrag" as extra timeline and invoke "resume()" on it (I now also can call this tween from "onDragEnd"): function pedalOnDragReaction(rotation) { const tl = gsap.timeline({ paused: true }) tl.to(pedal, { duration: 0.5, rotation: -rotation, overwrite: true }) return tl } const handleOnDrag = (rotation) => { pedalOnDragReaction(rotation).resume()} } Draggable.create(bikePedal, { type: "rotation", onDrag: function () { handleOnDrag(parseInt(this.rotation % 360, 10)); }, onDrag: function () { handleOnDrag(parseInt(this.rotation % 360, 10)); }, [...] }); https://codepen.io/rowild/pen/bGLpbQe?editors=1111 It seems to work - but is it an improvement performance-wise?
  17. Thanks for bringing "quickTo" to my attention! However, in my case it does not work. No idea, what I am missing... I do not know what you mean by "you could just use an onComplete on that tween to know when it's done". When using "onMove", when is there an "onComplete" event fired? I might have been unclear in my question: I am looking for an "onMoveEnd" option, one, that detects that the mouse is not moving (but it is still clicked). UPDATE You mention that I create a tween every time there is a movement. Is there a better way?
  18. I played around with what was suggested here and stuck with the getBB approach (couldn't find a way how to use the MotionPathPlugin to find the angle point for the sprocket). Meanwhile I applied Draggable (new for me, and extremely exciting!). Out of curiosity: I was wondering if there is a "onMoveEnd" functionality? "onDragEnd" is fired, when the mouse is released, but in this case I was playing with the idea to react to the sprocket's "onMoveEnd" motion and let the, e.g., pedal swing a bit (which does not necessarily mean that the user stopped dragging it; (s)he might just be waiting...) The codepen in the first (updated) post would still be my "plaground" for reference... Thank you! PS: I implemented a function in "onDrag" that updates the rotation of the pedal. That seems to pretty much seem to do what I need. I only wonder: is this the proper way to go in terms of performance?
  19. Wow! That was quick! Thank you so much! I will study your solutions!
  20. I am trying to imitate a "sprocket turn". Using "transformOrigin: 50% 50%" won't work in this case, since there is an extending part with the pedal. But the center of the sprocket is a separate svg child element (called "sprocket-center" in the example). Is there any way I can get the position of that sprocket center and use those values for transformation origin? Also, the pedal itself has a center point around which it should turn. If there was a way to get its center point (svg child), would those value be affected by the rotation of the sprocket or would a proper grouping and nesting of svg children take care of a "constant" value that does not need to be reevaluated on each of the sprocket's turns? Eventually, a physics engine might probably be a better approach... but I have no idea, if there is any that can deal with svg children relations. Do you happen to have any suggestions? Thank you!
  21. Excellent! Once again thank you for your support, @nico fonseca! Very much appreciated!
  22. Thank you very much for your help! I do set the zIndex, via JavaScript (as a "style" property), but not via GSAP. I thought that once a property is set somehow (be it via CSS or JS), GSAP picks it up? I remember that this was a problem once, because I had set a property that interfered with GSAP...
  23. Thank you very much for your quick response! And yes, of course I know Carl's video (however I thought my problem was related to the onCompleteParams method, not the scope...) I use the arrow function now as you suggested, and it works fine, thank you! May I nevertheless dig a bit: When I remove "callbackScope: this", the context in the callback function should be the tween itself, right (screenshot)? (Even though a "data" property is undefined, but "_pt" references the "almond" div). Do you happen to know, why it is still not possible to assign zIndex?
  24. Hi, dear GSAPers! I would like to change the zIndex of a div after animation has completed. It seems this is what the callback functions are made for, however, the `onCompleteParams` remains a riddle to me. This: const cb_animCompleted = function (params) { gsap.set(this, params); }; gsap.to(almondBox, { duration: 0.5, x: 50, zIndex: 0, onComplete: cb_animCompleted, onCompleteParams: [{ zIndex: 20 }] }); throws this warning in the console: Invalid property" "zIndex" "set to" 20 "Missing plugin? gsap.registerPlugin() Can you please help understand what I am doing wrong? Thank you in advance! gsap: v3.7.1
  25. Awesome! Thank you very much! This has been waaaaaay more insightful than I expected! Much like as if a light bulb was turned on Happy tweening!
×
×
  • Create New...