How do you put multiple animations in one render loop?
Using Jquery, if you have multiple elements to animate, and want:
to give each element it's own discrete value (such as a unique left for each)
to put all elements inside a single master timer, and
the movement steps should be based on the collective, not any individual in the collection
each render loop should update all positions without releasing control to the browser between elements for a given step. (but it should release between steps)
How do you do that?
Example:
Let C represent a list of divs displayed as columns, positioned with absolute positioning and unique left values equal to the sum of the width of all columns to it's left.
CCCCCCCCCCCCCCCCCCCCCCCCC
Let ^P represent the user's mouse, dragging an element, P over the list of columns:
CCCCCCCCCCCCCCCCCCCCCCCCC
^P
The columns, C should split apart the width of ^P at the location of ^P to make room. Like:
CCCCCCCCCCCCCCC CCCCCCCCCCC
^P
The column split should be animated, but the mousemove event should not allow the column animations to break, where one column moves to the next step but other have not.
Problem
Given an object oPos that contains the correct new left values for each column after the animation is complete:
oPos[Index] = {
Left:120,
Right:300,
Center:75,
Width:150,
$Element:$(ACachedSelector),
}
Assigning an animation using the animate() method:
for(var i in oPos){
oPos[i].$Element.stop().animate({
left:oPos[i].Left,
},{
duration: 500,
queue:false,
});
}
... Does not work correctly, because each of the elements is animated using it's own animation loop and tries to move independently. This has horrible performance and looks awful.
The desired effect is to have all columns to the right of the insert point slide to the right as one unit and as part of one animation. For example, try opening multiple tabs in Firefox and dragging a tab around to reorder the tabs. A gap opens up for you using an animation.
So, how do you put multiple animations in one render loop with Jquery?
I have a project that support combination of animations, it may help you.
https://github.com/emn178/jquery-animations
Related
I'm trying to create a custom carousel. The way it works is that the items are contained in two "piles", both piles contain the same items.
When you click the "next" button, the topmost item from the second pile moves to the top of the first pile. The last item in the first pile will then move to the bottom of the second pile, meaning both piles always contain the same number of items.
When clicking the "prev" button it needs to perform the reverse animation.
When moving items from the second pile to the first, this needs to happen with an animation.
I created a fiddle here https://jsfiddle.net/n109rpp0/3/ with the HTML I have produced so far, but I am struggling to work out a way to do the animation.
I'm not sure if I've taken the right approach, e.g. by having the items duplicated in two ul elements. Also how do I ensure the items are cycled in the correct order?
Does anyone have any ideas on how I should go about this?
Here is a quick idea how to achieve what you want. Add this:
$(prevItem).animate({left: '-345px', top: '-30px', width: '+=50px', height: '+=50px'});
$(prevItem).css('zIndex', '1');
to your next button functionality.
You need to play with the code to make perfect transition.
Here is an updated fiddle
Google animate function for jQuery and you will find more examples
I'm a new web dev (student) trying to make a variation of a Tic Tac Toe game (basically a bigger version of Tic-Tac-Toe with more grids!) using jQuery/JavaScript and am having trouble with the last bit of functionality.
Basically, it's a 3x3 grid of 3x3 grids. When a player selects a square on one of the individual small grids, the location of that little square on the individual grid corresponds to the big grid that the next player has to play on.
Essentially, the next player is limited in where they can place their marker, and I want a class of 'inactive' to be added to all of the squares that the player can't select. I want to remove that class on the squares that the player can select. Each turn, different squares have the inactive class removed (depending on where the player can play).
My attempted solution/logic was this: Each square has three classes, two numbers and 'square' (the latter for styling reasons). One number corresponds to the position where it is on it's individual 9x9 grid (1 to 9), the second number corresponds to what position its grid is on the bigger 9x9 grid orientation (also 1 to 9). So the little square on the top-left position of the grid located in the top left position of the big 9x9 grid would have the classes '1,' (its position within its small 9x9 grid) 'square,' and '1' (its grid's position within the bigger 9x9 orientation). The second square beside it would have classes '2 square 1.' The squares on the grid beside it would all have '2' as their last number class.
On a player click, I basically want jQuery to put an 'Inactive' class on every square, to return the first number class of the clicked square (the number corresponding to its position within the small 9x9 grid) and remove the 'Inactive' class on the squares that have their second number class matching with the clicked square's returned first number class.
So when a player places an X or O on a square:
1) Add inactive to every square on the gameboard so the next player can't play everywhere
2) Return the first number class of the clicked square.
3) Remove the inactive class from all of the squares on the gameboard that match the returned value from step 2.
4) Next player places their marker and it repeats.
I have no clue if that made any sense to anyone, but here's the relevant bit of code (where what happens when the player places their marker is defined):
ticTacToe.placeMarker = function($square){
//don't do anything if the square is already taken
if ($square.hasClass('inactive')){
return;
}
// puts an X or an O on the board
// and marks the square as unavailable
$square.html(ticTacToe.currentPlayer).addClass('inactive');
// makes all squares unavailable
ticTacToe.$squares.addClass('inactive');
// returns the relevant (first) part (the number corresponding to its position in its individual grid) of the class of the clicked-on square (I know this part works because I console-logged it)
var myClass = $square.html(ticTacToe.currentPlayer).attr("class");
var classSpecific = myClass.slice(0,1);
return (classSpecific);
// this is supposed to check if any element with the class 'square' (so any square) has the class corresponding to the returned value in the last step, and remove the Inactive class from it if it does. It looks messy when I eyeball it. It's probably wrong.
('.square').hasClass(classSpecific).removeClass('inactive');
I wonder if anyone can help me (maybe my syntax is messed up? maybe I have to split it up into more steps? Maybe I have to (hopefully not) use regex) I'll be extremely thankful if I manage to get this working. It doesn't have to use my logic/method, so long as the functionality is there. Thanks in advance. I only posted the part of the code I thought was relevant, but I can post other parts as well if necessary.
RESOLVED
By removing the line where I'm returning the classSpecific variable my function works.
The last line is incorrect, it should be
$('.square').hasClass(classSpecific).removeClass('inactive');
instead of
('.square').hasClass(classSpecific).removeClass('inactive');
It might be useful to look over a jQuery tutorial on the web, as we can see from the jQuery selector documentation, you get an array of DOM elements from the jQuery constructor.
From the jQuery API docs jQuery() — which can also be written as $() — searches through the DOM for any elements that match the provided selector and creates a new jQuery object that references these elements:
Then you can perform actions on these elements, for instance changing the CSS class, which I think is what you need an example is on the CSS class selector documentation. It adds a red border to any DOM elements with the .myClass class
$( ".myClass" ).css( "border", "3px solid red" );
I am trying to write a Solitaire card game in Javascript. For dragging and dropping the cards I use jQueryUI. As shown in http://jsfiddle.net/HY8g7/1/ you can drag cards to the column where you stack the cards in a Solitaire game.
Here comes the problem. Say I have all three cards stacked in one column: card 1, card 2 and card 3 each on top of each other. When I drag card 1, card 2 and 3 also need to follow card 1 when dragging around etc.
In order to achieve this I have already tried to make each successor card a child of the previous card. Unfortunately this method causes lots of DOM manipulation and dragging does not work as expected.
When I move a card to an invalid droppable it should be moved back to its original position which I now achieve with:
$('.card').draggable({
revert: 'invalid'
});
This should still work when I move a stack of cards around.
Does anyone have an idea what could be a clean approach to drag the pile of cards around, when picked at an arbitrary point?
It turned out the most efficient approach was to use the DOM to nest the cards as show in this Fiddle: http://jsfiddle.net/HY8g7/3/
card.detach()
.appendTo(cardsInColumn.last());
This code adds the card to the last card of the row. When a parent is dragged the children are coming along automatically without the need to handle coordinates of each card manually.
You could use jQuery's next() - jQuery Next Function. Then using a click event you could simply get the next siblings and then use the position of the dragged card to align the other cards below it. Since when you stack the cards they are aligned in the DOM as you see them.
Div#1 gets dragged/dropped and then DIv#2 gets placed on top, and so on. So then you would use the click event to target one of the DIV's and if it has siblings grab those and position them with the card that's being dragged.
I have two matrix layout. The first one contains seven images placed like a grid. How can we arrange all the images vertically in the second layout with animation?
-Thanks
If you are able to 1) detect the location of your target matrixlayoutrowcells, 2) to detach the content of the source cell and 3) attach it to the target cell, than it's nothing more than just incorporating some CSS animations ;-)
See this example of a moving sap.ui.commons.Image : http://jsbin.com/jafuk/1/edit
I was wondering how to make a script that pushes in Divs from the right of my screen.
These Divs are floating right, so when there are too many on one row they one that is longest on the row (one on the left) hops to the next row.
But I want a function that adds a div (just outside of the screen) and pushes it into the screen.
Any idea's ?
Mocked up a demo for you http://jsfiddle.net/rW5rC/3/
Allows you to add a new element on button click which starts invisible offscreen and slides in.
I suggest you to use jQuery, then you can prepend or append certain container
so if you want to insert div in one container at the start use
$('#id_of_container').prepend('<div class="left">my div</div>');
if you want to add it at the end
$('#id_of_container').append('<div class="left">my div</div>');
its much easier to manipulate html with the jQuery, and you don't have to change your code for different browsers.
Use jQuery animate method, it's very simple to do:
$("div").animate({
left: 200
});
I made you a demo here:
http://jsbin.com/ububer