Trying to tween the alpha of a graphics object in AS3 using GreenSock, but the functions are not working. Trying to tween to from alpha 0 to 0.7 in 2 seconds. The fromTo(); method doesn't work either. I don't want to, but would I have to instead, use an incremental for loop to do this?—As this wouldn't give me control over the time of the tween.
public function overlayBox():void {
var overlaySquare:Sprite = new Sprite();
overlaySquare.graphics.beginFill(0x00000);
overlaySquare.graphics.drawRect(0, 0, displayRes, displayRes);
overlaySquare.graphics.endFill();
overlaySquare.x = xScreenPos;
overlaySquare.y = yScreenPos;
TweenMax.from(overlaySquare, 2, {autoAlpha:0});
TweenMax.to(overlaySquare, 2, {autoAlpha:0.7});
addChild(overlaySquare);
trace("overlaySquare index: " + getChildIndex(overlaySquare));
}
EDIT: I've fixed the fade from alpha 0 to 0.7 by replacing the TweenMax functions from above to this:
overlaySquare.alpha = 0;
TweenMax.to(overlaySquare, 5, {alpha:0.7});
However, there's a problem with the alpha tween when it's run with the rest of the program. The tween "flashes" and instantly becomes 0.7 (it looks like it's "jumping" from 0 to 0.7) as soon as you can see it. The problem has been isolated to the function which is being called after overlayBox(); An overview of the program: an image is loaded in using loader. Inside loader, there is a myTimer.start();. This is used to run the rest of the program once the image has been loaded. The overlayBox(); is the first method that follows and runs fine. The next method, textAnimation();, is what breaks it, and I have no idea why:
public function textAnimation():void {
//set text format
textFormat.font = "Helvetica Neue Light";
textFormat.size = 28;
textFormat.bold = false;
textFormat.color = 0xFFFFFF;
//textFormat.letterSpacing = 5;
//set text size
var size18bold:TextFormat = new TextFormat();
size18bold.size = 36;
size18bold.bold = true;
// pass text format
textOne.defaultTextFormat = textFormat;
textTwo.defaultTextFormat = textFormat;
var xScreenPosStart:Number = xScreenPos + 440;
var xScreenPosEnd:Number = xScreenPos - 300;
textOne.text = "Blah blah blah";
textOne.autoSize = TextFieldAutoSize.LEFT;
textOne.x = xScreenPosStart;
textOne.y = yScreenPos + 240;
TweenMax.to(textOne, 14, {x:xScreenPosEnd, ease:SlowMo.ease.config(1, 0), repeat:-1});
textTwo.text = "Blah blah blah";
textTwo.autoSize = TextFieldAutoSize.LEFT;
textTwo.x = xScreenPosStart;
textTwo.y = yScreenPos + 140;
TweenMax.to(textTwo, 12, {x:xScreenPosEnd, ease:SlowMo.ease.config(1, 0), repeat:-1, delay:4});
//add to stage
addChild(textOne);
trace("textOne index: " + getChildIndex(textOne));
addChild(textTwo);
trace("textTwo index: " + getChildIndex(textTwo));
textOne.setTextFormat(size18bold);
}
Instead of using TweenMax.from, set the alpha manually.
overlaySquare.alpha = 0;
TweenMax.to( overlaySquare, 2, { alpha : .7 } );
Give an initial value for alpha And use tweenMax.To only
Have you activated the auto alpha plugin? If not, then do it by
import com.greensock.TweenLite;
import com.greensock.plugins.TweenPlugin;
import com.greensock.plugins.AutoAlphaPlugin;
//activation is permanent in the SWF, so this line only needs to be run once.
TweenPlugin.activate([AutoAlphaPlugin]);
If you don't need auto alpha then just use alpha Property
I tried this:
private function _Show() : void {
var overlaySquare:Sprite = new Sprite();
overlaySquare.graphics.beginFill(0x00000);
overlaySquare.graphics.drawRect(0, 0, 200, 200);
overlaySquare.graphics.endFill();
overlaySquare.x = 100;
overlaySquare.y = 100;
TweenMax.to(overlaySquare, 2, {alpha:0.7});
addChild(overlaySquare);
trace("overlaySquare index: " + getChildIndex(overlaySquare));
}
This works.
Related
I am trying to add to rectangles to the stage dynamically using action script 3. When I use the code below I only see one shape with text. I'm not sure what I'm doing wrong. Matt
var room:Sprite = new Sprite();
var bgBlue:Shape = new Shape()
bgBlue.graphics.beginFill( 0xCEEDF0);
bgBlue.graphics.drawRect( 0, 0, 200, 30 );
bgBlue.graphics.endFill();
var tf:TextFormat = new TextFormat();
tf.color = 0xFFFFFF;
tf.font = "Verdana";
tf.size = 17;
tf.align = "center";
var hd_col1_txt:TextField = new TextField();
hd_col1_txt.text = "Shape 1";
hd_col1_txt.x = 0;
hd_col1_txt.y = 0;
hd_col1_txt.width = bgBlue.width;
hd_col1_txt.setTextFormat( tf );
var hd_col1_shp:MovieClip = new MovieClip();
hd_col1_shp.addChild( bgBlue );
hd_col1_shp.addChild(hd_col1_txt);
room.addChild(hd_col1_shp);
hd_col1_shp.x = room.width;
hd_col1_shp.y = 0;
var hd_col2_txt:TextField = new TextField();
hd_col2_txt.text = "Shape 2";
hd_col2_txt.x = 0;
hd_col2_txt.y = 0;
hd_col2_txt.width = bgBlue.width;
hd_col2_txt.setTextFormat(tf);
var hd_col2_shp:MovieClip = new MovieClip();
hd_col2_shp.addChild( bgBlue );
hd_col2_shp.addChild(hd_col2_txt);
room.addChild(hd_col2_shp);
hd_col2_shp.x = 220;
hd_col2_shp.y = 0;
stage.addChild(room)
bgBlue is just one instance, everytime you do
.addChild( bgBlue );
You are taking that instance and adding it to another parent display object: moving it from one parent to another.
If you are going to have just two shapes, just duplicate the code of bgBlue:
var bgBlue2:Shape = new Shape()
bgBlue2.graphics.beginFill( 0xCEEDF0);
bgBlue2.graphics.drawRect( 0, 0, 200, 30 );
bgBlue2.graphics.endFill();
And then add the new shape instead of the original bgBlue
hd_col2_shp.addChild( bgBlue2 );
Of course, if you are going to have more shapes added should be better to define a class and make instances of it to add the dynamically.
By the way, in your code you have:
hd_col1_shp.x = room.width;
Be careful, maybe the sprite width is not going to be defined just after adding it to stage
Usually when a task or a block of code is intended to be used many times, it's better to put it in a function to get a simpler and more maintainable code.
For your case, you want to create buttons, menu items or whatever. So you can write a function which will create one item every time according to data or parameters that you will pass to it ( background color, text color, width, height, ... ).
For that you can start by fixing your items parameters like this :
var items:Array = [
{bgcolor: 0xCEEDF0, width: 200, height: 30, x: 0, y: 0, label: 'Shape 1', color: 0x000090},
{bgcolor: 0xff9900, width: 200, height: 30, x: 201, y: 0, label: 'Shape 2', color: 0xffffff}
];
Then you can write the function that will create the item with its background and label and will be executed for all your items :
function create_item_with_label(item_data:Object, items_container:Sprite): void
{
var text_format:TextFormat = new TextFormat();
// set the color of the text
text_format.color = item_data.color;
text_format.font = 'Verdana';
text_format.size = 17;
text_format.align = 'center';
// create the background
var item_bg:Shape = new Shape();
item_bg.graphics.beginFill(item_data.bgcolor);
item_bg.graphics.drawRect(0, 0, item_data.width, item_data.height);
item_bg.graphics.endFill();
// create the label
var item_label:TextField = new TextField();
item_label.text = item_data.label;
item_label.x = item_label.y = 0;
item_label.width = item_bg.width;
item_label.selectable = false;
item_label.setTextFormat(text_format);
var item:Sprite = new Sprite();
item.x = item_data.x;
item.y = item_data.y;
item.addChild(item_bg);
item.addChild(item_label);
items_container.addChild(item);
}
Note here that I didn't use a MovieClip for the item and instead I used a Sprite because simply we don't need timelines, which is the only difference between these objects.
Then you can create the items container ( the room object ) :
var room:Sprite = new Sprite();
addChild(room);
And then, you can create your items to be added to your items container :
for(var i:int = 0; i < items.length; i++){
create_item_with_label(items[i], room);
}
Hope that can help.
I want to apply a gradient to my text in Flash Develop and read that using a mask is the easiest way. Problem is that I can not get it to work. I tried to create a mask with just the textField and by adding it to a sprite, neither work.
Another strange thing is that the textmask will function as a mask for start title if I reverse them like:
starttitle.mask =textmask
When I try the code below nothing displays.
var format2:TextFormat = new TextFormat();
format2.size = 40;
format2.font = "Times New Roman";
format2.bold = true
starttitle = new TextField;
starttitle.defaultTextFormat = format2;
starttitle.text = "Memory Circles";
starttitle.textColor = 0xFF0000
starttitle.autoSize = "center";
starttitle.background = false;
starttitle.backgroundColor = 0xFF4242;
starttitle.x = (300 - starttitle.width * .5);
starttitle.y = (150 - starttitle.height * .5);
starttitle.mouseEnabled = false;
addChild(starttitle)
var textmask:Shape = new Shape
var fillType:String = GradientType.LINEAR;
var colors:Array = [0xFF0000, 0];
var alphas:Array = [1, 1];
var ratios:Array = [0, 255];
var gradientBoxMatrix:Matrix = new Matrix();
gradientBoxMatrix.createGradientBox(50,100,45,0,0);
var spreadMethod:String = SpreadMethod.REPEAT;
textmask.graphics.beginGradientFill(fillType, colors, alphas, ratios,
gradientBoxMatrix, spreadMethod);
textmask.graphics.drawRect(200,100,300,100)
addChild(textmask)
textmask.mask =starttitle
I read something about the font needing to be embedded but I'm using Times New Roman and thought this would be embedded. Also other fonts don't work.
Try to use bitmap caching on starttitle and textmask:
starttitle.cacheAsBitmap=true;
textmask.cacheAsBitmap=true;
Hello there,
I'm making some tests with random color gradient tweenings (to use them as backgrounds). After trying different things, I've found a code here and slightly changed it into the one below, which unfortunately produces lots of lag (interfering with timers and so in the same class). I'm using the GreenSock TweenLite/TweenMax engine:
package{
//...
public class Main extends MovieClip{
var color1:uint = Math.floor(Math.random()*0xFFFFFF + 1);
var color2:uint = Math.floor(Math.random()*0xFFFFFF + 1);
var colors:Object = {left:color1, right:color2};
var newColor1:uint = Math.floor(Math.random()*0xFFFFFF + 1);
var newColor2:uint = Math.floor(Math.random()*0xFFFFFF + 1);
var newColors:Object = {left:newColor1, right:newColor2};
var mySprite:Sprite = new Sprite();
public function Main() {
mySprite.x = 0;
mySprite.y = 0;
stage.addChildAt(mySprite, 1);
drawGradient();
animateBackground();
//...
}
//...
function drawGradient(){
var m:Matrix = new Matrix();
m.createGradientBox(805, 485, 0, 0, 0);
mySprite.graphics.beginGradientFill(GradientType.LINEAR, [colors.left, colors.right], [1, 1], [0x00, 0xFF], m, SpreadMethod.REFLECT);
mySprite.graphics.drawRoundRect(0,0,805,485, 0);
stage.setChildIndex(mySprite, 1);
}
function animateBackground(){
TweenMax.to(colors, 3, {hexColors:{left:newColor1, right:newColor2}, onUpdate:drawGradient, onComplete:reRandomize});
}
function reRandomize(){
color1 = newColor1;
color2 = newColor2;
newColor1 = Math.floor(Math.random()*0xFFFFFF + 1);
newColor2 = Math.floor(Math.random()*0xFFFFFF + 1);
animateBackground();
}
Everything works fine, but the lag keeps increasing and increasing. To make yourself an idea, the swf, which was previously 36 kB large, rose up to 74 kB just with this color implementation.
I was wondering if there is any more efficient way to deal with this effect, or something particularly laggy in the code. Does anybody know a way? Any help would be awesome and greatly appreciated.
Thank you in advance!
NOTE: I know this is the cause of lag after several test with different things disabled, so it is very unlikely that the excessive lag is from another source.
You forgot clearing the old graphics from the mySprite, thus any extra commands produce layers upon layers of graphics on that sprite. Add mySprite.graphics.clear() call to drawGradient function prior to drawing another gradient, should do.
function drawGradient(){
var m:Matrix = new Matrix();
m.createGradientBox(805, 485, 0, 0, 0);
mySprite.graphics.clear(); // here
mySprite.graphics.beginGradientFill(GradientType.LINEAR, [colors.left, colors.right], [1, 1], [0x00, 0xFF], m, SpreadMethod.REFLECT);
mySprite.graphics.drawRoundRect(0,0,805,485, 0);
stage.setChildIndex(mySprite, 1);
}
I have been trying to convert a bitmap I've captured from a camera input into a vector to then convert the vectors points into an array for use later.
However I can not find any such functionality within Flash and so I've been trying to use 'Vectorization Package' created by Corey O'Neil. This seems to work but fails to remove the white background on my bitmap (I am capturing a picture of paper with a line on it). Even manually doing this and making the background transparent still yields no results.
Here is my code:
public class DocumentRich extends MovieClip{
public var initBox2D:Main;
var cam:Camera = Camera.getCamera();
var vid:Video = new Video(420, 300);
var myVector:Vectorize;
public function DocumentRich()
{
if(stage){
initBox2D = new Main();
addChild(initBox2D);
//addChild(new movieMonitor());
}
addEventListener(MouseEvent.CLICK, clickHandler, false, 0, true);
StartAnim();
}
function StartAnim():void
{
//SET UP WORLD
initBox2D.isDebugMode(false);
initBox2D.mouseDragEnabled(true);
Main.world.SetGravity(new b2Vec2(0,0));
cam.setQuality(0, 100);
cam.setMode(420, 300, 30, true);
trace(cam.height);
vid.attachCamera(cam);
addChild(vid);
addChild(go);
}
function clickHandler(m:MouseEvent){
trace(m.target.name);
switch(m.target.name){
case 'go':
goButtonFun();
break;
}
}
function goButtonFun():void{
var screenShot:BitmapData = new BitmapData(cam.width, cam.height);
var screenShot_image:Bitmap=new Bitmap(screenShot);
screenShot.draw(vid) ;
ReduceColors.reduceColors(screenShot, 0, true, false);
screenShot.colorTransform(new Rectangle(0, 0, screenShot.width, screenShot.height), new ColorTransform(2,2,2,1) );
///// --------- MAY NOT NEED THIS ----------- ////////////
for(var i:int = 0; i<screenShot.width; i++)
{
for(var j:int = 0; j<screenShot.height; j++)
{
if(screenShot.getPixel(i,j) == 0xffffff)
{
var transparent:uint = 0x00000000;
screenShot.setPixel32(i, j, transparent);
}
}
}
myVector = new Vectorize(screenShot_image, 23, 2, 1, 3, 0xFFFFFF);
myVector.addEventListener(Vectorize.INIT, traceStatus);
myVector.addEventListener(Vectorize.DESPECKLE_START, traceStatus);
myVector.addEventListener(Vectorize.DESPECKLE_COMPLETE, traceStatus);
myVector.addEventListener(Vectorize.GROUPING_START, traceStatus);
myVector.addEventListener(Vectorize.GROUPING_COMPLETE, traceStatus);
myVector.addEventListener(Vectorize.EDGING_START, traceStatus);
myVector.addEventListener(Vectorize.EDGING_COMPLETE, traceStatus);
myVector.addEventListener(Vectorize.DESPECKLE_PROGRESS, traceProgress);
myVector.addEventListener(Vectorize.GROUPING_PROGRESS, traceProgress);
myVector.addEventListener(Vectorize.EDGING_PROGRESS, traceProgress);
myVector.addEventListener(Vectorize.COMPLETE, showVector);
myVector.vectorize();
//addChild(screenShot_image);
addChild(go);
removeChild(vid);
cam = null;
vid.attachCamera(null);
vid = null;
}
function traceStatus(event:Event):void
{
trace(event.type);
}
function traceProgress(event:Event):void
{
var progress:int = event.target.percentDone * 100;
trace(event.type + ": " + progress + "%");
}
function showVector(event:Event):void
{
trace(event.type);
addChild(myVector);
}
}
Any suggestions?
Thanks.
UPDATE:
Sorry for any confusion, basically I would like a way to trace a transparent bitmap, and get an array of the points of the shape in said bitmap. An array of pixel data is simply too large... I'd like 4 points for a rectangle, regardless of it's size...
Apparently you are looking for BitmapData.getVector(). It's available from Flash player 10, so you should have it at your disposal.
EDIT: After I've reread your question, I understand you want your bitmap to be parsed into a vector - and a vector isn't an array of pixels, but instead a start and end of a certain line. Then yes, if you are capable of calling a threshold() so that the line's pixels will be of one color, and the background of another, you then can call getColorBoundsRect() and query all 4 corners of the rectangle. The ones which have the color of the line are your start and end coordinates, store these.
I'm trying to do some augmented reality projects with flartoolkit . I can now put simple 3d objects on my marker and it works fine , but I wanna give my project some events that the user can interact with . I'm trying to trace the rotation of the marker. there's a container:DisplayObject3D which my application uses to add the 3d objects , I traced this :"trace(container.rotationZ)" but it's just returning 0 . I studied another AR application's source code and it was using the rotation of it's container object without problem .and I think I should mention that I'm using the exercise file of seb lee delisle papervision3d course from lynda.com . anyone has any experience with flartoolkit? the main functions of my my code is as below:
public function AR_AlchemyBase()
{
super(640,480, false);
cameraParams = FLARParam.getDefaultParam(WIDTH * 0.5, HEIGHT * 0.5);
marker = new FLARCode(16, 16);
marker.loadARPattFromFile(new MarkerPattern());
init();
}
public function init():void
{
video = new Video(WIDTH, HEIGHT);
webCam = Camera.getCamera();
webCam.setMode(WIDTH, HEIGHT, 30);
video.attachCamera(webCam);
video.smoothing = true;
camBitmapData = new BitmapData(WIDTH *0.5, HEIGHT * 0.5,false, 0x000000);
camBitmap = new Bitmap(camBitmapData);
camBitmap.scaleX = camBitmap.scaleY = 2;
addChildAt(camBitmap,0);
raster = new FLARRgbRaster(WIDTH *0.5, HEIGHT * 0.5);
detector = new FLARSingleMarkerDetector(cameraParams, marker, 80);
result = new FLARTransMatResult();
viewport.x = -4;
_camera = new FLARCamera3D(cameraParams);
container = new FLARMarkerNode();
scene.addChild(container);
addSceneObjects();
stage.addEventListener(Event.ENTER_FRAME, enterFrame);
}
//the function to put our objects in
public function addSceneObjects() : void
{
var wmat:WireframeMaterial = new WireframeMaterial(0xff0000, 1, 2);
wmat.doubleSided = true;
var plane : Plane = new Plane(wmat, 80, 80);
container.addChild(plane);
var light:PointLight3D = new PointLight3D();
light.x = 1000;
light.y = 1000;
light.z = -1000;
var fmat:FlatShadeMaterial = new FlatShadeMaterial(light, 0xff22aa, 0x0);
var cube : Cube = new Cube(new MaterialsList({all: fmat}), 40, 40, 40);
cube.z = -20;
container.addChild(cube);
}
public function enterFrame(e:Event):void
{
var scaleMatrix:Matrix = new Matrix();
scaleMatrix.scale(0.5, 0.5);
camBitmapData.draw(video, scaleMatrix);
raster.setBitmapData(camBitmapData);
counter++;
if(counter == 3) counter = 0;
var imageFound : Boolean = false
currentThreshold = threshold+ (((counter%3)-1)*thresholdVariance);
currentThreshold = (currentThreshold>255) ? 255 : (currentThreshold<0) ? 0 : currentThreshold;
imageFound = (detector.detectMarkerLite(raster, currentThreshold) && detector.getConfidence() > 0.5) ;
if(imageFound)
{
detector.getTransformMatrix(result);
container.setTransformMatrix(result);
container.visible = true;
threshold = currentThreshold;
thresholdVariance = 0;
if(onImageFound!=null) onImageFound();
}
else
{
if(counter==2) thresholdVariance +=2;
if(thresholdVariance>128 ) thresholdVariance = 1;
if(onImageLost!=null) onImageLost();
}
singleRender();
}
I might not be able to help with the main problem but If you want users to interact with the models you need to set their materials to be interactive, otherwise they don't receive mouse events. Regarding the rotation...I might be missing something but it's the instances inside the container thar you're applying the rotation to, not the the container itself?
This helped me with getting a simple PV3D example running:
PV3D Tutorial for basic interactivity