JSFiddle - React, Tailwind, and code Playground
by rich_harris
HTML
<main></main>
<script id='template' type='text/ractive'>
<label>
<input type='range' min='0' max='999' value='{{value}}'/>
{{value}}
</label>
<label>
<input type='number' min='0' max='999' value='{{value}}'/>
{{value}}
</label>
<odometer value='{{value}}'/>
</script>
<script id='odometer' type='text/ractive'>
<wheel value='{{hundreds}}'/>
<wheel value='{{tens}}'/>
<wheel value='{{units}}'/>
</script>
<script id='wheel' type='text/ractive'>
<div class='viewport'>
<div class='digits' style='top: -{{offset}}%;'>
<span>9</span>
<span>8</span>
<span>7</span>
<span>6</span>
<span>5</span>
<span>4</span>
<span>3</span>
<span>2</span>
<span>1</span>
<span>0</span>
</div>
</div>
</script>
CSS
body {
font-family: 'Helvetica Neue', arial, sans-serif;
font-weight: 200;
color: #353535;
}
h1, h2, h3, h4, h5, h6 {
font-weight: 200;
}
.error {
color: #d00;
font-family: monospace;
}
label {
display: block;
margin: 0 0 1em 0;
font-family: inherit;
font-size: inherit;
}
.viewport {
display: inline-block;
position: relative;
width: 50px;
height: 50px;
overflow: hidden;
}
.viewport > div {
position: absolute;
top: 0;
}
.digits {
width: 50px;
height: 500px;
}
.digits span {
display: block;
width: 50px;
height: 50px;
background-color: #333;
color: white;
font-family: monospace;
font-size: 4em;
line-height: 1;
text-align: center;
}
JavaScript
var Odometer = Ractive.extend({
template: '#odometer',
computed: {
hundreds: '~~(${value}/100)',
tens: '~~((${value}%100)/10)',
units: '${value}%10'
}
});
var Wheel = Ractive.extend({
template: '#wheel',
oninit: function () {
this.observe( 'value', function ( value ) {
var offset = this.getOffset( value );
this.animate( 'offset', offset, {
duration: 200 + Math.random() * 400,
easing: 'easeInOut'
});
}, { init: false });
this.set( 'offset', this.getOffset( this.get( 'value' ) ) );
},
getOffset: function ( value ) {
return 100 * ( 9 - value );
}
});
Ractive.components.odometer = Odometer;
Ractive.components.wheel = Wheel;
var ractive = new Ractive({
el: 'main',
template: '#template',
data: {
value: 123
}
});