JSFiddle - React, Tailwind, and code Playground

by chriswilsondc

JavaScript

Raphael.fn.rosetta = function(x,y,length,breadth,N) {
    if (N == 0) {
        console.log("no dividing by zero please"); return;
    }
    var angle = 360 / N; // negative values of N are fine
    var path = "M" + x + "," + y;
    
    for (var c = 0; c < N; c += 1) {
        // need angle for each leaf of rosetta in radians
        var theta = angle * c * Math.PI / 18;

        // coords of farthest point from center for this leaf
        var dx = 2 * length * Math.cos(theta),
            dy = 2 * breadth * Math.sin(theta);

        // we'll draw the leaf in two parts
        path += "a" + length + "," + breadth + " " + angle*c + " 1,1 " + dx + "," + dy;
        path += "A" + length + "," + breadth + " " + angle*c + " 1,1 " + x + "," + y;
    }
    var rosetta = paper.path(path);    
    return rosetta;
}
var paper = Raphael(0, 0, 500, 500);

var rosetta = paper.rosetta(200, 200, 55, 35, 6);

paper.customAttributes.along = function (v) {
    var len = rosetta.getTotalLength();
    var point = rosetta.getPointAtLength(v * len);
    
    return {
        transform: "t" + [point.x, point.y] + "r" + point.alpha
    };
};

var circle = paper.circle(0, 0, 10).attr({
    fill: 'red',
    along: 0
});

circle.animate({ along: 1 }, 10000);