5. Making an actor transparent by changing its opacity

5.1. Problem

You want an actor to be transparent so that other actors are visible through it.

5.2. Solution

Change the actor's opacity so that it is partially (or even fully) transparent:

/* 25% transparency */
clutter_actor_set_opacity (actor, 191);

/* 50% transparency */
clutter_actor_set_opacity (actor, 122);

/* completely transparent */
clutter_actor_set_opacity (actor, 0);

Any actor covered or overlapped by the transparent actor should be visible through it; the Discussion section gives some examples of how visible you can expect the covered or overlapped actor to be.

5.3. Discussion

Opacity is a property of every ClutterActor. It is a float on a scale from 0 (invisible) to 255 (completely opaque). Actors with 0 < opacity < 255 will have a varying amount of solidity on the stage, so other actors may be visible through them.

For example, below are 4 yellow rectangles overlapping a white rectangle on a blue stage:

The effect of different opacities levels on an actor's appearance

The rectangles have the following opacities:

  • top-left: 255 (0% transparency)

  • top-right: 191 (25% transparency)

  • bottom-right: 122 (50% transparency)

  • bottom-left: 61 (75% transparency)

Notice how both the stage and the white rectangle are visible through the yellow rectangles.

As opacity is a property of every actor, it can be animated like any other GObject property, using any of the approaches in the animation API.

The following sections cover some other considerations when working with actor opacity.

5.3.1. Container and color opacity

If a container has its opacity set, any children of the container have their opacity combined with their parent's opacity. For example, if a parent has an opacity of 122 (50% transparent) and the child also has an opacity of 122, the child's effective opacity is 25% (opacity = 61, and it is 75% transparent).

To demonstrate the visual effect of this, here are three rectangles with the same color but different opacity settings, inside parents which also have different opacity settings:

How a container's opacity affects the opacity of its children
  • The left-hand rectangle has opacity = 255 and is in a ClutterGroup with opacity = 255. This means it is fully opaque.

  • The middle rectangle has opacity = 255 and is in a ClutterGroup with opacity = 122. Notice that the parent opacity makes the rectangle appear darker, as the stage colour is showing through from behind.

  • The right-hand rectangle has opacity = 122 and is in a ClutterGroup with opacity = 122. Notice that the rectangle appears to be even darker, as the stage colour is showing through both the rectangle and its parent.

Similarly, ClutterColor also contains an alpha property which governs the transparency of the color. Where an actor can have a color set (e.g. ClutterRectangle) the alpha value of the color also affects the transparency of the actor, for example:

/* color with 50% transparency */
ClutterColor half_transparent_color = { 255, 0, 0, 122 };

ClutterRectangle *actor = clutter_rectangle_new ();

/* set actor's transparency to 50% */
clutter_actor_set_opacity (actor, 122);

/* rectangle will be 25% opaque/75% transparent */
clutter_rectangle_set_color (CLUTTER_RECTANGLE (actor),
                           &half_transparent_color);

5.3.2. Depth and depth order

Each actor has two more aspects which affect its apparent opacity:

  • An actor's depth can have an effect if the stage has fog (a depth cueing effect) turned on. As an actor's depth increases, the actor apparently "recedes" from view and gradually blends into the colour of the stage. This produces an effect similar to making the actor transparent. See the ClutterStage documentation for more details about fog.

    Depth also needs to be considered if you want one actor to be visible through another: the actor you want to see through a transparent actor must be "deeper" than (or at the same depth as) the transparent actor.

  • The depth order governs how actors within a ClutterContainer implementation are placed with respect to each other.

    Note

    Depth ordering is not the same thing as depth: depth ordering records relationships between actors at the same depth.

    If you have two overlapping actors actorA and actorB in a container, and you want actorA (opaque) to be visible through actorB (transparent), you should ensure that actorB is "above" actorA in the depth ordering. You could do this as follows:

    /*
    * raise actorB so it is above actorA in the depth order;
    * NB actorA and actorB both need to be in the same container
    * for this to work
    */
    clutter_actor_raise (actorB, actorA);

    clutter_actor_set_child_above_sibling(), clutter_actor_set_child_below_sibling() and related ClutterActor functions set depth ordering on actors.