GSAP/TweenLite/TweenMax onComplete not firing when using updateTo on onUpdate - actionscript-3

onComplete not firing when using updateTo on onUpdate. if I remove updateTo line onComplete is triggered as it should.
I am using latest update of GSAP.
private function fingerLoop():void
{
// Set the gotoPlanet var
TweenMax.to(finger, 1, { x:gotoPlanet.x, y:gotoPlanet.y, onComplete:fingerLoop, onUpdate:moveFinger, onUpdateParams:["{self}", gotoPlanet] });
}
private function moveFinger(tween, gotoPlanet):void
{
tween.updateTo({x:gotoPlanet.x, y:gotoPlanet.y}, false);
}

Perhaps you can add an onComplete handler to the updateTo() call, like this:
tween.updateTo({x:gotoPlanet.x, y:gotoPlanet.y, onComplete:fingerLoop}, false);

Related

D3.js brushend function not properly called

I made a module that draws a bar chart including a d3.svg.brush(). Part of my code is
Bar.prototype.init = function ( ) {
//...
this.brush = d3.svg.brush()
.y( this.y)
.on("brushend", this.brushend);
console.log(this.brushend); // works
}
Bar.prototype.brushend = function() {
console.log(this.brush); // undefined. why?
}
To access this.* values, I cannot make brushend function a normal function by using function brushend() or var brushend = function().
How should I call it properly?
D3 will call the event handler provided for its brushend event much like event handlers for normal DOM events will get called. For standard events this will reference the element the event occured upon. This rule does also apply to D3's brush event handlers where this references the group containing the DOM elements of the brush. Obviously, this group doesn't have a property brush you could reference by using this.brush from with the handler.
A workaround would be to save your reference by using a closure:
Bar.prototype.init = function ( ) {
//...
this.brush = d3.svg.brush()
.y(this.y)
.on("brushend", this.brushend()); // Get handler by calling factory
}
// A factory returning the handler function while saving 'this'.
Bar.prototype.brushend = function() {
var self = this; // Save a reference to the real 'this' when the factory is called.
return function() { // Return the handler itself.
// By referencing 'self' the function has access to the preserved
// value of 'this' when the handler is called later on.
console.log(self.brush);
};
}

Flash cs6 AS3 Error #2007: Parameter child must be non-null

I just implemented that last piece of code you sent over - many thanks!!
This is the FULL context of this frame, the complete code with the other buttons as well, in case that is causing the problem. The 19 errors I get with this piece of code is:
1120: Access of undefined property fl_ProLoader_01
stop();
//home button
mythbutt_home.addEventListener(MouseEvent.CLICK, fl_ClickToLoadUnloadSWF_01_1,false,0,true);
function fl_ClickToLoadUnloadSWF_01_1(event:MouseEvent):void
{
removeChild(fl_ProLoader_01);
fl_ProLoader_01.unloadAndStop();
fl_ProLoader_01 = null;
}
mythbutt_home.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame_01_1,false,0,true);
function fl_ClickToGoToAndStopAtFrame_01_1(event:MouseEvent):void
{
removeChild(fl_ProLoader_01);
}
mythbutt_home.addEventListener(MouseEvent.CLICK, fl_ClickToStopAllSounds_01_1,false,0,true);
function fl_ClickToStopAllSounds_01_1(event:MouseEvent):void
{
SoundMixer.stopAll();
}
mythbutt_home.addEventListener(MouseEvent.CLICK, fl_ClickToGoToAndStopAtFrame_01_2,false,0,true);
function fl_ClickToGoToAndStopAtFrame_01_2(event:MouseEvent):void
{
gotoAndStop(1);
}
//other buttons at the bottom
mythbutt_aboriginal_culture.addEventListener(MouseEvent.CLICK, fl_ClickToGoToWebPage_01_1);
function fl_ClickToGoToWebPage_01_1(event:MouseEvent):void
{
navigateToURL(new URLRequest("http://www.bigmyth.com/fullversion/password033/download/ABORIGINAL_CULTURE.pdf"), "_blank");
}
mythbutt_aboriginal_pantheon.addEventListener(MouseEvent.CLICK, fl_ClickToGoToWebPage_01_2);
function fl_ClickToGoToWebPage_01_2(event:MouseEvent):void
{
navigateToURL(new URLRequest("http://www.bigmyth.com/fullversion/password033/download/ABORIGINAL_PANTHEON.pdf"), "_blank");
}
mythbutt_aboriginal_exercises.addEventListener( MouseEvent.CLICK, fl_ClickToGoToWebPage_01_3);
function fl_ClickToGoToWebPage_01_3(event:MouseEvent):void
{
navigateToURL(new URLRequest( "http://www.bigmyth.com/fullversion/password033/download/ABORIGINAL_EXERCISES.pdf"), "_blank");
}
//start button
//Change your event handler function.
start_button_aboriginal.addEventListener(MouseEvent.CLICK,fl_ClickToLoadSWF_01_2);
function fl_ClickToLoadSWF_01_2(event:MouseEvent):void {
fl_ProLoader_01=new ProLoader ;
fl_ProLoader_01.load(new URLRequest("myths/myth_aboriginal.swf"));
fl_ProLoader_01.contentLoaderInfo.addEventListener(Event.COMPLETE,
//Using closure callback instead of *onComplete_1* function
function( e : Event ) {
e.currentTarget.content.addEventListener( Event.ENTER_FRAME, OEF_01);
});
addChild(fl_ProLoader_01);
fl_ProLoader_01.x=323;
fl_ProLoader_01.y=41;
//Swap the event handlers,no need for flag,clear code blocks
start_button_aboriginal.removeEventListener(MouseEvent.CLICK,fl_ClickToLoadSWF_01_2);
start_button_aboriginal.addEventListener(MouseEvent.CLICK,fl_ClickToUnLoadSWF_01_2);
}
function fl_ClickToUnLoadSWF_01_2(event:MouseEvent):void {
fl_ProLoader_01.removeEventListener(Event.ENTER_FRAME,OEF_01);
removeChild(fl_ProLoader_01);
fl_ProLoader_01.unloadAndStop();
fl_ProLoader_01=null;
start_button_aboriginal.removeEventListener(MouseEvent.CLICK,fl_ClickToUnLoadSWF_01_2);
}
function OEF_01(e:Event):void {
if (e.currentTarget.currentFrame==e.currentTarget.totalFrames) {
e.currentTarget.stop();
fl_ClickToUnLoadSWF_01_2(null);
}
}
I think #GarryWong is right. If you click the start button after the external swf has been loaded and before his timeline has finished you will get an error.
I've changed your implementation, please try this.
No need to check for null object.
UPDATE
//Change your event handler function.
startbutton.addEventListener(MouseEvent.CLICK,fl_ClickToLoadSWF_1_2);
function fl_ClickToLoadSWF_1_2(event:MouseEvent):void {
fl_ProLoader_1=new ProLoader();
fl_ProLoader_1.load(new URLRequest("myths/myth_aboriginal.swf"));
fl_ProLoader_1.contentLoaderInfo.addEventListener(Event.COMPLETE,
//Using closure callback instead of *onComplete_1* function
function( e : Event ) {
e.currentTarget.content.addEventListener(Event.ENTER_FRAME, OEF_1);
});
addChild(fl_ProLoader_1);
fl_ProLoader_1.x=207;
fl_ProLoader_1.y=41;
//Swap the event handlers,no need for flag,clear code blocks
startbutton.removeEventListener(MouseEvent.CLICK,fl_ClickToLoadSWF_1_2);
startbutton.addEventListener(MouseEvent.CLICK,fl_ClickToUnLoadSWF_1_2);
}
function fl_ClickToUnLoadSWF_1_2(event:MouseEvent):void {
fl_ProLoader_1.removeEventListener(Event.ENTER_FRAME,OEF_1);
removeChild(fl_ProLoader_1);
fl_ProLoader_1.unloadAndStop();
fl_ProLoader_1=null;
startbutton.removeEventListener(MouseEvent.CLICK,fl_ClickToUnLoadSWF_1_2);
//Use the below line only if you want to repeat the procedure of loading the *Proloader*, otherwise omit it.
startbutton.addEventListener(MouseEvent.CLICK,fl_ClickToLoadSWF_1_2);
}
function OEF_1(e:Event):void {
if (e.currentTarget.currentFrame==e.currentTarget.totalFrames) {
e.currentTarget.stop();
fl_ClickToUnLoadSWF_1_2(null);
}
}
Sorry but I haven't Flash installed in my PC right now so maybe there will be some mistakes in my code. You made me boot my Windows partition!

AS3 add callbacks for listeners

lately I've been asked to change a small flash app i made to work with external callbacks instead of using the embedded buttons.
I tried to automate the process and came up with this function:
/**
* Add an External callback for all PUBLIC methods that listen to 'listenerType' in 'listenersHolder'.
* #param listenersHolder - the class that holds the listeners we want to expose.
* #param listenerType - a String with the name of the event type we want to replace with the external callback.
*/
public static function addCallbacksForListeners(listenersHolder:*, listenerType:String):void
{
// get the holder description
var description:XML = describeType(listenersHolder);
// go over the methods
for each(var methodXML:XML in description..method)
{
// go over the methods parameters
for each(var parameterXML:XML in methodXML..parameter)
{
// look for the requested listener type
var parameterType:String = parameterXML.#type;
if (parameterType.indexOf(listenerType) > -1)
{
var methodName:String = methodXML.#name;
trace("Found: " + methodName);
// get the actual method
var method:Function = listenersHolder[methodName];
// add the callback
try
{
ExternalInterface.addCallback(methodName, method);
trace("A new callback was added for " + methodName);
}
catch (err:Error)
{
trace("Error adding callback for " + methodName);
trace(err.message);
}
}
}
}
before using this function I had to change the listener's function to Public, add null default parameter and of course remove/hide the visuals.
for example, from :
private function onB1Click(e:MouseEvent):void
to :
public function onB1Click(e:MouseEvent = null):void
add this line to the init/onAddedToStage function:
addCallbacksForListeners(this, "MouseEvent");
and remove the button from stage or just comment the line that adds it.
My question is: can you find a better/ more efficient way to do that ?
any feedback is welcomed..
Maybe you should make the javascript to call a single method with different functionName param. Then you only need to add one callback and you don't need to make all those functions public.
ExternalInterface.addCallback('callback', onCallback);
public function onCallback(res:Object)
{
var functionName:String = res.functionName;
this[functionName]();
}

mootools | overwrite propery of a tween without create new tween everytime

Is there a way to overwrite the property of a tween?
If I write
el.set('tween', {duration: ‘long’, onComplete: callback});
and then
el.set('tween', {duration: 200, onComplete: secondcallback });
I can’t replace the old property (callback is triggered again)
Is possible to solve this problem without the creation of a new Fx.Tween everytime?
Each time you set onComplete on the same instance, callbacks are pushed and associated with the same 'complete' event and each callback will be called after the event is fired.
To 'replace' the onComplete callback, you could use removeEvent, i.e.
el.set('tween', {duration: ‘long’, onComplete: callback});
//and then...
el.get('tween')
.removeEvent('complete', callback)
.addEvent('complete', secondcallback);
demo => http://jsfiddle.net/NNzQ7/
I would create two independent tweens and keep them around:
var fx1 = new Fx.Tween(element, {onComplete: callback});
var fx2 = new Fx.Tween(element, {onComplete: anothercallback});
And then you can use them individually:
fx1.start('background-color', 'cyan', 'red');
fx2.start('background-color', 'red', 'cyan');

in mootools: calling a function after all events on an element is finished

i have this element to which various change events are applied
how can i trigger my own function after all change events have occurred in mootools
a sample scenario is a drop down list
$('ddl').addEvent('change', function () {
// some ajax call going on here and which i can't affect
// as the page is generated that way
});
i now want to call my function right after the change event is done but adding another change event will not do as i believe the events are executed async
pass on a callback function through the onComplete of the ajax that you reference.
eg:
$("ddl").addEvents({
change: function() {
new Request({
method: "get",
url: "somefile.php",
onComplete: function() {
// run your next stuff from within here, referencing
// this.response.text or whatevever and call up another function.
}
}).send("action=checkuser&id="+this.get("value").trim());
}
});
there's also the Chain class - http://mootools.net/docs/core/Class/Class.Extras#Chain but as you have async stuff going on, you really need the onComplete on the Request.