Hi everyone,
I have been working on a UI framework for Cobalt to enable its use for purposes other than just YouTube on devices with an existing port. However, I've encountered an issue that I can't resolve.
In my framework, I want to create a widget with an animated position. I understand that Cobalt has certain optimizations and allows animating CSS tags that do not affect the page layout. Therefore, to animate the position change of an element, I first use transform via translate, add a callback on animation end, and in this callback, I reset the animation state in the style, setting the new position of the element by modifying parameters (top, left, etc.).
Generally, the approach works, but only for the first time. Below are the example functions:
Resetting the animation state:
public resetAnimationState() {
if (this.style && this.style.cssRules.length > 0) {
this.style?.deleteRule(0);
}
this.isAnimated = false;
this.diff = 0;
this.direction = MoveDirection.Unknown;
this.element.style.animation = '';
this.element.style.animationDuration = '';
this.element.style.animationFillMode = '';
}
Animating the move to the left:
public animatedMoveLeft(diff: number) {
if (!this.style) {
console.error("style is null");
return;
}
if (this.isAnimated) return;
this.isAnimated = true;
this.diff = diff;
this.direction = MoveDirection.Left;
let animationName = `animation-move-left`;
// Use the direction to decide which translate method should be used
let animationDefinition = '';
animationDefinition = `{0% {transform: translateY(0px)} 100% {transform: translateX(-${diff}px)}}`;
let moveUpKeyframe = `@keyframes ${animationName} ${animationDefinition}`;
if (!this.checkIfRuleExists(animationName)) {
this.style.insertRule(moveUpKeyframe, 0);
}
this.element.style.animation = animationName;
this.element.style.animationDuration = '0.25s';
this.element.style.animationFillMode = 'forwards';
}
Handling the end of the animation:
const moveAnimationEndHandler = (ev: AnimationEvent) => {
if (ev.target !== this.element) return;
// ev.stopPropagation();
switch (this.direction) {
case MoveDirection.Left:
this.moveLeft(this.diff);
break;
case MoveDirection.Right:
this.moveRight(this.diff);
break;
case MoveDirection.Down:
this moveBottom(this.diff);
break;
case MoveDirection.Up:
this.moveTop(this.diff);
break;
case MoveDirection.Unknown:
break;
}
this.resetAnimationState();
};
The problem is that the animation works only once. I noticed that despite calling resetAnimationState, the animation remains in the computed style in Cobalt's debugger. If someone from the Cobalt team could take a look at my approach and possibly provide some advice, I would be very grateful.
Thank you for any suggestions and help!