ptts
ptts

Reputation: 1053

Trying the native Element.animate method, but cannot add keyframe percentages

Someone asked a related question and I am trying to make it work with the experimental technology Element.animate. The MDN documentation is rather...slim and the state of the technology is lets say infantile.

https://developer.mozilla.org/en-US/docs/Web/API/Element/animate

What I have is this markup:

<div class="container">
<div id="movetxt">left to right, right to left</div>
</div>

Just want the movetxt div to move from left to right ad infinity within the container div.

Css is hard coded, as I do not know how to get the width of the div text node.

.container {
margin: 0 auto;
width: 300px;
border: 1px solid red;
}

#movetxt {
width: 180px;
}

Now, the JS

var container = document.querySelector(".container");
var movingText = document.getElementById("movetxt");
 var containerWidth = container.offsetWidth;
var textWidth = movingText.offsetWidth;
var totalDistance = containerWidth - textWidth;
var oneWayDistance = totalDistance / 2; //just establishing the travel distance

And now the experiment part:

 movingText.animate([
// keyframes
{ transform: 'translateX(' + oneWayDistance + 'px)' }, 
{ transform: 'translateX(-' + totalDistance + 'px)' }
], { 
// timing options
duration: 1000,
iterations: Infinity
});

This kind of works, the console throws some errors, but the thing runs.

But, I want to have this kind of keyframas format, just an example:

  0%   { transform: 'translateX(' + oneWayDistance + 'px)' },
        10%  { transform: 'translateX(-' + totalDistance + 'px)' }

If I try that, I get Failed to execute 'animate' on 'Element': Keyframes must be objects, or null or undefined.

Link to fiddle:

http://jsfiddle.net/vdb3ofmL/1135/

There must be some way to place the keyframe % values there, can anyone figure this out?

Cheers

Upvotes: 1

Views: 697

Answers (2)

Abdulsattar Alkhalaf
Abdulsattar Alkhalaf

Reputation: 394

You should use offset like this

element.animate({
    opacity: [ 0, 0.9, 1 ],
    offset: [ 0, 0.8 ], // Shorthand for [ 0, 0.8, 1 ]
    easing: [ 'ease-in', 'ease-out' ],
}, 2000);

and in your case you can use like this and change your own

var container = document.querySelector(".container");
var movingText = document.getElementById("movetxt");
var containerWidth = container.offsetWidth;
var textWidth = movingText.offsetWidth;
var totalDistance = containerWidth - textWidth;
var oneWayDistance = totalDistance / 2;
movingText.animate(
  {transform:['translateX(' + oneWayDistance + 'px)','translateX(-' + totalDistance + 'px)','translateX(' + oneWayDistance + 'px)'],
  offset: [0,0.1]
}, { 
  duration: 1000,
  iterations: Infinity
});
.container {
  margin: 0 auto;
  width: 300px;
  border: 1px solid red;
}

#movetxt {
  width: 180px;
}
<div class="container">
<div id="movetxt">left to right, right to left</div>
</div>

Upvotes: 1

Temani Afif
Temani Afif

Reputation: 274024

You need to consider the fact that the text is initially on the left edge of the container, so you need to translate form 0 to width of container - width of text:

And what you are looking for is the offset valueref

var container = document.querySelector(".container");
var movingText = document.getElementById("movetxt");
var containerWidth = container.offsetWidth;
var textWidth = movingText.offsetWidth;
var totalDistance = containerWidth - textWidth;
var oneWayDistance = totalDistance / 2;
console.log(containerWidth);
console.log(textWidth);
movingText.animate([
  // keyframes
  { transform: 'translateX(0)',offset:0 },  /*0%*/
  {  transform: 'translateX(' + totalDistance + 'px)',offset:0.3 }, /*30%*/
  {  transform: 'translateX(0)',offset:1 } /*100%*/
], { 
  // timing options
  duration: 1000,
  iterations: Infinity
});
.container {
  margin: 0 auto;
  width: 300px;
  border: 1px solid red;
}

#movetxt {
  width: 180px;
  border:1px solid;
}
<div class="container">
<div id="movetxt">left to right, right to left</div>
</div>

Upvotes: 2

Related Questions