JQuery animation does not work - animation

Well, I have an image which animates by moving to the left by 1000px. Once it stops, this image is replaced to another image. My code:
function image1() {
$('#photo').animate({left: '1000px'}, 40000, function() {
$('#photo').attr('src', 'image2.jpg');
setTimeout(image1, "2000")
});
}
The image doe move, but when it stops, it does not change.. :(

Try this:
setTimeout(image1, 2000)
instead of this
setTimeout(image1, "2000")

To start, the second argument to setTimeout should be a number (less than 2^31), not a string.
setTimeout(image1, 2000);

Use $(this) instead of repeating the selector.

Related

SVG performance drop when animating 2 or more elements, RaphaelJS

I am testing SVG performance using RaphaelJS library.
My code works, can be found here: JSFiddle
When you type in textbox "1" and press "add", a rectangle will be generated on screen and 4 animations will loop on it- moving right, down, left, up (also rotating, scaling and changing colour).
Performance seems to be ok. But add another element on stage and the performance gets knocked down to minimum in 3-4 seconds. Checked in Chrome timeline, the thing that is getting stacked up is "Animation Frame Fired - > Install Timer".
Perhaps I am doing loop incorrectly? Altough next animation starts when the previous ends, through callback function. Or is it Raphael itself? Should I try doing this with SVG and SMIL? (Raphael uses VML)
Any ideas?
------------------------------------UPDATE--------------------------------------
With RaphaelJS I did bad animation loop hooks, see answer below.
But another problem that does occur - add 1 element 10 times and you can see how animations get distorted, not finishing their full cycle, or add 10 elements 1 time and after few seconds you can see delayed animations on some of the elements.
I made SMIL version JSFiddle (no Raphael here), animations do not lag, delay, but they get syncronized. Can anyone explain why? And how to make those animations NOT sync, but unique?
I think the problem is you are recursively calling animations on a set.
So at the end of each animation, each element in the set calls an animation for the set again, so it spirals and grinds to a halt. You can get around this, by using 'this' instead of the set 'rectangles'.
//define 4 animations
var move_up = Raphael.animation({fill: "green", transform: "t0,0r360s1,1"}, 400, function(){ this.attr({"transform" : "t0,0"}); this.animate(move_right); });
var move_left = Raphael.animation({fill: "yellow", transform: "t0,100r270s0.5,0.5"}, 400, function(){ this.animate(move_up); });
var move_down = Raphael.animation({fill: "red", transform: "t100,100r180s1,1"}, 400, function(){ this.animate(move_left); });
var move_right = Raphael.animation({fill: "blue", transform: "t100,0r90s1.5,1.5"}, 400, function(){this.animate(move_down); });
jsfiddle

dojo animation on interrupt?

Is there an equivalent of an 'on interrupt' function when using dojo.fx animations?
On my site, I clear an area by sliding the div off the screen to the left and then clearing the innerHTML. So that the div is available for future use in the same place, I set its final position to be equal to its original position (though it's empty and invisible, so the user doesn't see). I do this by referencing the position when the function is fired to avoid hard coding the position in.
function clear (node) {
// get the current position
var position = domGeom.position (node, true);
// slide the calendar off the screen
var anim = dojo.fx.slideTo ({
node: node,
left: -2000,
unit: "px"
});
// attach on onEnd function
dojo.connect (anim, "onEnd", function (n1, n2) {
node.innerHTML = "";
// Reset the node's position
domStyle.set (node, "left", position.x + "px");
});
anim.play();
}
The problem is that if the user clicks 'clear' while the function is in progress, for example if they accidentally double click, then the 'position' variable takes the value of the node mid-animation. If I later put some content in the node, it's in the wrong place, or sometimes completely off screen.
What I was thinking of doing was adding a listener to the animation so that if it was ever interrupted, it would stop the animation and instead execute the 'onEnd' function immediately, so that the second clear function would have the correct position variable.
Unfortunately, I can't find such a listener; could anyone point me in the right direction, or suggest an alternative solution?
You might be interrupting the flow of events in your page, but you're not really 'interrupting' in Animation terms: there's no way an Animation could give you an event to tell you that Clear has been pressed, I'm afraid.
If you want the animation to be stopped when the user presses Clear, you'll have to stop the animation manually when the user presses Clear: Dojo can't automatically detect there's any link between the two things, and indeed there may well be other animations that you want to continue even if the user does press Clear.
So, you'll probably be looking to call .stop on the animation when appropriate.

Resize last column in jqgrid

There seems to be a bug in jqgrid, where one can not resize the last column.
This seems to be a quite old issue raised in 2009. I had a look and the latest jqGrid sample seems to have this issue...
What I found however was that last column can be dragged to resize the grid itself.
See here Go to section what is new in 3.6.
Any pointers if this is already fixed.
Seems I found a solution.
Resizing of the last column can be done only within the area of the header wrapper (div.ui-jqgrid-hbox). In the outer space resizing process losing focus.
Because of existing some padding-right area with default 20 pixels, increasing the size can be done in this small part only.
In addition, we need to temporarily cancel table wrapper influence, because he also cause to stop resizing process.
Here is my solution. I assume, that your table wrapper id is gbox_DataTable_u:
1:
CSS: define new wide padding-right area:
.ui-jqgrid .ui-jqgrid-hbox {float: left; padding-right: 10000px;}
2:
Append 2 events to your grid:
resizeStart:function(event, index){ $('#gbox_DataTable_u').width($('#gbox_DataTable_u').outerWidth() + 10000);}
resizeStop: function(width, index) {$('#gbox_DataTable_u').width($('#DataTable_u').outerWidth());}
Example of working table: http://www.design.atplogic.co.il/aman/philips/users.htm#
I found that the best way is to add an empty unresizable column in the end of the grid.
I'm just doing it manually, by extending the colModel right before the execution of jqgrid constructor. Only problem being - I wasn't able to make it not draggable so far.
Here's an example:
colModel.push({align: "left", editable: false, hidden: false, index: "ghostCol", label: " ", name: "ghostCol", resizable: false, sortable: false, type: "text", width: 50});
Hope this helps.
It is resizing fine for me as well, although you have to resize from the right on the "RTL Support" example, which seems to make sense.
Also be aware that if you are using Chrome, there is a jqGrid bug that causes horizontal scroll bars to appear - see jqgrid-does-not-render-correctly-in-chrome-chrome-frame. This issue has since been resolved, but the demo page has not been updated yet. And it certainly gives the appearance of the last column's resizing not working because you have to scroll all the way over to the right before you can resize the last column.
I have tried to resize the last column with resizeStop, i do some trick like the other guy said. hope it help.
resizeStop(width, index) { var amGrid = $("#jsonmap"), colModel =
$("#jsonmap").jqGrid('getGridParam','colModel'); var oW =
$oldWidths[index]; var cW = colModel[index+1].width+
downCalSize(oW,width); $oldWidths[index+1] = cW; $oldWidths[index] =
width;
$('.ui-jqgrid-labels > th:eq('+(index+1)+')').css('width',cW);
$('#jsonmap .jqgfirstrow > td:eq('+(index+1)+')').css('width',cW);
var w = amGrid.jqGrid('getGridParam', 'width');
$('.ui-jqgrid-htable').css("width",w);
$('.ui-jqgrid-btable').css("width",w); }
i still looking for a common way, can do on more tables in one page and don't affect to each other.
After 2 days of struggling...I finally found a way to work around.
It seems that jqGrid calculates the resizing object in the dragMove event, where it uses passed event object to get the position of mouse and calculates the new width of resizing column. However when dragging exceeds the grid's boundry, the dragMove event stop shooting...
So my work around is simply modifying jqGrid to calculates resizing object again in the dragEnd event. Here's the modified code
first find the dragEnd event.
...
dragEnd: function(e) { // add a new input parameter
this.hDiv.style.cursor = "default";
if(this.resizing) {
this.dragMove(e); // call dragMove event to calculate resize object
...
then find the mouseup event where dragEvent is triggerd...
...
$(document).mouseup(function (e) { // get the event object
if(grid.resizing) { grid.dragEnd(e); return false;}// pass event to dragEnv
return true;
});
...
Then columns should be able to resize to wherever mouse points.
Hope this would help.

how to use toDataURL with image onload function?

function resetDisplayImg(){
var tempImage = new Image();
tempImage.src=document.getElementById("myCanvas").toDataURL("image/png");
tempImage.onload=function(){
context.drawImage(tempImage1,0,0,Canvas_WIDTH,Canvas_HEIGHT);
}
}
Everytime when i call the function above, i have to call two times then it will function correctly. I know with function "onload" can solve this problem but the problem still occur even if i applied it. Is there any mistake that i had made?
put the .src line after the onload
BUT you shouldnt be doing this in the first place. You are allowed to directly draw one canvas to another, so instead you can just write:
context.drawImage(document.getElementById("myCanvas"), 0, 0); and be done!

Raphael JS : mouseover/mouseout - problem with text-labels

I use Raphael JS to create an SVG-map with area's and textlabels. I want the area to highlight when you move the mouse over it.
I have this working now, but when I move the mouse over the label (in the center of the area) the mouseout-event for that area is triggered, so the area is unhighlighted again.
Is there any way to prevent this from happening, or a workaround ?
Create a rect with opacity set to 0 over the text and attach the event handlers on that rect. You can calculate the dimensions of the rect using getBBox() of the text.
Creating a set via Paper#set was the approach that worked for me. e.g.:
var st = paper.set();
st.push.apply(st, vectors); // `vectors`: my array of "hoverable" vectors
st.push(text); // `text`: my text vector for `vectors`
st.hover(function () {
text.show();
}, function () {
text.hide();
});

Resources