How can I get rangeslider.js to work on mobile devices? - javascript

I have the following problem, you will see I have a web page where I implement the rangeslider plugin on PC it works correctly but on mobile I can't explain myself: when on mobile I select the slider I cannot make it go up or down or change the amount it has, it is only modified while The scroll is used but as you know with the scroll the user moves on mobile, therefore it cannot work so check what I mean on the page
this is the link of the page: http://ucreativa.work/linux/nsite2/product.php
As you can see, it works well on PC, but if they try to use it on mobile, the slider does not work.
What do you think that might be? I append the js code that I use I don't append the css because it is a lot of code that is not relevant
my question is can this plugin work on mobile?
var cpu_cur_val = '2';
var ram_cur_val = '4';
var disk_cur_val = '8';
var backup_cur_val = '30';
var ips_cur_val = '0';
function new_range (wrapper) {
// Variables to use later
var rangeWrapper = document.querySelector('.' + wrapper + '__wrapper');
var rangeInput = document.querySelector('.' + wrapper + '__input');
var rangeValues = document.querySelector('.' + wrapper + '__values');
var rangeValueNumberBottom = document.querySelector('.' + wrapper + '__value__number--bottom');
var rangeValueTextBottom = document.querySelector('.' + wrapper + '__value__text--bottom');
var rangeSliderPaths = document.querySelectorAll('.' + wrapper + '__slider__path');
var mouseX = 0;
var mouseY = 0;
var mouseInitialY = 0;
var mouseDy = 0;
var mouseDyLimit = 25;
var mouseDyFactor = 3;
var max = parseInt(rangeInput.max);
var rangeMin = parseInt(rangeInput.min);
var rangeMax = parseInt(rangeInput.max);
var rangeValue = parseInt(rangeInput.value);
var rangeHeight = 320;
var currentY = rangeHeight * rangeValue / max;
var rangeMinY = rangeHeight * rangeMin / max;
var rangeMaxY = rangeHeight * rangeMax / max;
var scaleMax = 0.32;
var scale, newPath, newY, newSliderY, lastMouseDy, rangeWrapperLeft, pageX, pageY;
// Update slider value, initially using the `input` value
updateValue();
// Function to build the slider `path`, using the given `dy` and `ty` values
function buildPath(dy, ty) {
return 'M 0 ' + ty + ' q ' + mouseX + ' ' + dy + ' 120 0 l 0 320 l -120 0 Z';
}
// Function to update the slider value
function updateValue() {
// Clear animations if are still running
anime.remove([rangeValues, rangeSliderPaths[0], rangeSliderPaths[1]]);
// Calc the `input` value using the current `y`
rangeValue = parseInt(currentY * max / rangeHeight);
// Calc `scale` value for numbers
scale = (rangeValue - rangeMin) / (rangeMax - rangeMin) * scaleMax;
// Update `input` value
rangeInput.value = rangeValue;
// rangeSum.innerText = rangeValue;
rangeValueNumberBottom.innerText = rangeValue;
// Match the javascript value to real input value;
rangeInput.setAttribute('value', rangeValue);
switch (wrapper) {
default:
rangeValueNumberBottom.innerText = rangeValue;
break;
case 'cpu':
cpu_cur_val = rangeValue;
break;
case 'ram':
if (rangeValueNumberBottom.innerText == '0') {
rangeValueTextBottom.innerText = 'זיכרון (MB)';
rangeValueNumberBottom.innerText = '500';
} else {
rangeValueTextBottom.innerText = 'זיכרון (GB)';
}
ram_cur_val = rangeValue;
break;
case 'disk':
rangeValueNumberBottom.innerText = rangeValue + '0';
disk_cur_val = rangeValue;
break;
case 'backup':
if (rangeValueNumberBottom.innerText == '0') {
rangeValueNumberBottom.innerText = '0';
} else {
rangeValueNumberBottom.innerText = rangeValue + '0';
}
backup_cur_val = rangeValue;
break;
case 'ips':
ips_cur_val = rangeValue;
break;
}
// Some maths calc
if (Math.abs(mouseDy) < mouseDyLimit) {
lastMouseDy = mouseDy;
} else {
lastMouseDy = mouseDy < 0 ? -mouseDyLimit : mouseDyLimit;
}
// Calc the `newSliderY` value to build the slider `path`
newSliderY = currentY + lastMouseDy / mouseDyFactor;
if (newSliderY < rangeMinY || newSliderY > rangeMaxY) {
newSliderY = newSliderY < rangeMinY ? rangeMinY : rangeMaxY;
}
// Build `path` string and update `path` elements
newPath = buildPath(lastMouseDy, rangeHeight - newSliderY);
rangeSliderPaths[0].setAttribute('d', newPath);
rangeSliderPaths[1].setAttribute('d', newPath);
}
// Function to simulate the elastic behavior
function elasticRelease() {
// Morph the paths to the opposite direction, to simulate a strong elasticity
anime({
targets: rangeSliderPaths,
d: buildPath(-lastMouseDy * 1.3, rangeHeight - (currentY - lastMouseDy / mouseDyFactor)),
duration: 150,
easing: 'linear',
complete: function () {
// Morph the paths to the normal state, using the `elasticOut` easing function (default)
anime({
targets: rangeSliderPaths,
d: buildPath(0, rangeHeight - currentY),
duration: 4000,
elasticity: 880
});
}
});
}
// Handle `mousedown` and `touchstart` events, saving data about mouse position
function mouseDown(e) {
mouseY = mouseInitialY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY;
rangeWrapperLeft = rangeWrapper.getBoundingClientRect().left;
}
// Handle `mousemove` and `touchmove` events, calculating values to morph the slider `path` and translate values properly
function mouseMove(e) {
if (mouseY) {
pageX = e.targetTouches ? e.targetTouches[0].pageX : e.pageX;
pageY = e.targetTouches ? e.targetTouches[0].pageY : e.pageY;
mouseX = pageX - rangeWrapperLeft;
mouseDy = (pageY - mouseInitialY) * mouseDyFactor;
newY = currentY + mouseY - pageY;
// alert(newY);
if (newY >= rangeMinY && newY <= rangeMaxY) {
currentY = newY;
mouseY = pageY;
} else {
currentY = newY < rangeMinY ? rangeMinY : rangeMaxY;
}
// After doing maths, update the value
updateValue();
}
}
// Handle `mouseup`, `mouseleave` and `touchend` events
function mouseUp() {
// Trigger elastic animation in case `y` value has changed
if (mouseDy) {
elasticRelease();
}
// Reset values
mouseY = mouseDy = 0;
}
// Events listeners
rangeWrapper.addEventListener('mousedown', mouseDown);
rangeWrapper.addEventListener('touchstart', mouseDown);
rangeWrapper.addEventListener('mousemove', mouseMove);
rangeWrapper.addEventListener('touchmove', mouseMove);
rangeWrapper.addEventListener('mouseup', mouseUp);
rangeWrapper.addEventListener('mouseleave', mouseUp);
rangeWrapper.addEventListener('touchend', mouseUp);
}

Related

Increase and decrease SVG shape - JS

I would like you to help me for a thing here, for a function to increase and then decrease SVG shape when it hits limit.
It should go from 3 to 6 and then 6 to 3 and so on... but instead it goes from 3 to 6 and then 6 to minus infinite. And I don't understand why.
Here is my code :
var size = 3;
var sizeManager = 1;
function increaseAnimation(el){
var elem = document.getElementById(el);
elem.style.transform = "scale("+size+")";
timer = setTimeout('increaseAnimation(\''+el+'\',3000)');
size=size+0.005*sizeManager;
if(size >= 6){
sizeManager=sizeManager*-1;
}
if (size <= 3){
sizeManager=sizeManager*+1;
}
}
Your weird setTimeout implementation, with bound was broken.
There's also the issue that your sizeManager is not properly reflecting:
function increaseAnimation(id, interval) {
var size = 1;
var velocity = 0.05;
var elem = document.getElementById(id);
function iterate() {
elem.style.transform = "scale(" + size + ")";
size += velocity;
if (size > 2 || size < 1) {
velocity *= -1; // velocity reflected
}
}
var timer = setInterval(iterate, interval);
return function stop() {
clearInterval(timer)
}
}
I also added a stop function which you can call at a later point.
var stopper = increaseAnimation("content", 16);
setTimeout(stopper, 5000);
The error is with the line sizeManager=sizeManager*+1; Multiplying a number by one doesn't change it. You basically want to toggle sizeManager between -1 and +1, and you can do so by multiplying by -1, regardless of whether it is currently negative or positive.
I've tested this code and it seems to work:
var size = 3;
var sizeManager = 1;
function increaseAnimation(el) {
var elem = document.getElementById(el);
elem.style.transform = "scale(" + size + ")";
timer = setTimeout("increaseAnimation('" + el + "', 3000)");
size += 0.005 * sizeManager;
if (size >= 6 || size <= 3) {
sizeManager *= -1;
}
}
Full HTML for a POC demo at: https://pastebin.com/GW0Ncr9A
Holler, if you have questions.
function Scaler(elementId, minScale, maxScale, deltaScale, direction, deltaMsecs) {
var scale = (1 == direction)?minScale:maxScale;
var timer = null;
function incrementScale() {
var s = scale + deltaScale*direction;
if (s < minScale || s > maxScale) direction *= -1;
return scale += deltaScale*direction;
};
function doScale(s) {
document.getElementById(elementId).style.transform = 'scale(' + s + ')';
};
this.getDeltaMsecs = function() {return deltaMsecs;};
this.setTimer = function(t) {timer = t;};
this.run = function() {doScale(incrementScale());};
this.stop = function() {
clearInterval(timer);
this.setTimer(null);
};
};
var scaler = new Scaler('avatar', 3, 6, .05, 1, 50);
function toggleScaler(ref) {
if ('run scaler' == ref.value) {
ref.value = 'stop scaler';
scaler.setTimer(setInterval('scaler.run()', scaler.getDeltaMsecs()));
}
else {
scaler.stop();
ref.value = 'run scaler';
}
};

How to prevent randomly generated images from overlapping using Javascript

I'm trying to spawn randomly generated targets on the screen using a function to copy an invisible image of the target to be spawned at a random place within the screen using window object properties.
For this to happen I think the image have to have position set to absolute, but then several images may be spawned in a way that they will overlap, how can I prevent this from happening?
The div element where I copy my first image and also store the other copies.
<div id="targetsDiv">
<img src="target2.png" alt="target_shot" class="target" />
</div>
Inside the script:
var x_pixels = window.innerWidth - 180;
var y_pixels = window.innerHeight - 180;
var x_midScreen = window.innerWidth / 2;
var y_midScreen = window.innerHeight / 2;
var xRandom = Math.floor(Math.random()*x_pixels) +1;
var yRandom = Math.floor(Math.random()*y_pixels) +1;
var targetCollection = document.getElementById("targetsDiv");
var targetCopy = targetCollection.innerHTML
var targetList = document.getElementsByClassName("target");
targetList[0].style.display = "none";
var targetNr = 1;
var numberOfSpawns = 3;
function spawnTargets () {
while (targetNr <= numberOfSpawns) {
if ((xRandom < x_midScreen - 126 || xRandom > x_midScreen + 26) || (yRandom < y_midScreen - 126 || yRandom > y_midScreen + 26)) {
targetCollection.innerHTML += targetCopy;
targetList[targetNr].style.left = xRandom + "px";
targetList[targetNr].style.top = yRandom + "px";
targetNr++;
}
xRandom = Math.floor(Math.random()*x_pixels) +1;
yRandom = Math.floor(Math.random()*y_pixels) +1;
}
}
PS: I appreciate all help, tips and tweaks that you guys provide:) Thanks for helping
The area you want to exclude in the centre of the screen is rather large, and on my little laptop, there isn't even any room to still show the random positioned images.
But anyway, this piece of code should do the job -- I added some infinite loop protection which on my PC was a life-saver:
HTML (added style attribute)
<div id="targetsDiv">
<img src="target2.png" alt="target_shot" class="target"
style="visibility:hidden"/>
</div>
JavaScript:
window.addEventListener('load', function () {
var targetCollection = document.getElementById("targetsDiv");
var template = document.getElementsByClassName("target")[0];
var targetWidth = template.offsetWidth;
var targetHeight = template.offsetHeight;
var x_pixels = window.innerWidth - targetWidth;
var y_pixels = window.innerHeight - targetHeight;
var x_midScreen = window.innerWidth / 2;
var y_midScreen = window.innerHeight / 2;
function spawnTargets (numberOfSpawns) {
var targets = [];
var count = 0; // infinite recursion protection
for (var i = 0; i < numberOfSpawns; i++) {
do {
do {
var x = Math.floor(Math.random()*x_pixels);
var y = Math.floor(Math.random()*y_pixels);
if (count++ > 200) {
console.log('give up');
return;
}
} while ((x >= x_midScreen-450 && x <= x_midScreen+300) && (y >= y_midScreen-350 || y <= y_midScreen+200));
for (var j = 0; j < i; j++) {
if (x >= targets[j].x - targetWidth && x <= targets[j].x + targetWidth &&
y >= targets[j].y - targetHeight && y <= targets[j].y + targetHeight) break; // not ok!
}
} while (j < i);
targets.push({x, y});
img = document.createElement('img');
img.src = template.src;
img.setAttribute('width', targetWidth + 'px');
img.setAttribute('height', targetHeight + 'px');
img.className = template.className;
targetCollection.appendChild(img);
img.style.left = x + "px";
img.style.top = y + "px";
}
}
spawnTargets(3);
});

program flow animating in javascript

Hello I am having errors with my code:
https://jsfiddle.net/wzhm2whj/
<script>
//Initial Global variables
var mainloop_frame_time = 34;
var top = 0;
var rootMenu = document.getElementById('menu');
var rootMenuDivs = rootMenu.getElementsByTagName('div')[0];
var rootListDivs = rootMenuDivs.getElementsByTagName('ul')[0];
var childDivs = rootListDivs.getElementsByTagName('div');
var childDiv = childDivs[0];
var childDiv_counter = 0;
var child_change_flag = true;
var child_index_increment = 0;
var child_index_amount = childDivs.length;
//var child_animation_keyframe = 0;
var frame = 0;
var childDiv_tmp1_position = 0;
//finding the web browsers viewport size.
var elem = (document.compatMode === "CSS1Compat") ? document.documentElement : document.body;
var client_height = elem.clientHeight;
var process_array = new Array();
//Initial styling
for (var i = 0; i < childDivs.length; i++) {
var childDiv = childDivs[0];
childDiv.style.backgroundColor = "antiquewhite";
}
var childDiv = childDivs[0];
//rotate function variables
var rotate_div;
var rotate_passed_deg;
var rotate_deg_stop;
var rotate_results;
var rotate_current_deg = 0;
var speed_modifier = 1;
var tmp1_speed = 0;
//case flags
case2_flag = -1;
case3_flag = -1;
//This may not be needed >>> If not, put all code in mainloop.
var processes_logic = function() {
switch (frame) {
case 0:
process_array.push(menu_child0);
break;
//this case is when the previous case is 80% done
case 28:
rootMenu.style.transformOrigin = "top left";
process_array.push(menu_slant);
break;
case 35:
//Added the ability for paramaters, all push paramaters here are: function, menu_index, position, speed, tmp as flag for switching to next menu,
//process_index used to give the process index as refrence to delete..
window.alert(process_array.length);
process_array.push(new Array(menu_div_slide_out, child_index_amount - 1, 0, 0, 0, process_array.length-1));
break;
}
}
var initiate_all_processes = function() {
for (var i = 0; i < process_array.length; i++) {
//Added the ability for paramaters, considerer removing as its not used atm, or revising.
if (process_array[i] != undefined && process_array[i] != null && process_array[i] != "") {
if (process_array[i].length < 6) {
process_array[i]();
} else {
process_array[i][0](process_array[i][5]);
}
}
}
}
function menu_div_slide_out(process_index) {
/*process_array[process_index][
0 = function,
1 = current menu item (index length working backwards)
2 = position,
3 = speed,
4 = tmp,
5 = refrence to this process in array] */
//for debuging purposes to see if a ChildDiv is not devined, what process index is being pointed to.
//window.alert('Process index ' + process_index);
//!!!!!!!! You are probably mixing up how you are setting process index! try +1
process_array[process_index][2] += 3.5 + (process_array[process_index][3] * 1.7);
process_array[process_index][3] += (speed_modifier * .3);
childDivs[process_array[process_index][1]].style.left = process_array[process_index][2] + 'px';
if (process_array[process_index][2] > 100 && process_array[process_index][4] && process_array[process_index][1] > 0) {
// window.alert('CCC');
process_array[process_index][4] = true;
//Add another process at ever 100pxs
process_array.push(new Array(menu_div_slide_out, process_array[process_index][1] - 1, 0, 0, false, process_array.length-1));
//debugger;
} else
if (process_array[process_index][2] >= (900 - (process_array[process_index][2] / 20))) {
childDivs[process_array[process_index][1]].remove();
//process_array.splice(process_array[process_index][5], 1);
}
}
function menu_slant() {
rotate_return = rotate(rootMenu, .1 + (tmp1_speed), 27);
tmp1_speed += (speed_modifier * .5);
if (rotate_return === true) {
/////////////This can be unremoved because there is more animation, perhaps. or can be done in another key frame.
tmp1_speed = 0;
rotate_current_deg = 0;
remove_process(menu_slant);
} else {
if (rotate_return / 27 * 100 >= 60 && case3_flag < 0) {
case2_flag = frame;
}
}
}
var menu_child0 = function() {
childDiv_tmp1_position += 3 + (tmp1_speed * 1.7);
childDiv.style.top = childDiv_tmp1_position + 'px';
rotate(childDiv, .2 + (tmp1_speed), 170);
tmp1_speed += (speed_modifier * .7);
if (childDiv_tmp1_position / client_height * 100 >= 80 && case2_flag < 0) {
case2_flag = frame;
}
if (childDiv_tmp1_position >= client_height) {
childDiv.style.visibility = 'hidden';
tmp1_speed = 0;
childDiv_tmp1_position = 0;
rotate_current_deg = 0;
//may be bloated >>
remove_process(menu_child0);
}
}
function remove_process(index) {
var index_tmp = process_array.indexOf(index);
if (index_tmp >= 0) {
process_array.splice(index_tmp, 1);
}
}
function rotate(rotate_div, rotate_passed_deg, rotate_passed_deg_stop) {
rotate_current_deg += rotate_passed_deg;
rotate_deg = rotate_current_deg < rotate_passed_deg_stop ? rotate_current_deg : rotate_passed_deg_stop;
rotate_div.style.webkitTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.mozTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.msTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.oTransform = 'rotate(' + rotate_deg + 'deg)';
rotate_div.style.transform = 'rotate(' + rotate_deg + 'deg)';
if (rotate_current_deg >= rotate_passed_deg_stop) {
return true;
} else {
return rotate_current_deg;
}
}
//main loop for the animation
var mainloop = function() {
processes_logic();
initiate_all_processes();
frame++;
}
var loop_interval = setInterval(mainloop, mainloop_frame_time);
</script>
I am trying to animate my website falling apart but I am having a hard time articulation this into code. I thought of running the animation in a loop, creating events at specific frames and reusing some codes as functions. I have a rotate function which works to rotate several things.
THE PROBLEM:
The problem I am having is sliding my menu items one at a time to the right. I want one to slide a bit and the next to start sliding after. I wrote a function to slide an item and then in that function it adds another process to an array for the next menu item to be called and run the same function (with passed interval of who is calling). I do not know how many menu items there will be, thats why I am trying to make it dynamic.
I can get it so that the first mwnu item falls, the menu falls by rotating it (some times if there is an error in the code then it wont rotate, but when there are no errors it works better).
The issue is sliding each menu item.
my website is here: http://clearlove.ca/89-404-error
Can any one help me with why this isnt working, and if there is a better way to do what I am trying to do?

Calculating & setting scroll speed of object in viewport

I have image I am scrolling within a div.
It make sure the image is visible I am using
var isVisible = (
threshold.top >= -39 &&
threshold.bottom <= (window.innerHeight || document.documentElement.clientHeight)
);
What I am trying to do now is make sure that once the element is visible it is able to completely finish scrolling before going out of the view port.
I am thinking I can do this by effecting the speed value based on the the distance of the element from the top on the window. But I am having a very hard time doing this.
I am using .getBoundingClientRect() to get the distance the element is from the top of the viewport:
var threshold = document.getElementById('page-feature').getBoundingClientRect();
var thresholdY = threshold.top;
Below is my code so far:
function scrollImageInViewport() {
var threshold = document.getElementById('page-feature').getBoundingClientRect();
var thresholdY = threshold.top;
var isVisible = (
threshold.top >= -39 &&
threshold.bottom <= (window.innerHeight || document.documentElement.clientHeight)
);
if (isVisible && window.innerWidth > 550) {
scrollDir(thresholdY);
}
}
function scrollUp(thresholdY) {
if (thresholdCounter < maxScrollNegative) {
return;
} else {
pageScroll.setAttribute('style', '-webkit-transform:translate3d(0,' + (--thresholdCounter *speed) + 'px,0); -ms-transform:translate3d(0,' + (--thresholdCounter *speed) + 'px,0); transform:translate3d(0,' + (--thresholdCounter *speed) + 'px,0);');
}
};
function scrollDown(thresholdY) {
if (thresholdCounter > maxScrollPositive) {
return;
} else {
pageScroll.setAttribute('style', '-webkit-transform:translate3d(0,' + (++thresholdCounter *speed) + 'px,0); -ms-transform:translate3d(0,' + (++thresholdCounter *speed) + 'px,0); transform:translate3d(0,' + (++thresholdCounter *speed) + 'px,0);');
}
};
function scrollToTop(){
initScroll();
pageScroll.setAttribute('style', 'transform:translate3d(0,0,0);');
thresholdCounter = 0;
};
function scrollDir(thresholdY) {
var scroll = window.scrollY;
if(scroll > position) {
distanceFromTop(thresholdY);
scrollUp(thresholdY);
} else if (scroll < position ){
scrollDown(thresholdY);
}
position = scroll;
};
function distanceFromTop(thresholdY) {
if (thresholdY > 0) {
`enter code here`//set speed as distance from top /px of not shown content
speed = (scrollImageHeight - scrollVisibleHeight) / thresholdY;
}
};
function initScroll(){
position = window.scrollY;
pageScroll = document.getElementById('page-scroll');
scrollImageHeight = pageScroll.offsetHeight; //total height of scroll image
pagePanel = document.getElementById("pagePanel");
pageStyle = window.getComputedStyle(pagePanel,"");
size = pageStyle.getPropertyValue("height");
scrollVisibleHeight = parseInt(size, 10);//visible height of scroll image
scrollImageEnd = scrollImageHeight - scrollVisibleHeight;
maxScrollNegative = -scrollImageEnd / speed;
}
var speed;
var thresholdCounter = 0;
var maxScrollPositive = 0;
var position,
pageScroll,
scrollImageHeight,
pagePanel,
pageStyle,
size,
scrollVisibleHeight,
scrollImageEnd,
maxScrollNegative;
window.addEventListener('resize', scrollToTop);
document.addEventListener('scroll', scrollImageInViewport);
window.addEventListener('load', initScroll);
This is what I ended up with:
var featurePage = document.getElementById('page-feature')
var pageScroll = document.getElementById('page-scroll');
var startP, // where animation needs to begin
endP, // where animation needs to end
diff; // visible element size
function getElementOffset(){ //init
var de = document.documentElement;
var box = featurePage.getBoundingClientRect();
var top = box.top + window.pageYOffset - de.clientTop;
var bottom = box.bottom + window.pageYOffset - de.clientTop;
var winHight = window.innerHeight;
diff = bottom - top;
var elPadding = (winHight - diff);
startP = top - elPadding;
endP = bottom - elPadding;
scrollImage()
}
function scrollImage(){
var scrollImageHeight = pageScroll.offsetHeight;
var scrollPos = (window.pageYOffset !== undefined) ? window.pageYOffset : (document.documentElement || document.body.parentNode || document.body).scrollTop;
var s1 = scrollPos - startP;
var realPos = -s1/diff;
var lengthLeft = scrollImageHeight - (diff)
if ( realPos < 0.09 && realPos > -1){
pageScroll.setAttribute('style', '-webkit-transform:translate3d(0,' + (realPos * lengthLeft) + 'px,0); -ms-transform:translate3d(0,' + (realPos *lengthLeft) + 'px,0); transform:translate3d(0,' + (realPos *lengthLeft) + 'px,0);');
}
}
window.addEventListener('resize', getElementOffset);
document.addEventListener('scroll', getElementOffset);

Event on margin change

I have an element with animated top margin. I need to detect if it isn't too close from the border, and if it is, scroll parent div to lower position, to prevent animated element from hiding. Here is an example:
http://jsfiddle.net/zYYBR/5/
This green box shouldn't be below the red line after clicking the "down" button.
Do you mean this?
var new_margin;
var step = 75;
var limit = $("#max")[0].offsetTop;
$('#down').click(function() {
var goStep = step;
var elHeight = $("#animated")[0].offsetTop + $("#animated")[0].offsetHeight;
if((elHeight + step) > limit)
{
goStep = limit - elHeight;
}
new_margin = goStep + parseInt($('#animated').css('margin-top'));
$("#animated").animate({marginTop: new_margin}, 1000);
});
http://jsfiddle.net/zYYBR/8/
EDIT: Or maybe something like that (of course you can improve the calculation, because currently it's very buggy with scroll):
var new_margin;
var step = 75;
$('#down').click(function () {
scroll(1000);
});
var scrollTimer = null;
$("#container").bind("scroll", function () {
clearTimeout(scrollTimer);
scrollTimer = setTimeout(function () { scroll(1); }, 10);
});
function scroll(speed) {
var scrollStep, animationStep = step;
var currentBoxBottom = $("#animated")[0].offsetTop + $("#animated")[0].offsetHeight;
var nextCurrentBoxBottom = currentBoxBottom + step;
var limit = $("#max")[0].offsetTop + $("#container")[0].scrollTop;
if (nextCurrentBoxBottom > limit) {
if (limit >= $("#container")[0].scrollTop) {
scrollStep = $("#container")[0].scrollTop + nextCurrentBoxBottom - limit;
}
else {
scrollStep = $("#container")[0].scrollTop - nextCurrentBoxBottom - limit;
animationStep = nextCurrentBoxBottom - limit;
}
$("#container")[0].scrollTop = scrollStep;
}
new_margin = animationStep + parseInt($('#animated').css('margin-top'));
$("#animated").animate({ marginTop: new_margin }, speed);
}
http://jsfiddle.net/zYYBR/13/
Do you mean something like this?
I have the same visual result as Alex Dn did, but I added a little extra direction to what I think you're talking about. If it's what you're looking for I'll make updates:
var new_margin;
var step = 75;
var limit = $("#max")[0].offsetTop;
$('#down2').click(function() {
var anim = $("#animated");
var hrOff = $("#max").offset();
var thOff = anim.offset();
new_margin = Math.min(hrOff.top - thOff.top - anim.height(), 75);
console.log(new_margin, hrOff.top, thOff.top);
var st = 0;
if (new_margin < 75) {
st = 75 - new_margin;
//have container scroll by this much?
}
anim.animate({
marginTop: "+=" + new_margin
}, 1000);
});​
​
http://jsfiddle.net/zYYBR/10/

Categories

Resources