How to extend element width both ways? - javascript

Does that title sound confusing? I thought it might well anyways.
When I person clicks on the page I want them to be able to me a little line shorter and long.
You can see what I mean here:
http://jsfiddle.net/shawn31313/HKLhE/9/show/
Do a Mousedown and them move your move to the right. It works fine.
But now, move you mouse to the left. See the problem? It goes the same direction as it did when you dragged to the right. I know this is because i'm using width and obviously width on goes one way.
This is my code so far:
$(document).ready(function() {
var dragStatus = 0,
getPos, giveRandomID;
$(document).mousedown(function(event) {
dragStatus = 0;
getPos = {
top: event.clientY,
left: event.clientX
};
giveRandomID = Math.floor(Math.random() * 99999);
});
$(document).mousemove(function() {
var line = $('#line' + giveRandomID);
if (dragStatus == 0) {
$('body').append("<div id='line" + giveRandomID + "' class='line' style='position:absolute;top:" + getPos.top + "px;left:" + getPos.left + "px;background:black;width:2px;height:5px'></div>");
dragStatus = 1;
}
if (dragStatus == 1) {
if (event.clientX > line.offset().left) {
line.css({
width: event.clientX - line.offset().left
});
} else {
line.css({
width: line.offset().left - event.clientX
});
}
//for DEG "-" Top-Math.abs(DEG*2) for Deg "+" Top+(DEG*2)
}
});
$(document).mouseup(function() {
dragStatus = 2;
});
});​
I hope someone can help me out with this. Maybe a complete different way to set this up. Just something to fix this issue

To make the line stretch to the left, you have to update the left property:
if (event.clientX > getPos.left) {
line.css({
left: getPos.left,
width: event.clientX - getPos.left
});
} else {
line.css({
left: event.clientX,
width: getPos.left - event.clientX
});
}
jsFiddle: http://jsfiddle.net/HKLhE/16/

You'll need to modify the else case (moving right) to set the left property to auto and the right property to the initial mouse click X position. Comparing to the offset().left when moving left won't work because that value is changing.
Try this out for size:
http://jsfiddle.net/HKLhE/20/
Edit: Brilliand's solution is much more elegant.

Related

How to reverse direction of moving div once it reaches side of screen?

I have an absolutely positioned div that uses the jQuery .animate function to move horizontally from the right to left of the screen.
My problem is that once the div reaches the far left side, it continues and eventually disappears from the screen. How do you make it so that once the div reaches the left side, it will reverse and start going to the right? (and then vice versa so that the right side won't continue going right, but goes left again once it reaches the end)
HTML:
<div class="container">
<div class="block"></div>
</div>
CSS:
.block {
float:right;
position:absolute;
right:100px;
width:100px;
height:100px;
background:red;
}
jQuery:
$('.block').click(function() {
$(this).animate(
{"right": "+=100px"},"slow");
});
Here is my JSFiddle: https://jsfiddle.net/ebkc9dzL/
Thank you I really appreciate the help!
may be you should try like this:
$('.block').click(function() {
var leftPosition = $(this).position();
if (leftPosition.left > 100) {
$(this).animate({"right": "+=100px"},"slow");
} else {
$(this).animate({"right": "-=100px"},"slow");
}
});
when the element is close to the border the if..else part of the code will reverse the direction.
Here is a fiddle, try to click on the red box to get an idea on how it works:
https://jsfiddle.net/dimitrioglo/ebkc9dzL/14/
Working fiddle: https://jsfiddle.net/ebkc9dzL/19/
You need to have a variable outside the click function that will tell you the direction of the animation, so that once inside the click function you can calculate the location of the animated object using getBoundingClientRect() (mdn reference).
Then, if object is moving left and its left distance is less than its own width, you need to move it only enough so that it comes to the edge. If it's AT the edge (left is zero), you need to change the direction.
If it's moving right and its right distance is less than its own width, you need to move it only enough (calculated by window.innerWidth - 100, since 100 is width of your object) so that it comes to the edge. If it's AT the right edge, you need to change direction.
Changing direction in object you pass to jQuery's animate function is a simple matter of adding or subtracting from its "right" attribute.
var direction = "+";
$('.block').click(function() {
var obj = {},
distance = 100,
rect = this.getBoundingClientRect();
if(direction=="+"){
if(rect.left>0 && rect.left < 100)
distance = rect.left;
else if(rect.left<=0)
direction = "-";
}
else {
if(rect.right >(window.innerWidth-100) && rect.right+1<window.innerWidth)
distance = (window.innerWidth-rect.right);
else if(rect.right+1 >=window.innerWidth){
direction = "+";
}
}
obj = {"right": direction+"="+distance.toString()+"px"}
$(this).animate(obj,"slow");
});
Here you go: jsFiddle.
The new javascript is as follows:
var goLeft = true;
$('.block').click(function() {
var animateDist = 100;
var distLeft = $(this).position().left;
var distRight = window.innerWidth - distLeft;
if (goLeft) {
if (distLeft < 100) {
animateDist = "+="+distLeft+"px";
$(this).animate(
{"right": animateDist},"slow"
);
goLeft = false;
} else {
$(this).animate(
{"right": "+=100px"},"slow"
);
}
} else {
if (distRight < 100) {
animateDist = "-="+distRight+"px";
$(this).animate(
{"right": animateDist},"slow"
);
goLeft = true;
} else {
$(this).animate(
{"right": "-=100px"},"slow"
);
}
}
});
This isn't perfect, you need to adjust your internal window width to match the parent container, but this is enough to get you in the right direction.
Good luck!
Try this code:
var sign = [ "+" , "-" ];
var signPosition = 0;
var maxOffset = $(".block").offset().left;
$('.block').click(function() {
if ($(this).offset().left < 100) {
signPosition = 1;
} else if ($(this).offset().left == maxOffset) {
signPosition = 0;
}
$(this).animate(
{"right": sign[signPosition] + "=100px"},"slow");
});
The variable sign is the array that contains the directions in which the element might move, the variable signPosition contains the position of the direction currently in use, the variable maxOffset contains the starting position.
Hope this will help you.

chrome div randomly go to height 0px

I'm encountering a strange bug in chrome (also happen in chromium) but not under firefox.
I'm coding something to be able to resize some divs.
Sometimes in chrome a sibling div is displaying as 0px height when I'm resizing. For example, in this fiddle, if you drag the resizing line between the red and the blue div, the green div disappear.
I put a breakpoint on the code of the mousemove handler in order to inspect the div, but the css is exactly the same as the div displaying correctly.
To try it put a breakpoint here :
$("*").mouseup(function(event) {
if (downV) {
downV = false;
Is this a webkit related bug or am I doing something wrong? How can I fix this?
The problem seems to be, that it – for whatever reason – doesn't like the mixed units (percent and pixel values) while moving. Check out this fiddle, I've changed the code in $(".area").mousemove(function(event) to use percent values and commented out the conversion px => % in the $("*").mouseup(function(event) method and it seems to works correctly:
mouseup:
$("*").mouseup(function(event) {
if (downV) {
downV = false;
$("body").css("cursor","initial");
//upchild.css("height", upchild.height()*100/sizeTot+"%");
//downchild.css("height", downchild.height()*100/sizeTot+"%");
event.stopPropagation();
} else if (downH) {
downH = false;
$("body").css("cursor","initial");
upchild.css("width", upchild.width()*100/sizeTot+"%");
downchild.css("width", downchild.width()*100/sizeTot+"%");
event.stopPropagation();
}
});
mousemove:
$(".area").mousemove(function(event) {
if (downV){
var y = event.pageY - $(this).offset().top - upperSize;
if (y < 0) {
y = 0;
}
if (y > sizePart) {
y = sizePart;
}
upchild.css("height", (Math.floor(y)+1)*100/sizeTot+"%");
downchild.css("height", Math.floor(sizePart-y)*100/sizeTot+"%");
event.preventDefault();
} else if (downH) {
var x = event.pageX - $(this).offset().left - upperSize;
if (x < 0) {
x = 0;
}
if (x > sizePart) {
x = sizePart;
}
upchild.css("width", Math.floor(x)+1);
downchild.css("width", Math.floor(sizePart-x));
event.preventDefault();
}
});

Before / After Javascript issue

I am working on the currently codepen to display a hair treatment results
CODEPEN
But as soon as I add it to my website, it does not work.
I made a fiddle, and seems like the following class is breaking the code (on the fiddle works fine but does not follow the mouse pointer on the movement).
.wrapper_estudio {
width: 965px;
margin: 81px auto 0px auto;
padding-top: 100px;
}
EDIT
More especifically, the margin: 81px auto 0px auto; or the width: 965px; value.
DEMO (NOT JSFIDDLE) -> Check out this Demo to see what is exactly going on. Open console and uncheck the margin (or the width) on the div wrapper_estudio. Why does it work when margin is not set?
DEMO (JS FIDDLE)
$(function(){
var isDragging = false,
slide = $('.slide'),
controls = $('.controls');
$(".container").mousedown(function() {
$('.container').mousemove(function(e) {
var elemOffset = $(this).offset(),
relX = (e.pageX / $(this).width()) * 100;
console.log(relX);
if(relX < 98){
slide.css('width',relX + '%');
controls.css('left',relX - 3 + '%');
}
isDragging = true;
$(window).unbind("mousemove");
});
})
.mouseup(function() {
var wasDragging = isDragging;
isDragging = false;
$('.container').unbind("mousemove");
});
$('.container').mouseleave(function(){
isDragging = false;
$(this).unbind("mousemove");
});
});
Your problem lies in relX = (e.pageX / $(this).width()) * 100; where e.pageX gets the x position of the mouse relative to the left edge of the document as stated in the documentation.
Now when you add the margins with css the .container acquires an offset from the left side resulting in something like in this fiddle and the slider won't work correctly as happens in your website or in the fiddle you gave.
To solve this you need to modify the x coordinate like this:
relX = ((e.pageX-elemOffset.left) / $(this).width()) * 100;
What this does is subtracting the left offset of the image container from the distance from the left edge of the document thus returning the relative position of the mouse in the element.
So your final code should look like this:
$(function(){
var isDragging = false,
slide = $('.slide'),
controls = $('.controls');
$(".container").mousedown(function() {
$('.container').mousemove(function(e) {
var elemOffset = $(this).offset(),
relX = ((e.pageX-elemOffset.left) / $(this).width()) * 100;
console.log(relX);
if(relX < 98){
slide.css('width',relX + '%');
controls.css('left',relX - 3 + '%');
}
isDragging = true;
$(window).unbind("mousemove");
});
})
.mouseup(function() {
var wasDragging = isDragging;
isDragging = false;
$('.container').unbind("mousemove");
});
$('.container').mouseleave(function(){
isDragging = false;
$(this).unbind("mousemove");
});
});
And here is the working fiddle

clientX and clientY not giving correct mouse pointer location

I wrote this simple code to print a small dot on the location where I clicked with the mouse pointer:-
$(document).ready(function(){
$('#pane').click(function(e){
var pixel = $('<div />')
.addClass('pixel')
.css({
top: e.clientY,
left: e.clientX
});
$('#pane').append(pixel)
});
});
See this fiddle I created. When I click anywhere inside the rectangle, a small dot is printed in that location. But the problem is that dot is not printed where the mouse pointer's tip was. See the below image to see what I meant:-
I tried in both Firefox and Chrome.
Your code is working correctly,
Zoom your page and check,
i have changed pixel height and width for better understanding from 2px to 3px.
and drawing from e.clientX -1 and e.clientY -1 position so it looks exactly center.
You can find Fiddle
The most examples I've found don't work if there are a scrolled page... I used this algorythm in order to get the position:
var getOffsets = function($event){
var p = {};
var body = "search the document for the body element";
p.x = body.offsetLeft;
p.y = body.offsetTop;
while (body.offsetParent) {
p.x = p.x + body.offsetParent.offsetLeft;
p.y = p.y + body.offsetParent.offsetTop;
if (body == document.getElementsByTagName("body")[0]) {
break;
}
else {
body = body.offsetParent;
}
}
return p;
}
However, after that you have to consider also other elements, im my case:
var GetExactClickPosition = function($event){
var tr = $($event.target);
if ($event.target.localName != 'tr'){
tr = $($event.target).closest('tr');
}
var listDiv = $($event.target).closest('div');
var p = getOffsets($event);
var container = $('#mailingListExcludeMenuContainer');
container.css({
top: p.y - listDiv.scrollTop() - tr.height() - container.height() + $event.offsetY + "px",
left: p.x + $event.offsetX + "px"
});
container.show();
};
I have a list with scroller inside the main scroller of the page...
I used it in order to show a little menu at the position of the mouse click.

Moving a div left and right continously

I've been trying to get this javascript animation to work for hours now, and I got nothing. The problem isn't getting my div box to move from left to right(or from top to bottom), it's the opposite of each case that I have trouble with it. Here's what I have so far(In addition, I have set boundaries set to keep my moving box contained within the view window so if it hits any one of sides, it should move to the opposite direction). Any help is awesome at this point.
Note: the next step is to create a bouncing effect for the box, but i'll worry about that once i get simple animation working.
setInterval(function(){
if(parseInt(box.style.left) > parseInt(viewDim.width - 57)){
box.style.left -= parseInt(box.style.left) - 2 + 'px';
/* } else if(parseInt(box.style.left) < 0){
//debug_log("HIT!!");
//parseInt(box.style.left) += 2 + 'px';
} else if(parseInt(box.style.top) > parseInt(viewDim.height-58)){
} else if(parseInt(box.style.top) < 0){*/
} else {
box.style.left = parseInt(box.style.left) + 2 + 'px';
//box.style.top = parseInt(box.style.top) + 5 + 'px';
}
}, 20);
Code like this always works for me:
var boxWidth = 57, delta = 2;
setInterval(function(){
var left = parseInt(box.style.left);
if(left >= parseInt(viewDim.width - boxWidth)){
delta = -2;
}
if (left <= 0) {
delta = 2;
}
box.style.left = left + delta + 'px';
}, 20);
Although you have your solution now, I couldn't help myself from making complete code here.
The bouncing box bounces around inside the parent element. Tested in IE8, FF3, and Opera11.
This can give an idea, how to do it with jQuery
http://jsfiddle.net/rFkpy/
$('#myDiv').click(function() {
$(this).animate({
left: '+=250'
}, 1500, "easeOutBounce", function() {
// callBack
});
});

Categories