javascript beginner here! so i'm trying to do a box(that is inside a larger box) move from the top to the edge of the box. Here's the code:
var boxcont = document.getElementById("boxcont");
var boxbtn = document.getElementById("boxbtn");
boxbtn.addEventListener("click", function() {
var loc = 0;
var timebox = setInterval(boxmove, 5);
function boxmove() {
if (loc == 320) {
clearInterval(timebox);
} else {
loc++;
boxcont.style.top = loc + "px";
boxcont.style.left = loc + "px";
}
}
});
#movebox {
width: 300px;
height: 350px;
background-color: grey;
}
#boxcont {
width: 30px;
height: 30px;
background-color: indianred;
position: relative;
}
<div id="movebox">
<div id="boxcont"></div>
</div>
<button id="boxbtn">Move the box</button>
The problem is that the small box doesn't exactly ends up at the edge, it goes more to the right. I tried doing
boxcont.style.left = (loc - 0.5) + "px";
but doesn't work. pretty sure the solution is simple but as a newbie here it's confusing me :p. Oh and i also tried doing ++ to the 0.5 and Number(0.5) so it reads it as a decimal but still doesn't work!
the big gray box is not set to the correct height and width that corresponds with the small red box's movement. You have it going down 1 and to the right 1 every 5 however, your actually going across a rectangle, not a square. set your width and height the same for the gray box and slightly adjust the stopping point to a little bit less.
var boxcont = document.getElementById("boxcont");
var boxbtn = document.getElementById("boxbtn");
boxbtn.addEventListener("click", function() {
var loc = 0;
var timebox = setInterval(boxmove, 5); // every five milliseconds
function boxmove() {
if (loc == 290) {
clearInterval(timebox);
} else {
loc++;
boxcont.style.top = loc + "px";
boxcont.style.left = loc + "px";
}
}
});
#movebox {
width: 300px;
height: 350px;
background-color: grey;
}
#boxcont {
width: 30px;
height: 30px;
background-color: indianred;
position: relative;
}
<div id="movebox" style = "height: 320px; width: 320px">
<div id="boxcont" ></div>
</div>
<button id="boxbtn">Move the box</button>
if (loc == 270) {
instead of
if (loc == 320) {
Gets you there.
300px is the width of the containing div and the moving div is 30px wide so 300-30=270px
var boxcont = document.getElementById("boxcont");
var boxbtn = document.getElementById("boxbtn");
boxbtn.addEventListener("click", function() {
var loc = 0;
var timebox = setInterval(boxmove, 5);
function boxmove() {
if (loc == 270) {
clearInterval(timebox);
} else {
loc++;
boxcont.style.top = loc + "px";
boxcont.style.left = loc + "px";
}
}
});
#movebox {
width: 300px;
height: 350px;
background-color: grey;
}
#boxcont {
width: 30px;
height: 30px;
background-color: indianred;
position: relative;
}
<div id="movebox">
<div id="boxcont"></div>
</div>
<button id="boxbtn">Move the box</button>
Related
I was tasked with creating an animation in javascript using an existing code and altering to do two things. Switch modes, and go on until the person closes the program. The four modes are:
mode 0 - left to right
mode 1 - top to bottom
mode 2 - right to left
mode 3 - bottom to top
Switching from mode 0 - 1 is where the trouble starts. It's supposed to slide, but it jumps when I get there.
Below is my code as is.
<!DOCTYPE html>
<html>
<style>
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
</style>
<body>
<p><button onclick="myMove()">Click Me</button></p>
<div id ="container">
<div id ="animate"></div>
</div>
<script>
function myMove() {
var elem = document.getElementById("animate");
var pos = 350;
var id = setInterval(frame, 5);
}
function frame() {
if (pos == 0) {
pos++;
elem.style.bottom= pos + 'px';
} else {
pos--;
elem.style.left = pos + "px";
if (pos == 49.985) {
pos++;
elem.style.left = pos + "px";
}
}
I suggest you use two variables for both x and y, and replace posBottom with a variable for top style.
The issue before was that when pos was equal to 0 and thus triggered the if statement, it immediately incremented, causing it to instead trigger the else, and then decremented, going back to if, and so on. It jumped because the style.bottom = 0px was causing it to go straight down to the bottom.
function myMove() {
var elem = document.getElementById("animate");
var posLeft = 350;
var posTop = 0;
var id = setInterval(frame, 5);
function frame() {
if (posLeft == 0 && posTop != 350) {
stage=1;
posTop++;
elem.style.top= posTop + 'px';
} else if (posTop == 0) {
posLeft--;
elem.style.left = posLeft + "px";
} else if (posLeft != 350) {
posLeft++;
elem.style.left = posLeft + "px";
} else if (posTop != 0) {
posTop--;
elem.style.top= posTop + 'px';
}
}
}
#container {
width: 400px;
height: 400px;
position: relative;
background: yellow;
}
#animate {
width: 50px;
height: 50px;
position: absolute;
background-color: red;
}
<p><button onclick="myMove()">Click Me</button></p>
<div id ="container">
<div id ="animate"></div>
</div>
I've got a page that reads the cursor location in event.clientX/Y and compares it with element.getBoundingClientRect() to do hit testing. This works even when the page scrolls or when Cmd+ is used. I found that in Safari (not Chrome), when I zoom the page in with a pinch gesture and scroll, the .clientX/Y are wrong. I made this snippet that shows the fixed element not following the mouse when zoomed.
window.onmousemove = function(event)
{
// it seems like if document is not zoomed, correction is not needed. but if it is, correction IS needed.
var x = event.clientX /*+ window.pageXOffset*/;
var y = event.clientY /*+ window.pageYOffset*/;
document.getElementById('cursor').style.left = x+'px';
document.getElementById('cursor').style.top = y+'px';
document.getElementById('cursor').innerText = [x,y,document.getElementById('cursor').getBoundingClientRect().x,document.getElementById('cursor').getBoundingClientRect().y];
}
/* force a large page */
document.write('<pre>');
for (var i = 0; i <= 100; i++) { document.write("<mark>" + i + "</mark>"); }
for (var i = 1; i <= 100; i++) { document.write("<mark>" + i + "</mark><br>"); }
document.write('</pre>');
html, body { min-height: 100%; }
mark { display: inline-block; width: 30px; height: 30px; outline: thin solid black; }
<!DOCTYPE html5>
<div id=cursor style="position: fixed; left: 30px; top: 30px; background: red;"></div>
UPDATE: Run Snippet is behaving correctly, however the following code in a plain html file is not. S.O. might be doing something to the event before the snippet gets it.
<!DOCTYPE html5>
<style>
html, body { min-height: 100%; }
mark { display: inline-block; width: 30px; height: 30px; outline: thin solid black; }
</style>
<div id=cursor style="position: fixed; left: 30px; top: 30px; background: red;"></div>
<script>
window.onmousemove = function(event)
{
// it seems like if document is not zoomed, correction is not needed. but if it is, correction IS needed.
var x = event.clientX /*+ window.pageXOffset*/;
var y = event.clientY /*+ window.pageYOffset*/;
document.getElementById('cursor').style.left = x+'px';
document.getElementById('cursor').style.top = y+'px';
document.getElementById('cursor').innerText = [x,y,document.getElementById('cursor').getBoundingClientRect().x,document.getElementById('cursor').getBoundingClientRect().y];
}
/* force a large page */
document.write('<pre>');
for (var i = 0; i <= 100; i++) { document.write("<mark>" + i + "</mark>"); }
for (var i = 1; i <= 100; i++) { document.write("<mark>" + i + "</mark><br>"); }
document.write('</pre>');
</script>
In the custom slider i have created, the handle is moving beyond the container. But i want it to stay within the container limits. We could just do it simple by setting margin-left as offset in CSS. But My requirement is when the handle right end detect the container's end the handle should not be allowed to move anymore. Any help is appreciated. Thanks.
Demo Link: https://jsfiddle.net/mohanravi/1pbzdyyd/30/
document.getElementsByClassName('contain')[0].addEventListener("mousedown", downHandle);
function downHandle() {
document.addEventListener("mousemove", moveHandle);
document.addEventListener("mouseup", upHandle);
}
function moveHandle(e) {
var left = e.clientX - document.getElementsByClassName('contain')[0].getBoundingClientRect().left;
var num = document.getElementsByClassName('contain')[0].offsetWidth / 100;
var val = (left / num);
if (val < 0) {
val = 0;
} else if (val > 100) {
val = 100;
}
var pos = document.getElementsByClassName('contain')[0].getBoundingClientRect().width * (val / 100);
document.getElementsByClassName('bar')[0].style.left = pos + 'px';
}
function upHandle() {
document.removeEventListener("mousemove", moveHandle);
document.removeEventListener("mouseup", upHandle);
}
.contain {
height: 4px;
width: 450px;
background: grey;
position: relative;
top: 50px;
left: 40px;
}
.bar {
width: 90px;
height: 12px;
background: transparent;
border: 1px solid red;
position: absolute;
top: calc(50% - 7px);
left: 0px;
cursor: ew-resize;
}
<div class='contain'>
<div class='bar'></div>
</div>
You need to change
this
document.getElementsByClassName('bar')[0].style.left = pos + 'px';
to this
if(pos > 90){
document.getElementsByClassName('bar')[0].style.left = pos - 90 + 'px';
}
else{
document.getElementsByClassName('bar')[0].style.left = 0 + 'px';
}
since width of your bar is 90px I am subtracting 90.
See this updated fiddle
I have a div that animates up and down which works fine. The issue I'm getting is that every time the page loads the div starts at the very top of the page and then jumps down to where it needs to be after the animation starts.
<body id="body">
<div id="square"></div>
</body>
#body {
background: #000;
}
#square {
background-color: #fff;
margin: 0 auto;
position: relative;
width: 100px;
height: 100px;
}
var box = document.getElementById('square');
TOP = (window.innerHeight - box.offsetHeight)/2;
box.style.top = TOP;
var down = setInterval(animateDown, 15);
var up;
function animateDown()
{
TOP += 3;
box.style.top = TOP + 'px';
if(TOP > 900){
clearInterval(down);
up = setInterval(animateUp, 15);
}
}
function animateUp()
{
TOP -= 3;
box.style.top = TOP + 'px';
if(TOP <= (window.innerHeight - box.offsetHeight)/2){
clearInterval(up);
down = setInterval(animateDown, 15);
}
}
Here is a link to the jsfiddle as well >> https://jsfiddle.net/xgilmore/pLbgvc3L/
thanks in advance
This is sort of a work around, but you can start the box off as hidden, and then once you start animating, set it visible. https://jsfiddle.net/pLbgvc3L/1/
function animateDown()
{
box.style.visibility = 'visible';
#square {
background-color: #fff;
//margin: 0 auto;
position: relative;
width: 100px;
height: 100px;
top: 20%;
visibility: hidden;
}
Oh sorry, I actually know what is going on, it just took a second look to figure it out. top: 20% doesn't do anything because percentages only work if the parent element (body) has an explicit height. Like so https://jsfiddle.net/pLbgvc3L/2/
I have this HTML code:
<div class="inner">
<div class="nhood">
<div class="image"></div>
</div>
</div>
And this CSS:
.image {
width: 4000px;
height: 4000px;
background: beige;
margin: 150px;
position: absolute;
}
.nhood {
overflow: hidden;
width: 100%;
height: 100%;
box-sizing: border-box;
position: relative;
background: black;
}
The .image div is filled with 400 divs, all floating left, creating a huge 'chess'-pattern, the code is the following:
.image > div {
border: 1px dotted;
width: 5%;
height: 5%;
float: left;
box-sizing:border-box;
text-indent: 100%;
white-space: nowrap;
overflow: hidden;
position: relative;
user-select: none;
}
You are able to click on any cell to show its info, and the whole .image div is draggable. Now if you have selected a cell and you ZOOM (which basically only shrinks/extends the 4000x4000 div to 2000x2000 or the other way round) it zooms in ANYWHERE but I want to keep focus on the cell that was selected earlier.
I have made an image of this:
http://smimoo.lima-city.de/zoom.png
I hope this was any clear...
EDIT:
JS
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 0
});
});
}
function zoomOut() {
$(draggable).animate({
height: '2000',
width: '2000',
borderWidth: 0
}, 600, function() {
$divs.animate({
borderWidth: 1
});
});
EDIT2:
This is my js to center the function (written before Mario helped me out):
function centerField() {
var myObject = $(draggable).find('.selected');
var docWidth = ($(viewport).width() / 2) - (myObject.outerWidth()/2);
var docHeight = ($(viewport).height() / 2) - (myObject.outerWidth()/4);
var myOff = myObject.offset();
var distanceTop = myOff.top - docHeight;
var distanceLeft = myOff.left - docWidth;
var position = $(draggable).position();
var left = position.left;
var top = position.top;
var right = left - $(viewport).width() + draggable.outerWidth(true);
var bottom = top - $(viewport).height() + draggable.outerHeight(true);
if(left - distanceLeft > 0) {
distanceLeft = left;
}
if(right - distanceLeft < 0) {
distanceLeft = right;
}
if(top - distanceTop > 0) {
distanceTop = top;
}
if(bottom - distanceTop < 0) {
distanceTop = bottom;
}
$(draggable).animate({
left: '-=' + distanceLeft,
top: '-=' + distanceTop
}, { duration: 200, queue: false });
}
Assume that the selected div has the class .selected, this function will center the div:
function centerSelected() {
var selectedElement = $('.image .selected');
var p = selectedElement.position();
var w = $('.nhood').width();
var h = $('.nhood').height();
var offsetX = (w/2)-p.left - (selectedElement.width() / 2);
var offsetY = (h/2)-p.top - (selectedElement.height() / 2);
if(offsetX > 0) offsetX = 0;
if(offsetY > 0) offsetY = 0;
$('.image').css('left', offsetX + 'px');
$('.image').css('top', offsetY + 'px');
}
Just call centerSelected after every zoom operation.
Here is a jsfiddle with slightly modified css to get the presentation work:
http://jsfiddle.net/q1r95w3g/3/
Edit
If you want the div to get centered during jQuery animation, you can call centerSelected in the step callback of the animate method, e.g.:
function zoomIn() {
$(draggable).animate({
height: '4000',
width: '4000',
borderWidth: 0
},{
duration: 600,
complete: function() {
$divs.animate({
borderWidth: 0
});
},
step: function(now, fx) {
centerSelected();
}
});
}