jQuery or Javascript logarithmic repulsion
Okay, I know that is a funky-sounding title, but I couldn't think of a better one for my needs. Also, this is a lot of text, but just visiting the link below will explain 90% of what I need.
BACKGROUND: I am designing a price-range slider for an e-commerce site. An early prototype can be found here: http://mcdev3com00.web705.discountasp.net/collision-test.htm.
It may be helpful to visit this page before reading on. If you slide the left handle towards the right, it is almost accomplishing my goal and seeing that will make the rest easier to understand.
GOAL: I am trying to design the slider so that the information divs located at the top of the handle will repel each other logarithmic-ally the closer they come to each other.
The purpose is to allow the display of the price information without the divs containing that information colliding when the handles have only a little space between them.
DETAILS: So in other words, as the left handle slides to the right, the div containing the dollar value on the top of it should at first slide in small increments towards the left of the lower part of the handle, but as the whole left handle comes closer to the right handle, the increments become larger until the right-side of the div containing the price (upper part of handle) is flush with the right side of the lower part of the handle.
RULES/CONSTRAINTS:
- There must always be at least a few pixels of space between left and right handles, they can not overlap.
- When there is only the minimum distance between handles, the RIGHT SIDE of the left handle's price container must be flush with the RIGHT SIDE of the lower part of the left handle and the LEFT SIDE of the right handle's price container must be flush with the LEFT SIDE of the lower part of the right handle.
- When the left handle is as far left as it can go (x=0%) the LEFT side of the upper div (price container) must be flush with the left side of the lower part of the handle.
- When the right handle is as far right as it can go (x=100%) the RIGHT side of the upper div (price container) must be flush with the right side of the lower part of the handle.
- Moving one handle will move it's own price container and the price container of the opposite handle, as long as doing so doesn't violate rules 1-4.
VARIABLES: 1. Location of left handle 2. Location of right handle 3. Width of left handle price container 4. Width of right handle price container 5. Total width of slider control 6. Distance between left and right handles
PROGRESS SO FAR: The left handle (as you can see by visiting the link above) is almost functioning properly. The problem is that if you slide it almost all of the way over to the right, the price container bounces farther to the left than it is supposed to according to the if/then logic and that is baffling me.
The right handle really isn't functioning well at all.
Any help here would be GREATLY appreciated. I have been up all night trying to beat a deadline with a client and I am just hitting a wall.
Many thanks!
PS-The formula that should be working the magic is called "avoidCollision":
function avoidCollision(handle0, handle1) {
var lPrice = $("#test-left-handle-info"); //price container left
var rPrice = $("#test-right-handle-info"); //price container right
var lPriceWidth = lPrice.outerWidth(); //width of left price container
var rPriceWidth = rPrice.outerWidth(); //width of right price container
var lPriceOffsetLeft = (lPrice.offset().left); //document-level LEF开发者_StackOverflowT-EDGE position of left price container
var lPriceOffsetRight = lPriceOffsetLeft + lPriceWidth; //document-level RIGHT-EDGE position of left price container
var rPriceOffsetLeft = rPrice.offset().left; //document-level LEFT-EDGE position of right price container
var lContainer = $("#handle0"); //containing element for left-side price container and lower handle.
var rContainer = $("#handle1"); //containing element for right-side price container and lower handle.
var tW = $("#slider-range").width(); //total width of slider
var hw = $("#handle0").outerWidth(); //handle width
var hHw = ($("#handle0").outerWidth()) / 2; // half handle width
var cPosL = (lContainer.offset().left); //left edge of left handle
var cPosLre = cPosL + hw; //right edge of left handle
var cPosR = rContainer.offset().left; //left edge of right handle
//distance between handles as a percentage of total slider width:
var dis = ((cPosR - cPosLre) / tW);
//inverse of "dis" or remainder out of 100%:
var disInv = 1 - dis;
var mlt = -1; //multiplier to get the correct movement value (i.e. negative value to move left along the x-axis)
//if(cPosLRE < cPosLPrev){disInv = dis;} ?????
var lMove = ((lPriceWidth * disInv) * mlt) + hHw + 1; //css "left" value of lPrice
var rMove = rPriceWidth * disInv; //css "left" value of rPrice
//this is just helpful info for debugging:
$("#infoDivDiv").html("<br/><br/><strong>lInfoPosRE:</strong> " + lPriceOffsetRight + "<br/><strong>cPosLRE:</strong> " + cPosLre + "<br/><strong>lMove:</strong> " + lMove + "<br/><strong>lInfoWidth:</strong> " + lPriceWidth + "<br/><strong>Hw:</strong> " + hw + "<br/><strong>lInfoPos:</strong> " + lPriceOffsetLeft + "<br/><strong>cPosL:</strong> " + cPosL + "<br/><strong>cPosLPrev:</strong> " + cPosLPrev + "<br/><strong>cPosR:</strong> " + cPosR + "<br/><strong>rInfoPos:</strong> " + rPriceOffsetLeft + "<br/><strong>cPosRPrev:</strong> " + cPosRPrev);
//here is where the magic happens, also where I am lost.
if ((((lPriceOffsetRight >= cPosLre) && (lPriceOffsetLeft >= cPosL)) || (cPosLre < cPosLPrev)) && (cPosL > 10)) {
lPrice.css({ left: lMove });
}
if ((((rPriceOffsetLeft <= cPosR)) || (cPosR > cPosRPrev)) && (cPosR < (tW - 10))) {
rPrice.css({ left: rMove });
}
cPosLPrev = cPosLre; //assign the current value to the "previous" container to be used in the next run so we know in which direction we are moving.
cPosRPrev = cPosR; //assign the current value to the "previous" container to be used in the next run so we know in which direction we are moving.
}
I'd rather not delve into your code, but I can see the steps you need to get there:
- Find the midway point between the two sliders
- Find the proportion the sliders are between their home position and the middle point.
- This proportion indicates where the label should go. A value of 1 means all the way to one side, and a value of 0 all the way to the other.
I don't see how you plan to involve logarithms...
Here's some pseudocode:
var leftPos, rightPos; //Get these somehow
var leftHome = 0;
var rightHome = 1;
var midpoint = (leftPos + rightPos) / 2;
var leftProportion = (leftPos - leftHome) / (midpoint - leftHome);
var rightProportion = (rightPos - rightHome) / (midpoint - rightHome);
if leftProportion == 0
put label flush with left edge
up unto leftProportion == 1
put label flush with right edge
if rightProportion == 0
put label flush with right edge
up unto rightProportion == 1
put label flush with left edge
精彩评论