Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 35 additions & 2 deletions src/core/elementNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
type AnimationSettings,
type ElementText,
type Styles,
type AnimationEvents,
type AnimationEventHandler,
AddColorString,
TextProps,
type OnEvent,
Expand Down Expand Up @@ -676,7 +678,18 @@ export interface ElementNode extends RendererNode, FocusNode {
| Record<string, AnimationSettings | undefined | true | false>
| true
| false;

/**
* Optional handlers for animation events.
*
* Available animation events:
* - 'animating': Fired when the animation starts.
* - 'stopped': Fired (via setTimeout for the animation duration) when the animation completes.
*
* Each event handler is optional and maps to a corresponding event.
*
* @see https://lightning-tv.github.io/solid/#/essentials/transitions?id=animation-callbacks
*/
onAnimation?: Partial<Record<AnimationEvents, AnimationEventHandler>>;
/** Optional handler for when the element is created and rendered.
*
* @see https://lightning-tv.github.io/solid/#/flow/ondestroy
Expand Down Expand Up @@ -980,20 +993,40 @@ export class ElementNode {
{ [name]: value },
animationSettings,
);
this._fireAnimationEvents(name, value, animationSettings);
return animationController.start();
}

return (this.lng as any).animateProp(
const result = (this.lng as any).animateProp(
name,
value,
animationSettings || this.animationSettings || {},
);
this._fireAnimationEvents(name, value, animationSettings);
return result;
}

(this.lng[name as keyof (IRendererNode | INode)] as number | string) =
value;
}

_fireAnimationEvents(
name: string,
value: number,
animationSettings?: AnimationSettings,
) {
if (!this.onAnimation) return;
const settings = animationSettings || this.animationSettings;
const { animating, stopped } = this.onAnimation;
if (animating) {
animating.call(this, name, value);
}
if (stopped) {
const total = (settings?.duration ?? 0) + (settings?.delay ?? 0);
setTimeout(() => stopped.call(this, name, value), total);
}
}

animate(
props: Partial<INodeAnimateProps<CoreShaderNode>>,
animationSettings?: AnimationSettings,
Expand Down
7 changes: 7 additions & 0 deletions src/core/intrinsicTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,13 @@ export interface IntrinsicNodeProps extends NodeProps {}
export interface IntrinsicNodeStyleProps extends NodeStyles {}
export interface IntrinsicTextNodeStyleProps extends TextStyles {}

export type AnimationEvents = 'animating' | 'stopped';
export type AnimationEventHandler = (
this: ElementNode,
name: string,
endValue: number,
) => void;

type EventPayloadMap = {
loaded: lngr.NodeLoadedPayload;
failed: lngr.NodeFailedPayload;
Expand Down
Loading