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');
});
Related
Okay, I've seen a few things that sort of * answer my question, but none of them quite do what I want to do / I'd like to understand how to do this myself from start to finish as a learning exercise. I'm a novice at all this, so bear with me!
What I'm Trying to Do:
I have a black page and I'd like 20-30 small, white div boxes to fadeIn at random positions on the page (like stars is sort of the vibe I'm going for).
Ideally, they wouldn't overlap and they would be randomly sized between 5px and 10px, but I recognize that this might be getting a little too complicated.
Here's what I have so far
I've been working off this jsfiddle and well as this one. This is what I've come up with (that doesn't work, they all fade in equally spaced in a line and don't stay confined from to the site)
Here's my jsfiddle, code below
function randomPosition() {
var h = $(window).height()-10;
var w = $(window).width()-10;
var newHeight = Math.floor(Math.random() * h);
var newWidth = Math.floor(Math.random() * w);
return [newHeight, newWidth];
}
$(document).ready(function() {
var newPosition = randomPosition();
$('.star').css( {
'margin-left':newPosition[1]+'px',
'margin-top':newPosition[0]+'px'
}).each(function(index) { $(this).delay(1500*index).fadeIn('slow');
})
});
CSS
body {
background-color: black;
}
.star {
height: 10px;
width: 10px;
background-color: white;
display: none;
}
HTML (is there a way to do this with just a for loop or something similar?)
<div class="star"> </div>
<div class="star"> </div>
<div class="star"> </div>
<div class="star"></div>
The sizing and positioning isn't too hard. The thing is to do it all in the each loop - currently you get 1 position and use it for everything. Also you will want to make them position:absolute so they don't go off the page.
I've updated your fiddle to set the random position and a size between 5 and 10px:
The overlapping is a bit harder. You need to keep track of the sizes and positions you have generated and in the same .each function compare the current generated size+position to the previous ones to check for overlapping.
http://jsfiddle.net/5ocb5aww/3/
function randomPosition() {
var h = $(window).height()-10;
var w = $(window).width()-10;
var newHeight = Math.floor(Math.random() * h);
var newWidth = Math.floor(Math.random() * w);
return [newHeight, newWidth];
}
function randomSize() {
return Math.round(Math.random() * 5) + 5;
}
$(document).ready(function() {
// stores generated star positions
var stars = [];
$('.star').each(function(index) {
var newPosition, newSize;
// check for overlap
var isOverlap = true;
while(isOverlap)
{
newPosition = randomPosition();
newSize = randomSize();
// check previous stars to see if an edge of this one overlaps
isOverlap = $.grep(stars, function(s) {
return (
(newPosition[1] >= s.x1 && newPosition[1] <= s.x2)
|| (newPosition[1]+newSize >= s.x1 && newPosition[1]+newSize <= s.x2)
)
&& (
(newPosition[0] >= s.y1 && newPosition[0] <= s.y2)
|| (newPosition[0]+newSize >= s.y1 && newPosition[0]+newSize <= s.y2)
);
}).length > 0;
}
// store to check later stars against it
stars.push({
x1: newPosition[1],
x2: newPosition[1] + newSize,
y1: newPosition[0],
y2: newPosition[0] + newSize,
size: newSize});
$(this).css({
'margin-left':newPosition[1]+'px',
'margin-top':newPosition[0]+'px',
'width':newSize + 'px',
'height':newSize + 'px'
});
$(this).delay(800*index).fadeIn('slow');
})
});
Here is my approach to your exercise ... the overlapping position would require a little bit more effort ... I'll leave you that to sort for yourself (may require restructuring the code I'm handing here)
jsFiddle Demo
JS
function starDust(wdt, hgt, tSt, tAp){
var timer = tAp * 1000;
var defInt = tSt,
starInt = setInterval(function(){
var posX = Math.floor((Math.random() * wdt) + 1),
posY = Math.floor((Math.random() * hgt) + 1),
size = Math.floor((Math.random() * 10) + 1);
$('body').append('<div class="star"></div>');
$('.star:last').css({'width':size,'height':size,'left':posX,'top':posY}).hide().fadeIn('slow');
var totalStars = $('.star').length;
if(totalStars == defInt){
clearInterval(starInt);
}
}, timer);
}
$(function(){
// Function arguments: starDust(max X position in px, max Y position in px, total number of stars, time in seconds between stars show);
starDust(600,300,25,1);
});
CSS
body{
background-color:#000;
}
.star{
position: absolute;
background-color:#fff;
min-width:5px;
min-height:5px;
}
I trying to make the div fall from top to bottom.
Here is the code that i tried but it doesn't satisfy my needs .I want to generate the 20 div once ready then how to make that 20 div falling continuously from top to bottom consistently. Is it possible to do that in jquery.
http://jsfiddle.net/MzVFA/
Here is the code
function fallingSnow() {
var snowflake = $('<div class="snowflakes"></div>');
$('#snowZone').prepend(snowflake);
snowX = Math.floor(Math.random() * $('#site').width());
snowSpd = Math.floor(Math.random() + 5000);
snowflake.css({'left':snowX+'px'});
snowflake.animate({
top: "500px",
opacity : "0",
}, snowSpd, function(){
$(this).remove();
fallingSnow();
});
}
var timer = Math.floor(Math.random() +1000);
window.setInterval(function(){
fallingSnow();
}, timer);
Much Appreciate your Help.
Thanks
Not sure if this is what you want.
I am animating 20 snowflakes, wait until animation finishes for all of them, then restart all over again.
jsfiddle
function fallingSnow() {
var $snowflakes = $(), qt = 20;
for (var i = 0; i < qt; ++i) {
var $snowflake = $('<div class="snowflakes"></div>');
$snowflake.css({
'left': (Math.random() * $('#site').width()) + 'px',
'top': (- Math.random() * $('#site').height()) + 'px'
});
// add this snowflake to the set of snowflakes
$snowflakes = $snowflakes.add($snowflake);
}
$('#snowZone').prepend($snowflakes);
$snowflakes.animate({
top: "500px",
opacity : "0",
}, Math.random() + 5000, function(){
$(this).remove();
// run again when all 20 snowflakes hit the floor
if (--qt < 1) {
fallingSnow();
}
});
}
fallingSnow();
Update
This version creates 20 divs only once, and animate them again and again.
jsFiddle
function fallingSnow() {
var $snowflakes = $(),
createSnowflakes = function () {
var qt = 20;
for (var i = 0; i < qt; ++i) {
var $snowflake = $('<div class="snowflakes"></div>');
$snowflake.css({
'left': (Math.random() * $('#site').width()) + 'px',
'top': (- Math.random() * $('#site').height()) + 'px'
});
// add this snowflake to the set of snowflakes
$snowflakes = $snowflakes.add($snowflake);
}
$('#snowZone').prepend($snowflakes);
},
runSnowStorm = function() {
$snowflakes.each(function() {
var singleAnimation = function($flake) {
$flake.animate({
top: "500px",
opacity : "0",
}, Math.random() + 5000, function(){
// this particular snow flake has finished, restart again
$flake.css({
'top': (- Math.random() * $('#site').height()) + 'px',
'opacity': 1
});
singleAnimation($flake);
});
};
singleAnimation($(this));
});
};
createSnowflakes();
runSnowStorm();
}
fallingSnow();
Update2
This one that initializes the left once the animation is done for each snowflake, looks more natural in my opinion.
Also changed the delay from
Math.random() + 5000
to
Math.random()*-2500 + 5000
demo
This is simple.
Your design of function must be this.
function snowflake()
{
if($(".snowflakes").length <= 20)
{
generate_random_snowflake();
}
else
{
call_random_snowflake();
}
}
check this out, pretty simple i just added a function that triggers jquerysnow() and then calls itself again wit random time
updated code now it will just create 20 snow flakes
snowCount = 0;
function snowFlakes(){
console.log(snowCount);
if(snowCount > 20){
return false
}else{
var randomTime = Math.floor(Math.random() * (500) * 2);
setTimeout(function(){
snowCount = snowCount +1;
jquerysnow();
snowFlakes();
},randomTime);
}
}
function jquerysnow() {
var snow = $('<div class="snow"></div>');
$('#snowflakes').prepend(snow);
snowX = Math.floor(Math.random() * $('#snowflakes').width());
snowSpd = Math.floor(Math.random() * (500) * 20);
snow.css({'left':snowX+'px'});
snow.html('*');
snow.animate({
top: "500px",
opacity : "0",
}, 2000, function(){
$(this).remove();
//jquerysnow();
});
}
snowFlakes()
http://jsfiddle.net/v7LWx/22/
I am creating an image hover effect but I am having problem with it. When I hover over certain images, the scrollbars appear which I want to avoid but don't know how to do so. I believe it has to do with viewport and calculations but am not sure how that is done.
Example Here
JSBin Code
Here is the code:
$('.simplehover').each(function(){
var $this = $(this);
var isrc = $this[0].src, dv = null;
$this.mouseenter(function(e){
dv = $('<div />')
.attr('class', '__shidivbox__')
.css({
display: 'none',
zIndex : 9999,
position: 'absolute',
top: e.pageY + 20,
left: e.pageX + 20
})
.html('<img alt="" src="' + isrc + '" />')
.appendTo(document.body);
dv.fadeIn('fast');
})
.mouseleave(function(){
dv.fadeOut('fast');
});
});
Can anyone please help me how do I make it so that hovered image appears at such place that scrollbars dont appear? (Of course we can't avoid scrollbar if image size is very very big)
I just want to show original image on zoom while avoiding scrollbars as much as possible.
Please note that I am planning to convert it into jQuery plugin and therefore I can't force users of plugin to have overflow set to hidden. The solution has do with viewport, left, top, scroll width and height, window width/height properties that I can incorporate into plugin later on.
Update:
I have come up with this:
http://jsbin.com/upuref/14
However, it is very very hacky and not 100% perfect. I am looking for a better algorithim/solution. I have seen many hover plugins that do this very nicely but since I am not that good at this, I can't do it perfectly well. For example Hover Zoom Chrome Plugin does great job of showing hovered images at appropriate place based on their size.
Like this:
html{overflow-x:hidden;}
html{overflow-y:hidden;}
All you need to do is add these definitions to your CSS and you're done.
Update with Resize: this is the mouseenter code for resizing and repositioning the pictures BOTH horizontally and vertically. Now, no matter where the HOVER image shows up, it's resized and positioned to always show in full AND uncut. As far as the scrollbars are concerned, if you show more thumbnails than can fit on the page, you will have scrollbars even before the HOVER images show up.
FINAL AND WORKING UPDATE: Because you had focused on the scrollbars being hidden, I think you overlooked the fact that if you put more thumbnails than the viewport can contain, the scrollbars would show up anyway and that therefore, since the user can scroll down the document, when you calculate the position of the hover image, not only do you need to account for the resize but you also to account for the scrollTop position too! FINAL JSBIN HERE, all pictures are showing RESIZED and in FULL no matter where the scrollTop is and no matter what the viewport size is.
$this.mouseenter(function () {
dv = $('<div />')
.attr('class', '__shidivbox__')
.css({
'display': 'none',
'z-index': 9999,
'position': 'absolute',
'box-shadow': '0 0 1em #000',
'border-radius': '5px'
})
.html('<img alt="" src="' + isrc + '" />')
.appendTo(document.body);
var DocuWidth = window.innerWidth;
var DocuHeight = window.innerHeight;
var DvImg = dv.find('img');
var TheImage = new Image();
TheImage.src = DvImg.attr("src");
var DivWidth = TheImage.width;
var DivHeight = TheImage.height;
if (DivWidth > DocuWidth) {
var WidthFactor = (DivWidth / DocuWidth) + 0.05;
DivHeight = parseInt((DivHeight / WidthFactor), 10);
DivWidth = parseInt((DivWidth / WidthFactor), 10);
}
var ThumbHeight = $this.height();
var ThumbWidth = $this.width();
var ThumbTop = $this.position().top;
var ThumbLeft = $this.position().left;
var SpaceAboveThumb = ThumbTop - $(document).scrollTop();
var SpaceBelowThumb = DocuHeight - ThumbTop - ThumbHeight + $(document).scrollTop();
var MaxHeight = Math.max(SpaceAboveThumb, SpaceBelowThumb);
if (DivHeight > MaxHeight) {
var HeightFactor = (DivHeight / MaxHeight) + 0.05;
DivHeight = parseInt((DivHeight / HeightFactor), 10);
DivWidth = parseInt((DivWidth / HeightFactor), 10);
}
var HoverImgLeft = 0;
var HoverImgTop = 0;
if (SpaceBelowThumb > SpaceAboveThumb) {
HoverImgTop = ThumbTop + ThumbHeight;
} else {
HoverImgTop = ThumbTop - DivHeight;
}
HoverImgTop = (HoverImgTop < 0) ? 0 : HoverImgTop;
HoverImgLeft = (DocuWidth - DivWidth) / 2;
dv.find('img').css({
'width': DivWidth,
'height': DivHeight,
'border-radius': '5px'
});
dv.css({
'left': HoverImgLeft,
'top': HoverImgTop
});
dv.fadeIn('fast');
});
Well, this looks fun. Anyway, here's my answer. I've been watching this for a few days and though I'd chip in too. The following will make sure that the hovering images do not go out of the viewport and in the event that the width of the image is bigger than the available space for display, the display of the image will be resized (You can comment out the code that does this if you don't want it. Just look for the word "resize" in the code).
var $document = $(document);
$('.simplehover').each(function(){
var $this = $(this);
// make sure that element is really an image
if (! $this.is('img')) return false;
var isrc = $this[0].src, ibox = null;
if (! isrc) return false;
ibox = $('<img />')
.attr('class', 'simpleimagehover__shidivbox__')
.css({
display: 'none',
zIndex : 99,
MozBoxShadow: '0 0 1em #000',
WebkitBoxShadow: '0 0 1em #000',
boxShadow: '0 0 1em #000',
position: 'absolute',
MozBorderRadius : '10px',
WebkitBorderRadius : '10px',
borderRadius : '10px'
})
.attr('src', isrc)
.appendTo(document.body);
$this.bind('mouseenter mousemove', function(e) {
$('.simpleimagehover__shidivbox__').hide();
var left = e.pageX + 5,
top = e.pageY + 5,
ww = window.innerWidth,
wh = window.innerHeight,
w = ibox.width(),
h = ibox.height(),
overflowedW = 0,
overflowedH = 0;
// calucation to show element avoiding scrollbars as much as possible - not a great method though
if ((left + w + $document.scrollLeft()) > ww)
{
overflowedW = ww - (left + w + $document.scrollLeft());
if (overflowedW < 0)
{
left -= Math.abs(overflowedW);
}
}
// 25 is just a constant I picked arbitrarily to compensate pre-existing scrollbar if the page itself is too long
left -= 25;
left = left < $document.scrollLeft() ? $document.scrollLeft() : left;
// if it's still overflowing because of the size, resize it
if (left + w > ww)
{
overflowedW = left + w - ww;
ibox.width(w - overflowedW - 25);
}
if (top + h > wh + $document.scrollTop())
{
overflowedH = top + h - wh - $document.scrollTop();
if (overflowedH > 0)
{
top -= overflowedH;
}
}
top = top < $document.scrollTop() ? $document.scrollTop() : top;
ibox.css({
top: top,
left: left
});
ibox.show();
});
$('.simpleimagehover__shidivbox__').mouseleave(function(){
$('.simpleimagehover__shidivbox__').hide();
});
$document.click(function(e){
$('.simpleimagehover__shidivbox__').hide();
});
$document.mousemove(function(e){
if (e.target.nodeName.toLowerCase() === 'img') {
return false;
}
$('.simpleimagehover__shidivbox__').hide();
});
});
While my solution itself is not perfect, you might find something useful in there that can help you determine the viewport. Also, you might want to think about the performance of the code. Since this is a plugin that you're building, you'll want to make some optimizations before releasing it to public. Basically, just make sure it's not slow.
You can position the image based on the available width: http://jsbin.com/upuref/19/
This demo takes in account the available space for positioning the image (i.e. the window width minus the image width). Also I've improved the event order, with the popup div only starting its fade-in after the image has been loaded.
My answer too (JSBin DEMO)
$('.simplehover').each(function(){
var $this = $(this);
// make sure that element is really an image
if (! $this.is('img')) return false;
var isrc = $this[0].src, dv = null;
if (! isrc) return false;
$this.mouseenter(function(e){
// mouse x position
var initXPos = e.pageX;
var initYPos = e.pageY+20-$(window).scrollTop();
var windowWidth = $(window).width();
var windowHeight = $(window).height();
// load original image
var $img = $('<img/>');
$img.on('load',function(eload) {
var widthImage = this.width;
var heightImage = this.height;
// set inline style for get sizes after (see problems webkit and cache)
$(this).css('width',widthImage);
$(this).css('height',heightImage);
var ratio = widthImage/heightImage;
var finalXPos = initXPos+widthImage>windowWidth? windowWidth-widthImage-5 : initXPos;
var finalYPos = initYPos;
var img = this;
// resize image if is bigger than window
if(finalXPos<0) {
finalXPos = 0;
$img.css('width', windowWidth-10);
$img.css('height',(windowWidth-10)/ratio);
}
// If overflow Y
if(finalYPos+getSize($img,'height')>windowHeight) {
// calculate where is more space (top or bottom?)
var showOnTop = (windowHeight-initYPos-10)<windowHeight/2;
if(showOnTop) {
if(initYPos<getSize($img,'height')) {
$img.height(initYPos-30);
$img.width(getSize($img,'height')*ratio);
}
finalYPos = 0;
finalXPos = initXPos+getSize($img,'width')>windowWidth? windowWidth-getSize($img,'width')-5 : initXPos;
}else {
// show on bottom
if(windowHeight-initYPos<getSize($img,'height')) {
$img.height(windowHeight-initYPos-10);
$img.width(getSize($img,'height')*ratio);
}
finalXPos = initXPos+getSize($img,'width')>windowWidth? windowWidth-getSize($img,'width')-5 : initXPos;
}
}
dv = $('<div />')
.attr('class', '__shidivbox__')
.css({
display: 'none',
zIndex : 9999,
position: 'absolute',
MozBorderRadius : '5px',
WebkitBorderRadius : '5px',
borderRadius : '5px',
top: finalYPos+$(window).scrollTop(),
left: finalXPos
}).append($img)
.appendTo(document.body);
dv.fadeIn('fast');
});
// load the original image (now is the same, but I think is better optimize it)
$img.attr("src",$this.attr("src"));
function getSize($el,widthOrHeight) {
// horrible but working trick :)
return +$el.css(widthOrHeight).replace("px","");
}
})
.mouseleave(function(){
dv.fadeOut('fast');
});
});
this script adapt the image to window size and adjust x position if needed.
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'm trying to make Divs to appear randomly anywhere on a webpage with javascript. So a div appears then disappears, then another div appears somewhere else on the page then disappears, then another div appears again in another random spot on the page then disappears, and so on.
I'm not sure on how to generate random units in pixels or what technique to use to generate random positions.
How do I do that? Here's my code:
var currentDivPosition = myDiv.offset(),
myDivWidth = myDiv.width(),
myDivHeight = myDiv.height(),
var myDiv = $('<div>'),
finalDivPositionTop, finalDivPositionLeft;
myDiv.attr({ id: 'myDivId', class: 'myDivClass' }); // already defined with position: absolute is CSS file.
// Set new position
finalDivPositionTop = currentDivPosition.top + Math.floor( Math.random() * 100 );
finalDivPositionLeft = currentDivPosition.left + Math.floor( Math.random() * 100 );
myDiv.css({ // Set div position
top: finalDivPositionTop,
left: finalDivPositionLeft
});
$('body').append(myDiv);
myDiv.text('My position is: ' + finalDivPositionTop + ', ' + finalDivPositionLeft);
myDiv.fadeIn(500);
setTimeout(function(){
myDiv.fadeOut(500);
myDiv.remove();
}, 3000);
Here's one way to do it. I'm randomly varying the size of the div within a fixed range, then setting the position so the object is always placed within the current window boundaries.
(function makeDiv(){
// vary size for fun
var divsize = ((Math.random()*100) + 50).toFixed();
var color = '#'+ Math.round(0xffffff * Math.random()).toString(16);
$newdiv = $('<div/>').css({
'width':divsize+'px',
'height':divsize+'px',
'background-color': color
});
// make position sensitive to size and document's width
var posx = (Math.random() * ($(document).width() - divsize)).toFixed();
var posy = (Math.random() * ($(document).height() - divsize)).toFixed();
$newdiv.css({
'position':'absolute',
'left':posx+'px',
'top':posy+'px',
'display':'none'
}).appendTo( 'body' ).fadeIn(100).delay(1000).fadeOut(500, function(){
$(this).remove();
makeDiv();
});
})();
Edit: For fun, added a random color.
Edit: Added .remove() so we don't pollute the page with old divs.
Example: http://jsfiddle.net/redler/QcUPk/8/
Let's say you have this HTML:
<div id="test">test div</div>
And this CSS:
#test {
position:absolute;
width:100px;
height:70px;
background-color:#d2fcd9;
}
Using jQuery, if you use this script, whenever you click the div, it will position itself randomly in the document:
$('#test').click(function() {
var docHeight = $(document).height(),
docWidth = $(document).width(),
$div = $('#test'),
divWidth = $div.width(),
divHeight = $div.height(),
heightMax = docHeight - divHeight,
widthMax = docWidth - divWidth;
$div.css({
left: Math.floor( Math.random() * widthMax ),
top: Math.floor( Math.random() * heightMax )
});
});
The way this works is...first you calculate the document width and height, then you calculate the div width and height, and then you subtract the div width from the document width and the div height from the document height and consider that the pixel range you're willing to put the div in (so it doesn't overflow out of the document). If you have padding and border on the div, you'll need to account for those values too. Once you've figured out the range, you can easily multiple that by Math.random() and find the random position of your div.
So once more: first find the dimensions of the container, then find the dimensions of your element, then subtract element dimensions from container dimensions, and THEN use Math.random() on that value.
The basic idea is encapsulated here:
http://jsfiddle.net/5mvKE/
Some bugs:
You missed to position the div absolutely. Otherwise it will not
work.
I think you need to ad 'px' to the numbers.
The map is made of strings
Right in your jQuery css setup:
myDiv.css({
'position' : 'absolute',
'top' : finalDivPositionTop + 'px',
'left' : finalDivPositionLeft + 'px'
});
I changed an existant code by this one for our website, you can see it on tweefox.nc
<script>
function draw() {
$(canvas).attr('width', WIDTH).attr('height',HEIGHT);
con.clearRect(0,0,WIDTH,HEIGHT);
for(var i = 0; i < pxs.length; i++) {
pxs[i].fade();
pxs[i].move();
pxs[i].draw();
}
}
function Circle() {
this.s = {ttl:8000, xmax:10, ymax:4, rmax:10, rt:1, xdef:950, ydef:425, xdrift:4, ydrift: 4, random:true, blink:true};
this.reset = function() {
this.x = (this.s.random ? WIDTH*Math.random() : this.s.xdef);
this.y = (this.s.random ? HEIGHT*Math.random() : this.s.ydef);
this.r = ((this.s.rmax-1)*Math.random()) + 1;
this.dx = (Math.random()*this.s.xmax) * (Math.random() < .5 ? -1 : 1);
this.dy = (Math.random()*this.s.ymax) * (Math.random() < .5 ? -1 : 1);
this.hl = (this.s.ttl/rint)*(this.r/this.s.rmax);
this.rt = Math.random()*this.hl;
this.s.rt = Math.random()+1;
this.stop = Math.random()*.2+.4;
this.s.xdrift *= Math.random() * (Math.random() < .5 ? -1 : 1);
this.s.ydrift *= Math.random() * (Math.random() < .5 ? -1 : 1);
}
this.fade = function() {
this.rt += this.s.rt;
}
this.draw = function() {
if(this.s.blink && (this.rt <= 0 || this.rt >= this.hl)) {
this.s.rt = this.s.rt*-1;
this.dx = (Math.random()*this.s.xmax) * (Math.random() < .5 ? -1 : 1);
this.dy = (Math.random()*this.s.ymax) * (Math.random() < .5 ? -1 : 1);
} else if(this.rt >= this.hl) this.reset();
var newo = 1-(this.rt/this.hl);
con.beginPath();
con.arc(this.x,this.y,this.r,0,Math.PI*2,true);
con.closePath();
var cr = this.r*newo;
g = con.createRadialGradient(this.x,this.y,0,this.x,this.y,(cr <= 0 ? 1 : cr));
g.addColorStop(0.0, 'rgba(255,255,255,'+newo+')');
g.addColorStop(this.stop, 'rgba(255,255,255,'+(newo*.2)+')');
g.addColorStop(1.0, 'rgba(255,255,255,0)');
con.fillStyle = g;
con.fill();
}
this.move = function() {
this.x += (this.rt/this.hl)*this.dx;
this.y += (this.rt/this.hl)*this.dy;
if(this.x > WIDTH || this.x < 0) this.dx *= -1;
if(this.y > HEIGHT || this.y < 0) this.dy *= -1;
}
this.getX = function() { return this.x; }
this.getY = function() { return this.y; }
}
$(document).ready(function(){
// if( /Android|AppleWebKit|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ) {
// } else {
if(document.getElementById('pixie')) {
WIDTH = $(window).width();
HEIGHT = $(window).height();
canvas = document.getElementById('pixie');
$(canvas).attr('width', WIDTH).attr('height',HEIGHT);
con = canvas.getContext('2d');
pxs = new Array();
rint = 60;
for(var i = 0; i < 50; i++) {
pxs[i] = new Circle();
pxs[i].reset();
}
setInterval(draw,rint);
}
// }
});
</script>