Jump to content
GreenSock

peterPotter

Can the JS version of GSAP do grayscale?

Warning: Please note

This thread was started before GSAP 3 was released. Some information, especially the syntax, may be out of date for GSAP 3. Please see the GSAP 3 migration guide and release notes for more information about how to update the code to GSAP 3's syntax. 

Recommended Posts

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

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

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. 

  • Like 2
Link to comment
Share on other sites

 

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

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

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
    });
}

:)

  • Like 1
Link to comment
Share on other sites

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

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

  • Like 1
Link to comment
Share on other sites

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

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.

  • Like 1
Link to comment
Share on other sites

Thanks, Jonathan. I am aware of the className property, which is just fantastic.

Link to comment
Share on other sites

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

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

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×