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.
Related
To further elaborate on the title. I've noticed that when you have a spinning wheel, and select an item the wheel will as expected spin around to showcase the selected item. However.. if you leave your mouse where it is when you pressed an item, the new item that moves underneath the mouse will not be highlighted using the 'onhover' method. To force the hover effects on the item underneath the mouse you either have to move the mouse to the title of the item, or move away from the item and then move the mouse back onto the item to once again have the onhover effects displayed. This is an issue that is present on the examples on the homepage as well incase you want to try it out.
Is there any way to call the onhover method manually for the item underneath the mouse?
Here's a link to try it out.
The same issue applied when you invoke spreadWheel() and the cursor is at the newly activated wheels position. The items wont highlight until you move the mouse around, on the title or re-enter the div.
On the first image the mouse is hovering over the item 'CSS'. When I select the item, another item moves in during the spin, and 'SVG' is now placed under the mouse. The new item is not highlighted until the cursor moves over the title or re-enters the slice.
This behavior is by design so there is no built-in way to reset this.
If you want to modify the source code look around here.
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
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
Here is a jsFiddle so you can clearly see what I am about to describe:
http://jsfiddle.net/c26SK/5/
I have two boxes. The left hand one is filled with items, items that can be dragged into the right hand box.
Items in the right hand box can be rearranged. Items stack vertically.
Both boxes are a set height. If items go outside the lower bounds of the right hand box, I want a scroll bar to appear.
What I want to do (if its even possible) is this:
As I am dragging items in the right hand box, I want to be able to rearrange the items as I drag the item up and down, however, if I also want to detect if an item has been dragged outside of the right hand box.
Unfortunately all that happens now is the item scrolls inside the right hand box both horizontally and vertically.
Ideally I want something like overflow-y: auto; overflow-x: visible which I know isn't possible. Then I would just see if the x,y coordinates of the item is inside the right hand box when it is dropped.
Ive been playing about with appendTo, to see if that could solve the problem, but no luck so far.
Is what I am trying to do achievable? Can anyone help me out? Many thanks!
It's far from perfect or even a solution for that matter but I think this is a step in the right direction.
I've added a function to the out event which checks if you're dragging the sortable item back onto the sortable list. If not, it appends the item to body. It's not pretty and probably not very efficient.
out: function (event, ui) {
if(!$(event.toElement).hasClass('ui-draggable')&&!$(event.toElement).is('#rightitems')) {
ui.item.appendTo('body')
}
}
There are some obvious issues with positioning but hopefully it's something to work with. You'll also have to handle the drop event for the element as I haven't tried any of that with this code
JSFiddle
We've got a request from a customer to support the following scenario:
on a page we have a container: div element which is at the same time dojo.dnd.Source.
inside the container we've got 9 div elements with similar content: 2 buttons and 2 comboboxes
a user should be able to define the sequence of those 9 div elements by simply dragging them around inside the container.
The task is to present a possible layout preview while dragging.
Will appreciate any ideas.
Focusing on your comment and first attempt at this solution, I humbly suggest the following:
If things are being animated and sensitive to mouse pointer changes you should separate the two:
Leave the element with the drag/drop event subscription (the parent) alone. Do not change its appearance ever.
Create an element (the child) inside this element that gets animated, but does not affect its parent.
The parent can be transparent.
Can this be of help?