Share Posted November 5, 2013 I know we can easily remove the saturation from any movieClip in Flash with GSAP and thus turn the clip into a grayscale version of itself. How can we do the same with the JavaScript versions of GSAP? Essentially, I want to change the color of a div and all its children into a grayscale color. Link to comment Share on other sites More sharing options...
Share Posted November 5, 2013 Hello.. I dont see any support for GSAP JS version for animating CSS filters as of now.. But there are ways using CSS3 filters but they are limited to specific browsers.. for instance the grayscale filter is only available in the public releases of Webkit browsers. So for now, you can download Canary when testing the grayscale filter. img { -webkit-filter: grayscale(100%); } also using SVG+XML within a CSS filter grayscale: http://jsfiddle.net/KDtAX/487/ Im sure if you can provide a jsfiddle or codepen example with your JS, CSS, and HTML .. we can come up with a solution since the above i listed are really not ready for prime time due to browser compatibility http://caniuse.com/css-filters since you only want to change DIV and its children to grayscale, im sure that can be done with GSAP JS by animating the color values of the DIV and its children to a grayscale color value you could possible change color values on an element in JavaScript and jQuery like this: See the Pen dkyKu by jonathan (@jonathan) on CodePen Link to comment Share on other sites More sharing options...
Share Posted November 5, 2013 Yeah, jonathan is right - the reason GSAP can't just animate the saturation of any image or element in the browser is because the browsers haven't all agreed on a way to do it. Webkit has some "experimental" stuff, but we're not building GSAP around "experimental" things that may be here today and gone tomorrow. We're trying to make it a very reliable platform that supports things that are industry standards (for the most part at least). I've been around long enough to see whiz-bang "experimental" features added and then dropped in browsers, or the API completely changes as the committees argue and refine things. So the code you write today and works great in Chrome may break in 8 months or something - we really want to avoid that. You can use a canvas library to do saturation effects. For example, EaselJS. GSAP has an EaselPlugin that makes it really simple actually (even simpler than in EaselJS's own animation engine, TweenJS). But working with a canvas library is quite a bit different than just being able to target a DOM element and tweening its saturation. 2 Link to comment Share on other sites More sharing options...
Author Share Posted November 5, 2013 See the Pen dkyKu by jonathan (@jonathan) on CodePen Wow, Jonathan; that is a very impressive effort. Thanks for the thorough explanation. I didn't study your desaturate function enough to know if I can just use it on any web page's body tag to desaturate the entire page. That is what I want do: target the body tag to desaturate the entire page (all of the body tag's children). Can you tweak your desaturate function to do that? Link to comment Share on other sites More sharing options...
Author Share Posted November 5, 2013 Thanks, Carl. It makes sense that GASP will not support experimental features. The canvas solution wouldn't work for me, I just want to target the body tag and desaturate the entire page, as I noted above to Jonathan. Link to comment Share on other sites More sharing options...
Share Posted November 5, 2013 to do the whole page and all its elements would be some effort since i would need to know how many and what elements you were trying to make grayscale? basically that desaturate function just grabs the RGB values and interpolates them to grayscale values the example can also be modified so instead of just statically turning to grayscale you could animate it with GSAP and let GSAP animate from color to grayscale if you were doing all the elements at once you can use the to() method or you could use the GSAP stagggerTo() method to have each element turn grayscale one each after another modified previous codepen with GSAP tween: See the Pen HoBLp by jonathan (@jonathan) on CodePen so this: function desaturateElement(el) { var $el = $(el), color = $el.css('color').match(/\d+/g), bg = $el.css('backgroundColor').match(/\d+/g); $el.css({ "color": desaturate(color[0], color[1], color[2]), "backgroundColor": desaturate(bg[0], bg[1], bg[2]) }); } could possible become this: function desaturateElement(el) { var $el = $(el), color = $el.css('color').match(/\d+/g), bg = $el.css('backgroundColor').match(/\d+/g); TweenMax.to($el, 2, { css:{ "color": desaturate(color[0], color[1], color[2]), "backgroundColor": desaturate(bg[0], bg[1], bg[2]) }, ease:Power4.easeOut }); } 1 Link to comment Share on other sites More sharing options...
Author Share Posted November 5, 2013 Adding Tweenlite ani does make the transition to grayscale more lovely. I tried out your desaturate function on my page and it works fairly well on specific div elements. I could make it work for the entire web page, with a good bit of effort . I did notice that the overall grayscale did not maintain the brightness level of each color. For instance, if we have a red box on a blue box, the red box is almost the same grayscale color as the blue box, so the red box, which is actually a button, is barely noticeable after the desaturation. The bottom line is that this can work with some tweaking, but it does require some effort indeed, to desaturate the entire page. Thanks very much; this is the best bet for now I supposed. Link to comment Share on other sites More sharing options...
Share Posted November 5, 2013 you could try tweaking the inty variable in the desaturate() function which can help adjust luminance or perceived brightness function desaturate(r,g, { var inty = 0.4 * r + 0.60 * g + 0.12 * b, // intensity a = 1; // 0 to 1 amount of desaturation - can also be 0.5, etc r = inty * a + r * (1 - a) >> 0; g = inty * a + g * (1 - a) >> 0; b = inty * a + b * (1 - a) >> 0; return "rgb(" + r + ", " + g + ", " + b + ")"; } you could change this line: var inty = 0.4 * r + 0.60 * g + 0.12 * b, // intensity to this: var inty = 0.3 * r + 0.58 * g + 0.10 * b, // intensity more or less tweaking those values good reference on Luma and Luminance: http://en.wikipedia.org/wiki/Luma_%28video%29 http://en.wikipedia.org/wiki/Luminance_%28relative%29 1 Link to comment Share on other sites More sharing options...
Author Share Posted November 5, 2013 I thought of an easy way to make this work: dynamically add a new class to all children and their children, and add the saturation to that class, so I can later remove the class easily to restore the color. Link to comment Share on other sites More sharing options...
Share Posted November 5, 2013 thats a good solution.. GSAP also has methods to animate from classname to classname... but you need to include the CSSPlugin.js .. unless your using TweenMax, then it is included with Tweenmax http://api.greensock.com/js/com/greensock/plugins/CSSPlugin.html className - allows you to morph between classes on an element. For example, let's say myElement has a class of "class1" currently and you want to change to "class2" and animate the differences, you could do this: TweenMax.to(myElement, 1, {className:"class2"}); And if you want to ADD the class to the existing one, you can simply use the "+=" prefix. To remove a class, use the "-=" prefix like this: TweenMax.to(myElement, 1, {className:"+=class2"}); Note: there are some css-related properties that don't tween like IE filters, but almost every css property is recognized and animates great. Also, there is a slight speed penalty when using className because the engine needs to loop through all of the css properties to see which ones are different. 1 Link to comment Share on other sites More sharing options...
Author Share Posted November 5, 2013 Thanks, Jonathan. I am aware of the className property, which is just fantastic. Link to comment Share on other sites More sharing options...
Share Posted November 5, 2013 also one last thing.. if your adding a class.. you could just add the class to the top parent of teh page.. like the body tag or a wrapper div. And then when you target those elements you can just include that body tag or wrapper div in the CSS rule.. so this way you dont have to add/remove classes on all your elements on the page since manipulating the DOM can be very slow so instead of having every element have that class you just have it in your CSS rule declaration: body.myClass div { // css properties go here } body.myClass span { // css properties go here } body.myClass p { // css properties go here } also your jQuery element objects could be: $("body.myClass div") but you get the point Link to comment Share on other sites More sharing options...
Author Share Posted November 5, 2013 Well, I just gave it a very quick try and the elements are tuning black because the desaturation is being added more than once, it appears. I will get back to this later when I have more time to set it up properly. I have to complete another more urgent part of the project for now Link to comment Share on other sites More sharing options...
Share Posted November 6, 2013 Actually jonathan, you want the classes on the elements directly, otherwise it won't tween: See the Pen GLjBE by jamiejefferson (@jamiejefferson) on CodePen 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now