Jump to content

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

Acccent last won the day on June 5 2018

Acccent had the most liked content!


  • Posts

  • Joined

  • Last visited

  • Days Won


Everything posted by Acccent

  1. if you don't have a parent element handy, you can always use some good old maths:
  2. You could rotate the parent element, I think.
  3. There it is const dots = {}; function stipple(id, func, delay, throttle = false, leading = false) { if ( !dots.hasOwnProperty(id) ) { dots[id] = TweenLite .to({}, delay * ( throttle ? 2 : 1 ), {}) .eventCallback(( leading ? "onStart" : "onComplete" ), func); } if ( dots[id].progress() === 1 ) { dots[id].restart(true, false); } if ( dots[id].progress() > 0.5 ) { if ( leading ) { if ( throttle ) { dots[id].restart(true, false); } else { dots[id].progress(0.01, true); } } else { if ( throttle ) { dots[id].progress(1); } dots[id].restart(true, true); } } } And the codepen: There's a slight issue with the timing at the end of the non-immediate throttling version, I'm not sure if it's an easy fix and if it even really matters. Also, I had to use .progress(0.01, true); – using .restart() with suppressEvents = true seems to still call onStart? Maybe I'm missing something. This isn't the end of the thread btw, it would be great if others had suggestions on how to improve on this!
  4. haha I absolutely created this thread to encourage some unofficial messing-around I usually get a custom build of lodash with just debounce and throttle, and thought "I'm sure GSAP has enough under the hood to replace that entirely, possibly more efficiently too". So here I am, asking about it. Maybe we can come across an all-encompassing solution! Your last solution is great because you can remove .progress(1) and you end up with the previous solution, ie. the debouncing functionality. I'm making a codepen with a reusable function, I'll post it when I'm finished – posting this comment here first because I accidentally made my browser crash and am guessing it may happen again, haha.
  5. That's great! What does the isActive() check achieve in your pasted snippet? It's not in the codepen. Just limits the number of times you call restart()? Also, this is for debouncing, but I feel like it could work for throttling as well with just a small modification — I tried this: window.addEventListener("resize", function() { if(!tween.isTweening()){ tween.restart(true); } }); ...thinking it would restart the tween each time it reached completion (calling update every time), but it didn't work. Another thing I found just after posting the initial thread is how the documentation for .ticker https://greensock.com/docs/TweenLite/static.ticker basically has a throttling example in it, as long as you're willing to work with frames instead of seconds... which might be preferable, actually. (Would it work with a fps that's lower than 1?)
  6. Hello everyone, I'm about to implement some debouncing mechanisms into my website and was wondering what was the best approach to take. I've seen this snippet by @OSUblake: var requestId = null; window.addEventListener("resize", function() { if (!requestId) { requestId = requestAnimationFrame(update); } }); function update() { // run your update requestId = null; } Which is a (beautiful) GSAP-independent implementation of requestAnimationFrame. Considering GSAP uses rAF internally, is there a way to leverage this? (edit: removed awful faulty code) I feel like if there was a way, it would make it easier to subsequently use that tween, or at the very least generate new ones like it, while modifying some things like the delay between each update call etc. *edit* to be clear, I understand the code above would be for throttling, not debouncing. I'm thinking about both and focusing on the former for now. Here is the latest version of what I came up with! function stipple(f, ...args) { const opts = {}, tw = new TweenLite({}, 0.2, { onComplete: end, paused: true }); let isStarting = true, lastArgs; setOptions(args.length === 1 ? args[0] : {}); function dot(...thisArgs) { lastArgs = thisArgs; if ( isStarting ) { isStarting = false; if ( opts.leading ) { run(); } tw.restart(true, true); } else if ( !opts.throttle ) { tw.restart(true, true); } } function end() { isStarting = true; if ( !opts.leading ) { run(); } } function run() { opts.func.forEach(f => { new TweenLite({}, 0, { onComplete: f, onCompleteParams: opts.params || lastArgs || [] }); }); } Object.defineProperties(dot, { tween: { get: () => { return tw; }}, options: { get: () => { return opts; }, set: v => { setOptions(v); }}, func: { get: () => { return opts.func; }, set: v => { opts.func = makeArray(v); }}, params: { get: () => { return opts.params; }, set: v => { opts.params = v ? makeArray(v) : null; }}, throttle: { get: () => { return opts.throttle; }, set: v => { opts.throttle = v; }}, leading: { get: () => { return opts.leading; }, set: v => { opts.leading = v; }}, delay: { get: () => { return opts.delay; }, set: v => { v = Math.max(v, 0.001); if ( !isNaN(v) && v !== opts.delay ) { tw.duration(v); opts.delay = v; } }} }); return dot; function makeArray(e) { return Array.isArray(e) ? e : [e]; } function setOptions(obj) { opts.func = makeArray(obj.func || opts.func || f); opts.delay = Math.max(obj.delay || opts.delay || ( typeof args[0] === 'number' ? args[0] : 0.2 ), 0.001); opts.params = obj.params || opts.params || args[1]; opts.params = opts.params ? makeArray(opts.params) : null; opts.throttle = obj.throttle || opts.throttle || args[2] || false; opts.leading = obj.leading || opts.leading || args[3] || false; tw.duration(opts.delay); } }
  7. Ah, microsoft browsers. They never fail to surprise me. Thanks, and sorry about the late reply
  8. Hi all, I just ran into a weird thing – CssRulePlugin doesn't seem to work in neither Edge 41.16299.15.0 nor IE 11.192.16299.0. Here is what I'm doing (the old 'animate max-height and set height to auto' trick): infoCss = CSSRulePlugin.getRule('#info-input:checked ~ #info-inner'); TW.set(infoCss, {cssRule: {maxHeight: infoElm.clientHeight + 'px'}}); //TW is Tweenlite window.addEventListener('resize', () => { TW.set(infoCss, {cssRule: {maxHeight: infoElm.clientHeight + 'px'}}); }); This is no big deal as I can of course just use GSAP to do the same animation instead, but still, I thought I'd mention it. As soon as I remove the above code, everything else works fine.
  9. Ah, scope, my old friend*. *enemy Yep, all clear now, thanks again
  10. Alex, I'm afraid we don't have enough context to help you as it is... There's nothing in the code you posted that suggests anything should happen with mouseover, and there's nothing immediately wrong that I can see assuming everything else is set up right – except that your code should end with }); not })}. With no more information, it's hard to point you in the right direction beyond that. Please consider sharing more code, and if possible use a codepen following the instructions here:
  11. Another (last, I hope) question about this: What's the difference between parent.call(() => { child.play(0) }); and parent.call(child.play, [0]); ? As far as I'm aware, there should be none, but my code works with the former and not the latter. How come?
  12. Yep totally, that's what I figured; just wanted to make sure. Cheers!
  13. Do you mean that when you press "go back" on your browser, the current page stays visible and animates back to what was shown before? If that's the case, you need to use functionality that's beyond the scope of GSAP to intercept the browser's 'go back' behaviour. You should have a look at this page: https://developer.mozilla.org/en-US/docs/Web/API/History_API and potentially History.js which is no longer maintained but could still be useful. Once you successfully detect that the user is trying to go back and prevent the default browser behaviour of actually reloading the previous page, then you can look into how to reverse your timelines to make your website 'smoothly' go back to the state it was in before.
  14. Yep, all of this helps a lot, thanks! In my case, I'm indeed in a situation where the child timeline will always play uninterrupted till it reaches the end (or the start if it's playing backwards). But I understand how, if you need more flexibility, you're better off returning new instances of the child timeline. To be clear, regarding .tweenFromTo(), if you had a something like parent .add(child.tweenFromTo(0, 10)) .add(child.tweenFromTo(0, 10), 5); it would be the same child that's being tweened twice? what would happen during the overlap?
  15. Hi Alex, I'm not sure I understand what you mean – if you leave the page, wouldn't it be replaced by the new page that you opened? So, your timeline wouldn't be visible anymore...?
  16. Hi all I'd like to ask about the best, most efficient way to reuse a single timeline several times, from within other timelines. First, here are some threads I found: https://greensock.com/forums/topic/16303-reverse-a-child-timeline-of-a-modular-timeline-independently/ https://greensock.com/forums/topic/16333-re-run-tween-in-a-timeline-at-a-later-point-in-the-timeline/ https://greensock.com/forums/topic/16348-multiple-timelines-sharing-addplay-wont-play/ https://greensock.com/forums/topic/13241-nesting-timelinelite-multiple-times-doesnt-work/ Here's what I got from of all of that – for clarity, I'll be calling the timelines child (the one you want to reuse) and parent (the one that you want to embed into): when just use add() with the name of child, you make child impossible to play in a different context, and you also can't add it twice. It basically becomes a single, complex tween inside parent and nothing else. you can also add() a new linear tween of child using child.tweenFromTo(); that basically copies the content of child into a self-contained tween that's embedded inside parent. you can use add() with a function that builds and returns a new child timeline; that way, you write the code once, but you create a new instance of child every time that gets added to parent. subtly different to the above, you can add() or call() a function that builds a new child; you're also making new instances of the child each time, but here you're not adding it to parent, just playing it independently. So the function you call needs to play child but doesn't need to return anything. finally, what I do in the linked codepen, you can build a child somewhere else, and then add() or call() a function that only plays it. (Note: 'add' and 'call' are functionally identical I believe, 'add' just works with other things besides callbacks; and I'm not sure what the difference is between 'call' and 'addCallback'.) First of all: did I get all of that right, or did I misunderstand something? Second: is there one of these solutions that's preferred over the other ones? I picked the last one in the codepen because I feel like if you have a single child that you refer to each time, and play (or otherwise manipulate) that one when you need it, would be more memory-efficient. Of course, that means you can't have two parents playing at the same time, or you'd run into problems. Am I missing something?
  17. I feel like this is such a major shift in what GSAP is able to do; it's not really an 'animation' platform anymore, it's more like a 'universal real-time animation and element manipulation platform'. The one problem I have is that I feel the docs could benefit from a revamping now. I've come back to the forums to find the answer to my question above, and I did, but in the process I found out about a bunch of other things that could have made my life easier before, and that are only documented in forum posts or release announcements. (For example, the function-based values are not mentioned in the docs for TweenLite.to, when it feels like an incredibly important thing to know about.) This is not really a criticism or anything, I just feel like right now the thing that GSAP would benefit the most from is not new features or revisions, but rather an improved exposition of its capabilities (again, at this point it's so much more than an animation tool – I could probably make the case for its use as a full-blown HTML game engine) and a reorganisation of the docs to give an immediate idea of all the possibilities (the main page for TweenLite, TimelineLite and their Max counterparts are very long descriptions of their most basic use – and that could be relegated to the corresponding TweenLite.to page). Just my two cents!
  18. Ah, lovely! I don't know if the ModifiersPlugin will do it, but the function-based values surely will. That's a bit new, isn't it? ...I guess more than a year old, based on that post's date... well, I'm glad I learnt about it now, better late than never haha. Thanks!! edit: yep, they totally did. perfect
  19. Hi everyone So, I think this is something that must have been asked before, but I can't for the life of me find any references. Is there a way to have a tween inside a timeline get values based on the current state of elements that are being animated? You'll see what I mean in the codepen. (which has a nice url, by the way.) I assume it isn't possible because GSAP caches everything before the animation starts, so the values would be calculated based on how things look before any change. But I thought I'd ask, in case I'm wrong. I guess a solution to this would be to place a .call() inside a timeline, something like .call(() => { TweenLite.to(element, 1, { x: <get values here> }); }) ...but perhaps there's something easier/neater that I'm not thinking of? Cheers
  20. Yup, thank you very much! I've implemented it and it's working like a charm. I also got it to work by turning off RequestAnimationFrame and lagSmoothing to make GSAP run even when the window isn't visible, but I guess it's more efficient to leave those on and use your plugin to 'catch up' when going back to the tab. Thanks again
  21. Hi there! sorry to unearth such an old thread, but after a quick Google search, I thought it would be the best place to post. My website uses GSAP to move 'panels' around depending on what part of the site you want to see. Notably, when you open a link to a blog post, it automatically moves the blog section into view; you can see it in action here: https://robin-v.net/no-mans-sky/ Now, using the example above, you can see that if you switch to another tab before the transition has ended and then come back to it, you will still be on the 'front' section (with my name), and the website is now in a kinda buggy state. The two labels on the left and right side of the screen have turned black, and if you click on one of them, the site kinda glitches out, and you you have to click repeatedly on those labels to eventually make it go back to a normal state. This is because, when you tabbed out, the code kept running (so basically all the variables and CSS classes updated to reflect having moved to the blog section), but the animation itself stopped. Anyway: I'm wondering if the jQuery plugin you've made, @Jonathan, is still up-to-date and usable? Or is there a new and better way to detect visibility changes that you would recommend? (My plan is to use the plugin to detect regaining visibility, and when that happens, just skip to the end of the animation.)
  22. You're welcome! Don't forget to mark the thread as answered if you don't have any other questions
  23. If you're having trouble, have a look at this, but I'd suggest trying to figure it out on your own first