import {Block} from 'cyclow'
import {Ticker} from 'graflow'
import {lyrics} from '../../../lyrics'
const Singer = () => Block({
components: {ticker: Ticker(1500, {initialDelay: true})},
events: {
init: () => [['state', pos => 0], 'ticker'],
ticker: () => pos => (pos + 1) % lyrics.length
},
view: pos => ({content: lyrics[pos]})
})
export default Singer
The same file in an es6-iterator implementation using Cyclow (0.3.0):
import {Block} from 'cyclow'
import {Ticker, Iterator, Chain} from 'graflow'
import {lyrics} from '../../../lyrics'
const Singer = () => Block({
components: {
lineTicker: Chain(Ticker(1500), Iterator(lyrics, {cyclic: true}))
},
events: {
init: () => 'lineTicker',
lineTicker: line => text => line
},
view: text => ({content: text})
})
export default Singer
The same file in a TypeScript implementation using Angular (2.4.9):
import {Component, AfterViewInit} from '@angular/core';
import {lyrics} from '../../../lyrics'
@Component({
selector: '#app',
template: `{{line}}`
})
export class Singer implements AfterViewInit {
pos = 0
get line() {
return lyrics[this.pos]
}
ngAfterViewInit() {
setInterval(()=> this.pos = (this.pos+1)%4, 1500)
}
}
The same file in an xstream, driver implementation using CycleJS (12.2.2):
import {div} from '@cycle/dom'
function Singer ({line$}) {
return {
DOM: line$.map(line => div(line))
}
}
export default Singer
The same file in an xstream implementation using CycleJS (12.2.2):
import xs from 'xstream'
import {div} from '@cycle/dom'
import {lyrics} from '../../../lyrics'
function Singer (sources) {
let song$ = xs.periodic(1500).startWith(-1).map(
n => lyrics[(n + 1) % lyrics.length]
)
return {
DOM: song$.map(line => div(line))
}
}
export default Singer
The same file in a react-elm-comps implementation using Elm (0.17.1):
port module Singer exposing (main)
import Html exposing (Html, Attribute, div, input, text, button, p)
import Html.App as App
import Array exposing (..)
import Time exposing (Time, millisecond)
import Maybe exposing (withDefault)
main =
App.program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
-- MODEL
type alias Model =
Int
init : ( Model, Cmd Msg )
init =
( 0, Cmd.none )
-- UPDATE
type Msg
= Tick Time
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Tick index ->
( (model + 1) % 4, Cmd.none )
-- SUBSCRIPTIONS
subscriptions : Model -> Sub Msg
subscriptions model =
Time.every (millisecond * 1500) Tick
-- VIEW
lyrics : Array String
lyrics =
Array.fromList [ "Eeexiiit light", "Eeenteeer niight", "Taaake my haaand", "We're off to never never land" ]
getLyricPart : Array String -> Int -> String
getLyricPart lyricsArray index =
withDefault "" (get index lyricsArray)
view : Int -> Html a
view model =
div [] [ text (getLyricPart lyrics model) ]
The same file in a vanilla implementation using Preact (5.7.0):
/** @jsx h */
import { h, Component } from 'preact'
import {lyrics} from '../../../lyrics'
class Singer extends Component {
constructor () {
super()
this.state.pos = 0
setInterval(() => this.setState({
pos: (this.state.pos + 1) % lyrics.length
}), 1500)
}
render () {
return <div>{lyrics[this.state.pos]}</div>
}
}
export default Singer
The same file in a createClass implementation using React (15.3.1):
import React from 'react'
import {lyrics} from '../../../lyrics'
let Singer = React.createClass({
getInitialState: () => ({pos: 0}),
componentDidMount () {
setInterval(() => this.setState({
pos: (this.state.pos + 1) % lyrics.length
}), 1500)
},
render () {
return <div>{lyrics[this.state.pos]}</div>
}
})
export default Singer
The same file in an es6 class implementation using React (15.3.1):
import React from 'react'
import {lyrics} from '../../../lyrics'
class Singer extends React.Component {
constructor () {
super()
this.state = {pos: 0}
setInterval(() => this.setState({
pos: (this.state.pos + 1) % lyrics.length
}), 1500)
}
render () {
return <div>{lyrics[this.state.pos]}</div>
}
}
export default Singer
The same file in a vanilla implementation using Vue (1.0.26):
import Vue from 'vue'
import {lyrics} from '../../../lyrics'
Vue.component('singer', {
template: `<p>{{line}}</p>`,
data: () => ({pos: 0}),
computed: {
line () {
return lyrics[this.pos]
}
},
attached (arg) {
setInterval(() => this.$set(
'pos', (this.pos + 1) % lyrics.length
), 1500)
}
})