• AS3 水波纹


      AS3的水波纹,我看网上的素材虽然有,但是很少有合适的,找了很久才找到一个能凑合用的。虽然效果还凑合,但是缺陷也有,内存占用太大了。今天在此发一下水波纹的类,有需要的朋友也好找一点。

    这是 Rippler  类

    package
    {
        import flash.display.BitmapData;
        import flash.display.BitmapDataChannel;
        import flash.display.BlendMode;
        import flash.display.DisplayObject;
        import flash.events.Event;
        import flash.filters.ConvolutionFilter;
        import flash.filters.DisplacementMapFilter;
        import flash.geom.ColorTransform;
        import flash.geom.Matrix;
        import flash.geom.Point;
        import flash.geom.Rectangle;
        
        /** 
         * 
         * The Rippler class creates an effect of rippling water on a source DisplayObject.
         * 
         * @example The following code takes a DisplayObject on the stage and adds a ripple to it, assuming source is a DisplayObject already on the stage.
         * 
         *     <listing version="3.0">
         *         import be.nascom.flash.graphics.Rippler;
         *         
         *         // create a Rippler instance to impact source, with a strength of 60 and a scale of 6.
         *         // The source can be any DisplayObject on the stage, such as a Bitmap or MovieClip object.
         *         var rippler : Rippler = new Rippler(source, 60, 6);
         * 
         *         // create a ripple with size 20 and alpha 1 with origin on position (200, 50)
         *         rippler.drawRipple(100, 50, 20, 1);
         * </listing>
         * 
         * @author David Lenaerts
         * @mail david.lenaerts@nascom.be
         * 
          */
        public class Rippler
        {
            // The DisplayObject which the ripples will affect.(波纹将会影响到的DisplayObject。)
            private var _source : DisplayObject;
            
            // Two buffers on which the ripple displacement image will be created, and swapped.(两个缓冲区,将产生波纹位移图像,并交换。)
            // Depending on the scale parameter, this will be smaller than the source(根据比例参数,这个比源要小)
            private var _buffer1 : BitmapData;
            private var _buffer2 : BitmapData;
            
            // The final bitmapdata containing the upscaled ripple image, to match the source DisplayObject(最后一个包含放大的波纹图像的位图数据,以匹配源显示对象)
            private var _defData : BitmapData;
            
            // Rectangle and Point objects created once and reused for performance(为性能而创建的矩形和点对象)
            private var _fullRect : Rectangle;    // A buffer-sized Rectangle used to apply filters to the buffer(一个缓冲区大小的矩形用于将过滤器应用到缓冲区中)
            private var _drawRect : Rectangle;   // A Rectangle used when drawing a ripple(绘制波纹时使用的矩形)
            private var _origin : Point = new Point(); // A Point object to (0, 0) used for the DisplacementMapFilter as well as for filters on the buffer(一个点对象(0,0)用于位移映射过滤器和缓冲区上的过滤器)
            
            // The DisplacementMapFilter applied to the source DisplayObject(应用于源DisplayObject的位移映射过滤器)
            private var _filter : DisplacementMapFilter;
            // A filter causing the ripples to grow(一种导致波纹生长的过滤器)
            private var _expandFilter : ConvolutionFilter;
            
            // Creates a colour offset to 0x7f7f7f so there is no image offset due to the DisplacementMapFilter(创建一个颜色偏移到0x7f7f7f,因此没有图像偏移,因为位移映射)
            private var _colourTransform : ColorTransform;
            
            // Used to scale up the buffer to the final source DisplayObject's scale(用于将缓冲区扩展到最终的源DisplayObject的规模)
            private var _matrix : Matrix;
            
            // We only need 1/scale, so we keep it here(我们只需要1/1,所以我们把它放在这里)
            private var _scaleInv : Number;
            
            /**
             * Creates a Rippler instance.(创建一个涟漪实例。)
             * 
             * @param source The DisplayObject which the ripples will affect.(源代码将会影响到它的显示对象。)
             * @param strength The strength of the ripple displacements.(增强了波纹位移的强度。)
             * @param scale The size of the ripples. In reality, the scale defines the size of the ripple displacement map (map.width = source.width/scale). Higher values are therefor also potentially faster.
             * (大小是波纹的大小。实际上,这个比例定义了波纹位移贴图的大小(地图。宽度= source.width /规模)。更高的值也可能更快。)
             */
            public function Rippler(source : DisplayObject, strength : Number, scale : Number = 2)
            {
                var correctedScaleX : Number;
                var correctedScaleY : Number;
                
                _source = source;
                _scaleInv = 1/scale;
                
                // create the (downscaled) buffers and final (upscaled) image data, sizes depend on scale(创建(缩小的)缓冲区和最终(放大的)图像数据,大小取决于规模)
                _buffer1 = new BitmapData(source.width*_scaleInv, source.height*_scaleInv, false, 0x000000);
                _buffer2 = new BitmapData(_buffer1.width, _buffer1.height, false, 0x000000);
                _defData = new BitmapData(source.width, source.height);
                
                // Recalculate scale between the buffers and the final upscaled image to prevent roundoff errors.(重新计算缓冲区和最后的向上缩放图像之间的比例,以防止循环错误。)
                correctedScaleX = _defData.width/_buffer1.width;
                correctedScaleY = _defData.height/_buffer1.height;
                
                // Create reusable objects(创建可重用的对象)
                _fullRect = new Rectangle(0, 0, _buffer1.width, _buffer1.height);
                _drawRect = new Rectangle();
                
                // Create the DisplacementMapFilter and assign it to the source(创建位移-mapfilter并将其分配给源文件)
                _filter = new DisplacementMapFilter(_buffer1, _origin, BitmapDataChannel.BLUE, BitmapDataChannel.BLUE, strength, strength, "wrap");
                _source.filters = [_filter];
                
                // Create a frame-based loop to update the ripples(创建一个基于框架的循环来更新波纹)
                _source.addEventListener(Event.ENTER_FRAME, handleEnterFrame);
                
                // Create the filter that causes the ripples to grow.(创建过滤器,使波纹产生)
                // Depending on the colour of its neighbours, the pixel will be turned white(取决于邻居的颜色,像素会变成白色)
                _expandFilter = new ConvolutionFilter(3, 3, [0.5, 1, 0.5, 1, 0, 1, 0.5, 1, 0.5], 3);
                
                // Create the colour transformation based on (创建基于颜色转换的颜色转换)
                _colourTransform = new ColorTransform(1, 1, 1, 1, 127, 127, 127);
                
                // Create the Matrix object(创建矩阵对象)
                _matrix = new Matrix(correctedScaleX, 0, 0, correctedScaleY);
                
            }
            
            /**
             * Initiates a ripple at a position of the source DisplayObject.(在源DisplayObject的位置上发起一个波纹。)
             * 
             * @param x The horizontal coordinate of the ripple origin.(x是波纹原点的水平坐标。)
             * @param y The vertical coordinate of the ripple origin.(y是波纹原点的垂直坐标。)
             * @param size The size of the ripple diameter on first impact.(大小与第一次撞击时的波纹直径大小有关。)
             * @param alpha The alpha value of the ripple on first impact.(alpha值在第一次影响时的alpha值。)
             */
            public function drawRipple(x : int, y : int, size : int, alpha : Number) : void
            {
             var half : int = size >> 1;  // We need half the size of the ripple(我们需要波纹的一半大小。)
                var intensity : int = (alpha*0xff & 0xff)*alpha; // The colour which will be drawn in the currently active buffer(将在当前活动的缓冲区中绘制的颜色)
                
                // calculate and draw the rectangle, having (x, y) in its centre(计算并绘制矩形,在其中心有(x,y))
                _drawRect.x = (-half+x)*_scaleInv; 
                _drawRect.y = (-half+y)*_scaleInv;
                _drawRect.width = _drawRect.height = size*_scaleInv;
                _buffer1.fillRect(_drawRect, intensity);
            }
            
            /**
             * Returns the actual ripple image.(Returns the actual ripple image.)
             */
            public function getRippleImage() : BitmapData
            {
             return _defData;
            }
            
            /**
             * Removes all memory occupied by this instance. This method must be called before discarding an instance.(删除该实例所占用的所有内存。在丢弃实例之前必须调用此方法。)
             */
            public function destroy() : void
            {
                _source.removeEventListener(Event.ENTER_FRAME, handleEnterFrame);
                _buffer1.dispose();
                _buffer2.dispose();
                _defData.dispose();
            }
            
            // the actual loop where the ripples are animated(波纹是动画的实际循环)
            private function handleEnterFrame(event : Event) : void
            {
             // a temporary clone of buffer 2(缓冲区2的临时克隆)
                var temp : BitmapData = _buffer2.clone();
                // buffer2 will contain an expanded version of buffer1(buffer2将包含一个扩展版的buffer1)
                _buffer2.applyFilter(_buffer1, _fullRect, _origin, _expandFilter);
                // by substracting buffer2's old image, buffer2 will now be a ring(通过对buffer2的旧图像进行处理,buffer2将成为一个环)
                _buffer2.draw(temp, null, null, BlendMode.SUBTRACT, null, false);
                // scale up and draw to the final displacement map, and apply it to the filter(放大并绘制最终位移图,并将其应用到过滤器中)
                _defData.draw(_buffer2, _matrix, _colourTransform, null, null, true);
                _filter.mapBitmap = _defData;
                _source.filters = [_filter];
                temp.dispose();
                
                // switch buffers 1 and 2(switch buffers 1 and 2)
                switchBuffers();
            }
            
            // switch buffer 1 and 2, so that (切换缓冲1和2,这样)
            private function switchBuffers() : void
            {
                var temp : BitmapData;
                temp = _buffer1;
                _buffer1 = _buffer2;
                _buffer2 = temp;
            }
        }
    }


    用法如下

    var mc:Sprite=new Sprite();
    var r:Rippler;
    addChild(mc);
    //目标 水纹起伏强度 水纹宽度 r=new Rippler(mc,40,10); //x,y,范围,强度 r.drawRipple(mouseX,mouseY,50,1);


    其中mc是一个容器,r影响的是mc这个容器中的所有的对象。

  • 相关阅读:
    第五章4
    第五章3
    第五章2
    第五章1
    第四章14
    第四章13
    第四章12
    第四章11
    第五章例5-6
    第五章例5-4
  • 原文地址:https://www.cnblogs.com/lingLuoChengMi/p/8286916.html
Copyright © 2020-2023  润新知