4 Replies Latest reply on May 25, 2012 2:08 AM by Kyle Hawkins

    Duplicate then reverse 'perlin flag wave' effect

    Kyle Hawkins

      I would like to duplicate this excellent flag fluttering effect created with a perlin noise displacement filter.




      However I am unable to duplicate the clip and apply the effect to another different mc.

      Basically I want one flag fluttering to the right, the other to the left not both the same direction.


      Here is the code:


      Stage.scaleMode = 'noScale';

      Here, perlin noise is used to create random waves in
      a movie clip that is used as a displacement map for a
      flag movie clip making it appear as though it is waving

      // create a movie clip in displace_mc to
      // draw perlin noise in
      displace_mc.createEmptyMovieClip("perlin", 1);
      // ramp is a movie clip already in displace_mc that is
      // used to ease the perlin noise from non effective on the
      // left side of the flag to fully effective on the right
      var ramp:MovieClip = displace_mc.ramp;
      ramp.swapDepths(2); // place ramp above perlin noise

      // ** 50% red is no displacement in the displacement map
      // the ramp goes from 50% red to transparent letting
      // the perlin noise show through as you move further right

      // GENERAL variables
      var speed = 8; // speed at which noise is shifted (causes flap)
      var channel = 1; // red - red used to displace pixels along

      // DISPLACEMENT variables
      var flapX = 50; // power of pixel displacement along x axis
      var flapY = 100; // power of pixel displacement along y axis
      var mode = "clamp"; // clamp the image so none of the original is seen
      // ** inside the flag movie clip there is an invisible border that is
      // used to extend the bounds of the clip beyond that of the flag image
      // this lets the displacement map extend further past the extents of the flag
      var offset = new flash.geom.Point(0, 0); // displacment map offset

      // create BitmapData object encompasing the size of the displace ramp
      // for the displacement and create a displace filter that uses it
      var displaceBitmap:flash.display.BitmapData = new flash.display.BitmapData(ramp._width, ramp._height);
      var displaceFilter:flash.filters.DisplacementMapFilter = new flash.filters.DisplacementMapFilter(displaceBitmap, offset, channel, channel, flapX, flapY, mode);

      // PERLINNOISE variables
      var baseX = 80; // size of noise in x axis
      var baseY = 0; // size of noise in y axis
      var octs = 1; // noise functions for noise (smaller = faster)
      var seed = Math.floor(Math.random() * 50); // random seed for noise
      var stitch = true; // stitching makes the noise wrap making it easy to repeat
      var fractal = true; // use fractal noise
      var gray = false; // grayscale is not used because the red channel is

      // create BitmapData object for the noise and apply perlinNoise.  It will be repeated
      // along y so it  only needs to be 1 pixel high.  How long it is determines the
      // variants of noise produced.  With the stitching and thanks to beginGradientFill,
      // we will just loop the noise over time.
      var noiseBitmap:flash.display.BitmapData = new flash.display.BitmapData(500, 1);
      noiseBitmap.perlinNoise(baseX, baseY, octs, seed, stitch, fractal, channel, gray);

      // the shift matrix allows for the noise to be moved over time
      // using beginBitmapFill since the noise is only created once
      // and just looped for the flag effect
      var shift:flash.geom.Matrix = new flash.geom.Matrix();

      // every frame
      onEnterFrame = function(){

      // move the matrix by speed along x to shift the noise
      shift.translate(speed, 0);

      // drawing in the perlin movie clip,
      // create a rectangle with the perlin noise
      // drawn in it with an offset supplied by the
      // shift matrix
      with (displace_mc.perlin){
        beginBitmapFill(noiseBitmap, shift);
        lineTo(ramp._width, 0);
        lineTo(ramp._width, ramp._height);
        lineTo(0, ramp._height);
        lineTo(0, 0);

      // draw the displacement movie clip in the
      // displaceBitmap (used in displaceFilter)
      // apply displaceFilter to the flag
      flag_mc.filters = [displaceFilter];

      // show the displacement image when the mouse is pressed
      onMouseDown = function(){
      displace_mc._visible = true;
      flag_mc._visible = false;
      // go back to showing main image when the mouse is released
      onMouseUp = function(){
      displace_mc._visible = false;
      flag_mc._visible = true;

      // initiate