DEV Community

Discussion on: JavaScript: My animation doesn't make the element start from the right position.

Collapse
 
edreeseg profile image
Ed Reeseg • Edited

So, first we should start off by looking at why that img element appears where it appears in the first place:

#element {
  position: relative;
  cursor: pointer;
  top: 50px;
  right: 450px;
}

You position the element relatively, like you said, and tell it to go down 50px and left 450px from where its natural position on the DOM is.

Next, we look at what happens when you click the button:

move.onclick = function() {
  let start = Date.now();

  let timer = setInterval(function() {
    let timePassed = Date.now() - start;

    element.style.right = timePassed / 5 + 'px';

    if (timePassed > 2000) clearInterval(timer);

  }, 20);
}

When you click the interval, you capture the value of Date.now(), and then set an interval that calculates the time that has passed every 20ms and updates the style attribute in your HTML to make the right attribute equal to whatever amount of pixels equals to the time that has passed.

Note that inline HTML styling has a much higher specificity than the ID Selector you initially used in your CSS to set the img element's position. So, when the interval callback runs for the first time and sets the right property in the inline style attribute to whatever number of pixels represent the time passed so far, it overrides the ID selector in your CSS.

Suddenly, the right: 450px; you put in the CSS doesn't matter anymore. The only thing that matters is whatever amount of pixels is being indicated in your inline style attribute. When this happens, the element pops back over to near where its natural DOM position would be, because those 450px have been reduced to...whatever amount of time has passed, right after the button is clicked. It then increases every 20ms when the interval is run again, pulling it back toward where it originated.

EDIT:

Note that if we change our original styling of #element to be:

#element {
  position: relative;
  cursor: pointer;
}

The element doesn't teleport at all - it just starts moving to the left. This is because the element is starting from the default value of right: 0;, and so when that value begins ticking up when the button is clicked, there's no jarring teleportation when that 450px is overridden.

Collapse
 
andybullet profile image
AndyBullet

but I want that it start from the point that I set, not from 0.

Collapse
 
edreeseg profile image
Ed Reeseg • Edited

Difficult for me to test because I'm away from home, but if you're looking to check what the CSS value is, you could use getComputedStyle.

element.style.right =
            // we get the value "450px" from getComputedStyle, 
            // and slice off the px to create a number.
            Number(getComputedStyle(element).right.slice(0, -2)) +
            (timePassed / 5) +
            "px";

Or, alternatively, instead of declaring the right attribute in your CSS, just declare it in your HTML inline if that'll be the result anyways.

<img width="300" height="300" style="right:450px"id="element" src="element.png" />

You can then just reference that value with element.style.right to do the same addition.

Smarter might be to use a keyframes animation that'd be exclusively in CSS. I'd check out this page: developer.mozilla.org/en-US/docs/W...

.element-slide {
    animation: 2s ease forwards slide-left;
}

@keyframes slide-left {
    from {
        right: 450px;
    }
    to {
        right: 900px;
    }
}

You can then toggle the element-slide class on the img element as needed.