The easiest is probably to use some JS and the Web Animations API. You'd listen for the pointer events, and then control your animation status from there.
Since you want two different durations for the forward animation and the backward one, we need to add some trickery involving setting the playback-rate of our animation:
const forwardDur = 10_000; // in ms
const backwardDur = 3_000; // in ms
const box = document.querySelector(".box");
const anim = new Animation(new KeyframeEffect(
box,
[
{
transform: "translate(0px, 0px)",
},
{
transform: "translate(250px, 180px)",
background: "yellow",
},
{
transform: "translate(490px, 60px)",
background: "lightseagreen",
},
{
transform: "translate(550px, 390px)",
background: "crimson",
},
{
transform: "translate(600px, 450px)",
background: "orchid",
}
],
{ duration: forwardDur, fill: "forwards", easing: "linear" }
));
box.onmouseenter = (evt) => {
// We need to grab the current playState first,
// because updatePlaybackRate() does change it
const { playState } = anim;
anim.updatePlaybackRate(1); // go forward at normal speed
if (playState !== "running") { // we were either paused or finished
anim.currentTime = 0; // get out of "finished" state
anim.play();
}
};
box.onmouseout = (evt) => {
const { playState } = anim;
// go backward at higher speed
anim.updatePlaybackRate(forwardDur / backwardDur * -1);
if (playState !== "running") { // we were either paused or finished
anim.currentTime = forwardDur; // get out of "finished" state
anim.play();
}
}
.box {
width: 100px;
height: 100px;
padding: 2px;
background-color: lightblue;
color: White;
font-size: 40px;
text-align: center;
vertical-align: middle;
display: table-cell;
}
<div class="box">hello</div>
For a simpler case of the same speed animations in both ways, we could have used Animation#reverse()
:
const box = document.querySelector(".box");
const anim = new Animation(new KeyframeEffect(
box,
[
{
transform: "translate(0px, 0px)",
},
{
transform: "translate(250px, 180px)",
background: "yellow",
},
{
transform: "translate(490px, 60px)",
background: "lightseagreen",
},
{
transform: "translate(550px, 390px)",
background: "crimson",
},
{
transform: "translate(600px, 450px)",
background: "orchid",
}
],
{ duration: 10_000, fill: "forwards" }
));
anim.playbackRate = -1; // force reversed state so we can start with .reverse()
box.onmouseenter = (evt) => anim.reverse();
box.onmouseout = (evt) => anim.reverse();
.box {
width: 100px;
height: 100px;
padding: 2px;
background-color: lightblue;
color: White;
font-size: 40px;
text-align: center;
vertical-align: middle;
display: table-cell;
}
<div class="box">hello</div>