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
}
type alias Model =
Int
init : ( Model, Cmd Msg )
init =
( 0, Cmd.none )
type Msg
= Tick Time
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
Tick index ->
( (model + 1) % 4, Cmd.none )
subscriptions : Model -> Sub Msg
subscriptions model =
Time.every (millisecond * 1500) Tick
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 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)
}
}
visit this implementation
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
visit this implementation
The same file in an es6 implementation using Cyclow (0.3.0):
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
visit this implementation
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
visit this implementation
The same file in a vanilla implementation using Preact (5.7.0):
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
visit this implementation
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
visit this implementation
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
visit this implementation
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)
}
})
visit this implementation