Rectangle with rounded corners and gradient fill - actionscript-3

I'm trying to make a rectangle with rounded corners and a gradient. I have this code:
import flash.geom.*;
var rect:Shape = new Shape();
rect.graphics.lineStyle(5, 0x00ff00, 0); //(thickness, color, alpha)
var fillType:String = "linear";
var colors:Array = [0x000000, 0xFFFF00,0xFFFFFF];
var alphas:Array=[1,1,1];
var ratios:Array=[0,127,255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(20, 20, 0, 0, 0);
rect.beginGradientFill(fillType, colors, alphas, ratios, matrix) : Void;
rect.graphics.drawRoundRect(720,450, 213.4, 29.1, 12, 12);
rect.graphics.endFill();
addChild(rect);
I'm getting an error from this line :
rect.beginGradientFill(fillType, colors, alphas, ratios, matrix) : Void;
1078: Label must be simple identifier.
I'm a novice and everything I look up seems to have a bunch of terminology I don't quite understand, so please keep it simple.
I want the yellow (FFFF00) to actually be a color picked from the stage so if that can be thrown in there easily without complicating the answer to the above question, feel free.

In your code you have two errors in the same line :
rect.beginGradientFill(fillType, colors, alphas, ratios, matrix) : Void;
We use void ( with lower v, it's not Void ) to indicate the type of a function which will return nothing when we are defining it, not when calling that function.
Then beginGradientFill() is a function of the Graphics class so it should be used with rect.graphics :
rect.graphics.beginGradientFill(fillType, colors, alphas, ratios, matrix);
Then your code can be like this (it's an example) :
var fillType:String = "linear";
var colors:Array = [0x000000, 0xFFFF00, 0xFF0000];
var alphas:Array=[1, 1, 1];
var ratios:Array=[0, 127, 255];
var matrix:Matrix = new Matrix();
matrix.createGradientBox(200, 10, 0, 0, 0);
var rect:Shape = new Shape();
rect.graphics.lineStyle(5, 0x00ff00, 0);
rect.graphics.beginGradientFill(fillType, colors, alphas, ratios, matrix)
rect.graphics.drawRoundRect(0, 0, 200, 200, 12, 12);
rect.graphics.endFill();
addChild(rect);
For more about gradient, take a look on Graphics.beginGradientFill(), and on creating gradient lines and fills ...
Hope that can help.

preface: didn't see the comment from before, but that's the correct solution.
The breakpoint is here:
rect.beginGradientFill(fillType, colors, alphas, ratios, matrix) : Void;
The function call should not have the " : Void" identifier. That's used when the function is originally written.
try this:
rect.beginGradientFill(fillType, colors, alphas, ratios, matrix);

Related

As3: Draw overlapping rectangles to a sprite and apply alpha

I need to draw independet rectangles to a sprite. But the overlapping areas will get visible if I apply alpha to my sprite (the sprite will be fade in and out):
var spBox:Sprite = new Sprite();
this.addChild(spBox);
spBox.graphics.beginFill(0x123456)
spBox.graphics.drawRect(100, 100, 50, 50);
spBox.graphics.endFill();
spBox.graphics.beginFill(0x123456)
spBox.graphics.drawRect(125, 125, 50, 50);
spBox.graphics.endFill();
Is there a way to compine/flatten/merge the rectangles of my sprite? I want a seamless aplha appearence.
I suspect that the graphics object does not support this kind of functionality for parts of its data.
If both boxes are individual DisplayObjects, you can set the .blendMode of the DisplayObjectContainer to BlendMode.LAYER, which gives the desired result. Here's some example code that refactors the drawing of a rectangle into a Box class:
var spBox:Sprite = new Sprite();
this.addChild(spBox);
var a:Box = new Box(50, 50, 0x123456);
a.x = a.y = 100;
spBox.addChild(a);
var b:Box = new Box(50, 50, 0x123456);
b.x = b.y = 125;
spBox.addChild(b);
spBox.alpha = .5;
spBox.blendMode = BlendMode.LAYER;
The relevant parts of the Box class look like this:
public class Box extends Shape
{
public function Box(width:Number = 100, height:Number = 100, color:uint = 0)
{
graphics.beginFill(color)
graphics.drawRect(0, 0, width, height);
graphics.endFill();
}
}

Reduce lag in Random Color Gradient Tweening (Programatically Generated)

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);
}

ActionScript 3 - adding gradient to object

I have an instance of a MovieClip called 'BlueBox', which is just a 'Drawing Object' which is blue. It is inside a container called 'option1MC' which is inside 'option1Container' which is on the stage.. It's color can be changed like so:
option1Container.addEventListener(MouseEvent.MOUSE_OVER, option1ContainerOver);
var optionOver:ColorTransform = new ColorTransform();
optionOver.color = 0xC56516;
function option1ContainerOver(evt:Event):void {
option1Container.option1MC.BlueBox.transform.colorTransform = optionOver;
}
I want to change the color to a gradient. This is what I tried:
var mtr:Matrix = new Matrix();
mtr.createGradientBox(option1Container.option1MC.BlueBox.width, option1Container.option1MC.BlueBox.height, 0, 0, 0);
mtr.graphics.beginGradientFill(GradientType.LINEAR, [0xFF0000, 0x0000FF], [1, 1], [0x00, 0xFF], mtr);
mtr.graphics.drawRect(0,0,option1Container.option1MC.BlueBox.width, option1Container.option1MC.BlueBox.height);
However, right now when I run the .fla file, it i giving me an error saying:
Access of possible undefined property graphics through a reference with static type flasg.geom:Matrix:
and is referring to the lines
mtr.graphics.beginGradientFill(GradientType.LINEAR, [0xFF0000, 0x0000FF], [1, 1], [0x00, 0xFF], mtr);
mtr.graphics.drawRect(0,0,option1Container.option1MC.BlueBox.width, option1Container.option1MC.BlueBox.height);
Any idea why?
A Matrix does not have a graphics property. You would need to apply this to a DisplayObject with a graphics property. That would look something like this with your setup:
//create the sprite to do the gradient fill on or use your MovieClip
//var spriteObject:Sprite = new Sprite() or just use option1Container;
//enter your matrix
var mtr:Matrix = new Matrix();
mtr.createGradientBox(option1Container.BlueBox.width, option1Container.BlueBox.height, 0, 0, 0);
//apply it to the sprite
sprite.graphics.beginGradientFill("linear", [0xFF0000, 0x0000FF], [1, 1], [0x00, 0xFF], mtr);
sprite.graphics.drawRect(0, 0, 50, 40);
sprite.graphics.endFill();
addChild(sprite);
I created a sprite variable here, which is not necessary as you can just swap sprite with option1Container
You can reference adobe's help for this as well: http://help.adobe.com/en_US/as3/dev/WS5b3ccc516d4fbf351e63e3d118a9b90204-7dd7.html
Now if you drew the MovieClip graphics in the IDE you won't currently be able to change it. In which case you can create a new MovieClip and add it to your container like so:
//note I made a target variable just to save on typing:
var target:MovieClip = option1Container.option1MC.BlueBox;
var gradientLayer:MovieClip = new MovieClip();
var gradientBox:Matrix = new Matrix();
gradientBox.createGradientBox(target.width, target.height, 0, 0, 0);
gradientLayer.graphics.beginGradientFill("linear", [0xFF0000, 0x0000FF], [1, 1], [0x00, 0xFF], gradientBox);
gradientLayer.graphics.drawRect(0, 0, target.width, target.height);
gradientLayer.graphics.endFill();
//giving the asset a name will allow you to easily remove it later
gradientLayer.name = "gradientLayer";
target.addChild(gradientLayer);
Notice I gave the gradient asset a name of "gradientLayer". If you want to remove this child later on you can do that with:
option1Container.option1MC.BlueBox.removeChild( option1Container.option1MC.BlueBox.getChildByName( "gradientLayer" ) );

AS3 BitmapData threshold(): replace color that has an alpha?

Hi I would like to replace a specific color in a bitmap with another one.
The BitmapData.threshold() function works fine if the threshold color value has no alpha.
var threshold:uint = 0xFF004d5e; // this works, however if I use this 0x37004d5e, ie the same color with an alpha then it doesnt
var baseColour:uint = 0x3700c5e0;
var targetColour:uint = 0x37F38900;
var inputBitmapData:BitmapData = new BitmapData(200, 200, true, baseColour);
inputBitmapData.fillRect(new Rectangle(10, 10, 180, 180), threshold);
var input:Bitmap = new Bitmap(inputBitmapData);
addChild(input);
replaceColour(inputBitmapData,threshold,targetColour);
function replaceColour(bitmapData:BitmapData,colorToReplace:uint, newColor:uint):void
{
trace(" replaced:"+ bitmapData.threshold(bitmapData, new Rectangle(0, 0, bitmapData.width, bitmapData.height), new Point(), "==", colorToReplace, newColor, 0xFFFFFFFF));
}
The above works, unless you are trying to change a color that has an alpha, then it doesnt.
ie change the threshold variable's value from 0xFF004d5e to 0x37004d5e, ie to change a color which has an alpha channel, and then it wont work, but that is what I want!
Anyone has any ideas, how to make the BitmapData.threshold() function work when the threshold color has an alpha??

How do i draw an square with an alpha square in the center

I know how to draw a square:
graphics.moveTo(0, 0);
graphics.beginFill(0x00ff00, 1);
graphics.lineTo(point, 0);
graphics.lineTo(point, point);
graphics.lineTo(0, point);
graphics.lineTo(0, 0);
graphics.endFill();
now how would i draw another square inside the first one with an alpha of 0.5?
The following snippet will draw a green square then substract a square to its center (live demo).
// Size of the main square
var point:uint = 100;
// Create two sprites
var s1:Sprite = new Sprite();
var s2:Sprite = new Sprite();
// Shortcuts to graphics objects
var g1:Graphics = s1.graphics;
var g2:Graphics = s2.graphics;
// Draw the main square
g1.beginFill(0x00ff00, 1.0);
g1.drawRect(0, 0, point, point);
g1.endFill();
// Draw the eraser square
g2.beginFill(0x000000, 0.5);
g2.drawRect(0, 0, point/2, point/2);
g2.endFill();
// Configure blend modes to erase the center of the first square
s1.blendMode = BlendMode.LAYER;
s2.blendMode = BlendMode.ERASE;
// Add the eraser square to the first one and adjust its position
s1.addChild(s2);
s2.x = s2.y = point/4;
// Add the first square to the stage
addChild(s1);
Without having to use any blend modes, you can exclude portions of a drawn shape by drawing over (erasing) the desired portion before ending the fill.
Here's an example:
import flash.display.Shape;
var squares:Shape = new Shape();
squares.graphics.beginFill(0xFF0000, 1.0);
squares.graphics.drawRect(0, 0, 200, 200);
squares.graphics.drawRect(50, 50, 100, 100); //exclude
squares.graphics.endFill();
squares.graphics.beginFill(0x0000FF, 0.5);
squares.graphics.drawRect(75, 75, 100, 100);
squares.graphics.endFill();
addChild(squares);
var squ1:Sprite = new Sprite();
with(squ1.graphics){
beginFill(0xFF0000);
drawRect(0,0,100,100);
endFill();
}
addChild(squ1);
var inSq:Sprite = new Sprite();
with(inSq.graphics){
beginFill(0x00FF00,.5);
drawRect(0,0,25,25);
endFill();
}
squ1.addChild(inSq);
inSq.x = squ1.width/2 - inSq.width/2;
inSq.y = squ1.height/2 - inSq.height/2;