transition-like animation
by ShaCP
HTML
<p id="me" style="animation-duration: 3s" tabindex="-1">my animation code</p>
<div class="line line1">mid point</div>
<div class="line line2">end point</div>
CSS
#me {
/* -webkit-animation: text-orientation-change 1s infinite linear; */
/* text-orientation: upright;
writing-mode: vertical-rl; */
/* transition: margin-left 1.5s linear; */
border: 1px solid black;
display: inline-block;
}
.line {
width: 500px;
height: 1px;
background-color: red;
position: absolute;
top: 100px;
color: red;
font-size: 1rem;
text-align: center;
}
.line2 {
top: 200px;
}
#me.anim_on {
animation: transform linear forwards;
/* margin-left: 200px; */
/* pointer-events: none; */
}
#me.reverse_anim {
animation: transform_reverse linear forwards;
}
/* #me:focus {
animation: margin-top 1.5s linear forwards;
} */
body {
height: 100vh;
font-size: 2rem;
font-family: sans-serif;
}
@keyframes transform {
to {
transform: translateY(200px);
/* margin-left: 200px; */
}
}
@keyframes transform_reverse {
to {
transform: translate(0);
/* margin-left: 200px; */
}
}
JavaScript
const animationDuration = 3
let animationStartTime = 0;
let animationEndTime = 0;
let nextDuration = animationDuration;
let timeElapsedAtMouseIn;
let timeElapsedAtMouseOut;
let previousDuration = 0;
let prevNextDuration = 0;
const mouseIn = (e) => {
/*1*/
console.log("mouse in timestamp", performance.now() / 1000);
const {
x,
y
} = me.getBoundingClientRect();
me.classList.remove("reverse_anim");
/* new */
animationStartTime = performance.now() / 1000;
console.log("remove class to end anim timestamp (still in mouse in event)", animationStartTime);
/* end new */
if (animationEndTime) {
/* old but moved */
me.style.transform = `translate(${x}px, ${y}px)`
/* old but moved end */
console.log(`mouse in time ${animationStartTime} - mouse out time ${animationEndTime}`);
timeElapsedAtMouseIn = Math.min(animationStartTime - animationEndTime, animationDuration);
console.log("time elapsed at mouse in", timeElapsedAtMouseIn);
/* nextDuration */
console.log(`nextDuration ${nextDuration} = previousDuration ${previousDuration} - timeElapsedAtMouseOut ${timeElapsedAtMouseOut} + timeElapsedAtMouseIn ${timeElapsedAtMouseIn}`);
prevNextDuration = nextDuration;
nextDuration = previousDuration - timeElapsedAtMouseOut + timeElapsedAtMouseIn;
previousDuration = prevNextDuration;
console.log("nextDuration", nextDuration);
me.style["animation-duration"] = `${nextDuration}s`;
}
/* end nextDuration */
/* end new */
me.classList.add("anim_on");
}
const mouseOut = (e) => {
/*3*/
console.log("mouse out timestamp", performance.now() / 1000);
const {
x,
y
} = me.getBoundingClientRect();
me.classList.remove("anim_on");
animationEndTime = performance.now() / 1000;
console.log("remove class to end anim timestamp (still in mouse out event)", animationEndTime);
me.style.transform = `translate(${x}px, ${y}px)`;
console.log(`mouse out time ${animationEndTime} - mouse in time...