Skip to content

Instantly share code, notes, and snippets.

@jdnichollsc
Last active February 16, 2022 09:10
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save jdnichollsc/cecb152ecdd41e2a3733a3dfe03f0ce3 to your computer and use it in GitHub Desktop.
Save jdnichollsc/cecb152ecdd41e2a3733a3dfe03f0ce3 to your computer and use it in GitHub Desktop.
Animatable Components using Higher Order Component (HOC) with StencilJS πŸ™Œ - https://proyecto26.github.io/animatable-component
<animatable-component
autoplay
easing="ease-in-out"
duration="800"
delay="300"
animation="zoomIn"
iterations="Infinity"
direction="alternate"
>
<h1>Hello World</h1>
</animatable-component>
import { Component, h, Element, Prop, Host, Event, EventEmitter } from '@stencil/core';
@Component({
tag: 'animatable-component'
})
export class AnimatableComponent {
@Element() el!: HTMLElement;
@Prop() keyFrames: Keyframe[]
@Prop() options: KeyframeAnimationOptions
@Event() finish: EventEmitter;
animateComponent() {
const element = this.el.querySelectorAll(':first-child')[0];
const animation = element.animate(this.keyFrames, this.options)
animation.play();
animation.onfinish = () => this.finish.emit(element)
}
componentWillLoad() {
this.animateComponent()
}
componentDidUpdate() {
this.animateComponent()
}
render() {
return <Host>
<slot />
</Host>
}
}
import { Component, h } from '@stencil/core';
import {
SendMessageButton,
createAnimatableComponent,
keyFramesSendMessage,
optionsSendMessage,
} from './utils'
const AnimatableSendMessageButton = createAnimatableComponent(SendMessageButton)
@Component({
tag: 'my-animated-component'
})
export class MyAnimatedComponent {
render() {
return (
<AnimatableSendMessageButton
keyFrames={keyFramesSendMessage}
options={optionsSendMessage}
onClick={() => alert('Eureka')}
/>
)
}
}
export function createAnimatableComponent (
WrappedComponent: FunctionalComponent
) {
return (props) => {
const { keyFrames, options, onFinish, ...rest } = props
return (
<animatable-component
keyFrames={keyFrames}
options={options}
onFinish={onFinish}
>
<WrappedComponent {...rest} />
</animatable-component>
)
}
};
export const SendMessageButton = (props) => {
return (
<ion-fab-button {...props}>
<ion-icon name='send' />
</ion-fab-button>
)
}
export const keyFramesSendMessage: Keyframe[] = [
{
opacity: '0',
transform: 'rotate(0deg)'
},
{
opacity: '1',
transform: 'rotate(360deg)'
}
]
export const optionsSendMessage: KeyframeAnimationOptions = {
duration: 500,
easing: 'ease-in-out'
}
@bitflower
Copy link

That looks beautiful, gotta try!

@jdnichollsc
Copy link
Author

jdnichollsc commented Oct 30, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment