I have a bunch of divs that all have gotten the same class 'a'. They all have position:absolute and are placed somewhere on the screen (using css). The divs closest to the left edge should be moved to the left (out of picture), the divs closest to the right edge should be moved to the right and regarding the remaining divs, the top ones move upwards and the rest downwards. I have made a fairly simple code but it doesn't seem to work. Any help would be appreciated but please keep in mind that I'm a beginner so hopefully no extremely complicated solutions.
$(document).ready(function() {
$(".button").on("click", function() {
var name = ('.a');
for (var i = 0; i < name.length; i++) {
var left = $(name[i]).css("left");
var top = $(name[i]).css("top")
if (left <= 30 + '%') {
$(name[i]).animate({
left: left - 50 + '%',
}, "slow")
} else if (left >= 70 + '%') {
$(name[i]).animate({
left: left + 50 + '%',
}, "slow")
} else if (top <= 50 + '%') {
$(name[i]).animate({
top: top - 50 + '%',
}, "slow")
} else {
$(name[i]).animate({
top: top + 50 + '%',
}, "slow")
}
}
}
}
I think you are a bit confused about iterating elements.
Try:
$(document).ready(function() {
$(".button").on("click", function() {
$(".a").each(function () {
var left = $(this).position().left;
var top = $(this).position().top;
if (left <= screen.width * 0.3) {
$(this).animate({
left: left - 50 + 'px',
}, "slow")
} else if (left >= screen.width * 0.7) {
$(this).animate({
left: left + 50 + 'px',
}, "slow")
} else if (top <= screen.height * 0.5) {
$(this).animate({
top: top - 50 + 'px',
}, "slow")
} else {
$(this).animate({
top: top + 50 + 'px',
}, "slow")
}
}
}
}
Related
I'm making an animated background for a webpage that spawn div elements to look like bubbles and animates their transparency. I want the bubbles to only spawn within the left 400px and the right 400px of the screen. I can get them to spawn in the middle, but when I try to make it spawn on the edges it breaks the code. (maybe an infinite loop?)
function bubble() {
var rightOffset = $(window).width() - 400; //where i want them on the right
do {
var leftPx = Math.floor(Math.random() * $(window).width() - 100);
} while (leftPx >= 400 || rightOffset <= leftPx);
var topPx = Math.floor(Math.random() * $(window).height() - 100); //not even going to worry about the top yet
if(bubbleCount <= 30){
bubbleCount ++;
$('html').append("<div class=bubble style=' left: " + leftPx + "px; top: " + topPx + "px;'></div>");
$('.bubble').animate({
opacity: 0.5,
}, 3000, 'swing')
.animate({
opacity: 0,
}, 3000, 'swing', function(){
$(this).remove();
bubbleCount -= 1;
});
}
}
Why not simply randomize the side as well? This way you don't have to check and discard potential positions. Something like this.
function randomBetween(min,max) {
return Math.floor(Math.random()*(max-min+1)+min);
}
var width = $(window).width();
var leftPixels = Math.round(Math.random()) ? randomBetween(0, 400) :
randomBetween(width - 400, width);
What happens here is that it first randomly generates 0 or 1, and then if it's 1 it generates a LEFT side value and if 0 generates a RIGHT side value. No extra iterations that slow down your program.
I reproduced your bubble effect and didn't end up with a break in code!
I think what you are missing is that for an absolute-positioned bubble to be positioned from right, you need to give it a right CSS offset value; likewise, for a left absolute-positioned bubble, stick to the left property:
var rightOffset = $(window).width() - 400; //where i want them on the right
do {
var rightPx = Math.floor(Math.random() * $(window).width() - 100);
} while (rightPx >= 400 || rightOffset <= rightPx);
/*
* ...
*/
$('html').append("<div class='bubble' style=' right: " + rightPx + "px; top: " + topPx + "px;'></div>");
http://codepen.io/anon/pen/ZGBEyo
I have a difficult task as you saw in the title of the question.
I'm doing a plugin that makes the words move in the screen, increase in size with a sharpen effect, and decrease in size with a blur effect, and the most difficult — one respect other if they have the same name, you may ask: what do you mean?
They have this totally random behavior to grow and stay focus, get smaller and become blurred, however I need make two words with the same name never become clear at same time.
My plugin works like this:
<span class="word" data-float="true" data-range-x="100" data-range-y="100" data-top="500" data-left="50" data-size="25">Love</span>
If data-float is true, the word is authorised to use the plugin
data-range-x = the maximum x range that can move
data-range-y = the maximum y range that can move
data-top = the top initial position
data-left = the left initial position
data-size = the size of the word
So, is possible to make them respect each other, if they have the same name?
Working plugin it three love words:
+ function($) {
var Float = function(element) {
this.element = element;
this.wrapper;
this.settings = {
rangeX : element.data('range-x') || 100,
rangeY : element.data('range-y') || 100,
speed : element.data('speed') || 5000,
top : element.data('top') || 0,
left : element.data('left') || 0,
size : element.data('size') || 20
};
};
Float.prototype.init = function() {
this.setPosition();
this.setSize();
this.setWrapper();
this.andWalk();
};
Float.prototype.setPosition = function() {
this.element
.css('top', this.settings.top)
.css('left', this.settings.left);
};
Float.prototype.setSize = function() {
this.element.css('font-size', this.settings.size + 'px');
if (this.settings.size <= 20) this.setShadow();
};
Float.prototype.setShadow = function() {
console.log('test');
this.element.css('color', 'transparent');
};
Float.prototype.setWrapper = function() {
this.wrapper = $('<div/>').css({
'width': this.element.outerWidth(true),
'height': this.element.outerHeight(true),
'z-index': this.element.css('zIndex')
});
this.wrapper.css({
'position': this.element.css('position'),
'top': this.element.position().top,
'left': this.element.position().left,
'float': this.element.css('position') === 'absolute' ? 'none' : 'left'
});
this.element.wrap(this.wrapper).css({
'position': 'absolute',
'top': 0,
'left': 0
});
};
Float.prototype.andWalk = function() {
var self = this;
var newX = Math.floor(Math.random() * this.settings.rangeX) - this.settings.rangeX / 2;
var newY = Math.floor(Math.random() * this.settings.rangeY) - this.settings.rangeY / 2 - 0;
var newS = Math.floor(Math.random() * this.settings.speed) + this.settings.speed / 2;
var newF;
if (this.settings.size > 40) { newF = Math.floor(Math.random() * (70 - 15 + 1) + 15); }
else if (this.settings.size <= 25) { newF = Math.floor(Math.random() * (25 - 15 + 1) + 15); }
else { newF = Math.floor(Math.random() * (40 - 15 + 1) + 15); }
this.element.animate({
'fontSize': newF,
'color': newF >= 25 ? '#FFFFFF' : 'transparent',
'top': newY,
'left': newX
}, newS, function() {
self.andWalk();
});
};
$(window).on('load', function() {
$('[data-float]').each(function() {
var element = $(this).data('float') || false;
if (element) {
var float = new Float($(this));
float.init();
}
});
});
}(jQuery);
body {
background: black;
color: white;
}
.word {
position: absolute;
text-shadow: 0 0 5px rgba(255, 255, 255, 0.9);
}
<span class="word" data-float="true" data-index="1" data-range-x="100" data-range-y="100" data-top="500" data-left="50" data-size="25">Love</span>
<span class="word" data-float="true" data-index="2" data-range-x="100" data-range-y="100" data-top="90" data-left="290" data-size="40">Love</span>
<span class="word" data-float="true" data-index="3" data-range-x="100" data-range-y="100" data-top="500" data-left="290" data-size="70">Love</span>
<script src="//ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script>
<script src="//cdnjs.cloudflare.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
You may want to leverage the animate.css library as it uses CSS3 transitions to animate elements with pulse, flip, zoom, rotate, roll, fade and other effects. Then you could use jquery or pure javascript to call these effects.
Here is a jsfiddle I made to demonstrate how you can call the effects from this library with jQuery http://jsfiddle.net/ashk3l/qxfj8L2d/
Essentially your HTML could look something like this:
<h1 class="your-element">Hello!</h1>
And your jQuery call could look something like this:
$(document).ready(function () {
$('.your-element').addClass('animated pulse');
});
I have this jQuery code for a carousel but its not working as I supposed it should.
var totalItems = $('.inner li').length,
currentItem = 1,
$inner = $('.inner li'),
width = $inner.outerWidth(true);
setInterval(function() {
$inner.animate({
right: '+=' + width
}, 500);
currentItem += 1;
}, 500);
You can view the example at this FIDDLE
Thanks in advance.
EDIT:
This is the entire code I have working for another carousel.
$(document).ready(function() {
var totalItems = $('.inner li').length,
currentItem = 1,
$inner = $('.inner li'),
width = $inner.outerWidth(true),
speed = 400,
delay = 4000;
var timer = setInterval(function() {
if (currentItem === totalItems) {
$inner.animate({
right: '-=' + width * (totalItems-1) + 'px'
}, speed);
currentItem = 1;
} else {
$inner.animate({
right: '+=' + width
}, speed);
currentItem += 1;
}
}, delay);
$('.carousel').hover (function(ev) {
clearInterval(timer);
}, function(ev){
timer = setInterval(function() {
if (currentItem === totalItems) {
$inner.animate({
right: '-=' + width * (totalItems-1) + 'px'
}, speed);
currentItem = 1;
} else {
$inner.animate({
right: '+=' + width
}, speed);
currentItem += 1;
}
}, delay);
});
$('#right').click(function () {
if (currentItem === totalItems) {
$inner.animate({
right: '-=' + width * (totalItems-1) + 'px'
}, speed);
currentItem = 1;
} else {
$inner.animate({
right: '+=' + width,
}, speed);
currentItem += 1;
}
});
$('#left').click(function () {
if (currentItem === 1) {
$inner.animate({
right: '+=' + width * (totalItems-1) + 'px'
}, speed);
currentItem = totalItems;
} else {
$inner.animate({
right: '-=' + width
}, speed);
currentItem -= 1;
}
});
});
No, it doesn't.
It just set's up an interval at which the passed function is called, so if you pass 500ms as an interval, the function will be called (about) 500ms from now, then (about) 1 second from now, then ...
setInterval also has nothing to do with page load, if that is what you meant (e.g. it doesn't depend on body load or anything like that, but the moment it gets executed)
I'm saying about because browser timing isn't very exact (for several reasons). Also, you should save the returned value of setInterval in a variable, and make sure to clean up the interval when you don't need it anymore. Depending on browser, this is normally done automatically on page unload, but on some older browsers it might not happen until the browser is closed.
Edit: Looking at the fiddle, your problem is with css, not with javascript. Your li need to be positioned relative or absolute, otherwise setting right property will have no effect. You could also set margin-right/margin-left.
Im creating myself a drag functions just for my personal use so I can drag elements around. I'm having a problem. At the moment trying to make the drag so one you pick up the element you can drag it but once you drop it, it goes back to the original position. This is not working as you can see here. When I let go of #drag2 or #drag3 then it goes to the position of #drag1.
My Function:
function drag(el) {
var position = $(el).position();
var ptop = position.top;
var pleft = position.left;
var down = false;
$(el).mousedown(function(event) {
down = true;
$(this).css({
cursor: 'crosshair',
});
$(this).mousemove(function(event) {
if (down == true) {
$(this).css({
cursor: 'crosshair',
});
var w = $(this).width();
var h = $(this).height();
var left3 = (w / 2) + 7;
var top3 = (h / 2) + 7;
$(this).css({
cursor: 'crosshair',
left: (event.clientX) + (3 * 3) - left3,
top: (event.clientY) + (3 * 3) - top3
});
}
}).mouseup(function() {
down = false;
$(this).css({
cursor: 'default',
});
$(this).animate({
top: ptop,
left: pleft
}, 300);
});
});
}
I have to get the old position:
var position = $(el).position();
var ptop = position.top;
var pleft = position.left;
So should it not get the position of all of them and bring them self back to where they were? Any help will be appreciated.
EDIT: I DO NOT WANT TO USE ANY PLUGIN OR JQUERY UI, THANKS ANYWAYS
The solution is very simple
See this fiddle: http://jsfiddle.net/BggPn/4/
you define 1 var for left and 1 for top. All 3 the elements use the same variables. If you loop through the elements then you make a new scope where each element has it's own vars.
Working code:
$(document).ready(function() {
drag('#drag, #drag2, #drag3')
});
function drag(el) {
$(el).each(function(){
var position = $(this).position();
var ptop = position.top;
var pleft = position.left;
var down = false;
$(this).mousedown(function(event) {
down = true;
$(this).css({
cursor: 'crosshair',
});
$(this).mousemove(function(event) {
if (down == true) {
$(this).css({
cursor: 'crosshair',
});
var w = $(this).width();
var h = $(this).height();
var left3 = (w / 2) + 7;
var top3 = (h / 2) + 7;
$(this).css({
cursor: 'crosshair',
left: (event.clientX) + (3 * 3) - left3,
top: (event.clientY) + (3 * 3) - top3
});
}
}).mouseup(function() {
down = false;
$(this).css({
cursor: 'default',
});
$(this).animate({
top: ptop,
left: pleft
}, 300);
});
});
});
}
Make it a plugin:
$.fn.drag = function drag(){
return this.each(function(){
var position = $(this).position();
var ptop = position.top;
var pleft = position.left;
var down = false;
$(this).mousedown(function(event) {
down = true;
$(this).css({
cursor: 'crosshair',
});
$(this).mousemove(function(event) {
if (down == true) {
$(this).css({
cursor: 'crosshair',
});
var w = $(this).width();
var h = $(this).height();
var left3 = (w / 2) + 7;
var top3 = (h / 2) + 7;
$(this).css({
cursor: 'crosshair',
left: (event.clientX) + (3 * 3) - left3,
top: (event.clientY) + (3 * 3) - top3
});
}
}).mouseup(function() {
down = false;
$(this).css({
cursor: 'default',
});
$(this).animate({
top: ptop,
left: pleft
}, 300);
});
});
});
}
Now you can call it by:
$("#drag1, #drag2").drag();
2 thoughts:
1.) Why don't you use jQuery UI (draggable)?
2.) The idea of giving a selector in stead of an element is wrong, a selector can lead to multiple elements, and that's the first reason why it's failing. If you start with
function drag(selector) {
$(selector).each(function() {
var el = $(this);
//rest of code
}
}
it would be better. But I think you'll run into a few other problems eventually
The problem is whenever you're sending in the list of selectors '#drag, #drag2. #drag3' and your position variable only cares about the first one (try changing the order and you'll see they snap to the first in the list). If you want to go about it this way then you'll want to perform an each iteration over them to get the right values.
get the current position of div after drag and set via this
.mouseup(function() {
var position = $(this).position();
down = false;
$(this).css({
cursor: 'default',
});
$(this).animate({
top: position.top,
left: position.left
}, 300);
DEMO
why don't you use drag and drop plugin. see this article
http://viralpatel.net/blogs/2009/05/implement-drag-and-drop-example-jquery-javascript-html.html
or this one
http://plugins.jquery.com/project/dragndrop
I have the following function set to run on a hover over an image:
function() {
$('.slides .slide h3').each(function(i){
var owidth = $(this).width()
$(this).animate({"right":730 - owidth - 16}, 500);
});
}
You can view the page here. Over the image and click the next icon on the lower right of the image. For some reason, the function is calculating the first h3's width correctly, but then it thinks all other h3s have a width of 0. Can anyone offer a solution?
function() {
var owidth = 0;
$('.slides .slide h3').each(function(i){
owidth = $(this).width();
$(this).animate({"right":(730 - owidth - 16) + 'px'}, 500);
});
}
A better way:
function() {
$('.slides .slide h3').each(function(i){
$(this).stop().animate({
"right": (714 - $(this).width()) + 'px'
}, 500);
});
}