JS while loop change value - javascript

I have some JS code that can track positions of DOM elements by use of their class. However, I need this class name changed for a specific amount of times. My code so far is this:
All the code that says added, is my poor try to make it work, just to give you an idea of what I am meaning.
var offset = 0,
xPos = 0,
yPos = 0,
item_number = 0; //added code
$(document).ready(function(){
while(item_numer<5) { //added code
$(".item" + item_number ).draggable({ //added code, the "item" has to be shown on the website as "item0".
containment: '#house_wall1',
drag: function(){
offset = $(this).position();
xPos = offset.left;
yPos = offset.top;
$('#posX').text('x: ' + xPos);
$('#posY').text('y: ' + yPos);
},
// Find original position of dragged image.
start: function(event, ui) {
// Show start dragged position of image.
var Startpos = $(this).position();
$("div#start").text("START: \nLeft: "+ Startpos.left + "\nTop: " + Startpos.top);
},
// Find position where image is dropped.
stop: function(event, ui) {
// Show dropped position.
var Stoppos = $(this).position();
$("div#stop").text("STOP: \nLeft: "+ Stoppos.left + "\nTop: " + Stoppos.top);
}
});
item_number++;
}
});

You're placing the ending } a bit too soon.
The call to .draggable() and the Object literal passed to it actually stretch quite a few lines down to the 1st }); near the bottom. The loop should surround all of it.
$(document).ready(function(){
while (item_number < 5) {
$('.item' + item_number).draggable({
// around 20 lines
});
item_number++; // increment counter
} // and end of loop
});
Though, the counter may not be necessary. Since you're using a class selector, class names can be reused and .draggable() will apply to each of the matched elements.
$(document).ready(function () {
$('.item').draggable({
// ...
});
});

Are you simply missing an increment on item_number?
while(item_numer<5) {
$(".item" + item_number ).draggable({ /* stuff */ });
item_number++;
}

Related

Drag and Drop the images on canvas using jqueryui

I have completed the dragging and dropping of buttons and nav bar and it is draggable after drop also and working properly,
But now problem is now i want to drag and drop the image.i have tried many different things but unable to do this.
I am adding my fiddle please check
http://jsfiddle.net/Yousuf_007/d6gowym5/
Thanx
I'm now working on a project similar to yours, but in the left div I have a list and every draggable element is a list item. This function works perfect for me, maybe it will be useful for you:
$('#streams li').draggable({
helper: 'clone',
revert: 'invalid'
});
//Function for setting drag and drop settings
function foo(){
$('.foo').each(function() {
//Making dropped elements draggable again
$('.foo').draggable({
containment: $(this).parent(),
stack: '.foo',
snap: '.foo',
drop: function (event, ui) {
var pos = ui.draggable.offset(), dPos = $(this).offset();
alert("nodeid: " + ui.draggable.data("noteid") +
", Top: " + (pos.top - dPos.top) +
", Left: " + (pos.left - dPos.left));
},
drag: function(){
var draggedItemId = $(this).attr('id');
$(this).css({'z-index': '11'});
$(".class"+draggedItemId).css({'z-index':'15'});
},
stop: function(){
var draggedItemId = $(this).attr('id');
$(this).css({'z-index': '0'});
$(".class"+draggedItemId).css({'z-index':'10'});
}
});
});
}
var fooCount = $('.foo').length;
//Generating new table after drop
$('#mainDiv').droppable({
drop: function(event, ui) {
//Getting position where new item was dropped
var pos = ui.draggable.offset(), dPos = $(this).offset();
var droppedTop = ui.position.top - $(this).offset().top;
var droppedLeft = ui.position.left - $(this).offset().left;
//Generating new table if the item is dropped first time
if (!ui.draggable.hasClass('foo')) {
var Class = ui.draggable.attr("class");
var title = ui.draggable.text().trim();
var item = $('<table class="foo small elementTable ' + Class + '" name="' + title + '" id="'+(fooCount+1)+'" style="left: '+droppedLeft+'px; top: '+droppedTop+'px;"><tr class="tableHeader"><th class="thClass"><span class="header">' + title + '</span><span class="settings"><img src="Icons/pignon.png" width="17px" height="17px" alt="Settings" title="Settings" /></span></th></tr><tr><td class="add"><span class="addList">Add new link</span></td></tr></table>');
$(this).append(item);
fooCount += 1;
foo();
}
}
});
Try to rewrite your function and give it similar look. Also change your DOM structure from separate elements to list, that will help you to easily implement drag and drop. Here is the fiddle: https://jsfiddle.net/vaxobasilidze/7gvon7h1/
EDIT: Here is your fiddle. I have initialized drag and drop. The rest, styling and what you do to your content while dropping is up to you: http://jsfiddle.net/vaxobasilidze/rhz6ovyz/

how to animate image & change the direction from right to left

Please find the code, which iam facing issue with changing the direction of arrow, the arrow should change the facing from right to left once it reach the screen width. THE REQUIRED FUNCTIONALITY IS THE ARROW SHOULD NOT GO IN REVERSE it has to change its direction.
tried lot some one give solution.
http://jsfiddle.net/7xyuqe1k/5/
function AnimateFish() {
var Fish3 = $("[id^=fish]").not(".HoverFish"),
theContainer = $("#container"),
maxLeft = theContainer.width() - Fish3.width() - 50,
maxTop = theContainer.height() - Fish3.height(),
leftPos = Math.floor(Math.random() * maxLeft),
topPos = Math.floor(Math.random() * maxTop) + 100,
imgRight = "Assets/fish-glow3-right.gif",
imgLeft = "Assets/fish-glow3.gif";
/*Get position of the fish*/
//console.log(Fish3.position().left +" +"+leftPos);
//alert(Fish3.position().left);
if ($("[id^=fish]").position().left >= leftPos) {
$(this).css("background-image", 'url("' + imgRight + '")');
} else {
$(this).css("background-image", 'url("' + imgLeft + '")');
}
Fish3.animate({
"left": leftPos,
"top": topPos
}, 1800, AnimateFish);
}
There was a problem on fish's destination points(positions left & top) picking. First fish works properly since it's picking the destination point respective to itself, but rest of the fishes also were taking the destination points respective to 1st fish not themselves.
The working sample is available here http://jsfiddle.net/ravinila/7xyuqe1k/26/
$(document).ready(function(e) {
var newfishid = 0;
$('.post-button').click( function(e) {
var fish = $("<div/>", {"class":"large-fish fish", "id" : "fish"+(newfishid++)});
$('#container').append(fish);
fish.on("anim", function(e){
var _this = $(this),
theContainer = $("#container"),
maxLeft = theContainer.width() - _this.width() - 50,
maxTop = theContainer.height() - _this.height(),
leftPos = Math.floor(Math.random() * maxLeft),
topPos = Math.floor(Math.random() * maxTop) + 100,
imgLeft = "http://free-icon-download.com/modules/PDdownloads/images/screenshots/free-icon-download_left-arrow-blue.png",
imgRight = "http://www.newclassicdesign.com/r_arrow.png";
if (_this.position().left < leftPos) {
_this.css("background-image", 'url("' + imgRight + '")');
} else {
_this.css("background-image", 'url("' + imgLeft + '")');
}
_this.animate({
"left": leftPos,
"top": topPos
}, 2500, function(){
$(this).trigger("anim");
});
});
fish.trigger("anim");
fish.hover(function(e) {
$(this).stop();
}, function(e) {
$(this).trigger("anim");
});
});
});
I have taken a look at it and it looks like its a silly mistake. Your fiddle showed something was working since it changed something when the direction changed, so the basics are okay. You just forgot that there was an image tag inside you div that you're meant to be manipulating.
function AnimateFish() {
var Fish3 = $("#fish1").not(".HoverFish"),
theContainer = $("#container"),
maxLeft = theContainer.width() - Fish3.width() - 50,
maxTop = theContainer.height() - Fish3.height(),
leftPos = Math.floor(Math.random() * maxLeft),
topPos = Math.floor(Math.random() * maxTop) + 100;
imgRight = "http://www.newclassicdesign.com/r_arrow.png",
imgLeft = "http://free-icon-download.com/modules/PDdownloads/images/screenshots/free-icon-download_left-arrow-blue.png";
// below here you used $(Fish3), but Fish3 is already a JS object - you don't need to rewrap it.
// The biggest problem however, is that below that you used '$(this)', which won't work as there
// is no context defined (you're in an if, not a jQuery function).
// Replacing this with the same Fish3 does the job,
// as it already was a jQuery object anyhow.
// I have also changed your background from an image to red and green for testing purposes.
// As you can see, thats working. However, your image isn't changing..
// This is because you have an image inside you wrapper which you aren't changing.
if (Fish3.position().left >= leftPos) {
Fish3.css("background", 'green');
// So lets change the image...
Fish3.find("img").attr("src", imgLeft);
} else {
Fish3.css("background", 'red');
// So lets change the image...
Fish3.find("img").attr("src", imgRight);
}
Fish3.animate({
"left": leftPos,
"top": topPos
}, 1800, AnimateFish);
}
Check my comments inside the code to see what happened, but copying this into your fiddle and replacing the animation function did the trick.

Javascript/jQuery Drag and Drop Limit parent

got the following problem. i need the following just to be drag/dropable in the green area.
should be something like that:
limit($(this).parent());
but thats not working, im using this for dnd:
$('#dragThis').draggable({
drag: function () {
var offset = $(this).offset();
var xPos = Math.abs(offset.left);
var yPos = Math.abs(offset.top);
$('#posX').val('x: ' + xPos);
$('#posY').val('y: ' + yPos);
},
stop: function (event, ui) {
// Show dropped position.
var Stoppos = $(this).position();
var left = Math.abs(Stoppos.left);
var top = Math.abs(Stoppos.top);
$('#posX').val('x: ' + left);
$('#posY').val('y: ' + top);
}
});
hope someone can help me with that ;) thx so far
http://jsfiddle.net/DGbT3/1850/
///////////////
Update - getting correct x/y Position and just allow inside green area:
http://jsfiddle.net/DGbT3/1858/
You can use containment option for this which constrains dragging to within the bounds of the specified element or region.:
$('#dragThis').draggable({
drag: function() {
var offset = $(this).offset();
var xPos = Math.abs(offset.left);
var yPos = Math.abs(offset.top);
$('#posX').val('x: ' + xPos);
$('#posY').val('y: ' + yPos);
},
stop: function(event, ui) {
// Show dropped position.
var Stoppos = $(this).position();
var left = Math.abs(Stoppos.left);
var top = Math.abs(Stoppos.top);
$('#posX').val('x: ' + left);
$('#posY').val('y: ' + top);
$('#info').val('x: ' + left + ' y: ' + top);
},
containment: $("#content")
});
Example
If you want to get the position according to its parent then use .position(), then check if the xPos and yPos are bigger than 0 and smaller that its parent's width..
$('#dragThis').draggable({
drag: function() {
var offset = $(this).position();
var xPos = offset.left;
var yPos = offset.top;
$('#posX').val('x: ' + xPos);
$('#posY').val('y: ' + yPos);
if(xPos < 0 || xPos > $(this).parent().width())
console.log("outside");
},
stop: function(event, ui) {
// Show dropped position.
var Stoppos = $(this).position();
var left = Stoppos.left;
var top = Stoppos.top;
$('#posX').val('left: ' + left);
$('#posY').val('top: ' + top);
if(xPos < 0 || xPos > $(this).parent().width())
console.log("outside");
}
});
NOTE: there is a typo in your #content css position..

How to select all divs that overlay with a draggable div in jquery?

I'm building a graph displaying events happening over time. Each of my event is an horizontal bar that is created using a <div> as shown below:
<div class="aaaa" style="margin-left: 0.00%; width:100.00%;">aaaa</div>
<div class="aaaa" style="margin-left: 5.00%; width: 20.00%;">bbbb</div>
<div class="aaaa" style="margin-left:25.00%; width: 50.00%;">cccc</div>
<div class="aaaa" style="margin-left:55.00%; width: 45.00%;">dddd</div>
At the top of this graph, I have a "ruler" which is a draggable and resizable <div>
<div id="draggable2" class="draggable ui-widget-content">
<p>Ruler</p>
</div>
My intention is to drag this ruler horizontally and to use it to select all bars of my graphs that are below the ruler. When bars are selected, the background color should change.
So far I manage to drag and to resize my ruler as I want with the following code:
$(function () {
$("#draggable2").draggable({
axis: "x"
});
});
$(function () {
$("#draggable2").resizable({
helper: "ui-resizable-helper",
handles: "se, sw, e, w"
});
});
I also manage to select the bars I want using the following code:
$(".fake").selectable({
filter: "div"
});
You can see on the fiddle referenced below that when you do a "lasso selection", my bars become pink.
However, I would like to combine my ruler with this "lasso selection", or in other words, I would like that once my ruler is dragged, all <div> that are below become selected.
I've created a fiddle to illustrate my problem: http://jsfiddle.net/Lge93/
As I'm new to Javascript and Jquery, I would really appreciate any solution or suggestion.
Thanks for your time
Edit post answers:
My final solution based on the code provided by Jtromans is available here: http://jsfiddle.net/Lge93/5/
Here's my solution:
$(function() {
$( "#draggable2" ).draggable({
axis: "x",
drag: function(e) {
var selectableElements = $(".fake").data().uiSelectable.selectees;
var ruler = $(e.target);
$.each(selectableElements, function(i, v) {
if(ruler.offset().left >= $(v).offset().left) {
$(v).addClass("ui-selected");
}else {
$(v).hasClass("ui-selected") && $(v).removeClass("ui-selected");
}
});
}
});
});
$(function() {
$( "#draggable2" ).resizable({
helper: "ui-resizable-helper",
handles: "se, sw, e, w"
});
});
$(".fake").selectable({filter:"div"});
http://jsfiddle.net/Lge93/3/
If I understand your question correctly, it sounds like you could solve the problem in the following way.
Upon interacting with the ruler, you will be able to calculate the new width, x- and y-coordinates. This is pretty straight forward and requires only a few lines of jQuery code in the callback after any form of interaction with your ruler.
You could then check for each item in your (gant?) chart to see whether it occupies any of the same area that the ruler does. This would be relative to the parent container.
The devil is in the detail for how you would like to handle whether the ruler is 'in' the Gant chart div item. And below is some code to get your started on working out whether the Ruler occupies the some of the same location as the other divs:
function checkOverlays (x, width, y, height) {
$(".aaaa").each (function (i,e) {
var thisWidth = $(this).width();
var thisHeight = $(this).height();
var offsetTop = $(this).offset().top - $(this).parent().offset().top;
var offsetLeft = $(this).offset().left - $(this).parent().offset().left;
console.log('x coverage: ' + offsetLeft + " to " + parseFloat(thisWidth + offsetLeft));
console.log('y coverage: ' + offsetTop + " to " + parseFloat(thisHeight + offsetTop));
if (offsetLeft > x && offsetLeft < parseFloat(x + width) ) {
console.log("I'm in the same x space");
$(this).css('background-color', 'red');
}
if (offsetTop > y && offsetTop < parseFloat(y + height) ) {
console.log("I'm in the same y space");
$(this).css('background-color', 'red');
}
})
}
$("#draggable2").on("resize drag", function () {
var thisWidth = $(this).width();
var thisHeight = $(this).height();
var offsetTop = $(this).offset().top - $(this).parent().offset().top;
var offsetLeft = $(this).offset().left - $(this).parent().offset().left;
console.log('x coverage: ' + offsetLeft + " to " + parseFloat(thisWidth + offsetLeft));
console.log('y coverage: ' + offsetTop + " to " + parseFloat(thisHeight + offsetTop));
checkOverlays (offsetLeft, thisWidth, offsetTop, thisHeight)
});

jQuery - Fixing the animation

I am creating a new "whack-a-mole" style game where the children have to hit the correct numbers in accordance to the question.
I have the numbers animating from a set top position to another with a random width so that they look like they are floating up like bubbles.
The only problem I am having with it is that sometimes the numbers glitch and the width on them changes suddenly making it appear to jump from one side of the container to the other.
The only explanation I can think of is the width must be resetting somewhere which I have tried to look for.
Either I am blind or it is something else, can someone help me to find the source of the problem.
Here is the code that maps the numbers...
function randomFromTo(from, to) {
return Math.floor(Math.random() * (to - from + 1) + from);
}
function scramble() {
var children = $('#container').children();
var randomId = randomFromTo(1, children.length);
moveRandom("char" + randomId);
}
function moveRandom(id) {
var cPos = $('#container').offset();
var cHeight = $('#container').height();
var cWidth = $('#container').width();
var bWidth = $('#' + id).width();
var bHeight = $('#' + id).css(
'top', '400px'
).fadeIn(1000).animate({
' top': '-100px'
}, 10000).fadeOut(1000);
maxWidth = cPos.left + cWidth - bWidth;
minWidth = cPos.left;
newWidth = randomFromTo(minWidth, maxWidth);
$('#' + id).css({
left: newWidth
}).fadeIn(1000, function () {
setTimeout(function () {
$('#' + id).fadeOut(1000);
window.cont++;
}, 1000);
});
Here is also a working fiddle so you can see the issue I am talking about: http://jsfiddle.net/pUwKb/26/
The problem is that you are re-entering your moveRandom function for an ID that is already animated. The new width calculation causes the piece to seem to jump when it is reassigned during the already animated movement. One way to fix this is to reject new piece movements for pieces you are already animating. I modified your jsFiddle and fixed it with this code:
// Keep track of the pieces actually moving
var currentMoving = [];
function moveRandom(id) {
// If this one's already animating, skip it
if ($.inArray(id, currentMoving) !== -1) {
return;
}
// Mark this one as animating
currentMoving.push(id);
var cPos = $('#container').offset();
var cHeight = $('#container').height();
var cWidth = $('#container').width();
var bWidth = $('#' + id).width();
var bHeight = $('#' + id).css('top', '400px').fadeIn(1000).animate({
'top': '-100px'
}, 10000).fadeOut(1000);
maxWidth = cPos.left + cWidth - bWidth;
minWidth = cPos.left;
newWidth = randomFromTo(minWidth, maxWidth);
$('#' + id).css({
left: newWidth
}).fadeIn(1000, function () {
setTimeout(function () {
$('#' + id).fadeOut(1000);
// Mark this as no longer animating
var ix = $.inArray(id, currentMoving);
if (ix !== -1) {
currentMoving.splice(ix, 1);
}
window.cont++;
}, 1000);
});
}
Forked jsFiddle here.
Edit: The OP wanted to show more divs at once without speeding the animation up. To do this I added 20 more character divs (each a duplicate of the first 10 numbers), fixed the guarding code a bit, altered the CSS to specify the image of the character by class, and then put a limit of 20 animations at a given time. I also put a loop around the rejection of an already animated piece, to pick another. I made some other minor improvements. Updated JSFiddle here.

Categories