JSFiddle - React, Tailwind, and code Playground

by Andreas Renberg

HTML

<canvas id='canvas' width='400' height='100'></canvas>
Right click the canvas and choose "Save Image As..."

CSS

#canvas {
    border:1px solid #000000;
}

JavaScript

Math.TAU = Math.PI * 2;

// The sprite may rotate to overlap the edges.
// If this happens, please shrink it down in an external image editor.
// Will rotate around the center of the graphic
var src = 'http://www.zeldauniverse.net/wp-content/uploads/2009/12/Cow1.png';
var width = 100;
var height = 100;
var startRotation = 0;
var endRotation = Math.TAU; // not inclusive
var numRotations = 8;

var img = new Image();
img.onload = bakeRotations;
img.width = width;
img.height = height;
img.src = src;

var canvas = document.querySelector('#canvas');
canvas.width = width * numRotations;
canvas.height = height;
var context = canvas.getContext('2d');
function bakeRotations(event) {
    for (var i = 0; i < numRotations; i++) {
        var angle = (endRotation - startRotation) * (i/numRotations);
        var x = width * i;
        var y = 0;
        
        context.drawRotatedImage(img, x, y, width, height, angle, width/2, height/2);
    }
}

CanvasRenderingContext2D.prototype.drawRotatedImage = function(image, x, y, width, height, angle, originX, originY) {
    if (width === undefined)   { width = image.width; }
    if (height === undefined)  { height = image.height; }
    if (angle === undefined)   { angle = 0; }
    if (originX === undefined) { originX = 0; }
    if (originY === undefined) { originY = 0; }
    var cos = Math.cos(angle);
    var sin = Math.sin(angle);
    
    context.setTransform(cos, sin, -sin, cos, x+originX, y+originY);
    this.drawImage(image, -originX, -originY, width, height);
    this.resetTransform();
}

CanvasRenderingContext2D.prototype.resetTransform = function() {
	this.setTransform(1, 0, 0, 1, 0, 0);
}