How could I queue KineticJS transitions? - queue

I want to queue some kineticJS transitions with variable duration, for example:
scrub.transitionTo({
x:400,
duration: 4,
callback: function() {
console.log('complete 400');
scrub.transitionTo({
x:500,
duration: 1,
callback: function() {
console.log('complete 100');
}
});
}
});
These are just two nested transitions of the same object, but I want to automate this procedure for 10 or more nested callbacks.

You can create a new object and place your transition data in it.
var transition1 = {
x:400,
duration: 4,
callback: function(){
console.log('complete 400');
....
}
};
var transition2 = {
x:500,
duration: 1,
callback: function() {
console.log('complete 100');
}
};
Then you can just create a while loop to call the transitions without a need for a callback.
But since you do want a callback, you need to create a function which the callback will call and a condition will be checked.
function callFunction(scrub, numberOfExecutions){
if(condition == myCondition){
scrub.transitionTo(transition1);
numberOfExecutions--;
}
else if(condition2 == myCondition2){
scrub.transitionTo(transition2);
numberOfExecutions--;
}
if(numberOfExecutions < 1) return 0;
else return 0;
};
As a note, it's not wise to do these nested recursive calls as some browsers will automatically think the scripts are stuck in an infinite loop and won't execute.

Related

how can you use oncanplaythrough after a setimeout?

i assume this doesn't work because canplaythrough is fired too early?
function splasher() {
showDelay = setTimeout(vidCheck, 6000);
};
function vidCheck() {
vid.addEventListener("canplaythrough", showPage);
};

Drag and Drop Sortable

I just want to know where can I place some function in my drag and drop. I tried using alert messages to know where the event takes place but it's not executing any of my alert boxes. I put alert boxes in comment, those are places i used to place it but nothing happens. My drag and drop works but it cant fire alert box. I dont know what is wrong. Help me. Thanks.
var adjustment;
$(function () {
$("#container1, #container2").sortable({
group: 'ol.simple_with_animation',
pullPlaceholder: false,
onDragStart: function ($item, container, _super) {
var offset = $item.offset(),
pointer = container.rootGroup.pointer;
adjustment = {
left: pointer.left - offset.left,
top: pointer.top - offset.top
};
_super($item, container);
},
onDrag: function ($item, position) {
$item.css({
left: position.left - adjustment.left,
top: position.top - adjustment.top
});
// alert('oink');
},
onDrop: function ($item, container, _super) {
var $clonedItem = $('<li/>').css({ height: 0 });
$item.before($clonedItem);
$clonedItem.animate({ 'height': $item.height() });
// alert('wew');
$item.animate($clonedItem.position(), function () {
$clonedItem.detach();
_super($item, container);
// alert('oink');
});
// alert('oink');
},
});
//alert('oink');
});
This works perfect to me. Hope it will help those who struggle too :)
$("#container1, #container2").sortable(
{
group: 'ol.simple_with_animation',
onDrop: function ($item, container, _super) {
var $clonedItem = $('<li/>').css({ height: 0 });
$item.before($clonedItem);
$clonedItem.animate({ 'height': $item.height() });
$item.animate($clonedItem.position(), function () {
$clonedItem.detach();
_super($item, container);
});
alert('oink');
}
});

W2ui grid Scroll

I want to scrollIntoView a record when the grid has been sort. This is what I'm using:
onSort: function(event) {
event.onComplete = function () {
w2ui.grid.scrollIntoView(10);
}
}
You need to delay the scrollIntoView()
https://jsfiddle.net/zxcgxkxa/1/
onSort: function(event) {
event.onComplete = function () {
setTimeout(function(){
w2ui.grid.scrollIntoView(10);
}, 10);
};
}
because after grid.sort() is executed, w2grid will internally execute grid.refresh(), which internally executes a delayed scrolling:
setTimeout(function () { // allow to render first
obj.resize(); // needed for horizontal scroll to show (do not remove)
obj.scroll();
}, 1);

SailsJS how to write non-async Model.CRUD functions?

I've a Parent and Child models in my app.
Parent.create receives parent_name and an array of children that I want to add to the Parent model, the following flow describes the function:
1) Create parent object
2) Create all children
3) Save parent with updated children array
The problem is that Parent.create is probably async, and the 'created_children' array when saved to parent is empty (because it doesn't wait until the Parent.create finishes.
How can I make Model.create dependent (or synchronic)?
See the code below (I commented the buggy part //BUG: EMPTY ARRAY!!!!!!!!!!):
create: function(req, res, next) {
var childrenInput = req.param('children');
var parentObj = {
name: req.param('parent_name')
};
Parent.create(parentObj, function parentCreated(err, parent) {
if (err) {
return res.redirect('/parent/new');
}
// assign children
var created_children = new Array();
for(var i=0; i < childrenInput.length; i++) {
var childObj = {
name: parentObj.childrenInput[i],
parent_id: parent.id
};
// create child
Child.create(childObj, function childCreated(err, child) {
if (err) {
for(var j=0; j < created_children.length; j++) {
Child.destroy(created_children[j].id, function childDestroyed(err) {
if (err)
{
// BIG ERROR
return next(err);
}
});
}
return res.redirect('/parent/new');
}
// add created child
created_children.push(child.id);
}) // end of Child.create;
} // end of for;
// save created children to parent
parent.children = created_children.slice();
parent.save(function(err, c) {
if (err)
{
// TODO: FUNCTION TO DESTROY ALL CHILDREN
return next(err);
}
});
return res.redirect('/parent/show/' + parent.id);
});
},
Parent model
module.exports = {
schema: true,
attributes: {
name: {
type: 'string',
required: true,
unique: true
},
children: {
type: 'array',
defaultsTo: []
}
}
};
Performing asynchronous operations on an array can be a real pain. I'd suggest using a module like async, which provides synchronous-like functionality for asynchronous code. You could then rewrite your code as:
Parent.create(parentObj, function parentCreated(err, parent) {
if (err) {
return res.redirect('/parent/new');
}
// You only really need this for error handling...
var created_children_ids = new Array();
// Create an array of child instances from the array of child data
async.map(
// Array to iterate over
childrenInput,
// Iterator function
function(childObj, callback) {
Child.create(childObj, function childCreated(err, child) {
if (err) {return callback(err);}
created_children_ids.push(child.id);
// 'null' indicates no error
return callback(null, child);
});
},
// Callback for when loop is finished.
// If any run of the iterator function resulted in the
// callback being called with an error, it will immediately
// exit the loop and call this function. Otherwise the function
// is called when the loop is finished, and "results" contains
// the result of the mapping operation
function (err, results) {
if (err) {return destroyChildren();}
// Save the children to the parent
parent.children = results;
parent.save(function(err, c) {
if (err) {return destroyChildren();}
return res.redirect('/parent/show/' + parent.id);
});
function destroyChildren(err) {
Child.destroy({id: created_children_ids}).exec(function() {
// Respond with an error
return res.serverError(err);
});
}
}
);
});
Note that if you're using Sails v0.10, you can use actual associations to bind the parent and child records, and use parent.children.add(childObj) (which is a synchronous operation) in a regular loop prior to calling parent.save(). Calling .add with an object will cause that model to be created during the save operation.

for loop not waiting for function to end

I have 5 links on a page and i have to check if all are links are working or not. Here is the code
// iterate through each link and check if ti works.
for(var i=0; i < 5; i++) {
var ifLinkWorks = verifyLinkWorks(links[i]);
if(ifLinkWorks){ OK }
else{ error }
}
This is verifyLinkWorks function. It opens a link. After it get opened, it checks if the page is loaded properly
function verifyLinkWorks(link) {
return winjs.Promise(function(complete) {
link.click();
// wait for page to load
return winjs.promise.timeout(4000).then(function () {
// check if page is loaded
var islinkOK = IsPageLoaded();
complete(islinkOK); // i want verifyLinkWorks to return this value
});
});
}
After reaching link.click(), it is not waiting for page to load. Instead it jumps to the if condtion in outer for loop (which makes linkWorks = undefined therefore,gives Error). How to make it wait in the verfifyLinkWorks function.
Thanks in advance...
You'll need to wait for the results of each promise, either all at once, or individually. As the actions are all async in nature, the code can't wait, but it can call a function when it completes all of the work.
Here, I've created an array which will hold each Promise instance. Once the loop has completed, the code waits for all to complete, and then using the array that is passed, checking the result at each index.
// iterate through each link and check if it works.
var verifyPromises = [];
for(var i=0; i < 5; i++) {
verifyPromises.push(verifyLinkWorks(links[i]));
}
WinJS.Promise.join(verifyPromise).done(function(results) {
for(var i=0; i < 5; i++) {
var ifLinkWorks = results[i];
if (ifLinkWorks) { /* OK */ }
else { /* error */ }
}
});
In case the link.click() call fails, I've wrapped it in a try/catch block:
function verifyLinkWorks(link) {
return WinJS.Promise(function(complete, error) {
try {
link.click();
} catch (e) {
complete(false); // or call the error callback ...
}
// wait for page to load, just wait .. no need to return anything
WinJS.Promise.timeout(4000).then(function () {
// check if page is loaded
var islinkOK = IsPageLoaded();
// finally, call the outer promise callback, complete
complete(islinkOK);
});
});
}
If you want to check the validity of a URL, I'd suggest you consider using WinJS.xhr method to perform a HEAD request instead (rfc). With each link variable, you can use a timeout to validate that there's a reasonable response at the URL, without downloading the full page (or switch to a GET and check the response body).
WinJS.Promise.timeout(4000,
WinJS.xhr({
type: 'HEAD',
url: link
}).then(function complete(result) {
var headers = result.getAllResponseHeaders();
}, function error(err) {
if (err['name'] === 'Canceled') {
}
if (err.statusText) {
}
})
);
Ok heres the link to the msdn code sample for win js promise object.
Promise winjs
now going through the code
<button id="start">StartAsync</button>
<div id="result" style="background-color: blue"></div>
<script type="text/javascript">
WinJS.Application.onready = function (ev) {
document.getElementById("start").addEventListener("click", onClicked, false);
};
function onClicked() {
addAsync(3, 4).then(
function complete(res) {
document.getElementById("result").textContent = "Complete";
},
function error(res) {
document.getElementById("result").textContent = "Error";
},
function progress(res) {
document.getElementById("result").textContent = "Progress";
})
}
function addAsync(l, r) {
return new WinJS.Promise(function (comp, err, prog) {
setTimeout(function () {
try {
var sum = l + r;
var i;
for (i = 1; i < 100; i++) {
prog(i);
}
comp(sum);
}
catch (e) {
err(e);
}
}, 1000);
});
}
</script>
you will see the addAsync(3,4).then() function. So all the code is to be kept inside that function in order to have a delayed response . Sorry m using a tab so cannot write it properly.
Also go through link then for winjs promise