Create round corner video object - actionscript-3

I want to create a rounded corner video object to my video player. This is how I create my object:
var videoCamera:Video = new Video(300, 225);
The problem is that it will make the object square video. But i want the corner of the object to be round instead of square. I have searched a lot on google and could not find any example or fix to this problem.
I also did this, but it dont work..
videoCamera.graphics.lineStyle(5, 0x00ff00, 1); //Last arg is the alpha
videoCamera.graphics.beginFill(0xff0000, 1); //Last arg is the alpha
videoCamera.graphics.drawRoundRect(0, 0, 100, 100, 25, 25)
videoCamera.graphics.endFill();
addChild( videoCamera);
Please help me to make the video object have rounded corner.

To do what you are looking for, you can simply use a mask, like this :
var video:Video = new Video(320, 180);
video.x = video.y = 50;
addChild(video);
var rounded:Shape = new Shape();
rounded.graphics.beginFill(0xff0000);
rounded.graphics.drawRoundRect(video.x, video.y, video.width, video.height, 25, 25);
rounded.graphics.endFill();
addChild(rounded);
video.mask = rounded;
That's all !
Hope that can help.

Related

Dynamically generated display object as a gradient mask

I just want to create a gradient mask –which is generated dynamically through AS3 code– for an object (a pentagon in my following example,) and I simply, cannot! [The SWF file of what I've tried.]
The code works just fine unless it ignores the alpha gradient of the dynamically created Sprite for being used as a gradient mask (it's being treated as a solid mask), while the exact code acknowledges the "on-stage" created object (through the user interface) for being a gradient mask!
I think the runtime just cannot cache the object as bitmap and hence the ignorance! However, I'm stuck at making that happen! So please, shed some lights on this, any help is greatly appreciated in advance :)
var X:Number = 100, Y:Number = 35, W:Number = 350, H:Number = 150;
var mat:Matrix = new Matrix();
mat.createGradientBox(W, H, 0, X, Y);
var gradientMask:Sprite = new Sprite();
gradientMask.graphics.beginGradientFill(GradientType.LINEAR, [0, 0], [1, 0], [0, 255], mat);
gradientMask.graphics.drawRect(X, Y, W, H);
gradientMask.graphics.endFill();
pentagon1.cacheAsBitmap = true;
pentagon2.cacheAsBitmap = true;
onStageGradient.cacheAsBitmap = true;
gradientMask.cacheAsBitmap = true;
pentagon1.mask = gradientMask;
pentagon2.mask = onStageGradient;
stage.addEventListener(Event.ENTER_FRAME, _onEnterFrame);
function _onEnterFrame(e:Event):void {
pentagon1.x += 7;
pentagon2.x += 7;
if (pentagon1.x > 500) {
pentagon1.x = 0;
pentagon2.x = 0;
}
}
You have to add the gradientMask to the display list to have it in effect.
pentagon1.parent.addChild(gradientMask);

HTML5 Canvas image resize on Chrome & easeljs

I'm struggling to make smooth image resized in canvas in Chrome. In firefox it works well, but in Chrome I'm stuck on making it smooth.
Here is the jsfiddle
http://jsfiddle.net/flashmandv/oxtrypmy/
var AVATAR_SIZE = 100;
var WHITE_BORDER_SIZE = 3;
var stage = new createjs.Stage("canvas");
var avCont = new createjs.Container();
stage.addChild(avCont);
avCont.x = avCont.y = 20;
//add white circle
var whiteBorderCircle = new createjs.Shape();
var radius = (AVATAR_SIZE+WHITE_BORDER_SIZE*2)/2;
whiteBorderCircle.graphics.beginFill("white").drawCircle(radius, radius, radius);
avCont.addChild(whiteBorderCircle);
//add avatar image mask
var avatarMask = new createjs.Shape();
avatarMask.graphics.beginFill("red").drawCircle(AVATAR_SIZE/2+WHITE_BORDER_SIZE, AVATAR_SIZE/2+WHITE_BORDER_SIZE, AVATAR_SIZE/2);
//add avatar image
var image = new Image();
image.onload = function(){
var bitmap = new createjs.Bitmap(image);
bitmap.mask = avatarMask;
var bounds = bitmap.getBounds();
bitmap.scaleX = (AVATAR_SIZE+WHITE_BORDER_SIZE*2) / bounds.width;
bitmap.scaleY = (AVATAR_SIZE+WHITE_BORDER_SIZE*2) / bounds.height;
avCont.addChild(bitmap);
stage.update();
};
image.src = 'http://files.sharenator.com/sunflowers-s800x800-423444.jpg';
Notice the jagged image
Please help
It is due to how clipping works in Chrome. Clip masks are pretty brutal in Chrome while in Firefox you get anti-aliasing along the non-straight edges.
Here is a proof-of-concept for this (run this in Chrome and in FF to see the difference):
http://jsfiddle.net/r65fcqoy/
The only way to get around this is to use composite modes instead, which basically means you need to rewrite your code unless the library you're using support this in some way.
One use of a composite mode is to use it to fill anything inside an existing drawing on the canvas.
We'll first create the filled circle we want the image to appear inside
Change comp mode to source-in and draw image
Then we go back to normal comp mode and draw the outer border
Here is an approach using vanilla JavaScript where you can control how you plug things together - this is maybe not what you're after but there is really not much option if the library as said doesn't support comp mode instead of clipping:
var canvas = document.getElementById('canvas'),
ctx = canvas.getContext('2d'),
img = new Image,
x = 70, y =70;
var AVATAR_SIZE = 100;
var WHITE_BORDER_SIZE = 3;
var radius = (AVATAR_SIZE+WHITE_BORDER_SIZE*2)/2;
img.onload = function() {
// first draw the circle for the inner image:
ctx.arc(x, y, AVATAR_SIZE*0.5, 0 , 2*Math.PI);
ctx.fill();
// now, change composite mode:
ctx.globalCompositeOperation = 'source-in';
// draw image in top
ctx.drawImage(img, x-AVATAR_SIZE*0.5, y-AVATAR_SIZE*0.5,
AVATAR_SIZE, AVATAR_SIZE);
// change back composite mode to default:
ctx.globalCompositeOperation = 'source-over';
// now draw border
ctx.beginPath();
ctx.arc(x, y, radius + 5, 0, 2*Math.PI);
ctx.closePath();
ctx.lineWidth = 10;
ctx.strokeStyle = '#ffa94e';
ctx.stroke();
};
img.src = 'http://i.stack.imgur.com/PB8lN.jpg';
<canvas id=canvas width=500 height=180></canvas>
Another solution to this would be in onload function to add another shape above the masked image to simply cover the jagged edges of the clipping mask

Draw Text on a generated Sprite object as3

Everyone, I'm just a beginner and I have question. The idea of my program is that when the user clicks a button a circle is generated and it should be counting for each additional circle it should look something like this :
The number should be in center and I should be able to move the object with the number together this is my code:
add_s.addEventListener(MouseEvent.CLICK,new_sond);
function new_sond(event:MouseEvent):void
{
var btn:Sprite = new Sprite();
btn.graphics.beginFill(0x00FF00, 1);
btn.graphics.drawCircle(400, 300, 25);
btn.graphics.endFill();
this.addChild(btn);
}
//----------------------------Drag And Drop----------------------
this.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownH);
this.addEventListener(MouseEvent.MOUSE_UP, mouseUpH);
function mouseDownH(evt:MouseEvent):void {
var object = evt.target;
object.startDrag();
}
function mouseUpH(evt:MouseEvent):void {
var obj = evt.target;
obj.stopDrag();
}
I will be very thankful if someone can help me.
How do i make the text to apear on the center of the circles and i still will be able to move them with the text
This is what Vesper should have posted as an answer :)
Add a TextField object to your Sprite. Since the TextField is a child of the Sprite, it will move w/the Sprite. All you need to do is position the text in the middle of the circle:
function new_sond(event:MouseEvent):void
{
var btn:Sprite = new Sprite();
btn.graphics.beginFill(0x00FF00, 1);
btn.graphics.drawCircle(400, 300, 25);
btn.graphics.endFill();
var textField = new TextField();
textField.text = "1";
textField.width = textField.textWidth; // default width is 100
textField.height = textField.textHeight;
textField.x = (25 - textField.textWidth)/2; // center it horizontally
textField.y = (25 - textField.textHeight)/2; // center it vertically
btn.addChild(textField);
this.addChild(btn);
}
Note, as suggested by #Joeson Hwang, you could use a Shape object instead of a Sprite to draw the circles. The Shape is more lightweight than a Sprite. However, since Shape does not extend DisplayObjectContainer, you cannot add child objects to a Shape like you can with a Sprite.
#Joeson Hwang's answer suggests to add the Shape and the text to a Sprite. But that won't be saving you anything, so just draw the graphics directly to the Sprite as you are doing now.
use btn:Shape (saves a lot of system resources). and then put the Shape and your text into a Sprite. You could also add a Sprite into another Sprite.
You can use also flash.text.engine package:
function new_sond(event:MouseEvent):void
{
var btn:Sprite = new Sprite();
btn.graphics.beginFill(0x00FF00, 1);
btn.graphics.drawCircle(cx, cy, cr);
btn.graphics.endFill();
// Font format
var fontDescription:FontDescription = new FontDescription("Arial");
var format:ElementFormat = new ElementFormat(fontDescription, 16, 0x000088);
// Display text
var textElement:TextElement = new TextElement('1', format);
var textBlock:TextBlock = new TextBlock();
textBlock.content = textElement;
// New display object containing text
var textLine:TextLine = textBlock.createTextLine(null, 500);
// Centers the text inside the circle
textLine.x = cx + (cr - textLine.width) / 2;
textLine.y = cy + (cr - textLine.height) / 2;
// Add text into button
btn.addChild(textLine);
this.addChild(btn);
}
More info about creating text: Creating and displaying text in ActionScript 3.0 Developer’s Guide

As3 draw bitmap + copyPixel around mouseX and mouseY

I am doing a magnifying glass effect?
I have a working version. However the performance is not good enough on the tablet.
What i have done so far:
I had a ENTERFRAME event on a mouseDown
So it start capture the screen when the mouse click down, and follow the mouseX and mouseY
It works, but the only problem it keep draw the whole stage rather than maybe (300px * 300px) around the mouseX and mosueY. is there a way i can make the draw area according to your mouseX and mouseY. I guess that would help the performance as well. :)
e.target.removeEventListener(Event.ENTER_FRAME, startCapture);
function startCapture(e:Event):void{
var glassWidth:uint=80;
var glassHeight:int=80;
var curBd:BitmapData;
var curBmp:Bitmap;
var posX:int = _parentStage.mouseX - 40;
var posY:int = _parentStage.mouseY - 40;
//-------------------------------------------------------------
//var subArea:Rectangle = new Rectangle(0,0,500,500);
//var newBmp:Bitmap = new BitmapData(500,500);
//var cutoutBmp:Bitmap = new Bitmap( newBmp, PixelSnapping.ALWAYS, true );
//cutoutBmp.bitmapData.draw( jpgSource, new Matrix(1, 0, 0, 1, -357, -341) , null, null, subArea, true );
//-------------------------------------------------------------
bd = new BitmapData(1024, 768, true, 0);
var subArea:Rectangle = new Rectangle(_parentStage.mouseX, _parentStage.mouseY, 500, 500);
// bd = new BitmapData(500, 500);
bd.draw(_parentStage.mc_mainContainer);
// bd.draw(_parentStage.mc_mainContainer);
curBmp=new Bitmap(new BitmapData(glassWidth,glassHeight), PixelSnapping.ALWAYS);
curBmp.bitmapData.copyPixels(bd,new Rectangle(posX,posY,_parentStage.mouseX,_parentStage.mouseY),new Point(0,0));
curBd=curBmp.bitmapData;
var ma:Matrix = new Matrix(1, 0, 0, 1, -40, -40);
glass.name = 'glass';
glass.alpha = 1;
glass.graphics.clear();
glass.graphics.beginBitmapFill(curBd, ma);
glass.graphics.drawCircle(0, 0, 35);
//glass.graphics.drawCircle(0, 0, 35);
glass.graphics.endFill();
//var imageCircle:Bitmap = new _magGlass();
//trace(_magGlass);
//glass.addChild(_magGlass);
if(!_parentStage.contains(glass))_parentStage.addChildAt(glass, _parentStage.numChildren - 2);
glass.x = _parentStage.mouseX;
glass.y = _parentStage.mouseY - 75;
}
Where your performance problem is coming from is where you're creating new bitmaps and bitmapdatas and rectangles on every frame. Instead, just create one or two in the constructor or on click and then reuse them. Since you already have a BitmapData, you can probably just put that on the stage and mask it, rather than using the graphics object in glass. At least pick one approach or the other. Doing both is killing you, performance wise.

ActionScript - Drawing BitmapData While Maintaining Center Registration of Display Object

maintaining the center registration point of a circle shape, or any other display object with center registration, while being converted to a bitmap object is proving to be difficult.
the following code converts a circle shape into a bitmap object and positions it in the center of the stage and subsequently removes its center registration poin.
the x and y origin of a new bitmapData object (top left) is the same as the x and y origin of the circle (center), but it's not possible to translate the x and y position of the bitmapData.draw() - its parameters only accept width, height, transparency and fill color.
var myCircle:Shape = new Shape();
myCircle.graphics.beginFill(0xFF0000, 1.0);
myCircle.graphics.drawCircie(0, 0, 100);
myCircle.graphics.endFill();
var matrix:Matrix = new Matrix();
matrix.tx = myCircle.width / 2;
matrix.ty = myCircle.height / 2;
var myCircleBitmapData:BitmapData = new BitmapData(myCircle.width, myCircle.height, true, 0x00FFFFFF);
myCircleBitmapData.draw(myCircle, matrix);
var result:Bitmap = new Bitmap(myCircleBitmapData, PixelSnapping.AUTO, true);
result.x = stage.stageWidth / 2 - matrix.tx;
result.y = stage.stageHeight / 2 - matrix.ty;
addChild(result);
with the help of a matrix translation, the new bitmap object will appear centered in the stage, but applying a regular or 3D rotation, etc., will clearly demonstrate that the registration point is now the top left corner instead of the center.
how can i convert a center registered display object into a bitmap while maintaining its center registration?
it appears the most common approach is to simply add the bitmap as a child of a sprite container and rotate the sprite container rather than the bitmap itself.
var myCircle:Shape = new Shape();
myCircle.graphics.beginFill(0xFF0000, 1.0);
myCircle.graphics.drawCircie(0, 0, 100);
myCircle.graphics.endFill();
var matrix:Matrix = new Matrix();
matrix.tx = myCircle.width / 2;
matrix.ty = myCircle.height / 2;
var myCircleBitmapData:BitmapData = new BitmapData(myCircle.width, myCircle.height, true, 0x00FFFFFF);
myCircleBitmapData.draw(myCircle, matrix);
var myCircleBitmap:Bitmap = new Bitmap(myCircleBitmapData, PixelSnapping.AUTO, true);
myCircleBitmap.x -= matrix.tx;
myCircleBitmap.y -= matrix.ty;
var circleContainer:Sprite = new Sprite();
circleContainer.addChild(myCircleBitmap);
alternatively, for those using Flash Professional IDE, there is the option to employ fl.motion.MatrixTransformer.rotateAroundInternalPoint instead of using a container sprite.
The following tutorial looks like what you're trying to do.
http://www.8bitrocket.com/2007/10/30/Actionscript-3-Tutorial-BitmapData-rotation-with-a-matrix/