So this is my box
<div ></div>
And i have a animation
.mybox{
animation:right 5s;
animation-fill-mode:forwards;
padding:50px;
width:0px;
height:0px;
display:block;
background-color:black;
}
@keyframes
right{from{left:0px;}to{left:300px
;}}
@keyframes
left{from{right:0px;}to{right:300p
x;}}
And i have two button
<button onclick="leftFunction">left</button>
<button onclick="rightFunction">right</button>
Then if i click left it will go left while it is going left then i click right i want to stop the left animation and go right but the right animation must start on current position and not teleport and go right.
Please help :( Im new to stack overflow
Here is the js
function leftFunction() {
document.getElementById("myDIV").style.animation
= "left 4s";
}
function rightFunction() {
document.getElementById("myDIV").style.
animation = "right 4s";
}
CodePudding user response:
There were a number of issues I found with the code that you posted, but you were on the right track.
Your DOM method was looking for an element with an ID of
myDIV
which does not exist, I changed it todocument.querySelector(".mybox")
since that is the class name of your div.You weren't invoking the function call on your
onclick
handler, not sure you were getting anything to happen at all... Add the()
invoke it onclick.Your code layout was not following normal spacing conventions, but it is difficult to write code into stack overflow, so I understand. I made the changes I saw necessary.
You were setting position values to your div, but there was no
position
property declared. Position isstatic
by default which doesn't respond toleft
orright
. I usedrelative
as that will keep the div in the document flow.Changing
left
on one animation andright
on another will maintain the previous left or right values, respectively and could cause your div to shrink or grow unexpectedly. I changed it to only affect theleft
property.
And now for the solution
Change your keyframes to only update the left
property. Call the function from onclick and pass in the event
object. This will allow you to have just one function to handle the change in animation, and can take the event target's innerHTML
to set the name of the animation desired.
Make use of CSS custom properties, so that value can be mutated in javascript, and make your from
properties start at the custom property. In this case --cur-pos
.
When the function is called, get the div element, and find it's computed left
value with document.getComputedStyle()
, then update the custom property --cur-pos
with that value. That way the animation always starts where the div is currently positioned.
Et voila! You should be good to go. You might have to tweak the starting --cur-pos
value to have the div start where you want, and also update the to
values to end where you want, just make sure to choose either left
or right
for updating horizontal position, not both.
function changeAnimation(e) {
const box = document.querySelector(".mybox")
const pos = window.getComputedStyle(box).left
box.style.setProperty("--cur-pos", pos)
box.style.animationName = e.target.innerHTML
}
.mybox {
--cur-pos: 150px;
width: 100px;
height: 100px;
background-color: black;
position: relative;
animation: right 4s forwards;
}
@keyframes right {
from { left: var(--cur-pos); }
to { left: 300px; }
}
@keyframes left {
from { left: var(--cur-pos); }
to { left: 0px; }
}
<div ></div>
<button onclick="changeAnimation(event)">left</button>
<button onclick="changeAnimation(event)">right</button>