JSFiddle - React, Tailwind, and code Playground

by Marty Nelson

HTML

<script id='template' type='text/html'>
	<h1>Sprite Things</h1>
	
	{{#each sprites}}
		<Sprite options='{{this}}'></Sprite>
	{{/each}}
</script>

JavaScript

var repeater = [
    {id: "stalkerOne", width: 225, height: 432, left: 8, spriteSheetURL: "spriteSheets/stalkerone.jpg", rows: 5, columns: 5, totalFrames:  24},
    {id: "stalkerTwo", width: 175, height: 432, left: 230, spriteSheetURL: "spriteSheets/stalkertwo.jpg", rows: 6, columns: 5, totalFrames:  26},
    {id: "stalkerThree", width: 251, height: 432, left: 404, spriteSheetURL: "spriteSheets/stalkerthree.jpg", rows: 6, columns: 5, totalFrames:  28}
]

class CanvasSprite {
	constructor( options ) {
		this.id = options.id;
		this.height = options.height;
		// ...
	}
	
	setFrame( frame ) {
		console.log( 'sprite', this.id, 'set frame', frame );
	}
}

var CanvasAnimation = Ractive.extend( {
    oninit() {
        var sprites = this.get('repeaters').map( repeater => new CanvasSprite(repeater) );
		this.set( 'sprites', sprites );
    }
});    

var Sprite = Ractive.extend({
	template: `<li on-click='setFrame'>{{sprite.id}}</li>`,
	oninit() {
	    const sprite = new CanvasSprite( this.get( 'options' ) );

		// since example template is using properties from sprite,
		// we add it to the data
		this.set( 'sprite',  sprite );
		
		this.on('setFrame', function (event) {
            var offsetY = event.original.clientY - event.node.getBoundingClientRect().top;
            var relY = offsetY/sprite.height;
            sprite.setFrame(relY);
        });
	},
	onrender() {
		this.get( 'sprite' ).setFrame(0);
	}
});

var canvasAnimation = new CanvasAnimation({
    el: document.body,
    template: '#template',
    data: { repeaters: repeater },
	components: { Sprite }
});