Jump to content


  • Posts

  • Joined

  • Last visited

Recent Profile Visitors

1,330 profile views

ad_bel's Achievements

  • Week One Done
  • One Month Later
  • One Year In

Recent Badges



  1. @Greensock Performance Well I can honestly say I know zero about writing high performance based animation libraries But I'm not sure why a packaging system would hurt that? End of the day its still javascript and your code is not changed Features This is a different conversation. It really depends on who your customers are. TBH when you do a new release, your features are pretty much irrelevant to me because I don't even know how to use probably 10% of what you already have lol. I mainly upgrade for bug fixes and performance enhancements (that may or may not be documented). Out of curiosity who are the primary greensock users? Animators I would assume? Are there many UX developers? Remember this conversation? This is what *I* really want greensock to be i.e. and animation library for UX developers (what Flash was). There are tons of animation libraries out there i.e. velocity, anime etc... but none of them do this. If you are successful, then I could live with manually putting everything together because it is a game changer. Now if your customers don't need this and that's not your target market then fair enough but I can assure you there is a demand for this. When someone eventually does this I will move to that product. Technology Yep it changes and it changes fast. Just the nature of the business we are in ...but I think that's a good thing because we have lots of options and our products get better if you are willing to embrace change of course. As far as the technologies you mentioned: You can omit Angular/React/Vue because they can write wrappers to use your code. In the future you should have official support for those however, because you will see new customers come in droves. That can come down the road. Webpack is to packaging what jquery was to javascription dom manipulation. It's dominant and good at what it does. Will it change... it's inevitable but so will all web based technology. As far as the big companies coming in, I agree you shouldn't operate in fear rather focus on making your product better. If it's the best then people will use it (word gets out fast on this internet thing! ) @danehansen mentioned some good points about the code quality. If you are going to upgrade it, then you have an opportunity to go to es6 modules. Although this is a painful hit up front it will make life so much easier down the road. Also he also pointed out, the better the code is at understanding/reading the more you can have the community help make it better (especially true of the public components). This is more important that adding another *wiggle* effect... although those are very cool Patrons Totally different approach but maybe another option is to completely skip the paid thing and move to a patron model? Many open source libraries that have strong followings are successfully doing this now . Having said this it may not make sense for you with an already strong customer base but just throwing it out there. The patrons would get perks like you get now, plus priority support, chat channels etc..
  2. @OSUblake - well you can use tokens - I have used this in a production app: https://github.com/auth0/node-jsonwebtoken but that's assuming you have a backend system that already does the authentication. In my case it was used to secure the client since the single page app was stateless. You probably should look at: https://auth0.com/ and would have to run one of their packages like: https://github.com/auth0/node-auth0 I think what you would probably do is generate a token when someone subscribes (or renews) and then set the expiry 1 year from then. They would just use that token and you would write a bit of code to validate it before serving up the files. You can then manage all the users manually in the Auth0 dashboard. As far as pricing, I don't know how many users you have but it looks like the first 7000 are free: https://auth0.com/pricing
  3. @danehansen excellent points! This is a fantastic library but for it to remain relevant it must adapt as technologies change @OSUblake that's a good start. As long as you have it use npm you also get warnings for dependencies issues etc... you might want to start with github submodules to the public gasp library. This way you update the core stuff in that library and it's automatically included in the full library. This would help with not having to have two code bases to maintain as well as keeping all git history. Ultimately you would want to put a package.json with a dependency to the gasp library. Only reason you may not do it right away is because all your link dependencies will change. Not sure how big of a task that is but if it's not I think that's a better approach as for the token/permissions I'm not sure. That would require some research. I have never done anything like that :/
  4. @Greensock - because we all have had major problems getting this to work with webpack. In fact I originally posted this problem and I still never got this to work in my environment so I gave up and used the free plugins. I have been a paying customer for over 3 years and I do not use your paid plugins (so basically I pay for nothing other than to support you guys ) not because they aren't good or I don't want to but because it is 1 million times more important for me to have webpack than this library. I build business apps and I use greensock for UX but I cannot build these apps without webpack due to the complexity. You were saying why not grab the files every once in awhile... well I can't work if I have to do this for my 1000's of dependencies (project I'm looking on right now has 2,981 lol). Then add in CI/CD, automation etc... that we use in the corporate development world and it is hard enough to manage. I mean I get it that your perspective is probably different from us but judging by the comments there are others here that are struggling with this as well As far as your concerns: 1. When a membership expires permissions should be provoked. Whatever solution you use should have this baked in or its useless 2. Access and giving out passwords... well someone can drop your files in dropbox or email them around now. I don't see how this makes it any less secure. 3. I don't understand your last point? Are you referering to a common u/p? No don't do that lol.... any subscription based software should have that baked in (see point #1) I think this is worth doing some research on. I have never had a need for this so haven't ever looked into but maybe someone else here has? *Note to self* make sure you unsubscribe to posts otherwise you get sucked back into conversations! lol
  5. Maybe you can do it with npm private packages? https://www.npmjs.com/pricing although I'm not sure whether you would be their first tier or second? You would just tie that to a private github repo I would think for the paid customers. I would contact their customer support and see what they say
  6. Wow lot's of traffic to this post all of a sudden Part of the the problem here is that we are used to keeping our packages up to date via npm update. This is especially true when doing continuous deployment and automated builds while working in larger teams (as @danehansen mentioned). This works great until we hit the paid libraries for obvious reasons. @GreenSock I agree with @OSUblake that you you want to upgrade everything at once. Updating only portions of libraries (no matter how hard you try) can lead to hard to fix intermittent bugs. @OSUblake - Sure you can install from your own git repo but that still means that you have to keep that up to date manually. That is much more work then doing: "npm update gsap" which is all we should have to do. Now in reality, gsap really doesn't change that often (unlike many other libraries) so it is doable but not ideal. I think a better way is for *Greensock* to setup a private repo for paid members that provides them with a username/password that they receive their subscription. This way paid members update *everything* from this private repo and non paying members just update via the public repo. Also *your* deployment is now only in only 2 places vs distributing files and having to help people debug when things inevitably go wrong or people can't get it to work I know you guys focus more on the actual greensock product suite (as you should) but the reality is we need a better packaging system here. I understand you can't support every option out there but Webpack is pretty much the defacto standard and integration should be supported
  7. Also removed the npm install of gsap and just tried using *flat structure* (without webpack alias) in my project and imported in my component like this: import CustomEase from 'src/vendor/gsap/CustomEase'; and it gives me an empty object (none of the modules work) :/
  8. Hi Jack, Nope. I am using the uncompressed one (so I can have source in dev if needed) and just let webpack compress it when i build it. My structure is as follows: package.json "dependencies": { ... "gsap": "^1.19.1", ... } I get the public modules from npm and just add the club ones (1.19.1) I need like this in my project: vendor/gsap/easing CustomEase.js index.js vendor/gsap/plugins MorphSVGPlugin.js (VERSION: 0.8.8) ThrowPropsPlugin.js (VERSION: 0.11.0) index.js vendor/gsap/utils SplitText.js index.js ...where index.js looks like this for example: import CustomEase from './CustomEase.js'; console.log(CustomEase); // <---- This is undefined (see my original post to see the module.exports in the actual component is undefined) export { CustomEase } export default { CustomEase } Also note in the plugins I changed the following: //export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date) (function(name) { "use strict"; var getGlobal = function() { return (_gsScope.GreenSockGlobals || _gsScope)[name]; }; if (typeof(define) === "function" && define.amd) { //AMD define(["TweenLite"], getGlobal); } else if (typeof(module) !== "undefined" && module.exports) { //node require("TweenLite"); // <--- ***** Changed this for all since I have it aliased in Webpack. Was looking for a specific path but I get it from npm **** module.exports = getGlobal(); } }("CustomEase")); My webpack config looks like this (note: I am using vbuild - https://vbuild.js.org so the syntax is different but its still just webpack2): const path = require('path'); const OfflinePlugin = require('offline-plugin'); const webpack = require('webpack'); module.exports = options => ({ entry: 'src/index.js', html: { template: './src/index.ejs' }, webpack(config) { // inject offline-plugin in production build if (!options.dev) { config.plugins.push(new OfflinePlugin({ ServiceWorker: { events: true } })) } config.plugins.push(new webpack.ProvidePlugin({ TweenLite: "gsap" })); var gsapVendor = './src/vendor/gsap'; config.resolve.alias.TweenLite = 'gsap'; //Tried aliasing as well but didn't make a difference // config.resolve.alias.CustomEase = path.resolve(gsapVendor + '/easing/CustomEase.js'); // config.resolve.alias.MorphSVGPlugin = path.resolve(gsapVendor + '/plugins/MorphSVGPlugin.js'); // config.resolve.alias.ThrowPropsPlugin = path.resolve(gsapVendor + '/plugins/ThrowPropsPlugin.js'); console.log(config); return config } }); Finally inside my component I do the following: import { TimelineMax, TweenMax } from 'gsap'; console.log(TimelineMax); // <---- Good console.log(TweenMax); // <---- Good import CustomEase from 'src/vendor/gsap/easing'; console.log(CustomEase); // <---- Good import { SplitText } from 'src/vendor/gsap/utils'; console.log(SplitText); // <---- Good import MorphSVGPlugin from 'MorphSVGPlugin'; console.log(MorphSVGPlugin); // <---- Undefined import ThrowPropsPlugin from 'src/vendor/gsap/plugins'; console.log(ThrowPropsPlugin); // <---- Undefined That's pretty much all I am doing :/ Any other ideas?
  9. Hi, I know webpack has been talked about extensively here but all the solutions I have found involve the same publicly available modules. I am doing something like this (I use vbuild so the syntax is different): https://github.com/OSUblake/gsap-webpack/blob/master/gsap-webpack/gsap-webpack/webpack.config.js ...where I have an alias for Tweenlite the same way as above. When I go to import private (club membership) modules I can sucessfully import CustomEase from easing as well as SplitText from the utils folder but I cannot import MorphSVGPlugin or ThrowPropsPlugin from the plugins folder??? If I debug the module value: //export to AMD/RequireJS and CommonJS/Node (precursor to full modular build system coming at a later date) (function(name) { "use strict"; console.log(module); //module.exports -> undefined var getGlobal = function() { return (_gsScope.GreenSockGlobals || _gsScope)[name]; }; if (typeof(define) === "function" && define.amd) { //AMD define(["TweenLite"], getGlobal); } else if (typeof(module) !== "undefined" && module.exports) { //node require("TweenLite"); module.exports = getGlobal(); } }("ThrowPropsPlugin")); the module.exports value is undefined (it is not in the CustomEase or SplitText components for example). I am importing like this (note: there is an index.js file in the easing and plugin folders that export those modules): import { CustomEase } from 'src/vendor/gsap/easing'; console.log(CustomEase); import ThrowPropsPlugin from 'src/vendor/gsap/plugins'; console.log(ThrowPropsPlugin); CustomEase imports perfectly fine while ThrowPropsPlugin does not (because module.exports is undefined from above). I am not sure how to get these plugins to work... Anyone have any ideas??? Thanks!
  10. Hey Blake, Have you seen this library? https://github.com/Rich-Harris/ramjet I was able to get this working for morphing elements. It basically clones the nodes as well but morphs to another hidden element (and then shows it). I used ramjet just for the morph and then used gsap for the remaining animations. What I thought was nice with this approach is you don't have to track state or position because its already in the document workflow. Unfortunately, I still can't do bezier curves like we were doing above because it just supports an ease function :/ It would be nice if this approach was adopted by gsap and made into a plugin with the appropriate hooks so we could control the morph with gsap as well
  11. Hi Blake, Cool stuff - thanks for sharing! Yes the second demo is a good example of the type of animation we need. I would be interested in seeing how you achieve reverse in this case (assuming you support that) since this particular example implies workflow in a single path. Also how do you control the life cycle of the cloned elements i.e. destroy vs hide? Your approach seems good to me, and since it works with third party framework hooks, it should work in popular ones like react, angular and vue. Is this something you can share here or is it proprietary code? I was about to go down this path but it might save some time to piggy back what you already have I would love to see something like this built as a plugin or high level service in gsap (hint hint @Jack lol). As you said Blake, there really isn't anything out there that allows UI developers to make these kinds of interactive applications easily. This would be a real game changer for application developers and gsap seems like a perfect fit here. I think this would lure developers in droves to gsap if something like this was available. Animation developers can continue to work with the core components but the rest of us could leverage these high level wrappers. For the most part, I find myself always trying to do the same sort of transitions i.e. fade in/out, slide, push etc... and rarely do complex artistic animations that I see from the many talented artists on this site. I still however, need the performance, features and ease of use of gsap.
  12. Updated version. Animating the cloned node instead of the actual element http://codepen.io/ad_bel/pen/mWrpbW I ended up doing the following (notice I set the values of circle & circleClone twice) because I could not get it to the right state on the reverse. Not sure if there is a better way but it works :/ tl.set(circle, { autoAlpha: 1 }) .set([card, circle], { autoAlpha: 0 }) .set(circleClone, { autoAlpha: 0 }) .set([ripple, circleClone], { autoAlpha: 1 }) Also notice I did not remove the clone from the DOM. If I did I could not get the reverse to work. I do think I would need to be able to reset it (to its original position) though for when that button is available again. For example, do other animations that close the box and the circle button is available again. I would not want the clonedNode sitting in the reverse state. This could also be made more modular maybe if this was turned into a hero function with a signature something like (fromElement, toElement, timeline). I will probably see if I can animate to other positions next using clones as well
  13. I forked your project and here is what I have so far: http://codepen.io/ad_bel/pen/vxKpgW I made some changes so that the ripple is hidden at the end of the animation otherwise you cannot see the card content Also made it so the card is not visible before hand. I think it should be a blank place holder and then morph into a card (or whatever other components you want). I added dotted lines to show different targets to animate to. For simplicity, to switch the location of where it animates to I just set the cardNum property to 1 or 2. When I animate to card 1 it looks fine. When I animate to card 2 the button starts to scale immediately. I think this is because of the delay function - it appears as if the value is 0. I haven't dug deep into this yet but maybe this is obvious to you and you can save me some time In my card as you can see I added some actions i.e. expand button, previous, next and "animate to next box" button. Ideally I would like to be able to do multiple transitions but in order to keep the code from getting crazy, I think it needs to be made modular. Next I was thinking of implementing you idea of using the cloned node. This way each action has its own animation timeline (including reverse). What do you think? Is this the right approach? If this works, I would think it would be easy to do the animation and then leverage the transition hooks of whatever framework you are using. In my case it would be this: https://vuejs.org/v2/guide/transitions.html (scroll to transitioning between components) but if you were using React for instance you can use the ReactTransitionGroup. Basically do the complex animations in gsap and use the hooks of your specific framework to transition views when it's complete
  14. Hi Blake, Sorry I have not been ignoring you - I was just working on a new pen based on your previous posts. Wow this is incredible stuff... seriously mind blown I actually did not have a problem finding that control point. That worked very well and it looks very natural! Can't lie and say I understand the math though What I was trying to work on was the hero piece with 3 elements: the from, to and the clone. This impressed me the most and never thought to do it that way. That technique solves so many issues I was having with positioning (especially in responsive design) because I can always keep the to and from elements in the regular document flow (and can easily position using flex). This seems like it should be the recommended way to build animations for ui developers... unless it is and I'm just late to the party lol What I am trying to do next is to make it so I can make something like your hero demo where it morphs into multiple steps. For example button goes from one card to the bottom, then clicked goes to a card on the side, then maybe opens full screen or something to that effect. Some questions: 1. Would you create a single timeline for those interactions or one for each. I am building this in vue.js and it is component based. I was approaching it from the multiple timelines idea and recreate as necessary but would like to hear your thoughts on this. 2. Should I remove the cloned element or simply hide it? Is there an advantages to either approach? I'm on my phone now but I will study the code of you new pens when I have acres to my computer. I will also post my pen when it is more stable (disclaimer: it probably won't be as good as your latest posts lol). Again thanks so much for your help! This is simply fantastic!
  15. Hi, I am trying to reproduce some animations based on google material design motion: https://material.io/guidelines/motion/movement.html I've got a decent start on making a floating action button morph into a card and here is what I have thus far: http://codepen.io/ad_bel/pen/wJMrYq Although it's ok, I have 2 questions that maybe someone can help me with to make this better: 1. For the Bezier plugin curve I am doing this: var dw = window.innerWidth; var dh = window.innerHeight; var mw = dw * 0.1; var mh = dh * 0.5; var points = [ {x:0, y:0}, {x:mw, y:mh}, //Is there a better way to do this? {x:(dw/2)-28, y:dh-130}, ]; which is a hack to find the control points. Is there a better way to do this? The multiplication factors are hard coded with a value chosen based on the end point. Since my example is in the center/bottom of the screen it looks ok but if I change the location it doesn't look as good :/ All the examples I have seen for this plugin were to animate along a known path but in this case the path needs to be derived based on the end point. 2. When I animate the opening of the card it seems pretty static. Is there a way to make it look more like the following? https://dribbble.com/shots/1640866-Alarm-Material-UI I tried a few things like starting the expanding of the card animation as the button is moving along the curve but that messed up the reverse animation Thanks!