Cobalt Animations

37 views
Skip to first unread message

Michał Szczeciński

unread,
Jun 6, 2024, 1:22:27 AM6/6/24
to cobalt-dev

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:

typescript
Skopiuj kod
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:

typescript
Skopiuj kod
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:

typescript
Skopiuj kod
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!

Reply all
Reply to author
Forward
0 new messages