I am new to as3.0 and want to complete my project.
I am using the below code for my xml slideshow but I want the pictures to fade into each other it should never fade to complete white. Hope any expert can help me.
import gs.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
import fl.transitions.easing.*;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
//hides the description box until the image is loaded
//hides the image until it is loaded
theImage.alpha=0;
loadingBar.visible = false;
//variables to hold the final coordinates of the image tween
var finalX:Number;
var finalY:Number;
//variable to hold the number of images in the XML
var listLength:Number;
//keeps track of what image should be displayed
var currPainting:Number=0;
//arrays to hold the contents of the XML, using this to allow
//for the random order of the images
var imageArray:Array = new Array();
//Loader event for the XML
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onLoaded);
var xml:XML;
loader.load(new URLRequest("galleries/xml/maingallery.xml"));
function onLoaded(e:Event):void {
//load XML
xml=new XML(e.target.data);
var il:XMLList=xml.images;
listLength=il.length();
populateArray();
}
function populateArray():void {
//takes the properties defined in the XML and stores them
//into arrays
var i:Number;
for (i = 0; i < listLength; i++) {
imageArray[i]=xml.images[i].pic;
}
beginImage();
}
function beginImage():void {
//grabs a random number between 0 and the number
//of images in the array
//load description
var imageLoader = new Loader();
//catches errors if the loader cannot find the URL path
imageLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, catchFunction);
//actually loads the URL defined in the image array
imageLoader.load(new URLRequest(imageArray[currPainting]));
//adds a listener for while the image is loading
imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, imgLoading);
//adds a listener for what to do when the image is done loading
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);
function catchFunction(e:IOErrorEvent) {
trace("Bad URL: " + imageArray[currPainting] + " does not exist");
//take out the bad URL from the array
imageArray.splice(currPainting,1);
//check to see if there are images left,
//else restart the slideshow
if (imageArray.length==0) {
populateArray();
} else {
beginImage();
}
}
function imgLoading(event:ProgressEvent):void{
//show the loading bar, and update the width
//based on how much is loaded
loadingBar.visible = true;
loadingBar.bar.scale = (event.bytesLoaded/event.bytesTotal)*100;
loadingBar.x = stage.stageWidth/2;
loadingBar.y = stage.stageHeight - 400;
}
var widthRatio:Number;
var heightRatio:Number;
function imgLoaded(event:Event):void {
loadingBar.visible = false;
//add the image and get the dimensions to center the image
theImage.addChild(imageLoader);
if (imageLoader.width > stage.stageWidth){
widthRatio=imageLoader.width/stage.stageWidth;
trace(widthRatio)
trace(imageLoader.width);
}
if (imageLoader.height > stage.stageHeight - 207){
heightRatio=imageLoader.height/(stage.stageHeight - 207) ;
trace(heightRatio)
trace(imageLoader.height)
}
if (widthRatio > heightRatio){
imageLoader.width = stage.stageWidth;
imageLoader.height = imageLoader.height/widthRatio;
} else {
imageLoader.height = stage.stageHeight - 207;
imageLoader.width = imageLoader.width/heightRatio;
}
imageLoader.x = (imageLoader.stage.stageWidth / 2) - (imageLoader.width / 2);
imageLoader.y = 0
//take the contents of the loaded image and cast it as bitmap data
//to allow for bitmap smoothing
var image:Bitmap = imageLoader.content as Bitmap;
image.smoothing=true;
//start tween function
easeIn();
}
}
function easeIn():void {
TweenLite.to(theImage, 5, {onComplete:hideStuff});
TweenLite.to(theImage, 1, {alpha:1, overwrite:0});
}
function hideStuff():void {
TweenLite.to(theImage, 1, {alpha:0, onComplete:nextImage});
}
function nextImage():void {
//take out the image that was just displayed
imageArray.splice(currPainting,1);
//remove the picture
theImage.removeChildAt(0);
//start over
if (imageArray.length==0) {
populateArray();
} else {
beginImage();
}
}
Ok, first you need to create a variable for the image you wish to fade in. Let's organise it so it is clear which is which.
var theCurrentImage:DisplayObject;
var theNextImage:DisplayObject;
Load in the first image (now theCurrentImage) in the same way as before.
Now here's how you could load in the next image in the array:
function loadNextImage():void {
currPainting++;
// you should also make sure currPainting is not out of bounds here
loadImage();
}
function loadImage():void {
imageLoader = new Loader();
imageLoader.addEventListener(Event.COMPLETE, onImageLoaded);
// other listeners go here too
imageLoader.load(new URLRequest(imageArray[currPainting]));
}
function onImageLoaded(e:Event):void {
theNextImage = imageLoader; // stores the next image ready to be faded in
theNextImage.alpha = 0;
addChild(theNextImage); // now ready to be cross-faded in
crossFade();
}
function crossFade():void {
TweenLite.to(theCurrentImage, 1, {alpha:0});
TweenLite.to(theNextImage, 1, {alpha:1});
// remove theCurrentImage (now invisible) from the stage
removeChild(theCurrentImage);
// theNextImage is now the displayed image so...
theCurrentImage = theNextImage;
theNextImage = null;
// ready to load the next image by calling loadNextImage()
}
Related
I have an application I'm trying to build where it will display a large map image (1920x1040 which is set as the base layer of frame one, then all my AS is on the layer above on the first frame too), then draw lines to it by reading in their coordinates from an external file (lines.txt) and associate a particular image with each line.
When a user clicks on a line, a ScrollPane should open, showing the image associated with the line they clicked on. These images are 1040 in height, and at least 4000px wide, so I want the image to fill the screen height, and then allow the user to use a scroll bar along the bottom to scroll left and right to see the full image.
Right now, I have it working where it reads in my lines.txt file, and draws the lines correctly. Then when I click on a line, it will load the corresponding image in the ScrollPane (along with a button to click that will remove the scroll pane and allow them to select a new line).
However, I can't get a horizontal scroll bar to work. I have it so that the space shows up at the bottom where a scroll bar should be, but there's no bar to drag left/right, and no way to scroll around.
I saw that it's possible to use dragging to scroll, which would be nice, but that hasn't worked either (it' now commented out), and when I have it turned on, when I click my Back Button and attempt to click another line, it throws an error saying,
"TypeError: Error #1009: Cannot access a property or method of a null object reference.
at fl.containers::ScrollPane/endDrag()"
Anybody able to help me clean this up and get it figured out what's going wrong here?
My code:
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.geom.ColorTransform;
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import fl.containers.ScrollPane;
import fl.events.ScrollEvent;
import fl.controls.ScrollPolicy;
import fl.controls.DataGrid;
import fl.data.DataProvider;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLLoader;
import fl.controls.UIScrollBar;
import flash.events.Event;
import fl.controls.ScrollBar;
var worldLines:Array = new Array();
var lineSprites:Array = new Array();
var lineSpritesLength:int;
var basicColorTransform:ColorTransform = new ColorTransform();
basicColorTransform.color = 0x00FF00;
var hoverColorTransform:ColorTransform = new ColorTransform();
hoverColorTransform.color = 0xFFFF00;
populateWorldLines();
function populateWorldLines():void
{
var textFile:File = File.applicationDirectory.resolvePath("lines.txt");
var fileContents:String = getFileData(textFile);
var contentsLength:int = fileContents.split("$").length;
for(var i:int = 0; i < contentsLength; i++)
{
trace(i);
worldLines[i] = new Object();
worldLines[i]["x1"] = fileContents.slice(0, fileContents.indexOf(","));
fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);
worldLines[i]["y1"] = fileContents.slice(0, fileContents.indexOf(","));
fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);
worldLines[i]["x2"] = fileContents.slice(0, fileContents.indexOf(","));
fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);
worldLines[i]["y2"] = fileContents.slice(0, fileContents.indexOf(","));
fileContents = fileContents.slice(fileContents.indexOf(",") + 1, fileContents.length);
worldLines[i]["image"] = fileContents.slice(0, fileContents.indexOf(";"));
fileContents = fileContents.slice(fileContents.indexOf("$") + 1, fileContents.length);
}
drawLines(worldLines);
}
function drawLines(lines:Array):void
{
for(var i:int = 0; i < lines.length; i++)
{
var line:Sprite = new Sprite;
line.graphics.moveTo(lines[i]["x1"], lines[i]["y1"]);
line.graphics.lineStyle(3, basicColorTransform.color);
line.graphics.lineTo(lines[i]["x2"], lines[i]["y2"]);
lineSprites.push(line);
addChild(line);
}
lineSpritesLength = lineSprites.length;
this.addEventListener(MouseEvent.MOUSE_OVER, checkLines);
}
function checkLines(e:MouseEvent):void
{
var targetSprite:* = e.target;
for(var i:int = 0; i < lineSpritesLength; i++)
{
if(targetSprite == lineSprites[i])
{
targetSprite.transform.colorTransform = hoverColorTransform;
targetSprite.addEventListener(MouseEvent.CLICK, lineClicked);
targetSprite.addEventListener(MouseEvent.MOUSE_OUT, resetColorTransform);
}
}
}
function lineClicked(e:MouseEvent):void
{
var targetSprite:* = e.target;
for(var i:int = 0; i < lineSpritesLength; i++)
{
if(targetSprite == lineSprites[i])
{
showImage(worldLines[i]["x1"], worldLines[i]["y1"], worldLines[i]["image"]);
}
}
//e.target.removeEventListener(e.type, lineClicked);
}
function showImage(xPos:int, yPos:int, imageName:String):void
{
var aSp:ScrollPane = new ScrollPane();
var aBox:MovieClip = new MovieClip();
drawBox(aBox, imageName);
aSp.source = aBox;
aSp.setSize(1920, 1040);
aSp.move(0, 0);
aSp.name = "scrollyPaneThing";
//aSp.scrollDrag = true;
aSp.horizontalScrollPolicy=ScrollPolicy.ON;
aSp.addEventListener(ScrollEvent.SCROLL, scrollListener);
addChild(aSp);
}
function scrollListener(event:ScrollEvent):void {
var mySP:ScrollPane = event.currentTarget as ScrollPane;
trace("scrolling");
trace("\t" + "direction:", event.direction);
trace("\t" + "position:", event.position);
trace("\t" + "horizontalScrollPosition:", mySP.horizontalScrollPosition, "of", mySP.maxHorizontalScrollPosition);
trace("\t" + "verticalScrollPosition:", mySP.verticalScrollPosition, "of", mySP.maxVerticalScrollPosition);
};
function drawBox(box:MovieClip,imageName:String):void {
trace(imageName + ":imageName");
var file:File = File.applicationDirectory.resolvePath("dataImages/"+imageName);
var imageLoader:Loader = new Loader();
var image:URLRequest = new URLRequest(file.url);
imageLoader.load(image);
imageLoader.x = 1;
imageLoader.y = 1;
box.addChild (imageLoader);
trace("backButton.png:imageName");
var file2:File = File.applicationDirectory.resolvePath("backButton.png");
var imageLoader2:Loader = new Loader();
var image2:URLRequest = new URLRequest(file2.url);
imageLoader2.load(image2);
imageLoader2.x = 10;
imageLoader2.y = 950;
box.addChild (imageLoader2);
imageLoader2.addEventListener(MouseEvent.CLICK, removeScrollyPaneThing);
}
function removeScrollyPaneThing(MouseEvent):void
{
removeChild(getChildByName("scrollyPaneThing"));
}
function resetColorTransform(e:MouseEvent):void
{
e.target.transform.colorTransform = basicColorTransform;
e.target.removeEventListener(e.type, resetColorTransform);
}
function getFileData(file:File):String
{
var fDataStream:FileStream;
var sContent:String;
fDataStream = new FileStream();
fDataStream.open(file, FileMode.READ);
sContent = fDataStream.readUTFBytes(fDataStream.bytesAvailable);
fDataStream.close();
return sContent;
}
Your Loader Object has a scrollRect property that is built in.
It is MUCH easier to use a simple ScrollBar than a ScrollPane,
but mouse dragging is much cleaner:
see: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#scrollRect
To mouse drag:
private var scrollyThingy:Rectangle;
private var map:Loader;
// holders for the location of the view
//(to allow for cancelling the drag):
private var _cx:int = 0;
private var _cy:int = 0;
private var downpoint:Point = null;
public function init():void{
// Load your image:
/* I prefer to use embeded png files
or draw simple line images, but
Loader objects also have a scrollRect property
From this point I will assume your main image ('map') is loaded,
and 'scrollyThingy' is the part you want diplayed
I could not follow the code once you added the
loader to the stage very well...
*/
// to enable mouse dragging:
map.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
var w:int = 100;
var h:int = 100;
scrollyThingy = new Rectangle(_cx, _cy, w, h);
map.scrollRect = scrollyThingy;
AddChild(map);
}
private function onMouseDown(event:MouseEvent):void{
_downpoint = new Point(event.stageX, event.stageY);
map.removeEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
map.addEventListener(MouseEvent.MOUSE_DRAG, onMouseDrag);
map.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
map.addEventListener(MouseEvent.RELEASE_OUTSIDE , onReleaseOutside);
}
private function onMouseDrag(event:MouseEvent):void{
if (_downpoint == null)
return;
// the movement delta:
_dx = int((event.stageX - _downpoint.x));
_dy = int((event.stageY - _downpoint.y));
// (if the movement is backwards, use scrollyThingy.x -= _dx)
scrollyThingy.x += _dx;
scrollyThingy.y += _dy;
Loader.scrollRect = scrollyThingy;
}
private function onMouseUp(event:MouseEvent):void{
if (_downpoint == null)
return;
// new corner coords
_cx += int((event.stageX - _downpoint.x));
_cy += int((event.stageY - _downpoint.y));
resetListeners();
}
private function onReleaseOutside(event:MouseEvent):void{
// put it back where it was
resetListeners();
}
private function resetListeners():void{
scrollyThingy.x = _cx;
scrollyThingy.y = _cy;
Loader.scrollRect = scrollyThingy;
_downpoint = null;
if(!map.hasEventListener(MouseEvent.MOUSE_DOWN)
map.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
//(if it has one, it has them all!)
if(map.hasEventListener(MouseEvent.MOUSE_DRAG){
map.removeEventListener(MouseEvent.MOUSE_DRAG, onMouseDrag);
map.removeEventListener(MouseEvent.MOUSE_UP, onMouseUp);
map.removeEventListener(MouseEvent.RELEASE_OUTSIDE , onReleaseOutside);
}
}
if you still want a ScrollBar, just scale it to your Loader dimensions less the
size of the viewport (xScrollBar.maximum = loader.content.width - scrollyThingy.width,
yScrollbar.maximum = loader.content.height - scrollyThingy.height) then you can use the
same listener for both bars:
function onScrollBarChange(e:event):void{
scrollyThingy.x = xScrollBar.value;
scrollyThingy.y = yScrollBar.value;
}
listen for a change Event and set the Loader.scrollRect.x and Loader.scrollRect.y
properties to the scrollBarx.value & scrollBary.value.
Note also that I did not include any value checking.
You should check the values before moving the scrollRect
to avoid rangeErrors
i.e. if (_cx > loader.width - loader.scrollRect.width)
_cx = Loader.width - Loader.scrollRect.width;
Below is the code of my slideshow, the problem I am having is that after 1st image that loads has the perfect size which I needs but the second image loads has different size I want it to be of same size as of 1st one. Also the images are not loading in a sequence. Can any expert figure out and solve the problem.
stop();
import gs.*;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.events.Event;
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
//hides the description box until the image is loaded
//hides the image until it is loaded
theImage.alpha=0;
loadingBar.visible = false;
//variables to hold the final coordinates of the image tween
var finalX:Number;
var finalY:Number;
//variable to hold the number of images in the XML
var listLength:Number;
//keeps track of what image should be displayed
var currPainting:Number=0;
//arrays to hold the contents of the XML, using this to allow
//for the random order of the images
var imageArray:Array = new Array();
//Loader event for the XML
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onLoaded);
var xml:XML;
loader.load(new URLRequest("paintings.xml"));
function onLoaded(e:Event):void {
//load XML
xml=new XML(e.target.data);
var il:XMLList=xml.images;
listLength=il.length();
populateArray();
}
function populateArray():void {
//takes the properties defined in the XML and stores them
//into arrays
var i:Number;
for (i = 0; i < listLength; i++) {
imageArray[i]=xml.images[i].pic;
}
beginImage();
}
function beginImage():void {
//grabs a random number between 0 and the number
//of images in the array
currPainting=Math.floor(Math.random()*imageArray.length);
//load description
var imageLoader = new Loader();
//catches errors if the loader cannot find the URL path
imageLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, catchFunction);
//actually loads the URL defined in the image array
imageLoader.load(new URLRequest(imageArray[currPainting]));
//adds a listener for while the image is loading
imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, imgLoading);
//adds a listener for what to do when the image is done loading
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imgLoaded);
function catchFunction(e:IOErrorEvent) {
trace("Bad URL: " + imageArray[currPainting] + " does not exist");
//take out the bad URL from the array
imageArray.splice(currPainting,1);
//check to see if there are images left,
//else restart the slideshow
if (imageArray.length==0) {
populateArray();
} else {
beginImage();
}
}
function imgLoading(event:ProgressEvent):void{
//show the loading bar, and update the width
//based on how much is loaded
loadingBar.visible = true;
loadingBar.x = stage.stageWidth/2;
loadingBar.y = stage.stageHeight/3
loadingBar.bar.width = (event.bytesLoaded/event.bytesTotal)*100;
}
function imgLoaded(event:Event):void {
loadingBar.visible = false;
var scale:Number = stage.stageWidth * 0.292708 / theImage.width;
//add the image and get the dimensions to center the image
theImage.addChild(imageLoader);
theImage.x = stage.stageWidth/2.85;
theImage.y = 0;
if(theImage.height * scale > stage.stageHeight){
scale = stage.stageHeight * 0.704918 / theImage.height;
}
// apply the scale to the image
theImage.scaleX = theImage.scaleY = scale;
//take the contents of the loaded image and cast it as bitmap data
//to allow for bitmap smoothing
var image:Bitmap = imageLoader.content as Bitmap;
image.smoothing=true;
//start tween function
easeIn();
}
}
function easeIn():void {
TweenLite.to(theImage, 8, {onComplete:hideStuff});
TweenLite.to(theImage, 1, {alpha:1, overwrite:0});
}
function hideStuff():void {
TweenLite.to(theImage, 1, {alpha:0, onComplete:nextImage});
}
function nextImage():void {
//take out the image that was just displayed
imageArray.splice(currPainting,1);
//remove the picture
theImage.removeChildAt(0);
//start over
if (imageArray.length==0) {
populateArray();
} else {
beginImage();
}
}
Here is the xml
<xml>
<images><pic>portfolio1.jpg</pic></images>
<images><pic>portfolio2.jpg</pic></images>
<images><pic>portfolio3.jpg</pic></images>
<images><pic>portfolio4.jpg</pic></images>
<images><pic>portfolio5.jpg</pic></images>
</xml>
I don't think theImage's height represents image height after loading. That should be available with loader. To accommodate for different sized images, you'd have to bring actual height/width of image while applying scale. Else, of course, you can pre-resize all the images to same size.
About random loading, that's exactly what
currPainting=Math.floor(Math.random()*imageArray.length);
in beginImage is doing. To have the loading done in order, you can pick up 0th element directly.
This is a script for when i click an object, it opens a small book with some page flip effect.
I'm done with almost everything but i want that when i click in a back button everything desapears and i go back to only seeing the original object. It is not working because its only deleting one of the pages! I tried doing an array but it didnt work either and Im not very good with arrays too. Can anyone help?
import fl.transitions.Tween;
import fl.transitions.easing.*;
import fl.transitions.TweenEvent;
import flash.display.Sprite;
import flash.display.Loader;
var cont : DisplayObject;
var cont2 : DisplayObject;
var imgLoader : Loader;
//loads pages
for (var i:int=0; i<=4; i++){
imgLoader = new Loader();
imgLoader.contentLoaderInfo.addEventListener(Event.INIT, onLoadJPEG);
imgLoader.load(new URLRequest(""+i+".png"));
}
var imgLoader2 : Loader;
//loads back button
imgLoader2 = new Loader();
imgLoader2.contentLoaderInfo.addEventListener(Event.INIT, onLoadSketch);
imgLoader2.load(new URLRequest("voltaatrassketchbook.png"));
function onLoadJPEG (e : Event) : void {
cont = e.target.loader;
cont.x =250;
cont.y =50;
cont.width = (445-100)/2;
cont.height = (604-100)/2;
addChild(cont);
cont.addEventListener(MouseEvent.MOUSE_UP, FlipPage);
}
function onLoadSketch (e : Event) : void {
cont2 = e.target.loader;
cont2.x =450;
cont2.y =300;
cont2.width = 181/2;
cont2.height = 127/2;
addChild(cont2);
cont2.addEventListener(MouseEvent.MOUSE_UP, volta);
}
function FlipPage(e:MouseEvent):void{
setChildIndex(DisplayObject(e.currentTarget), this.numChildren - 1);
if (e.currentTarget.rotationY == 0) {
var myTween:Tween = new Tween(e.currentTarget, "rotationY",
Regular.easeInOut,0, 180, 1, true);
}
if (e.currentTarget.rotationY == 180) {
var myTween:Tween = new Tween(e.currentTarget, "rotationY",
Regular.easeInOut, 180, 0, 1, true);
}
}
//function to go back
function volta (e: MouseEvent): void {
gotoAndStop(1);
cont.visible=false;
cont2.visible=false;
}
Option 1
You are right that you could use an array. Put this at the top of your code, before you start loading the pages:
var pages:Array = [];
Then put this as the final line inside onLoadJPEG()
pages.push(cont);
That will add each image to the array when it is loaded.
Then in volta() you can loop through the array and make each image invisible
for(var i:int = 0; i < pages.length; i++) {
DisplayObject(pages[i]).visible = false;
}
Option 2
Another approach would be to add all the images to a container Sprite and then all you would have to do is make the container Sprite invisible.
Add this to the top of your code before you load the pages :
var pages:Sprite = new Sprite();
addChild(pages);
Then in onLoadJPEG() add cont as a child of the container
pages.addChild(cont);
Then in volta() :
pages.visible = false;
If you use this approach, don't forget to call setChildIndex() on the container inside of FlipPage() :
pages.setChildIndex(DisplayObject(e.currentTarget), this.numChildren - 1);
i actually try to do the following: I have loaded an external image in a bitmapdata object and create a bitmap from it which i attach it to a sprite/MovieClip in order to have mouse events on it. Now under the previous logic i loaded two images (let's say circles) of the same size one that has a particular color and is covered by its black foreground circle. When i press left mouse button and hold it down i want while the mouse is moved to erase the foreground circle's pixels and so the background image starting to appear. I tried this to achieve but had no luck. In my best attempt i achieve to draw a line in the foreground image but i cannot reveal the background!
package
{
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.display.BlendMode;
public class Test2 extends MovieClip
{
// properties - state
// to attach the image and have mouse events
private var frontImage:Sprite;
private var backImage:Sprite;
// to load the image
private var myLoader:Loader;
// to get the bitmap data of the image
private var frontBitmapData:BitmapData;
private var frontBitmap:Bitmap;
// test
private var frontMask:Bitmap;
// constructor
function Test2():void
{
// load the background image
backImage = new Sprite();
attachImageToSprite1(new URLRequest("btest.jpg"));
backImage.mouseEnabled = false;
this.addChild( backImage );
// load the front image
frontImage = new Sprite();
attachImageToSprite2(new URLRequest("test.jpg"));
frontImage.mouseEnabled = true; // enable mouse
frontImage.buttonMode = true; // set button mode
this.addChild(frontImage); // load to stage
this.frontImage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);
this.frontImage.addEventListener(MouseEvent.MOUSE_UP, onMouseUp);
}
// methods
private function attachImageToSprite1(Name:URLRequest):void
{
this.myLoader = new Loader();
this.myLoader.load(Name);
this.myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete1);
}
private function attachImageToSprite2(Name:URLRequest):void
{
this.myLoader = new Loader();
this.myLoader.load(Name);
this.myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoadComplete2);
}
private function getImageBitmapDataFromSprite(srcImage:Sprite):BitmapData
{
var tmpBitmapData:BitmapData = new BitmapData(frontImage.width, frontImage.height, true, 0xFFCCCCCC);
tmpBitmapData.lock();
tmpBitmapData.draw(frontImage);
tmpBitmapData.unlock();
return tmpBitmapData;
}
private function isPixelAlpha(bitmapdata:BitmapData):Boolean
{
var pixelValue:uint = bitmapdata.getPixel32(mouseX, mouseY);
var alphaValue:uint = pixelValue >> 24 & 0xFF;
//var red:uint = pixelValue >> 16 & 0xFF;
//var green:uint = pixelValue >> 8 & 0xFF;
//var blue:uint = pixelValue & 0xFF;
return (alphaValue == 0x00) ? true : false;
}
private function deletePixelUnderMouse(bitmapdata:BitmapData, bitmap:Bitmap):void
{
bitmapdata.lock();
if ( !isPixelAlpha(bitmapdata) ) {
bitmapdata.setPixel32(mouseX, mouseY, 0xFF << 24); // how to make the current pixel's alpha
} // equal to zero.
bitmap = new Bitmap(bitmapdata);
bitmap.x = frontImage.x;
bitmap.y = frontImage.y;
this.frontImage.addChild(bitmap);
bitmapdata.unlock();
}
// events
public function onLoadComplete1(e:Event):void
{
frontImage.addChild(this.myLoader.content);
}
public function onLoadComplete2(e:Event):void
{
backImage.addChild(this.myLoader.content);
}
public function onMouseDown(e:MouseEvent):void
{
// delete a pixel from the sprite under the mouse
frontBitmapData = getImageBitmapDataFromSprite(frontImage);
deletePixelUnderMouse(frontBitmapData, frontBitmap);
frontImage.addEventListener(MouseEvent.MOUSE_MOVE, onMouseDown);
trace("start");
}
public function onMouseUp(e:MouseEvent):void
{
frontImage.removeEventListener(MouseEvent.MOUSE_MOVE, onMouseDown);
trace("stop")
}
}
}
Not sure if I got it right, but if you want a 'reveal' effect, as in you draw a mask to display a hidden image for example, this could be achieved slightly easier:
var bitmapToReveal:BitmapData = new BitmapToReveal(0,0);
var brush:BitmapData = new Brush(0,0);
var canvasData:BitmapData = new BitmapData(bitmapToReveal.width,bitmapToReveal.height,true,0x00FFFFFF);
var cursor:Point = new Point();//used as destination point when painting
var zero:Point = new Point();//reused for painting
var reveal:Bitmap = new Bitmap(bitmapToReveal);
var canvas:Bitmap = new Bitmap(canvasData);
reveal.cacheAsBitmap = canvas.cacheAsBitmap = true;
addChild(reveal);
addChild(canvas);
reveal.mask = canvas;
stage.addEventListener(MouseEvent.MOUSE_DOWN, brushDown);
stage.addEventListener(MouseEvent.MOUSE_UP, brushUp);
function brushDown(event:MouseEvent):void {
this.addEventListener(Event.ENTER_FRAME, paint);
}
function brushUp(event:MouseEvent):void {
this.removeEventListener(Event.ENTER_FRAME, paint);
}
function paint(event:Event):void {
cursor.x = mouseX-brush.width*.5;
cursor.y = mouseY-brush.height*.5;
canvasData.copyPixels(brush,brush.rect,cursor,brush,zero,true);
}
I'm using two Bitmaps form the library(bitmapToReveal and brush).
The main thing to look at is the copyPixels() method. I copy
the brush bitmap into the canvas(an empty transparent bitmap data),
using the offset cursor position(so the brush centered), and using the
alpha channel to do that. Note that I've set cacheAsBitmap to true
for both mask and maskee. You need to do that to get a transparent mask,
which is key to the effect.
Here is the result:
You can 'paint' the mask here. CS4 Source is here.
HTH,
George
The preloader does not show up after 3% like it should have, it shows up when the file has loaded entirely.
Can someone help explain to me what I am doing wrong? My code is in the first frame, and it makes use of a rectangle object, and a textfield object. In other preloaders I have seen with code like this, it uses a movieclip with 100 frames. Does that make the difference? I have code updating the width of the rectangle, and something to update the text in the dynamic textbox as well.
My entire code in the first frame:
import flash.display.MovieClip;
import flash.events.ProgressEvent;
function update(e:ProgressEvent):void {
//trace(e.bytesLoaded);
if (loader) {
loader.text = Math.round(e.bytesLoaded*100/e.bytesTotal).toString() + " %";
}
if (bar) {
bar.width = Math.round(e.bytesLoaded*100/e.bytesTotal)*2;
}
}
loaderInfo.addEventListener(ProgressEvent.PROGRESS, update);
var loader:TextField = new TextField();
var bar:preloader_bar = new preloader_bar();
addEventListener(Event.ENTER_FRAME, checkFrame);
var loaderTextFormat:TextFormat = new TextFormat("_sans", 16, 0x000000, true);
loaderTextFormat.align = TextFormatAlign.CENTER;
loader.defaultTextFormat = loaderTextFormat;
bar.color = 0x000000;
addChild(bar);
addChild(loader);
// Extra test for IE
var percent:Number = Math.floor( (this.loaderInfo.bytesLoaded*100)/this.loaderInfo.bytesTotal );
if (percent == 100) {
nextFrame();
}
stop();
if (loader) {
loader.x = (stage.stageWidth - loader.width) / 2;
loader.y = stage.stageHeight / 2;
}
if (bar) {
bar.x = (stage.stageWidth - 200) / 2;
bar.y = (stage.stageHeight - bar.height) / 2;
}
function checkFrame(e:Event):void {
if (currentFrame == totalFrames) {
removeEventListener(Event.ENTER_FRAME, checkFrame);
startup();
}
}
function startup():void {
// hide loader
stop();
loaderInfo.removeEventListener(ProgressEvent.PROGRESS, update);
var mainClass:Class = Main as Class;
addChild(new mainClass() as DisplayObject);
}
It really should be showing up, is there some fancy export option I need to change? I tried this with the bandwidth profiler, it only shows anything after the 100% mark.
EDIT: progress_bar is a movieclip which was exported for actionscript.
You problem seem very similar to this.
Short version: Do you have a single frame ?
If so, move as much as you can on the 2nd frame and also
set that as the Export Frame for actionscript.
Once your first frame has a small size, you will see the preloader easily.
HTH,
George