how do i change image in start of transition and end? - javascript

I am trying to make a walking animation, the program does that the character goes to the mouse click. but I can't make it when it's moving to change the image and when it's stopping return to the first image.
here is the code for the js file and the css file:
import "./styles.css";
var theThing = document.querySelector("#thing");
var cont = document.querySelector("#contentCont");
cont.addEventListener("click", getClickPosition, false);
function getClickPosition(e) {
theThing.src = "ddd2.gif";
var parentPosition = getPosition(cont);
var xPosition = e.clientX - parentPosition.x - theThing.offsetWidth / 2;
var yPosition = e.clientY - parentPosition.y - theThing.offsetHeight / 2;
var translate3dValue =
"translate3d(" + xPosition + "px," + yPosition + "px,0)";
theThing.style.transform = translate3dValue;
}
function getPosition(element) {
var xPos = 0;
var yPos = 0;
while (element) {
xPos += element.offsetLeft - element.scrollLeft + element.clientLeft;
yPos += element.offsetTop - element.scrollTop + element.clientTop;
element = element.offsetParent;
}
return {
x: xPos,
y: yPos
};
}
body {
background-color: #fff;
padding: 50px;
margin: 0;
}
#contentCont {
width: 600px;
height: 600px;
border: 15px #ededed solid;
overflow: hidden;
background-color: #f2f2f2;
cursor: pointer;
}
#thing {
width: 80px;
height: 80px;
transition: transform 0.7s ease-in;
}
right now its start at image 1 and change to image 2 when walking but doesnt return to image 1 when stopping.

Related

Draggable element gets stuck near edges

Dragging the element seems to make it get stuck randomly before touching the edges of its parent container. Would someone be able to spot why this is going on?
On a side note, I could not get the remembered position transferred to "updateDrag" correctly.
And no, I don't want any jQuery solution, like one created with jQuery UI.
let $container = document.getElementById('container');
let $element = document.getElementById('element');
let mousePosition;
let offset = [0, 0];
let isDown = false;
function initDrag(event) {
isDown = true;
// Element also remembers previous position wrong
// offset = [
// $element.offsetLeft - event.clientX,
// $element.offsetTop - event.clientY
// ];
offset = [
0,
0
];
}
function updateDrag(event) {
event.preventDefault();
if (isDown) {
mousePosition = {
x: event.clientX,
y: event.clientY
};
let diffY = mousePosition.y - offset[1];
let diffX = mousePosition.x - offset[0];
if (diffY >= 0 && diffY + $element.offsetHeight <= $container.offsetHeight) {
$element.style.top = (mousePosition.y + offset[1]) + 'px';
}
if (diffX >= 0 && diffX + $element.offsetWidth <= $container.offsetWidth) {
$element.style.left = (mousePosition.x + offset[0]) + 'px';
}
}
}
function haltDrag() {
isDown = false;
}
$element.addEventListener('mousedown', initDrag, false);
document.addEventListener('mouseup', haltDrag, false);
document.addEventListener('mousemove', updateDrag, false);
#container {
position: relative;
top: 10px;
left: 10px;
height: 300px;
width: 300px;
background-color: green;
}
#element {
position: absolute;
left: 0;
top: 0;
width: 100px;
height: 100px;
background: red;
color: blue;
}
<div id="container">
<div id="element"></div>
</div>

How Can I Detect If One Div Is Outside Another Div?

I am making a game and I am using div's instead of canvas.rect's and I want one div to always be inside of another div. I ran into this problem when I made a test script that looked like this.
var mousex, mousey;
function mousepos(e){
mousex = e.clientX;
mousey = e.clientY;
document.getElementById("xy").innerText = mousex + " , " + mousey;
}
function testdiv(){
document.getElementById("testdiv").style.left = mousex;
document.getElementById("testdiv").style.top = mousey;
setTimeout(testdiv, 30);
}
#city{
border: 1px dotted white;
background-color: lightgreen;
height: 500;
width: 500;
resize: both;
overflow: hidden;
max-height: 500px;
max-width: 500px;
min-height: 100px;
min-width: 100px;
}
#xy{
color: white;
}
#testdiv{
background-color: white;
position: absolute;
width: 100px;
height: 100px;
}
#body{
background-color: black;
}
<body id="body" onload="testdiv()">
<center>
<div id="city" onmousemove="mousepos(event);">
<div id="testdiv"></div>
</div>
<p id="xy"></p>
</center>
</body>
The code detects your mouse X and mouse Y when your mouse is over the big green div, then it puts the white div's left corner on your mouse X and mouse Y. My problem is that when my mouse is draging the white div down or right, I can drag it off of the green div.
Is there a way I could fix this problem?
Since there are no supported parent selectors in the current JS.
You could either use Jquery or CSS, I am listing both Javascript options, and CSS options
Option 1: $("a.active").parents('li').css("property", "value");
Option 2: Sibling Combination to match any ParentElement
element that is preceded by an ChildElement element.
// Just change the parent and child elemets below
ParentElement ~ ChildElement {
property: value;
}
You can make a check before changing the child div position, if its new position is outside of where you want it to be, you can skip it.
Something like:
if (mouse.x > parent_div_width){
return;
}
else {
child_div_Xpos = mouse.x
}
You can to try this code:
var mousex, mousey;
function mousepos(e) {
mousex = e.clientX;
mousey = e.clientY;
document.getElementById("xy").innerText = mousex + " , " + mousey;
}
var coordCity = document.getElementById("city").getBoundingClientRect();
var elem = document.getElementById("testdiv");
let i = 0
function testdiv() {
elem.style.left = mousex + 'px';
elem.style.top = mousey + 'px';
var coord = elem.getBoundingClientRect();
if(coord.left < coordCity.left ||
coord.right > coordCity.right ||
coord.bottom > coordCity.bottom ||
coord.top < coordCity.top) {
console.log('rect is out');
};
i++;
if(i === 100) {
return;
}
setTimeout(testdiv, 50);
}
And you need add in css px to value of width and height:
#city{
border: 1px dotted white;
background-color: lightgreen;
height: 500px;
width: 500px;
resize: both;
overflow: hidden;
max-height: 500px;
max-width: 500px;
min-height: 100px;
min-width: 100px;
}
And always save youre nodes to variable, because it does youre code faster, I use variable i for stop test. You can use another solution.
I created next app:
https://codepen.io/piotrazsko/pen/VrrZBq
I figured out a simple, more understandable way to do this.
I created a variables for the testdiv's width, height, x, y, x offset from
mouse, and y offset from mouse.
var divw = 50;
var divh = 50;
var divofx = 25;
var divofy = 25;
Then I made a variable for the city divs width.
var cityw = 500;
Then, I used screen.width / 2 to find the center of the screen.
var centerx = screen.width / 2;
Then, I made the size of the testdiv changeable at any time by putting the code below into the main function :
document.getElementById("testdiv").style.width = divw;
document.getElementById("testdiv").style.height = divh;
Then I used the width variable to find the edges of the city div.
Then, based off of the edges, I made some simple collision detecting if statements. I also did not need to change the Y mutch since it pretty mutch stays the same.
if(mousex + divw > centerx + (cityw / 2)){
mousex = centerx + (cityw / 2) - divw;
}
else{
document.getElementById("testdiv").style.left = mousex;
}
if(mousey > (cityw - divh) + 10){
mousey = (cityw - divh) + 10;
}
else{
document.getElementById("testdiv").style.top = mousey;
}
if(mousex < centerx - cityw / 2){
mousex = centerx - cityw / 2;
}
if(mousey < 8){
mousey = 8;
}
setTimeout(testdiv, 1);
Now the whole program looks like:
<html>
<head>
<style>
#city{
border: 1px dotted white;
background-color: lightgreen;
height: 500;
width: 500;
overflow: none;
max-height: 500px;
max-width: 500px;
min-height: 100px;
min-width: 100px;
}
#xy{
color: white;
}
#testdiv{
background-color: white;
position: absolute;
width: 100px;
height: 100px;
}
#body{
background-color: black;
}
</style>
<script>
var mousex, mousey;
var divw = 50;
var divh = 50;
var divofx = 25;
var divofy = 25;
var cityw = 500;
function mousepos(e){
mousex = e.clientX - divofx;
mousey = e.clientY - divofy;
document.getElementById("xy").innerText = mousex + " , " + mousey;
}
function testdiv(){
var centerx = screen.width / 2;
document.getElementById("city").style.width = cityw;
document.getElementById("testdiv").style.width = divw;
document.getElementById("testdiv").style.height = divh;
if(mousex + divw > centerx + (cityw / 2)){
mousex = centerx + (cityw / 2) - divw;
}
else{
document.getElementById("testdiv").style.left = mousex;
}
if(mousey > (cityw - divh) + 10){
mousey = (cityw - divh) + 10;
}
else{
document.getElementById("testdiv").style.top = mousey;
}
if(mousex < centerx - cityw / 2){
mousex = centerx - cityw / 2;
}
if(mousey < 8){
mousey = 8;
}
setTimeout(testdiv, 1);
}
</script>
</head>
<body id="body" onload="testdiv()" onmousemove="mousepos(event);">
<center>
<div id="city" onmousemove="mousepos(event);">
<div id="testdiv"></div>
</div>
<p id="xy"></p>
</center>
</body>
</html>

How to prevent element from exceeding his container borders

I have a square, when clicked it appears in a random location and it also change size (so for example if I have a 30px box but it is 10px from the left border I still get 10px outside the gamespace).
sometimes the square exceed his container border
How can I make sure that the square will never exceed his container?
function position() {
var positionTop = Math.random() * 100;
var positionLeft = Math.random() * 100;
var position = "position:relative;top:" + positionTop + "%;left:" + positionLeft + "%;"
return position;
}
document.getElementById("shape").onclick = function() {
document.getElementById("shape").style.cssText = position();
}
#gameSpace {
width: 100%;
height: 470px;
background: blue;
margin: 0;
padding-top: 30px;
}
#playSpace {
width: 90%;
height: 90%;
margin: 0 auto;
margin-top: 10px;
border: 1px black solid;
}
#shape {
width: 100px;
height: 100px;
background-color: red;
}
<div id="gameSpace">
<div id="playSpace">
<!-- here we put the shape -->
<div id="shape"></div>
</div>
</div>
You need to set position: relative; to the parent element and position: absolute; to the shape element. Then use max min value for random where max is the parent width/height and subtract the shape width/height ...
This is snippet before update
function position() {
var playSpace = document.querySelector('#playSpace');
var shape = document.getElementById("shape");
var maxHeight = playSpace.offsetHeight - shape.offsetHeight;
var maxWidth = playSpace.offsetWidth - shape.offsetWidth;
var positionTop = Math.random() * (maxHeight - 0) + 0;
var positionLeft = Math.random() * (maxWidth - 0) + 0;
// think of this like so:
// var positionTop = Math.random() * (max - min) + min;
// more information about it https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
var position = "position:absolute;top:" + positionTop + "px;left:" + positionLeft + "px;"
return position;
}
document.getElementById("shape").onclick = function() {
document.getElementById("shape").style.cssText = position();
}
#gameSpace {
width: 100%;
height: 470px;
background: blue;
margin:0;
padding-top: 30px;
}
#playSpace {
position: relative; /* add this line */
width: 90%;
height: 90%;
margin: 0 auto;
border: 1px black solid;
}
#shape {
width: 100px;
height: 100px;
background-color: red;
}
<div id="gameSpace">
<div id="playSpace">
<!-- here we put the shape -->
<div id="shape"></div>
</div>
</div>
Updated after comment
Not sure how you added the size() function but probably the problem was with using ...cssText that you overwrote the changes. So now I changed the code with passing the element to the functions and then only change the single CSS statements which need to be changed.
function position(element) {
var playSpace = document.querySelector('#playSpace');
var shape = document.getElementById("shape");
var maxHeight = playSpace.offsetHeight - shape.offsetHeight;
var maxWidth = playSpace.offsetWidth - shape.offsetWidth;
var positionTop = Math.random() * (maxHeight - 0) + 0;
var positionLeft = Math.random() * (maxWidth - 0) + 0;
// think of this like so:
// var positionTop = Math.random() * (max - min) + min;
// more information about it https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
element.style.position = 'absolute';
element.style.top = positionTop + "px";
element.style.left = positionLeft + "px";
}
function size(element) {
var sizeMath = (Math.random() * 200) + 50;
element.style.width = sizeMath + "px";
element.style.height = sizeMath + "px";
}
document.getElementById("shape").onclick = function() {
size(document.getElementById("shape"));
position(document.getElementById("shape"));
}
#gameSpace {
width: 100%;
height: 470px;
background: blue;
margin:0;
padding-top: 30px;
}
#playSpace {
position: relative; /* add this line */
width: 90%;
height: 90%;
margin: 0 auto;
border: 1px black solid;
}
#shape {
width: 100px;
height: 100px;
background-color: red;
}
<div id="gameSpace">
<div id="playSpace">
<!-- here we put the shape -->
<div id="shape"></div>
</div>
</div>
You can use a specify the range (min/max) in Math.random function and then use this function Math.floor(Math.random() * (max - min + 1)) + min; to limit the returned value of the random function between min and max.
maxTop : height of the container - height of shape
maxLeft : width of the container - width of shape
minTop : 0
minLeft : 0
You need to use position:absolute and px value on shape for this to work
See code snippet:
function position() {
var minTop = 0;
var maxTop = document.getElementById("playSpace").clientHeight - document.getElementById("shape").clientHeight;
var minLeft = 0;
var maxLeft = document.getElementById("playSpace").clientWidth - document.getElementById("shape").clientWidth ;
var positionTop = Math.floor(Math.random() * (maxTop - minTop + 1) + minTop);
var positionLeft = Math.floor(Math.random() * (maxLeft - minLeft + 1) + minLeft);
var position = "position:absolute;top:" + positionTop + "px;left:" + positionLeft + "px;"
return position;
}
document.getElementById("shape").onclick = function() {
document.getElementById("shape").style.cssText = position();
}
#gameSpace {
width: 100%;
height: 470px;
background: blue;
margin: 0;
padding-top: 30px;
text-align:center;
}
#playSpace {
width: 90%;
height: 90%;
border: 1px black solid;
position:relative;
display:inline-block;
}
#shape {
width: 100px;
height: 100px;
background-color: red;
}
<div id="gameSpace">
<div id="playSpace">
<!-- here we put the shape -->
<div id="shape"></div>
</div>
</div>
With CSS calc, limit the position inside playSpace area (you can use different units, here % and px).
Then with offsetTop/offsetLeft, get the real position of the square and avoid negative positions (when positionTop < 100px or positionLeft < 100px).
function position() {
var positionTop = Math.random() * 100;
var positionLeft = Math.random() * 100;
var position = "position:relative;top: calc(" + positionTop + "% - 100px);left: calc(" + positionLeft + "% - 100px);";
return position;
}
document.getElementById("shape").onclick = function() {
var shapeDiv = document.getElementById("shape");
shapeDiv.style.cssText = position();
var top = shapeDiv.offsetTop;// Result of calc(" + positionTop + "% - 100px) in px
if(top < 0) {
shapeDiv.style.top = '0px';
}
var left = shapeDiv.offsetLeft;// Result of calc(" + positionLeft + "% - 100px) in px
if(left < 0) {
shapeDiv.style.left = '0px';
}
}
Don't forget to add position: relative to #playSpace, to get offsetTop/left correct
#playSpace {
position:relative;/* mandatory */
}
You can get the parent element size, so that in your scirpt, use a condition to prevent the square to exceed.
function position() {
var maxWidth = document.getElementById("playSpace").offsetWidth;
var maxTop = document.getElementById("playSpace").offsetHeight;
var positionTop = Math.random() * 100;
var positionLeft = Math.random() * 100;
if (positionTop > maxTop) { positionTop = maxTop;)
if (positionLeft > maxWidth) { positionLeft = maxWidth;)
var position = "position:relative;top:" + positionTop + "%;left:" + positionLeft + "%;"
return position;
}
I'm not sure if .offsetWidth and .offsetHeight works well, but you got the idea :)
By tweaking just a little your positionTop and positionLeft variable, I managed to keep the square inside. You just need to change the maximum % that it needs to have to not exceed the container. I found that 75% for the top and 80% for the left seems to be the max!
var positionTop = Math.floor(Math.random() * 75) ;
var positionLeft = Math.random() * 80;
Here's a fiddle
If you set the containing element to position: relative; and the inner element with position: absolute; the inner elements top left right and bottom properties will calculate from the borders of the containing element.
Here is a good source of css positioning.
In your case additional validation should be set to positionTop and positionLeft.
positionTop should be in the interval [( shapeHeight/2 ) - (100 - shapeHeight/2 ) ]
positionLeft should be in the interval [( shapeWidth/2 ) - (100 - shapeWeight/2 ) ]

position bug in draggable div

I have div that behaves a little strange,
When I move it the first time its working good, but the second time the position starts to bug
I have position: absolute in the main div, but thats all.
Any idea how to clean from bugging ?
http://jsfiddle.net/dymond/tQdFZ/14/ <-- the jsfiddle
javascript.
var draggable = document.getElementsByClassName('hand'),
draggableCount = draggable.length,
i, currZ = 1;
function startDrag(evt) {
var diffX = evt.clientX - this.offsetLeft,
diffY = evt.clientY - this.offsetTop,
that = this;
this.style.opacity = "0.5";
this.style.zIndex = currZ++;
function moveAlong(evt) {
that.parentNode.style.left = (evt.clientX - diffX) + 'px';
that.parentNode.style.top = (evt.clientY - diffY) + 'px';
}
function stopDrag() {
document.removeEventListener('mousemove', moveAlong);
document.removeEventListener('mouseup', stopDrag);
changeClass()
}
function changeClass() {
var diceClass = document.getElementsByClassName("hand");
for (var i = 0; i < diceClass.length; i++) {
diceClass[i].style.opacity = "1";
}
}
document.addEventListener('mouseup', stopDrag);
document.addEventListener('mousemove', moveAlong);
}
for (i = 0; i < draggableCount; i += 1) {
draggable[i].addEventListener('mousedown', startDrag);
}
Css
**.draggable {
position: absolute;
width: 100px;
height: 100px;
background: red;
}
.hand{
cursor : move;
width: 98px;
min-height: 16px;
background: yellow;
border:1px solid black;
}
textarea{
padding-top:20px;
resize : none;
overflow : hidden;
background : transparent;
width:95px;
border:none;
}
offsetLeft and offsetTop of this is always 0 because this refers to .hand not .dragabble so this:
var diffX = evt.clientX - this.offsetLeft,
diffY = evt.clientY - this.offsetTop,
Should be this:
var diffX = evt.clientX - this.parentNode.offsetLeft,
diffY = evt.clientY - this.parentNode.offsetTop,
Updated Fiddle: http://jsfiddle.net/knoxzin1/tQdFZ/15/

how to animate div from its center

I am trying to animate a div tag from center. Initially I want the div tag to be none visible. when user clicks on link then this div tag should animate from its center. How can I achieve this using jquery. Here is my current code.
link one<br><br><br><br>
<section class="one">one</section>
here is css
.one {
margin: 0 auto;
width: 200px;
height: 200px;
border: 1px solid red;
background: lightblue;
}
and here is my jquery
$('a').on('click', function (e) {
e.preventDefault();
var w = 200; //$('.one').outerWidth();
var h = 200; //$('.one').outerHeight();
var x = $('.one').width() / 2;
var y = $('.one').height() / 2;
var startW = h - y/2;
var startH = w - x/2;
var endTop = y - h/2;
var endLeft = x - w/2;
$('.one').animate({
opacity: 1,
width: (w+200) + 'px',
height: (h+200) + 'px',
top: endTop+'px',
left: endLeft+'px'
}, 1000);
console.log(endLeft);
});
Something like this:
http://jsfiddle.net/TJNTq/
$('.linkone').on('click', function (e) {
e.preventDefault();
var w = 200; //$('.one').outerWidth();
var h = 200; //$('.one').outerHeight();
var x = $('.one').width() / 2;
var y = $('.one').height() / 2;
var startW = h - y/2;
var startH = w - x/2;
var endTop = y - h/2;
var endLeft = x - w/2;
$('.one').show().animate({
opacity: 1,
width: (w+200) + 'px',
height: (h+200) + 'px',
marginTop: 0 + 'px'
}, 1000);
console.log(endLeft);
});
note that your animations of top and left weren't doing anything because the .one div isn't positioned absolutely or relatively.

Categories