//////////////////////////////////////////////////////////////////////////////// // WavePict (1) // // 置き換えマップ効果 (3) // http://www.project-nya.jp/modules/weblog/details.php?blog_id=480 // BitmapDataでノイズ生成 (3) // http://www.project-nya.jp/modules/weblog/details.php?blog_id=481 // [AS3.0] PerlinNoiseクラスに挑戦! // http://www.project-nya.jp/modules/weblog/details.php?blog_id=1114 // // 動作を軽くするための方法 (東京てらこ7 @trick7) // Bitmap.filters を使わず、BitmapData.applyFilter() を用いる // // [AS3.0] FileLoaderクラスに挑戦! // http://www.project-nya.jp/modules/weblog/details.php?blog_id=1207 //////////////////////////////////////////////////////////////////////////////// package { import flash.display.Sprite; import flash.display.BitmapData; import flash.display.Bitmap; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Rectangle; import flash.geom.Point; import flash.geom.Matrix; import flash.filters.DisplacementMapFilter; import flash.display.BitmapDataChannel; import flash.filters.DisplacementMapFilterMode; [SWF(backgroundColor="#FFFFFF", width="465", height="465", frameRate="30")] public class Main extends Sprite { private var loader:FileLoader; private var loadBtn:Btn; private var container:Sprite; private var bitmap:Bitmap; private var bitmapData:BitmapData; private var map:DisplacementMapFilter; private static var color:uint = BitmapDataChannel.RED; private var noise:PerlinNoise; private static var octaves:uint = 2; private var speeds:Array; private var slider1:Slider; private var slider2:Slider; private var scale:Number = 10; private var amplitude:Number = 3; public function Main() { //Wonderfl.capture_delay(10); init(); } private function init():void { graphics.beginFill(0xE0E0E0); graphics.drawRect(32, 2, 400, 400); graphics.endFill(); var rect:Rectangle = new Rectangle(0, 0, 400, 400); //ノイズ生成 noise = new PerlinNoise(rect, 32, 32, octaves, false, color); speeds = new Array(); for (var n:uint = 0; n < octaves; n++) { var sx:Number = (Math.random() - 0.5)*amplitude; var sy:Number = (Math.random() - 0.5)*3 + 2.5; speeds.push(new Point(sx, sy)); } map = new DisplacementMapFilter(noise, new Point(), color, color, scale, scale, DisplacementMapFilterMode.CLAMP); bitmapData = new BitmapData(400, 400, true, 0x00000000); bitmap = new Bitmap(bitmapData); bitmap.smoothing = true; container = new Sprite(); addChild(container); container.x = 32; container.y = 2; container.addChild(bitmap); loader = new FileLoader(); loader.addEventListener(Event.INIT, initialize, false, 0, true); loader.addEventListener(Event.CANCEL, cancel, false, 0, true); loadBtn = new Btn(); addChild(loadBtn); loadBtn.x = 57; loadBtn.y = 435; loadBtn.init({label: "load"}); loadBtn.addEventListener(MouseEvent.CLICK, load, false, 0, true); slider1 = new Slider(); slider1.x = 112; slider1.y = 405; addChild(slider1); slider1.init({label: "scale", width: 200, min: 0, max: 100, grid: 10, init: 10}); slider1.addEventListener(CompoEvent.CHANGE, change1, false, 0, true); slider2 = new Slider(); slider2.x = 332; slider2.y = 405; addChild(slider2); slider2.init({label: "amplitude", width: 100, min: 0, max: 50, grid: 5, init: 2}); slider2.addEventListener(CompoEvent.CHANGE, change2, false, 0, true); } private function cancel(evt:Event):void { } private function load(evt:MouseEvent):void { loader.load(); } private function initialize(evt:Event):void { var bd:BitmapData = evt.target.bitmapData; var bw:Number = 400/bd.width; var bh:Number = 400/bd.height; var scale:Number = Math.min(bw, bh); var matrix:Matrix = new Matrix(); matrix.scale(scale, scale); matrix.translate(uint(400 - bd.width*scale)/2, uint(400 - bd.height*scale)/2); bitmapData.draw(bd, matrix); bd.dispose(); bitmap.bitmapData = bitmapData.clone(); addEventListener(Event.ENTER_FRAME, update, false, 0, true); } private function update(evt:Event):void { //ノイズ生成 noise.update(speeds); //フィルタ適用 bitmap.bitmapData.lock(); bitmap.bitmapData.applyFilter(bitmapData, bitmapData.rect, new Point(), map); bitmap.bitmapData.unlock(); } private function change1(evt:CompoEvent):void { scale = evt.value; map = new DisplacementMapFilter(noise, new Point(), color, color, scale, scale, DisplacementMapFilterMode.CLAMP); } private function change2(evt:CompoEvent):void { speeds = new Array(); for (var n:uint = 0; n < octaves; n++) { var sx:Number = (Math.random() - 0.5)*amplitude; var sy:Number = (Math.random() - 0.5)*3 + 2.5; speeds[n] = new Point(sx, sy); } } } } ////////////////////////////////////////////////// // PerlinNoiseクラス ////////////////////////////////////////////////// import flash.display.BitmapData; import flash.geom.Rectangle; import flash.geom.Point; class PerlinNoise extends BitmapData { private var bx:uint; private var by:uint; private var octaves:uint; private var seed:uint; private var stitch:Boolean = true; private var fractalNoise:Boolean = true; private var channel:uint = 0; private var grayScale:Boolean = true; private var offsets:Array = new Array(); public function PerlinNoise(rect:Rectangle, x:uint, y:uint, o:uint = 1, g:Boolean = true, c:uint = 0, s:uint = 1, st:Boolean = false, f:Boolean = true) { super(rect.width, rect.height, false, 0xFF000000); bx = x; by = y; octaves = o; grayScale = g; channel = c; if (grayScale) channel = 0; for (var n:uint = 0; n < octaves; n++) { var point:Point = new Point(); offsets.push(point); } stitch = st; fractalNoise = f; create(s, offsets); } private function create(s:uint, o:Array = null):void { seed = s; offsets = o; if (offsets == null) offsets = [new Point()]; lock(); perlinNoise(bx, by, octaves, seed, stitch, fractalNoise, channel, grayScale, offsets); draw(this); unlock(); } public function update(speeds:Array):void { for (var n:uint = 0; n < octaves; n++) { var offset:Point = offsets[n]; var speed:Point = speeds[n]; offset.x += speed.x; offset.y += speed.y; } lock(); perlinNoise(bx, by, octaves, seed, stitch, fractalNoise, channel, grayScale, offsets); draw(this); unlock(); } } ////////////////////////////////////////////////// // FileLoaderクラス ////////////////////////////////////////////////// import flash.events.EventDispatcher; import flash.net.FileReference; import flash.net.FileFilter; import flash.display.Loader; import flash.display.BitmapData; import flash.display.Bitmap; import flash.events.Event; import flash.events.ProgressEvent; import flash.events.DataEvent; import flash.events.IOErrorEvent; import flash.events.HTTPStatusEvent; import flash.events.SecurityErrorEvent; class FileLoader extends EventDispatcher { private var file:FileReference; private static var typeFilter:Array; public var data:*; private var loader:Loader; public var bitmapData:BitmapData; public function FileLoader() { init(); } private function init():void { file = new FileReference(); file.addEventListener(Event.SELECT, select, false, 0, true); file.addEventListener(Event.CANCEL, cancel, false, 0, true); file.addEventListener(Event.OPEN, open, false, 0, true); file.addEventListener(ProgressEvent.PROGRESS, progress, false, 0, true); file.addEventListener(Event.COMPLETE, complete, false, 0, true); file.addEventListener(IOErrorEvent.IO_ERROR, ioerror, false, 0, true); file.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpstatus, false, 0, true); file.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityerror, false, 0, true); var fileFilter:FileFilter = new FileFilter("画像ファイル", "*.jpg;*.gif;*.png"); typeFilter = [fileFilter]; loader = new Loader(); loader.contentLoaderInfo.addEventListener(Event.INIT, initialize, false, 0, true); } public function load():void { file.browse(typeFilter); } private function select(evt:Event):void { file.load(); dispatchEvent(evt); } private function cancel(evt:Event):void { dispatchEvent(evt); } private function open(evt:Event):void { dispatchEvent(evt); } private function progress(evt:ProgressEvent):void { dispatchEvent(evt); } private function complete(evt:Event):void { data = evt.target.data; loader.loadBytes(data); dispatchEvent(evt); } private function ioerror(evt:IOErrorEvent):void { dispatchEvent(evt); } private function httpstatus(evt:HTTPStatusEvent):void { dispatchEvent(evt); } private function securityerror(evt:SecurityErrorEvent):void { dispatchEvent(evt); } private function initialize(evt:Event):void { bitmapData = null; var bitmap:Bitmap = Bitmap(evt.target.content); bitmapData = bitmap.bitmapData; dispatchEvent(evt); } } ////////////////////////////////////////////////// // Btnクラス ////////////////////////////////////////////////// import flash.display.Sprite; import flash.display.Shape; import flash.text.TextField; import flash.text.TextFieldType; import flash.text.AntiAliasType; import flash.text.TextFormat; import flash.text.TextFormatAlign; import flash.filters.GlowFilter; import flash.events.MouseEvent; class Btn extends Sprite { public var id:uint; private var shade:Shape; private var bottom:Shape; private var light:Shape; private var base:Shape; private var txt:TextField; private var label:String = ""; private static var fontType:String = "_ゴシック"; private var _width:uint = 60; private static var _height:uint = 20; private static var corner:uint = 5; private var type:uint = 1; private static var bColor:uint = 0xFFFFFF; private static var sColor:uint = 0x000000; private static var upColor:uint = 0x666666; private static var overColor:uint = 0x333333; private static var offColor:uint = 0x999999; private static var gColor:uint = 0x0099FF; private var blueGlow:GlowFilter; private var shadeGlow:GlowFilter; private var _clicked:Boolean = false; private var _enabled:Boolean = true; public function Btn() { } public function init(option:Object):void { if (option.id != undefined) id = option.id; if (option.label != undefined) label = option.label; if (option.width != undefined) _width = option.width; if (option.type != undefined) type = option.type; draw(); } private function draw():void { switch (type) { case 1 : bColor = 0xFFFFFF; sColor = 0x000000; upColor = 0x666666; overColor = 0x333333; offColor = 0x999999; break; case 2 : bColor = 0x000000; sColor = 0xFFFFFF; upColor = 0x666666; overColor = 0x999999; offColor = 0x333333; break; } blueGlow = new GlowFilter(gColor, 0.6, 5, 5, 2, 3, false, true); shadeGlow = new GlowFilter(sColor, 0.3, 4, 4, 2, 3, false, true); shade = new Shape(); bottom = new Shape(); light = new Shape(); base = new Shape(); txt = new TextField(); addChild(shade); addChild(bottom); addChild(light); addChild(base); addChild(txt); createBase(shade, _width, _height, corner, sColor); shade.filters = [shadeGlow]; createBase(bottom, _width, _height, corner, sColor, 0.3); createBase(light, _width, _height, corner, gColor); light.filters = [blueGlow]; createBase(base, _width, _height, corner, bColor); txt.x = -_width*0.5; txt.y = -_height*0.5; txt.width = _width; txt.height = _height - 1; txt.type = TextFieldType.DYNAMIC; txt.selectable = false; //txt.embedFonts = true; //txt.antiAliasType = AntiAliasType.ADVANCED; var tf:TextFormat = new TextFormat(); tf.font = fontType; tf.size = 12; tf.align = TextFormatAlign.CENTER; txt.defaultTextFormat = tf; txt.text = label; enabled = true; mouseChildren = false; } private function rollOver(evt:MouseEvent):void { _over(); } private function rollOut(evt:MouseEvent):void { _up(); } private function press(evt:MouseEvent):void { _down(); } private function release(evt:MouseEvent):void { _up(); } private function click(evt:MouseEvent):void { } private function _up():void { txt.y = -_height*0.5; txt.textColor = upColor; base.y = -1; light.visible = false; light.y = -1; } private function _over():void { txt.y = -_height*0.5; txt.textColor = overColor; base.y = -1; light.visible = true; light.y = -1; } private function _down():void { txt.y = -_height*0.5 + 1; txt.textColor = overColor; base.y = 0; light.visible = true; light.y = 0; } private function _off():void { txt.y = -_height*0.5 + 1; txt.textColor = offColor; base.y = 0; light.visible = false; light.y = 0; } public function get clicked():Boolean { return _clicked; } public function set clicked(param:Boolean):void { _clicked = param; enabled = !_clicked; if (_clicked) { _down(); } else { _up(); } } public function get enabled():Boolean { return _enabled; } public function set enabled(param:Boolean):void { _enabled = param; buttonMode = _enabled; mouseEnabled = _enabled; useHandCursor = _enabled; if (_enabled) { _up(); addEventListener(MouseEvent.MOUSE_OVER, rollOver, false, 0, true); addEventListener(MouseEvent.MOUSE_OUT, rollOut, false, 0, true); addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true); addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true); addEventListener(MouseEvent.CLICK, click, false, 0, true); } else { _off(); removeEventListener(MouseEvent.MOUSE_OVER, rollOver); removeEventListener(MouseEvent.MOUSE_OUT, rollOut); removeEventListener(MouseEvent.MOUSE_DOWN, press); removeEventListener(MouseEvent.MOUSE_UP, release); removeEventListener(MouseEvent.CLICK, click); } } private function createBase(target:Shape, w:uint, h:uint, c:uint, color:uint, alpha:Number = 1):void { target.graphics.beginFill(color, alpha); target.graphics.drawRoundRect(-w*0.5, -h*0.5, w, h, c*2); target.graphics.endFill(); } } ////////////////////////////////////////////////// // Sliderクラス ////////////////////////////////////////////////// import flash.display.Sprite; import flash.display.Shape; import flash.text.TextField; import flash.text.TextFieldType; import flash.text.AntiAliasType; import flash.text.TextFieldAutoSize; import flash.text.TextFormat; import flash.text.TextFormatAlign; import flash.filters.DropShadowFilter; import flash.filters.GlowFilter; import flash.geom.Rectangle; import flash.geom.Matrix; import flash.display.GradientType; import flash.display.SpreadMethod; import flash.display.InterpolationMethod; import flash.events.Event; import flash.events.MouseEvent; class Slider extends Sprite { private var hole:Shape; private var line:Sprite; private var thumb:Sprite; private var light:Shape; private var shade:Shape; private var base:Shape; private var title:TextField; private var txt:TextField; private var label:String = ""; private static var fontType:String = "_ゴシック"; private var _width:uint = 100; private static var tHeight:uint = 20; private static var bHeight:uint = 30; private var grid:uint = 5; private static var bColor:uint = 0xFFFFFF; private static var tColor:uint = 0x666666; private static var gColor:uint = 0x999999; private static var mColor:uint = 0x333333; private static var bgColor:uint = 0x0099FF; private static var sColor:uint = 0x000000; private static var offColor:uint = 0x999999; private var min:Number = 0; private var max:Number = 100; private var initValue:Number = 0; private var blueGlow:GlowFilter; private var shadeDrop:DropShadowFilter; private var value:Number; private var _enabled:Boolean = true; public function Slider() { } public function init(option:Object):void { if (option.label != undefined) label = option.label; if (option.width != undefined) _width = option.width; if (option.min != undefined) min = option.min; if (option.max != undefined) max = option.max; if (option.grid != undefined) grid = option.grid; if (option.init != undefined) initValue = option.init; draw(); } private function draw():void { shadeDrop = new DropShadowFilter(1, 90, sColor, 0.5, 4, 4, 2, 3, false, false); blueGlow = new GlowFilter(bgColor, 0.6, 5, 5, 2, 3, false, true); hole = new Shape(); line = new Sprite(); title = new TextField(); txt = new TextField(); thumb = new Sprite(); shade = new Shape(); light = new Shape(); base = new Shape(); addChild(hole); addChild(line); addChild(title); addChild(txt); addChild(thumb); thumb.addChild(shade); thumb.addChild(light); thumb.addChild(base); hole.y = bHeight; createGradientHole(hole, _width, 3); line.y = bHeight; createGrid(line); title.height = tHeight-1; title.type = TextFieldType.DYNAMIC; title.selectable = false; //title.embedFonts = true; //title.antiAliasType = AntiAliasType.ADVANCED; title.textColor = tColor; title.autoSize = TextFieldAutoSize.LEFT; var tfl:TextFormat = new TextFormat(); tfl.font = fontType; tfl.size = 12; tfl.align = TextFormatAlign.LEFT; title.defaultTextFormat = tfl; title.text = label; //txt.x = title.textWidth; txt.x = 50; txt.width = 50; txt.height = tHeight-1; txt.selectable = false; //txt.embedFonts = true; //txt.antiAliasType = AntiAliasType.ADVANCED; var tfr:TextFormat = new TextFormat(); tfr.font = fontType; tfr.size = 12; tfr.align = TextFormatAlign.RIGHT; txt.defaultTextFormat = tfr; reset(); thumb.y = bHeight; createThumb(shade, 8, 20, 12, sColor); shade.filters = [shadeDrop]; createThumb(light, 8, 20, 12, bgColor); light.filters = [blueGlow]; createThumb(base, 8, 20, 12, bColor); _up(); enabled = true; thumb.mouseChildren = false; } private function rollOver(evt:MouseEvent):void { _over(); } private function rollOut(evt:MouseEvent):void { _up(); } private function press(evt:MouseEvent):void { _down(); var rect:Rectangle = new Rectangle(0, bHeight, _width, 0); thumb.startDrag(false, rect); thumb.addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true); stage.addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true); stage.addEventListener(Event.MOUSE_LEAVE, leave, false, 0, true); thumb.addEventListener(Event.ENTER_FRAME, change, false, 0, true); } private function release(evt:MouseEvent):void { _up(); thumb.stopDrag(); checkValue(); var e:CompoEvent = new CompoEvent(CompoEvent.SELECT, value); dispatchEvent(e); thumb.removeEventListener(MouseEvent.MOUSE_UP, release); stage.removeEventListener(MouseEvent.MOUSE_UP, release); stage.removeEventListener(Event.MOUSE_LEAVE, leave); thumb.removeEventListener(Event.ENTER_FRAME, change); } private function leave(evt:Event):void { _up(); thumb.stopDrag(); checkValue(); dispatchEvent(new CompoEvent(CompoEvent.SELECT, value)); thumb.removeEventListener(MouseEvent.MOUSE_UP, release); stage.removeEventListener(MouseEvent.MOUSE_UP, release); stage.removeEventListener(Event.MOUSE_LEAVE, leave); thumb.removeEventListener(Event.ENTER_FRAME, change); } private function _up():void { light.visible = false; } private function _over():void { light.visible = true; } private function _down():void { light.visible = true; } private function _off():void { light.visible = false; txt.textColor = offColor; } private function change(evt:Event):void { _down(); checkValue(); dispatchEvent(new CompoEvent(CompoEvent.CHANGE, value)); } private function checkValue():void { value = min + Math.round(thumb.x/_width*(max-min)); txt.text = String(value); } public function get enabled():Boolean { return _enabled; } public function set enabled(param:Boolean):void { _enabled = param; if (!_enabled) _off(); thumb.buttonMode = _enabled; thumb.mouseEnabled = _enabled; thumb.useHandCursor = _enabled; if (_enabled) { thumb.addEventListener(MouseEvent.MOUSE_OVER, rollOver, false, 0, true); thumb.addEventListener(MouseEvent.MOUSE_OUT, rollOut, false, 0, true); thumb.addEventListener(MouseEvent.MOUSE_DOWN, press, false, 0, true); thumb.addEventListener(MouseEvent.MOUSE_UP, release, false, 0, true); } else { thumb.removeEventListener(MouseEvent.MOUSE_OVER, rollOver); thumb.removeEventListener(MouseEvent.MOUSE_OUT, rollOut); thumb.removeEventListener(MouseEvent.MOUSE_DOWN, press); thumb.removeEventListener(MouseEvent.MOUSE_UP, release); } } public function reset():void { thumb.x = _width*(initValue-min)/(max-min); value = initValue; txt.text = String(value); } private function createGrid(target:Sprite):void { for (var n:uint = 0; n <= grid; n++) { var w:uint = Math.floor(_width/grid); if (n == 0 || n == grid*0.5 || n == grid) { createGridLine(target, w*n, mColor); var _txt:TextField = new TextField(); target.addChild(_txt); _txt.x = w*n - 20; _txt.y = 13; _txt.width = 40; _txt.height = 14; _txt.selectable = false; //_txt.embedFonts = true; //_txt.antiAliasType = AntiAliasType.ADVANCED; //_txt.antiAliasType = AntiAliasType.NORMAL; _txt.textColor = mColor; var tfc:TextFormat = new TextFormat(); tfc.font = fontType; tfc.size = 8; tfc.align = TextFormatAlign.CENTER; _txt.defaultTextFormat = tfc; if (n == 0) _txt.text = String(min); if (n == grid*0.5) _txt.text = String(min+(max-min)*0.5); if (n == grid) _txt.text = String(max); } else { createGridLine(target, w*n, gColor); } } } private function createThumb(target:Shape, w:uint, h:uint, y:uint, color:uint, alpha:Number = 1):void { target.graphics.beginFill(color, alpha); target.graphics.drawRoundRect(-w*0.5, -y, w, h, w); target.graphics.endFill(); } private function createGradientHole(target:Shape, w:uint, c:Number):void { var colors:Array = [0x000000, 0x000000]; var alphas:Array = [0.4, 0]; var ratios:Array = [0, 255]; var matrix:Matrix = new Matrix(); matrix.createGradientBox(w+c*2, c*2, 0.5*Math.PI, -c, -c); target.graphics.beginGradientFill(GradientType.LINEAR, colors, alphas, ratios, matrix, SpreadMethod.PAD, InterpolationMethod.RGB, 0); target.graphics.drawRoundRect(-c, -c, w+c*2, c*2, c*2); target.graphics.endFill(); } private function createGridLine(target:Sprite, x:uint, color:uint):void { target.graphics.lineStyle(0, color); target.graphics.moveTo(x, 8); target.graphics.lineTo(x, 12); } } ////////////////////////////////////////////////// // CompoEventクラス ////////////////////////////////////////////////// import flash.events.Event; class CompoEvent extends Event { public static const SELECT:String = "select"; public static const CHANGE:String = "change"; public var value:*; public function CompoEvent(type:String, value:*) { super(type); this.value = value; } public override function clone():Event { return new CompoEvent(type, value); } } WavePict (1)