万花筒之等边三角形镜面反射
点击图像打开实例文件。操作提示:点击用来变化万花筒图案。<img class="aligncenter size-medium wp-image-937" title="kal4" alt="" src="http://www.everyinch.net/wp-content/uploads/2013/05/kal4-300x300.jpg" width="300" height="300" />
主类:
[code lang="as3"]package{
import flash.display.Sprite;
import flash.events.MouseEvent;
import net.everyinch.kals.KaleidoscopeThreeMirrors;
[SWF(width=800,height=600,backgroundColor=0x000000)]
public class KaleidoscopeThreeMirrorsTest1 extends Sprite{
private var kal:KaleidoscopeThreeMirrors;
public function KaleidoscopeThreeMirrorsTest1(){
kal = new KaleidoscopeThreeMirrors("assets/Flower0.jpg",60,200);
addChild(kal);
kal.x = 100;
kal.y = 10;
stage.addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);
}
private function onMouseDown(e:MouseEvent):void{
kal.doSpin();
}
}
}[/code]
等边三角形镜面反射的实现:
[code lang="as3"]package net.everyinch.kals{
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.Loader;
import flash.display.Shape;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.IOErrorEvent;
import flash.events.ProgressEvent;
import flash.geom.Matrix;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.net.URLRequest;
import flash.text.TextFieldAutoSize;
public class KaleidoscopeThreeMirrors extends Sprite{
private var loaderText:TextField;
private var loader:Loader;
private var bmpd:BitmapData;
private var picWidth:Number;
private var picHeight:Number;
private var angle:Number;
private var triangleSide:Number;
private var triangleHeight:Number;
private var segments:Array;
private var segmentEven:Shape;
private var segmentOdd:Shape;
private var hexagons:Array;
private var hexagonRadius:Number;
private var numCols:int;
private var numRows:int;
private var radius:Number;
public var displayWidth:Number;
public var displayHeight:Number;
private var isReady:Boolean;
public function KaleidoscopeThreeMirrors(url:String,hr:Number,dr:Number){
hexagonRadius = hr;
angle = 60;
triangleSide = hexagonRadius;
triangleHeight = triangleSide * Math.sin(Math.PI/3);
radius = dr;
isReady = false;
setUpLoaderText();
loadImg(url);
}
private function setUpLoaderText():void{
var loaderFormat:TextFormat = new TextFormat();
loaderFormat.font = "Arial";
loaderFormat.size = 20;
loaderFormat.color = 0xEEEEEE;
loaderText = new TextField();
loaderText.defaultTextFormat = loaderFormat;
loaderText.text = "";
loaderText.autoSize = TextFieldAutoSize.CENTER;
loaderText.x = 0;
loaderText.y = 0;
loaderText.mouseEnabled = false;
addChild(loaderText);
}
private function loadImg(s:String):void{
loader = new Loader();
loader.load(new URLRequest(s));
loaderText.text = "开始加载... ...";
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR,onError);
loader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS,onProgress);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onComplete);
}
private function onError(e:IOErrorEvent):void{
loaderText.text = "无法加载图像,请刷新页面!";
loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,onError);
loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,onProgress);
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onComplete);
loader = null;
}
private function onProgress(e:ProgressEvent):void{
loaderText.text = "已加载: " + String(Math.floor(e.bytesLoaded/1024)) + "KB/" + String(Math.floor(e.bytesTotal/1024)) + "KB.";
}
private function onComplete(e:Event):void{
bmpd = Bitmap(loader.content).bitmapData;
picWidth = bmpd.width;
picHeight = bmpd.height;
loader.contentLoaderInfo.removeEventListener(IOErrorEvent.IO_ERROR,onError);
loader.contentLoaderInfo.removeEventListener(ProgressEvent.PROGRESS,onProgress);
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE,onComplete);
loader = null;
loaderText.text = "";
loaderText.visible = false;
createDisplay();
drawDisplay();
isReady = true;
}
private function createDisplay():void{
numCols = Math.ceil(radius*2/(triangleSide*3/2))+1; // 直径/(三角形边长*3/2)
numRows = Math.ceil(radius*2/(triangleHeight*2))+1; // 直径/(三角形高*2)
displayWidth = numCols*3/2*triangleSide+triangleSide/2; // 三角形边长*3/2*列数+三角形边长/2
displayHeight = numRows*2*triangleHeight+triangleHeight; //三角形高*2*行数+三角形高
segmentEven = new Shape();
segmentOdd = new Shape();
hexagons = [];
segments = [];
for(var i:int=0;i<numRows;i++){
hexagons[i] = [];
segments[i] = [];
for(var j:int=0;j<numCols;j++){
segments[i][j] = [];
hexagons[i][j] = new Sprite();
addChild(hexagons[i][j]);
hexagons[i][j].x = triangleSide*3/2*j + triangleSide; // 六边形中心点的水平坐标 = 三角形边长*3/2*j+三角形边长
if(j % 2 == 0){
// 如果是偶数列,六边形中心点的垂直坐标 = 三角形高*2*i+三角形高
hexagons[i][j].y = triangleHeight*2*i + triangleHeight;
}
else{
// 如果是奇数列,六边形中心点的垂直坐标 = 三角形高*2*i+三角形高*2
hexagons[i][j].y = triangleHeight*2*i + triangleHeight*2;
}
for(var k:int=0;k<6;k++){
segments[i][j][k] = new Shape();
hexagons[i][j].addChild(segments[i][j][k]);
segments[i][j][k].rotation = k*angle;
}
}
}
}
private function drawDisplay():void{
segmentEven.graphics.clear();
segmentOdd.graphics.clear();
for(var i:int=0;i<numRows;i++){
for(var j:int=0;j<numCols;j++){
for(var k:int=0;k<6;k++){
segments[i][j][k].graphics.clear();
}
}
}
var matrix1:Matrix = new Matrix();
matrix1.translate(picWidth/2,picHeight/2);
matrix1.rotate(Math.random()*2*Math.PI);
matrix1.scale(Math.random()*0.3+0.7,Math.random()*0.3+0.7);
segmentEven.graphics.lineStyle();
segmentEven.graphics.beginBitmapFill(bmpd,matrix1,true,true);
segmentEven.graphics.moveTo(0,0);
segmentEven.graphics.lineTo(-triangleSide/2,-triangleHeight);
segmentEven.graphics.lineTo(triangleSide/2,-triangleHeight);
segmentEven.graphics.lineTo(0,0);
segmentEven.graphics.endFill();
var matrix2:Matrix = matrix1.clone();
matrix2.concat(new Matrix(-1,0,0,1,0,0));
segmentOdd.graphics.lineStyle();
segmentOdd.graphics.beginBitmapFill(bmpd,matrix2,true,true);
segmentOdd.graphics.moveTo(0,0);
segmentOdd.graphics.lineTo(-triangleSide/2,-triangleHeight);
segmentOdd.graphics.lineTo(triangleSide/2,-triangleHeight);
segmentOdd.graphics.lineTo(0,0);
segmentOdd.graphics.endFill();
for(i=0;i<numRows;i++){
for(j=0;j<numCols;j++){
for(k=0;k<6;k++){
if(k % 2 == 0){
segments[i][j][k].graphics.copyFrom(segmentEven.graphics);
}
else{
segments[i][j][k].graphics.copyFrom(segmentOdd.graphics);
}
}
}
}
}
public function doSpin():void{
if(isReady){
drawDisplay();
}
}
public function destroy():void{
if(!isReady){
return;
}
for(var i:int=0;i<numRows;i++){
for(var j:int=0;j<numCols;j++){
for(var k:int=0;k<6;k++){
segments[i][j][k].graphics.clear();
}
}
}
bmpd.dispose();
isReady = false;
}
}
}[/code]
查看完整版本: 万花筒之等边三角形镜面反射
Tags: Kaleidoscope