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

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

Related

Dashed Line SVG Animation

I'm newer to working with SVG animations so I apologize in advanced if there is a straightforward answer to this. With a combination of utilizing Scrollmajic.js and GASP I was able to get the SVG to animate when the user scrolls to a specific position. The issue i'm running into is that the animation converts it from a dashed line to a solid stroke. I've done some research and found that using a mask would be the best way to accomplish this though I'm a bit lost on how to approach this method.
https://codepen.io/ncanarelli/pen/wvaeLNa
js:
$(document).ready(function() {
function pathPrepare ($el) {
var lineLength = $el[0].getTotalLength();
$el.css("stroke-dasharray", lineLength);
$el.css("stroke-dashoffset", lineLength);
}
// init controller
var controller = new ScrollMagic.Controller();
// loop through all elements
$(".svg-animation").each(function() {
var $thePath = $(this).find("path#thePath");
// prepare SVG
pathPrepare($thePath);
// build tween
var tween = new TimelineMax()
.add(TweenMax.to($thePath, 1, {
strokeDashoffset: 0,
ease:Linear.easeNone
}))
// build scene
var scene = new ScrollMagic.Scene({
triggerElement: $(this)[0],
duration: 200,
tweenChanges: true,
reverse: true
})
.setTween(tween)
.addTo(controller)
.addIndicators();
});
});
UPDATE: Updated .js to reflect an .each loop + other modifications. Still having issues with implementing a mask.

Ext js event fired or called after renderer

I have a grid column which uses the renderer function. Are the any events fired or called after this? I have tried several ones but they all get called on the whole column and they all fire before the renderer (even event afterrender)
thanks in advance
afterrender only fires once when the column is laid out on the page. It is a basic ExtJS component event that almost all ExtJS components have and doesn't relate to the renderer function used for grid columns.
Not totally sure what you're trying to do this for... but if I wanted to trigger an event whenever my renderer function was executed I would fire a custom event from the renderer function itself. Something like this:
Ext.create('Ext.grid.Panel', {
title: 'After Renderer Event Demo',
store: Ext.getStore('DummyData'),
columns: [{
text: 'Column 1',
dataIndex:'aNumber',
// dummy renderer function that fires an event after execution
renderer: function(value) {
// wrapping in a deferred function so that it fires AFTER
Ext.defer(function() {
this.fireEventArgs('aftercolumnrenderer', arguments);
}, 10);
if (value === 1) {
return '1 person';
}
return value + ' people';
}
}, {
text: 'Column 2',
dataIndex:'aString'
}],
width: 400,
forceFit: true,
renderTo: Ext.getBody()
});
I could listen for it directly with:
myColumn.on('aftercolumnrenderer', function(value, metaData, record, rowIndex, colIndex, store, view) {
// do stuff
});
Or from within a controller's control function if you're using ExtJS MVC.
Also see fireEventArgs and the on method for reference.

Do not fire 'zoom_changed' event when calling fitBounds function on map

Is there a way to prevent the zoom_change event from being triggered if it occurs due to fitBounds() ?
I am having an issue where I need to do a search on the server from client when there is a zoom change to map but every time I call fitBounds() it causes zoom_change to trigger which causes the client to do another search on the server. I am only interested in zoom_change done by users and not programmatically using fitBounds.
When you do a fitBounds in your program, set a global flag. When the zoom_changed event fires, if the flag is set, clear it, otherwise send your request off to the server.
After many frustrating hours, here is my solution:
var tiles_listener = google.maps.event.addListenerOnce(map, 'tilesloaded', function() {
var zoom_listener = google.maps.event.addListener(map, 'zoom_changed', function() {
reloadMarkers();
});
});
Note that I am calling addListenerOnce for tilesloaded to ensure that the zoome_changed listener is only added once, after the first fitBounds completes.
It's an old question, but it may be useful to others. I had the same problem, zoom_changed been triggered every time I called fitBounds() when adding several markers to a map. What I did was to add the listener to the map_changed event after the map was completely loaded, like this:
google.maps.event.addListener(map, 'tilesloaded', function() {
google.maps.event.addListener(map, 'zoom_changed', function() {
There is another way to do that by removing that that event. I think it would be much easier and cleaner than adding a global variable.
vm.map.events.bounds_changed = function() {
google.map.event.removeListener(zoom_changed);
}
Another way (forgotten to add that):
vm.map.events.bounds_changed = function() {
google.map.event.addEventListener(zoom_changed,function(mapper,eventName,args){});
}
In my app, I may fire off zoom change events programmatically, either via setZoom(), fitBounds(), or setOptions().
MAN = {};
MAN.globalMap = google.maps.Map(document.getElementById('map'));
I then route all programmatic calls to set the zoom through wrapper functions that flip a flag to false before they go on to set the zoom.
MAN.savedZoom = MAN.globalMap.getZoom();
MAN.saveZoomFlag = true;
// we want it to always be true, unless zoom was
// changed programatically.
MAN.setZoom = function setZoom(zoomLevel) {
console.log("won't save that I'm setting zoomLevel to " + zoomLevel);
this.saveZoomFlag = false;
MAN.globalMap.setZoom(zoomLevel);
};
MAN.fitBounds = function fitBounds(bounds) {
console.log("setting bounds, won't save zoomlevel.");
this.saveZoomFlag = false;
MAN.globalMap.fitBounds(bounds);
};
MAN.setOptions = function setOptions(options) {
console.log("setting options, won't save zoomlevel.");
this.saveZoomFlag = false;
MAN.globalMap.setOptions(options);
};
I then declare a listeners. At first I was declaring only the first, and was puzzled that it wasn't working:
google.maps.event.addListener(
MAN.globalMap,
'zoom_changed',
function zoom_changed_listener() {
console.log(
"zoom changed to " +
MAN.globalMap.getZoom() + "; " +
(MAN.saveZoomFlag ? "saving." : "not saving.")
);
if (MAN.saveZoomFlag) {
console.trace("saving");
MAN.savedZoom = MAN.globalMap.getZoom();
}
MAN.saveZoomFlag = true;
}
);
you may also find the idle event helpful, however, if you're just trying to avoid the initial set. See more about the maps events here: https://developers.google.com/maps/documentation/javascript/events
I suppose this should be simple. Have a variable say
var z = map.getZoom(); //scope this variable appropriately(somewhere before you call the fitbounds()
and then after the map.fitbounds() immediately do
map.setZoom(z); //this automatically changes the zoom level back to the previous level

delay or setInterval in mootools

Good morning,
I have a problem with mootools, and I make an alpha effect from 0 to 100 but I would like to make a delay before loading the next effect.
code is as follows:
<script type="text/javascript">
var miEfecto1 = new Fx.Style('texto42' ,'opacity',{duration: 9000,onComplete: function(){setInterval(miEfecto2.start(1,0) , 15000 );}});
var miEfecto2 = new Fx.Style('texto14' ,'opacity',{duration: 9000,onComplete: function(){setInterval(miEfecto3.start(1,0) , 15000 );}});
...etc...
var miEfecto59 = new Fx.Style('texto45' ,'opacity',{duration: 9000,onComplete: function(){setInterval(miEfecto60.start(1,0) , 15000 );}});
var miEfecto60 = new Fx.Style('texto39' ,'opacity',{duration: 9000,onComplete: function(){setInterval(miEfecto61.start(1,0) , 15000 );}});
window.addEvent('domready',function() {
miEfecto1.start(1,0);});
</script>
thank you very much for your help!
setInterval sets interval for some function you pass as the first parameter, where setTimeout just delays the execution. Use the latter to avoid multiple execution.
Also in your code you immediately execute start() method (eg. miEfecto2.start(1,0)), because you do not pass it - you pass its result. To fix this you can enclose it in an anonymous function (but do not call it).
The example code could look like this (notice setInterval being replaced by setTimeout and that I enclosed the function call in anonymous function):
var miEfecto1 = new Fx.Style('texto42', 'opacity', {
duration: 9000,
onComplete: function(){
setTimeout(function(){
miEfecto2.start(1,0);
}, 15000);
}
});
Make similar changes in the rest of your code.
what you need to do is to chain the effects and set the delay to whatever you need..
check this example : http://demos111.mootools.net/Chain
or check the doc : http://mootools.net/docs/core/Class/Class.Extras
Hope this helps
THE SOLUTION:
var miEfecto_i1 = new Fx.Style('texto19', 'opacity', {
duration: 1000,
onComplete: function(){
setTimeout(function(){
miEfecto_o1.start(1,0);
}, 10000);
}
});
var miEfecto_o1 = new Fx.Style('texto19', 'opacity', {
duration: 1000,
onComplete: function(){
miEfecto_i2.start(0,1);
}
});
THANKS!!

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.