4 Replies Latest reply on Nov 8, 2007 2:20 PM by Greg Dove

    Trying to make sense of AS2 gradient fill matrices

    Level 7
      This one will likely interest kglad, but I'm all ears for insight from
      anyone who digs math.

      I've been working with gradient fills lately in AS2, which means I've
      been reading through related entries in the ActionScript 2.0 Language
      Reference. Here's a quick example right out of the docs (slightly revised
      to boil it down to the essentials). The Drawing API draws a square and
      fills it with a linear gradient that goes from red (upper left) to blue
      (lower right).

      this.createEmptyMovieClip("gradient_mc",this.getNextHighestDepth());
      with (gradient_mc) {
      colors = [0xFF0000, 0x0000FF];
      fillType = "linear";
      alphas = [100, 100];
      ratios = [0, 0xFF];
      matrix = {matrixType:"box", x:100, y:100, w:200, h:200,
      r:(45/180)*Math.PI};
      beginGradientFill(fillType,colors,alphas,ratios,matrix);
      moveTo(100,100);
      lineTo(100,300);
      lineTo(300,300);
      lineTo(300,100);
      lineTo(100,100);
      endFill();
      }

      The point of interest, to me, is that generic Object instance, matrix,
      with properies x, y, w, h, r, and matrixType. The x and y are for position
      and correspond to the moveTo(100,100) call. The w and h represent width and
      height. The r is rotation in radians. The matrixType is arbitrary (I
      guess), because the same matrix can be used for a radial gradient -- never
      mind that for now.

      The properties shown, arbitrary or not, are the ones demonstrated in the
      docs. That snippet does draw a 45deg red to blue gradient.

      The docs recommend a slightly different approach for Flash Payer 8 and
      higher; namely, the native Matrix class. Everything in the above sample
      remains except that the existing matrix line changes to these two lines:

      matrix = new Matrix();
      matrix.createGradientBox(200, 200, (45/180)*Math.PI, 100, 100);

      Pretty obvious to see where they overlap. The matrixType property is
      gone, but hey ... everything works, so I'm not going to go looking for
      trouble.

      Here's the punch line. The docs *also* show an alternative Object
      approach, one in which the properties describe a 3x3 matrix whose properties
      are a, b, c, d, e, f, g, h, and i. After toying with this a-through-i
      example, I noticed a pattern in the values: c, f, and i are 0, 0, and 1
      respectively. That seems to correspond to the conventional graphics matrix
      ...

      a b u
      c d v
      tx ty w

      ... where u, v, and x are 0, 0, and 1. Seems fairly clear that tx and ty
      would correspond to x and y. After tracing the properties of the matrix
      variable (after the createGradientBox() call) it seemed reasonable to me to
      make the following mapping:

      a:a b:b c:0
      d:c e:d f:0
      g:tx g:ty i:1

      ... which led me to replace the original matrix declaration with this (back
      to a single line):

      matrix = {
      a:0.086316745750311,
      b:0.086316745750311,
      c:0,
      d:-0.086316745750311,
      e:0.086316745750311,
      f:0,
      g:200,
      h:200,
      i:1
      };

      Those values, by the way, come from my tracing the properties of this
      ...

      matrix.createGradientBox(200, 200, (45/180)*Math.PI, 100, 100);

      The weird part is, that still gives a 45deg angled gradient, but it's
      super-heavily banded. Not really a gradient at all, but more like four
      colored stripes -- red, blue, red, blue -- from upper left to lower right.

      Can anyone explain to me why?


      David Stiller
      Adobe Community Expert
      Dev blog, http://www.quip.net/blog/
      "Luck is the residue of good design."