JSFiddle - React, Tailwind, and code Playground
by rich_harris
HTML
<main></main>
<script id='template' type='text/html'>
<label><input type='range' min=1 max=100 value='{{major}}'>major: {{major}}</label>
<label><input type='range' min=0 max=1 step='0.01' value='{{minor}}'>minor: {{minor}}</label>
<label><input type='range' min=1 max=50 value='{{numPoints}}'>numPoints: {{numPoints}}</label>
<p>{{pathData}}</p>
<svg width='500' height='500'>
<g transform='scale(5) translate(50,50)'>
<Star numPoints='{{numPoints}}' minor='{{minor}}' major='{{major}}'/>
</g>
</svg>
</script>
CSS
body {
font-family: 'Helvetica Neue', arial, sans-serif;
font-weight: 200;
color: #353535;
}
h1, h2, h3, h4, h5, h6 {
font-weight: 200;
}
label {
display: block;
}
.error {
color: #d00;
font-family: monospace;
}
Babel + JSX
Ractive.components.Star = Ractive.extend({
template: `<path d='M{{points.join("L")}}Z'/>`,
css: `path { fill: #eee; stroke: black; }`,
computed: {
outerPoints () {
const radius = this.get( 'major' );
const numPoints = this.get( 'numPoints' );
let points = [];
for ( let i = 0; i < numPoints; i += 1 ) {
var angle = i * Math.PI * 2 / numPoints;
var x = Math.sin( angle ) * radius;
var y = -Math.cos( angle ) * radius;
points.push( `${x.toFixed(2)},${y.toFixed(2)}` );
}
return points;
},
innerPoints () {
const radius = this.get( 'minor' ) * this.get( 'major' );
const numPoints = this.get( 'numPoints' );
let points = [];
for ( let i = 0; i < numPoints; i += 1 ) {
var angle = ( i + 0.5 ) * Math.PI * 2 / numPoints;
var x = Math.sin( angle ) * radius;
var y = -Math.cos( angle ) * radius;
points.push( `${x.toFixed(2)},${y.toFixed(2)}` );
}
return points;
},
points () {
const outerPoints = this.get( 'outerPoints' );
const innerPoints = this.get( 'innerPoints' );
let merged = [];
outerPoints.forEach( ( outer, i ) => {
merged.push( outer, innerPoints[i] );
});
merged.push( outerPoints[0] );
return merged;
}
}
});
var ractive = new Ractive({
el: 'main',
template: '#template',
data: {
minor: 0.4,
major: 5,
numPoints: 5,
pathData: ''
}
});
ractive.findComponent( 'Star' ).observe( 'points', points => {
ractive.set( 'pathData', `M${points.join('L')}Z` );
});