package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Loader; import flash.display.LoaderInfo; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.net.URLRequest; import flash.text.TextField; [SWF(width=550, height=400, backgroundColor=0xFFFFFF)] /** * Draws a bitmap into a rectangle using drawTriangles, allowing for points on the rectangle to be moved * in order to distort the bitmap. */ public class graphic_flex_image_effects_01_Flex_RenderingTriangles extends Sprite { private var _anchors:Vector.; private var _anchor:Sprite; private var _anchorIndex:uint; private var _vertices:Vector.; private var _indices:Vector.; private var _uvtData:Vector.; private var _image:BitmapData; /** * Constructor. */ public function graphic_flex_image_effects_01_Flex_RenderingTriangles() { loadImage(); } /** * Loads the image to distort. */ private function loadImage():void { var loader:Loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded); loader.load(new URLRequest("../../assets/footprints.jpg")); } /** * Defines the vertices, indicies and uvtData for the four triangles. * For the vertices, adds visual anchor points so that the vertices can be moved by dragging the anchors. */ private function defineTriangles():void { // the padding between the image and the sides of the stage var border:Number = 50; var width:Number = stage.stageWidth; var height:Number = stage.stageHeight; // holds the five anchor points _anchors = new Vector.(); addAnchor(border, border); addAnchor(width-border, border); addAnchor(width/2, height/2); addAnchor(border, height-border); addAnchor(width-border, height-border); _vertices = new Vector.(); for each (var anchor:Sprite in _anchors) { _vertices.push(anchor.x, anchor.y); } _indices = new Vector.(); _indices.push(1, 0, 2); _indices.push(0, 2, 3); _indices.push(1, 2, 4); _indices.push(2, 3, 4); _uvtData = new Vector.(); _uvtData.push(0, 0); _uvtData.push(1, 0); _uvtData.push(.5, .5); _uvtData.push(0, 1); _uvtData.push(1, 1); } /** * Adds a visual anchor point at the specified x/y position. * * @param x The x position of the anchor. * @param y The y position of the anchor. */ private function addAnchor(x:Number, y:Number):void { var anchor:Sprite = new Sprite(); // creates a circle of thick radius by setting a thick linestyle and drawing a line of 1 pixel anchor.graphics.lineStyle(20); anchor.graphics.lineTo(1, 0); anchor.addEventListener(MouseEvent.MOUSE_DOWN, onAnchorDown); anchor.addEventListener(MouseEvent.MOUSE_UP, onAnchorUp); anchor.x = x; anchor.y = y; // places a label in the anchor that shows its index in the _anchors vector var label:TextField = new TextField(); label.x = -4; label.y = -9; label.mouseEnabled = false; label.textColor = 0xFFFFFF; label.text = String(_anchors.length); anchor.addChild(label); addChild(anchor); _anchors.push(anchor); } /** * Redraws the bitmap based on the current vertex positions. */ private function draw():void { graphics.clear(); graphics.beginBitmapFill(_image); graphics.drawTriangles(_vertices, _indices, _uvtData); graphics.endFill(); } /** * Handler for when an anchor gets clicked. This begins drag of the anchor. * * @param event Event dispatched by anchor sprite. */ private function onAnchorDown(event:MouseEvent):void { _anchor = event.target as Sprite; _anchor.startDrag(); _anchorIndex = _anchors.indexOf(_anchor); stage.addEventListener(MouseEvent.MOUSE_MOVE, onAnchorMove); } /** * Handler for when an anchor is dragged. This updates the associated vertex position and redraws the bitmap. * * @param event Event dispatched by anchor sprite. */ private function onAnchorMove(event:MouseEvent):void { _vertices[_anchorIndex*2] = _anchor.x; _vertices[_anchorIndex*2+1] = _anchor.y; draw(); event.updateAfterEvent(); } /** * Handler for when an anchor is released after dragging. This stops the dragging. * * @param event Event dispatched by anchor sprite. */ private function onAnchorUp(event:MouseEvent):void { if (_anchor) { _anchor.stopDrag(); stage.removeEventListener(MouseEvent.MOUSE_MOVE, onAnchorMove); } } /** * Handler for when the image loads in. This saves the image in memory and draws the bitmap into the triangles. * * @param event Event dispatched by loader info. */ private function onImageLoaded(event:Event):void { var loaderInfo:LoaderInfo = event.target as LoaderInfo; var bitmap:Bitmap = loaderInfo.content as Bitmap; _image = bitmap.bitmapData; defineTriangles(); draw(); } } }