Skip to content

Instantly share code, notes, and snippets.

@kevinresol
Last active April 8, 2021 12:17
Show Gist options
  • Save kevinresol/f501081ca667b8bbdbd103f4cd833a67 to your computer and use it in GitHub Desktop.
Save kevinresol/f501081ca667b8bbdbd103f4cd833a67 to your computer and use it in GitHub Desktop.
Coconut Animation
import haxe.Timer;
import tink.state.Observable;
import coconut.ui.View;
import coconut.ui.RenderResult;
import coconut.ui.Renderer;
import tink.pure.List;
using tink.CoreApi;
typedef Data = {
final text:String;
final hidden:Bool;
}
class Main extends View {
static function main() {
Renderer.mount(js.Browser.document.getElementById('app'), '<Main/>');
}
@:state var list:List<Data> = [for(i in 0...3) {text: '$i', hidden: false}];
function render() '
<>
<for ${v in list}>
<Hideable
key=${v.text}
hidden=${v.hidden}
renderChildren=${style -> (<div style=${{width: '100px', height: '100px', border: 'solid 2px black', opacity: style.opacity}}>${v.text}</div>)}
// onAnimationEnd=${hidden -> if(hidden) list = list.filter(i -> i != v)}
/>
<button onClick=${() -> list = list.replace(v, {text: v.text, hidden: !v.hidden})}>${!v.hidden ? 'Hide Me' : 'Unhide Me'}</button>
</for>
</>
';
}
class Hideable extends View {
@:attr var hidden:Bool = false;
@:attr var onAnimationEnd:(hidden:Bool)->Void = null;
@:attr var renderChildren:(style:{opacity:String})->RenderResult;
@:state var opacity:Float = 1;
@:computed var shouldRender:Bool = opacity > 0;
var timer:Timer;
function render() return shouldRender ? renderChildren({opacity: '$opacity'}) : null;
function viewDidMount() {
untilUnmounted(Observable.auto(() -> hidden).bind(_ -> startAnimation()));
}
function startAnimation() {
if(timer != null)
timer.stop();
timer = new Timer(20);
timer.run = function() {
opacity += hidden ? -0.01 : 0.01;
if(hidden ? opacity <= 0 : opacity >= 1) {
timer.stop();
timer = null;
switch onAnimationEnd {
case null:
case f: f(hidden);
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment